Add Chromium-only Blender WebEngine parity work
This commit is contained in:
26
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/AUTHORS
vendored
Normal file
26
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/AUTHORS
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
The main developers of release series 1.x are
|
||||
|
||||
* Balazs Dezso <deba@inf.elte.hu>
|
||||
* Alpar Juttner <alpar@cs.elte.hu>
|
||||
* Peter Kovacs <kpeter@inf.elte.hu>
|
||||
* Akos Ladanyi <ladanyi@tmit.bme.hu>
|
||||
|
||||
For more complete list of contributors, please visit the history of
|
||||
the LEMON source code repository: http://lemon.cs.elte.hu/hg/lemon
|
||||
|
||||
Moreover, this version is heavily based on version 0.x of LEMON. Here
|
||||
is the list of people who contributed to those versions.
|
||||
|
||||
* Mihaly Barasz <klao@cs.elte.hu>
|
||||
* Johanna Becker <beckerjc@cs.elte.hu>
|
||||
* Attila Bernath <athos@cs.elte.hu>
|
||||
* Balazs Dezso <deba@inf.elte.hu>
|
||||
* Peter Hegyi <hegyi@tmit.bme.hu>
|
||||
* Alpar Juttner <alpar@cs.elte.hu>
|
||||
* Peter Kovacs <kpeter@inf.elte.hu>
|
||||
* Akos Ladanyi <ladanyi@tmit.bme.hu>
|
||||
* Marton Makai <marci@cs.elte.hu>
|
||||
* Jacint Szabo <jacint@cs.elte.hu>
|
||||
|
||||
Again, please visit the history of the old LEMON repository for more
|
||||
details: http://lemon.cs.elte.hu/hg/lemon-0.x
|
||||
373
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/CMakeLists.txt
vendored
Normal file
373
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,373 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
|
||||
|
||||
SET(PROJECT_NAME "LEMON")
|
||||
PROJECT(${PROJECT_NAME})
|
||||
|
||||
INCLUDE(FindPythonInterp)
|
||||
INCLUDE(FindWget)
|
||||
|
||||
IF(EXISTS ${PROJECT_SOURCE_DIR}/cmake/version.cmake)
|
||||
INCLUDE(${PROJECT_SOURCE_DIR}/cmake/version.cmake)
|
||||
ELSEIF(DEFINED ENV{LEMON_VERSION})
|
||||
SET(LEMON_VERSION $ENV{LEMON_VERSION} CACHE STRING "LEMON version string.")
|
||||
ELSE()
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND
|
||||
hg log -r. --template "{latesttag}"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE HG_REVISION_TAG
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND
|
||||
hg log -r. --template "{latesttagdistance}"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE HG_REVISION_DIST
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND
|
||||
hg log -r. --template "{node|short}"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE HG_REVISION_ID
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
IF(HG_REVISION_TAG STREQUAL "")
|
||||
SET(HG_REVISION_ID "hg-tip")
|
||||
ELSE()
|
||||
IF(HG_REVISION_TAG STREQUAL "null")
|
||||
SET(HG_REVISION_TAG "trunk")
|
||||
ELSEIF(HG_REVISION_TAG MATCHES "^r")
|
||||
STRING(SUBSTRING ${HG_REVISION_TAG} 1 -1 HG_REVISION_TAG)
|
||||
ENDIF()
|
||||
IF(HG_REVISION_DIST STREQUAL "0")
|
||||
SET(HG_REVISION ${HG_REVISION_TAG})
|
||||
ELSE()
|
||||
SET(HG_REVISION
|
||||
"${HG_REVISION_TAG}+${HG_REVISION_DIST}-${HG_REVISION_ID}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
SET(LEMON_VERSION ${HG_REVISION} CACHE STRING "LEMON version string.")
|
||||
ENDIF()
|
||||
|
||||
SET(PROJECT_VERSION ${LEMON_VERSION})
|
||||
|
||||
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
FIND_PACKAGE(Doxygen)
|
||||
FIND_PACKAGE(Ghostscript)
|
||||
|
||||
SET(LEMON_ENABLE_GLPK YES CACHE STRING "Enable GLPK solver backend.")
|
||||
SET(LEMON_ENABLE_ILOG YES CACHE STRING "Enable ILOG (CPLEX) solver backend.")
|
||||
SET(LEMON_ENABLE_COIN YES CACHE STRING "Enable COIN solver backend.")
|
||||
SET(LEMON_ENABLE_SOPLEX YES CACHE STRING "Enable SoPlex solver backend.")
|
||||
|
||||
IF(LEMON_ENABLE_GLPK)
|
||||
FIND_PACKAGE(GLPK 4.33)
|
||||
ENDIF(LEMON_ENABLE_GLPK)
|
||||
IF(LEMON_ENABLE_ILOG)
|
||||
FIND_PACKAGE(ILOG)
|
||||
ENDIF(LEMON_ENABLE_ILOG)
|
||||
IF(LEMON_ENABLE_COIN)
|
||||
FIND_PACKAGE(COIN)
|
||||
ENDIF(LEMON_ENABLE_COIN)
|
||||
IF(LEMON_ENABLE_SOPLEX)
|
||||
FIND_PACKAGE(SOPLEX)
|
||||
ENDIF(LEMON_ENABLE_SOPLEX)
|
||||
|
||||
IF(GLPK_FOUND)
|
||||
SET(LEMON_HAVE_LP TRUE)
|
||||
SET(LEMON_HAVE_MIP TRUE)
|
||||
SET(LEMON_HAVE_GLPK TRUE)
|
||||
ENDIF(GLPK_FOUND)
|
||||
IF(ILOG_FOUND)
|
||||
SET(LEMON_HAVE_LP TRUE)
|
||||
SET(LEMON_HAVE_MIP TRUE)
|
||||
SET(LEMON_HAVE_CPLEX TRUE)
|
||||
ENDIF(ILOG_FOUND)
|
||||
IF(COIN_FOUND)
|
||||
SET(LEMON_HAVE_LP TRUE)
|
||||
SET(LEMON_HAVE_MIP TRUE)
|
||||
SET(LEMON_HAVE_CLP TRUE)
|
||||
SET(LEMON_HAVE_CBC TRUE)
|
||||
ENDIF(COIN_FOUND)
|
||||
IF(SOPLEX_FOUND)
|
||||
SET(LEMON_HAVE_LP TRUE)
|
||||
SET(LEMON_HAVE_SOPLEX TRUE)
|
||||
ENDIF(SOPLEX_FOUND)
|
||||
|
||||
IF(ILOG_FOUND)
|
||||
SET(DEFAULT_LP "CPLEX")
|
||||
SET(DEFAULT_MIP "CPLEX")
|
||||
ELSEIF(COIN_FOUND)
|
||||
SET(DEFAULT_LP "CLP")
|
||||
SET(DEFAULT_MIP "CBC")
|
||||
ELSEIF(GLPK_FOUND)
|
||||
SET(DEFAULT_LP "GLPK")
|
||||
SET(DEFAULT_MIP "GLPK")
|
||||
ELSEIF(SOPLEX_FOUND)
|
||||
SET(DEFAULT_LP "SOPLEX")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT LEMON_DEFAULT_LP OR
|
||||
(NOT ILOG_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CPLEX")) OR
|
||||
(NOT COIN_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CLP")) OR
|
||||
(NOT GLPK_FOUND AND (LEMON_DEFAULT_LP STREQUAL "GLPK")) OR
|
||||
(NOT SOPLEX_FOUND AND (LEMON_DEFAULT_LP STREQUAL "SOPLEX")))
|
||||
SET(LEMON_DEFAULT_LP ${DEFAULT_LP} CACHE STRING
|
||||
"Default LP solver backend (GLPK, CPLEX, CLP or SOPLEX)" FORCE)
|
||||
ELSE()
|
||||
SET(LEMON_DEFAULT_LP ${DEFAULT_LP} CACHE STRING
|
||||
"Default LP solver backend (GLPK, CPLEX, CLP or SOPLEX)")
|
||||
ENDIF()
|
||||
IF(NOT LEMON_DEFAULT_MIP OR
|
||||
(NOT ILOG_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CPLEX")) OR
|
||||
(NOT COIN_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CBC")) OR
|
||||
(NOT GLPK_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "GLPK")))
|
||||
SET(LEMON_DEFAULT_MIP ${DEFAULT_MIP} CACHE STRING
|
||||
"Default MIP solver backend (GLPK, CPLEX or CBC)" FORCE)
|
||||
ELSE()
|
||||
SET(LEMON_DEFAULT_MIP ${DEFAULT_MIP} CACHE STRING
|
||||
"Default MIP solver backend (GLPK, CPLEX or CBC)")
|
||||
ENDIF()
|
||||
|
||||
|
||||
IF(DEFINED ENV{LEMON_CXX_WARNING})
|
||||
SET(CXX_WARNING $ENV{LEMON_CXX_WARNING})
|
||||
ELSE()
|
||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
SET(CXX_WARNING "-Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG CACHE STRING "-ggdb")
|
||||
SET(CMAKE_C_FLAGS_DEBUG CACHE STRING "-ggdb")
|
||||
ELSEIF(MSVC)
|
||||
# This part is unnecessary 'cause the same is set by the lemon/core.h.
|
||||
# Still keep it as an example.
|
||||
SET(CXX_WARNING "/wd4250 /wd4355 /wd4503 /wd4800 /wd4996")
|
||||
# Suppressed warnings:
|
||||
# C4250: 'class1' : inherits 'class2::member' via dominance
|
||||
# C4355: 'this' : used in base member initializer list
|
||||
# C4503: 'function' : decorated name length exceeded, name was truncated
|
||||
# C4800: 'type' : forcing value to bool 'true' or 'false'
|
||||
# (performance warning)
|
||||
# C4996: 'function': was declared deprecated
|
||||
ELSE()
|
||||
SET(CXX_WARNING "-Wall")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
SET(LEMON_CXX_WARNING_FLAGS ${CXX_WARNING} CACHE STRING "LEMON warning flags.")
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LEMON_CXX_WARNING_FLAGS}")
|
||||
|
||||
IF(MSVC)
|
||||
SET( CMAKE_CXX_FLAGS_MAINTAINER "/WX ${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING
|
||||
"Flags used by the C++ compiler during maintainer builds."
|
||||
)
|
||||
SET( CMAKE_C_FLAGS_MAINTAINER "/WX ${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING
|
||||
"Flags used by the C compiler during maintainer builds."
|
||||
)
|
||||
SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
|
||||
"${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING
|
||||
"Flags used for linking binaries during maintainer builds."
|
||||
)
|
||||
SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
|
||||
"${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING
|
||||
"Flags used by the shared libraries linker during maintainer builds."
|
||||
)
|
||||
ELSE()
|
||||
SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb -O0" CACHE STRING
|
||||
"Flags used by the C++ compiler during maintainer builds."
|
||||
)
|
||||
SET( CMAKE_C_FLAGS_MAINTAINER "-Werror -O0" CACHE STRING
|
||||
"Flags used by the C compiler during maintainer builds."
|
||||
)
|
||||
SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
|
||||
"${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING
|
||||
"Flags used for linking binaries during maintainer builds."
|
||||
)
|
||||
SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
|
||||
"${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING
|
||||
"Flags used by the shared libraries linker during maintainer builds."
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
CMAKE_CXX_FLAGS_MAINTAINER
|
||||
CMAKE_C_FLAGS_MAINTAINER
|
||||
CMAKE_EXE_LINKER_FLAGS_MAINTAINER
|
||||
CMAKE_SHARED_LINKER_FLAGS_MAINTAINER )
|
||||
|
||||
IF(CMAKE_CONFIGURATION_TYPES)
|
||||
LIST(APPEND CMAKE_CONFIGURATION_TYPES Maintainer)
|
||||
LIST(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
|
||||
SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
|
||||
"Add the configurations that we need"
|
||||
FORCE)
|
||||
endif()
|
||||
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE "Release")
|
||||
ENDIF()
|
||||
|
||||
SET( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
|
||||
"Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel Maintainer."
|
||||
FORCE )
|
||||
|
||||
|
||||
INCLUDE(CheckTypeSize)
|
||||
CHECK_TYPE_SIZE("long long" LONG_LONG)
|
||||
SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
|
||||
|
||||
INCLUDE(FindThreads)
|
||||
|
||||
IF(NOT LEMON_THREADING)
|
||||
IF(CMAKE_USE_PTHREADS_INIT)
|
||||
SET(LEMON_THREADING "Pthread")
|
||||
ELSEIF(CMAKE_USE_WIN32_THREADS_INIT)
|
||||
SET(LEMON_THREADING "Win32")
|
||||
ELSE()
|
||||
SET(LEMON_THREADING "None")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
SET( LEMON_THREADING "${LEMON_THREADING}" CACHE STRING
|
||||
"Choose the threading library, options are: Pthread Win32 None."
|
||||
FORCE )
|
||||
|
||||
IF(LEMON_THREADING STREQUAL "Pthread")
|
||||
SET(LEMON_USE_PTHREAD TRUE)
|
||||
ELSEIF(LEMON_THREADING STREQUAL "Win32")
|
||||
SET(LEMON_USE_WIN32_THREADS TRUE)
|
||||
ENDIF()
|
||||
|
||||
ENABLE_TESTING()
|
||||
|
||||
IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
|
||||
ADD_CUSTOM_TARGET(check ALL COMMAND ${CMAKE_CTEST_COMMAND})
|
||||
ELSE()
|
||||
ADD_CUSTOM_TARGET(check COMMAND ${CMAKE_CTEST_COMMAND})
|
||||
ENDIF()
|
||||
|
||||
ADD_SUBDIRECTORY(lemon)
|
||||
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
|
||||
ADD_SUBDIRECTORY(contrib)
|
||||
ADD_SUBDIRECTORY(demo)
|
||||
ADD_SUBDIRECTORY(tools)
|
||||
ADD_SUBDIRECTORY(doc)
|
||||
ADD_SUBDIRECTORY(test)
|
||||
ENDIF()
|
||||
|
||||
CONFIGURE_FILE(
|
||||
${PROJECT_SOURCE_DIR}/cmake/LEMONConfig.cmake.in
|
||||
${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
|
||||
@ONLY
|
||||
)
|
||||
IF(UNIX)
|
||||
INSTALL(
|
||||
FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
|
||||
DESTINATION share/lemon/cmake
|
||||
)
|
||||
ELSEIF(WIN32)
|
||||
INSTALL(
|
||||
FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
|
||||
DESTINATION cmake
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
CONFIGURE_FILE(
|
||||
${PROJECT_SOURCE_DIR}/cmake/version.cmake.in
|
||||
${PROJECT_BINARY_DIR}/cmake/version.cmake
|
||||
@ONLY
|
||||
)
|
||||
|
||||
SET(ARCHIVE_BASE_NAME ${CMAKE_PROJECT_NAME})
|
||||
STRING(TOLOWER ${ARCHIVE_BASE_NAME} ARCHIVE_BASE_NAME)
|
||||
SET(ARCHIVE_NAME ${ARCHIVE_BASE_NAME}-${PROJECT_VERSION})
|
||||
ADD_CUSTOM_TARGET(dist
|
||||
COMMAND cmake -E remove_directory ${ARCHIVE_NAME}
|
||||
COMMAND hg archive ${ARCHIVE_NAME}
|
||||
COMMAND cmake -E copy cmake/version.cmake ${ARCHIVE_NAME}/cmake/version.cmake
|
||||
COMMAND tar -czf ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_NAME}
|
||||
COMMAND zip -r ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.zip ${ARCHIVE_NAME}
|
||||
COMMAND cmake -E copy_directory doc/html ${ARCHIVE_NAME}/doc/html
|
||||
COMMAND tar -czf ${ARCHIVE_NAME}.tar.gz ${ARCHIVE_NAME}
|
||||
COMMAND zip -r ${ARCHIVE_NAME}.zip ${ARCHIVE_NAME}
|
||||
COMMAND cmake -E copy_directory doc/html ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
|
||||
COMMAND tar -czf ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
|
||||
COMMAND zip -r ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.zip ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
|
||||
COMMAND cmake -E remove_directory ${ARCHIVE_NAME}
|
||||
COMMAND cmake -E remove_directory ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}
|
||||
DEPENDS html
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
|
||||
# CPACK config (Basically for NSIS)
|
||||
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
|
||||
SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
|
||||
SET(CPACK_PACKAGE_VENDOR "EGRES")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
|
||||
"LEMON - Library for Efficient Modeling and Optimization in Networks")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
|
||||
SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
|
||||
|
||||
SET(CPACK_PACKAGE_INSTALL_DIRECTORY
|
||||
"${PROJECT_NAME} ${PROJECT_VERSION}")
|
||||
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
|
||||
"${PROJECT_NAME} ${PROJECT_VERSION}")
|
||||
|
||||
SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
|
||||
|
||||
SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
|
||||
SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
|
||||
SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
|
||||
SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
|
||||
|
||||
SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
|
||||
"C++ header files")
|
||||
SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
|
||||
"DLL and import library")
|
||||
SET(CPACK_COMPONENT_BIN_DESCRIPTION
|
||||
"Command line utilities")
|
||||
SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
|
||||
"Doxygen generated documentation")
|
||||
|
||||
SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
|
||||
|
||||
SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
|
||||
SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
|
||||
SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
|
||||
|
||||
SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
|
||||
"Components needed to develop software using LEMON")
|
||||
SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
|
||||
"Documentation of LEMON")
|
||||
|
||||
SET(CPACK_ALL_INSTALL_TYPES Full Developer)
|
||||
|
||||
SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
|
||||
SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
|
||||
SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
|
||||
|
||||
SET(CPACK_GENERATOR "NSIS")
|
||||
SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico")
|
||||
SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico")
|
||||
#SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
|
||||
SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
|
||||
SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
|
||||
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
|
||||
SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu")
|
||||
SET(CPACK_NSIS_CONTACT "lemon-user@lemon.cs.elte.hu")
|
||||
SET(CPACK_NSIS_CREATE_ICONS_EXTRA "
|
||||
CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\index.html\\\"
|
||||
")
|
||||
SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
|
||||
!insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
|
||||
Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Documentation.lnk\\\"
|
||||
")
|
||||
|
||||
INCLUDE(CPack)
|
||||
ENDIF()
|
||||
167
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/INSTALL
vendored
Normal file
167
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/INSTALL
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
Installation Instructions
|
||||
=========================
|
||||
|
||||
This file contains instructions for building and installing LEMON from
|
||||
source on Linux. The process on Windows is similar.
|
||||
|
||||
Note that it is not necessary to install LEMON in order to use
|
||||
it. Instead, you can easily integrate it with your own code
|
||||
directly. For instructions, see
|
||||
https://lemon.cs.elte.hu/trac/lemon/wiki/HowToCompile
|
||||
|
||||
|
||||
In order to install LEMON from the extracted source tarball you have to
|
||||
issue the following commands:
|
||||
|
||||
1. Step into the root of the source directory.
|
||||
|
||||
$ cd lemon-x.y.z
|
||||
|
||||
2. Create a build subdirectory and step into it.
|
||||
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
|
||||
3. Perform system checks and create the makefiles.
|
||||
|
||||
$ cmake ..
|
||||
|
||||
4. Build LEMON.
|
||||
|
||||
$ make
|
||||
|
||||
This command compiles the non-template part of LEMON into
|
||||
libemon.a file. It also compiles the programs in the 'tools' and
|
||||
'demo' subdirectories.
|
||||
|
||||
5. [Optional] Compile and run the self-tests.
|
||||
|
||||
$ make check
|
||||
|
||||
5. [Optional] Generate the user documentation.
|
||||
|
||||
$ make html
|
||||
|
||||
The release tarballs already include the documentation.
|
||||
|
||||
Note that for this step you need to have the following tools
|
||||
installed: Python, Doxygen, Graphviz, Ghostscript, LaTeX.
|
||||
|
||||
6. [Optional] Install LEMON
|
||||
|
||||
$ make install
|
||||
|
||||
This command installs LEMON under /usr/local (you will need root
|
||||
privileges to be able to do that). If you want to install it to
|
||||
some other location, then pass the
|
||||
-DCMAKE_INSTALL_PREFIX=DIRECTORY flag to cmake in Step 3.
|
||||
For example:
|
||||
|
||||
$ cmake -DCMAKE_INSTALL_PREFIX=/home/username/lemon'
|
||||
|
||||
Configure Options and Variables
|
||||
===============================
|
||||
|
||||
In Step 3, you can customize the build process by passing options to CMAKE.
|
||||
|
||||
$ cmake [OPTIONS] ..
|
||||
|
||||
You find a list of the most useful options below.
|
||||
|
||||
-DCMAKE_INSTALL_PREFIX=PREFIX
|
||||
|
||||
Set the installation prefix to PREFIX. By default it is /usr/local.
|
||||
|
||||
-DCMAKE_BUILD_TYPE=[Release|Debug|Maintainer|...]
|
||||
|
||||
This sets the compiler options. The choices are the following
|
||||
|
||||
'Release': A strong optimization is turned on (-O3 with gcc). This
|
||||
is the default setting and we strongly recommend using this for
|
||||
the final compilation.
|
||||
|
||||
'Debug': Optimization is turned off and debug info is added (-O0
|
||||
-ggdb with gcc). If is recommended during the development.
|
||||
|
||||
'Maintainer': The same as 'Debug' but the compiler warnings are
|
||||
converted to errors (-Werror with gcc). In addition, 'make' will
|
||||
also automatically compile and execute the test codes. It is the
|
||||
best way of ensuring that LEMON codebase is clean and safe.
|
||||
|
||||
'RelWithDebInfo': Optimized build with debug info.
|
||||
|
||||
'MinSizeRel': Size optimized build (-Os with gcc)
|
||||
|
||||
-DTEST_WITH_VALGRIND=YES
|
||||
|
||||
Using this, the test codes will be executed using valgrind. It is a
|
||||
very effective way of identifying indexing problems and memory leaks.
|
||||
|
||||
-DCMAKE_CXX_COMPILER=path-to-compiler
|
||||
|
||||
Change the compiler to be used.
|
||||
|
||||
-DBUILD_SHARED_LIBS=TRUE
|
||||
|
||||
Build shared library instead of static one. Think twice if you
|
||||
really want to use this option.
|
||||
|
||||
-DLEMON_DOC_SOURCE_BROWSER=YES
|
||||
|
||||
Include the browsable cross referenced LEMON source code into the
|
||||
doc. It makes the doc quite bloated, but may be useful for
|
||||
developing LEMON itself.
|
||||
|
||||
-DLEMON_DOC_USE_MATHJAX=YES
|
||||
|
||||
Use MathJax (http://mathjax.org) for rendering the math formulae in
|
||||
the doc. It of much higher quality compared to the default LaTeX
|
||||
generated static images and it allows copy&paste of the formulae to
|
||||
LaTeX, Open Office, MS Word etc. documents.
|
||||
|
||||
On the other hand, it needs either Internet access or a locally
|
||||
installed version of MathJax to properly render the doc.
|
||||
|
||||
-DLEMON_DOC_MATHJAX_RELPATH=DIRECTORY
|
||||
|
||||
The location of the MathJax library. It defaults to
|
||||
http://www.mathjax.org/mathjax, which necessitates Internet access
|
||||
for proper rendering. The easiest way to make it usable offline is
|
||||
to set this parameter to 'mathjax' and copy all files of the MathJax
|
||||
library into the 'doc/html/mathjax' subdirectory of the build
|
||||
location.
|
||||
|
||||
See http://docs.mathjax.org/en/latest/installation.html for more details.
|
||||
|
||||
|
||||
-DLEMON_ENABLE_GLPK=NO
|
||||
-DLEMON_ENABLE_COIN=NO
|
||||
-DLEMON_ENABLE_ILOG=NO
|
||||
|
||||
Enable optional third party libraries. They are all enabled by default.
|
||||
|
||||
-DLEMON_DEFAULT_LP=GLPK
|
||||
|
||||
Sets the default LP solver backend. The supported values are
|
||||
CPLEX, CLP and GLPK. By default, it is set to the first one which
|
||||
is enabled and succesfully discovered.
|
||||
|
||||
-DLEMON_DEFAULT_MIP=GLPK
|
||||
|
||||
Sets the default MIP solver backend. The supported values are
|
||||
CPLEX, CBC and GLPK. By default, it is set to the first one which
|
||||
is enabled and succesfully discovered.
|
||||
|
||||
-DGLPK_ROOT_DIR=DIRECTORY
|
||||
-DCOIN_ROOT_DIR=DIRECTORY
|
||||
-DILOG_ROOT_DIR=DIRECTORY
|
||||
|
||||
Root directory prefixes of optional third party libraries.
|
||||
|
||||
Makefile Variables
|
||||
==================
|
||||
|
||||
make VERBOSE=1
|
||||
|
||||
This results in a more verbose output by showing the full
|
||||
compiler and linker commands.
|
||||
32
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/LICENSE
vendored
Normal file
32
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/LICENSE
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
LEMON code without an explicit copyright notice is covered by the following
|
||||
copyright/license.
|
||||
|
||||
Copyright (C) 2003-2012 Egervary Jeno Kombinatorikus Optimalizalasi
|
||||
Kutatocsoport (Egervary Combinatorial Optimization Research Group,
|
||||
EGRES).
|
||||
|
||||
===========================================================================
|
||||
Boost Software License, Version 1.0
|
||||
===========================================================================
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
337
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/NEWS
vendored
Normal file
337
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/NEWS
vendored
Normal file
@@ -0,0 +1,337 @@
|
||||
2014-07-07 Version 1.3.1 released
|
||||
|
||||
Bugfix release.
|
||||
|
||||
#484: Require CMAKE 2.8
|
||||
#471, #472, #480: Various clang compatibility fixes
|
||||
#481, #482: Fix shared lib build and versioning
|
||||
#476: Fix invalid map query in NearestNeighborTsp
|
||||
#478: Bugfix in debug checking and lower bound handling
|
||||
in min cost flow algorithms
|
||||
#479, #465: Bugfix in default LP/MIP backend settings
|
||||
#476: Bugfix in tsp_test
|
||||
#487: Add missing include header and std:: namespace spec.
|
||||
#474: Fix division by zero error in NetworkSimplex
|
||||
|
||||
2013-08-10 Version 1.3 released
|
||||
|
||||
This is major feature release
|
||||
|
||||
* New data structures
|
||||
|
||||
#69 : Bipartite graph concepts and implementations
|
||||
|
||||
* New algorithms
|
||||
|
||||
#177: Port Edmonds-Karp algorithm
|
||||
#380, #405: Heuristic algorithm for the max clique problem
|
||||
#386: Heuristic algorithms for symmetric TSP
|
||||
----: Nagamochi-Ibaraki algorithm [5087694945e4]
|
||||
#397, #56: Max. cardinality search
|
||||
|
||||
* Other new features
|
||||
|
||||
#223: Thread safe graph and graph map implementations
|
||||
#442: Different TimeStamp print formats
|
||||
#457: File export functionality to LpBase
|
||||
#362: Bidirectional iterator support for radixSort()
|
||||
|
||||
* Implementation improvements
|
||||
|
||||
----: Network Simplex
|
||||
#391: Better update process, pivot rule and arc mixing
|
||||
#435: Improved Altering List pivot rule
|
||||
#417: Various fine tunings in CostScaling
|
||||
#438: Optional iteration limit in HowardMmc
|
||||
#436: Ensure strongly polynomial running time for CycleCanceling
|
||||
while keeping the same performance
|
||||
----: Make the CBC interface be compatible with latest CBC releases
|
||||
[ee581a0ecfbf]
|
||||
|
||||
* CMAKE has become the default build environment (#434)
|
||||
|
||||
----: Autotool support has been dropped
|
||||
----: Improved LP/MIP configuration
|
||||
#465: Enable/disable options for LP/MIP backends
|
||||
#446: Better CPLEX discovery
|
||||
#460: Add cmake config to find SoPlex
|
||||
----: Allow CPACK configuration on all platforms
|
||||
#390: Add 'Maintainer' CMAKE build type
|
||||
#388: Add 'check' target.
|
||||
#401: Add contrib dir
|
||||
#389: Better version string setting in CMAKE
|
||||
#433: Support shared library build
|
||||
#416: Support testing with valgrind
|
||||
|
||||
* Doc improvements
|
||||
|
||||
#395: SOURCE_BROWSER Doxygen switch is configurable from CMAKE
|
||||
update-external-tags CMAKE target
|
||||
#455: Optionally use MathJax for rendering the math formulae
|
||||
#402, #437, #459, #456, #463: Various doc improvements
|
||||
|
||||
* Bugfixes (compared to release 1.2):
|
||||
|
||||
#432: Add missing doc/template.h and doc/references.bib to release
|
||||
tarball
|
||||
----: Intel C++ compatibility fixes
|
||||
#441: Fix buggy reinitialization in _solver_bits::VarIndex::clear()
|
||||
#444: Bugfix in path copy constructors and assignment operators
|
||||
#447: Bugfix in AllArcLookUp<>
|
||||
#448: Bugfix in adaptor_test.cc
|
||||
#449: Fix clang compilation warnings and errors
|
||||
#440: Fix a bug + remove redundant typedefs in dimacs-solver
|
||||
#453: Avoid GCC 4.7 compiler warnings
|
||||
#445: Fix missing initialization in CplexEnv::CplexEnv()
|
||||
#428: Add missing lemon/lemon.pc.cmake to the release tarball
|
||||
#393: Create and install lemon.pc
|
||||
#429: Fix VS warnings
|
||||
#430: Fix LpBase::Constr two-side limit bug
|
||||
#392: Bug fix in Dfs::start(s,t)
|
||||
#414: Fix wrong initialization in Preflow
|
||||
#418: Better Win CodeBlock/MinGW support
|
||||
#419: Build environment improvements
|
||||
- Build of mip_test and lp_test precede the running of the tests
|
||||
- Also search for coin libs under ${COIN_ROOT_DIR}/lib/coin
|
||||
- Do not look for COIN_VOL libraries
|
||||
#382: Allow lgf file without Arc maps
|
||||
#417: Bug fix in CostScaling
|
||||
#366: Fix Pred[Matrix]MapPath::empty()
|
||||
#371: Bug fix in (di)graphCopy()
|
||||
The target graph is cleared before adding nodes and arcs/edges.
|
||||
#364: Add missing UndirectedTags
|
||||
#368: Fix the usage of std::numeric_limits<>::min() in Network Simplex
|
||||
#372: Fix a critical bug in preflow
|
||||
#461: Bugfix in assert.h
|
||||
#470: Fix compilation issues related to various gcc versions
|
||||
#446: Fix #define indicating CPLEX availability
|
||||
#294: Add explicit namespace to
|
||||
ignore_unused_variable_warning() usages
|
||||
#420: Bugfix in IterableValueMap
|
||||
#439: Bugfix in biNodeConnected()
|
||||
|
||||
|
||||
2010-03-19 Version 1.2 released
|
||||
|
||||
This is major feature release
|
||||
|
||||
* New algorithms
|
||||
* Bellman-Ford algorithm (#51)
|
||||
* Minimum mean cycle algorithms (#179)
|
||||
* Karp, Hartman-Orlin and Howard algorithms
|
||||
* New minimum cost flow algorithms (#180)
|
||||
* Cost Scaling algorithms
|
||||
* Capacity Scaling algorithm
|
||||
* Cycle-Canceling algorithms
|
||||
* Planarity related algorithms (#62)
|
||||
* Planarity checking algorithm
|
||||
* Planar embedding algorithm
|
||||
* Schnyder's planar drawing algorithm
|
||||
* Coloring planar graphs with five or six colors
|
||||
* Fractional matching algorithms (#314)
|
||||
* New data structures
|
||||
* StaticDigraph structure (#68)
|
||||
* Several new priority queue structures (#50, #301)
|
||||
* Fibonacci, Radix, Bucket, Pairing, Binomial
|
||||
D-ary and fourary heaps (#301)
|
||||
* Iterable map structures (#73)
|
||||
* Other new tools and functionality
|
||||
* Map utility functions (#320)
|
||||
* Reserve functions are added to ListGraph and SmartGraph (#311)
|
||||
* A resize() function is added to HypercubeGraph (#311)
|
||||
* A count() function is added to CrossRefMap (#302)
|
||||
* Support for multiple targets in Suurballe using fullInit() (#181)
|
||||
* Traits class and named parameters for Suurballe (#323)
|
||||
* Separate reset() and resetParams() functions in NetworkSimplex
|
||||
to handle graph changes (#327)
|
||||
* tolerance() functions are added to HaoOrlin (#306)
|
||||
* Implementation improvements
|
||||
* Improvements in weighted matching algorithms (#314)
|
||||
* Jumpstart initialization
|
||||
* ArcIt iteration is based on out-arc lists instead of in-arc lists
|
||||
in ListDigraph (#311)
|
||||
* Faster add row operation in CbcMip (#203)
|
||||
* Better implementation for split() in ListDigraph (#311)
|
||||
* ArgParser can also throw exception instead of exit(1) (#332)
|
||||
* Miscellaneous
|
||||
* A simple interactive bootstrap script
|
||||
* Doc improvements (#62,#180,#299,#302,#303,#304,#307,#311,#331,#315,
|
||||
#316,#319)
|
||||
* BibTeX references in the doc (#184)
|
||||
* Optionally use valgrind when running tests
|
||||
* Also check ReferenceMapTag in concept checks (#312)
|
||||
* dimacs-solver uses long long type by default.
|
||||
* Several bugfixes (compared to release 1.1):
|
||||
#295: Suppress MSVC warnings using pragmas
|
||||
----: Various CMAKE related improvements
|
||||
* Remove duplications from doc/CMakeLists.txt
|
||||
* Rename documentation install folder from 'docs' to 'html'
|
||||
* Add tools/CMakeLists.txt to the tarball
|
||||
* Generate and install LEMONConfig.cmake
|
||||
* Change the label of the html project in Visual Studio
|
||||
* Fix the check for the 'long long' type
|
||||
* Put the version string into config.h
|
||||
* Minor CMake improvements
|
||||
* Set the version to 'hg-tip' if everything fails
|
||||
#311: Add missing 'explicit' keywords
|
||||
#302: Fix the implementation and doc of CrossRefMap
|
||||
#308: Remove duplicate list_graph.h entry from source list
|
||||
#307: Bugfix in Preflow and Circulation
|
||||
#305: Bugfix and extension in the rename script
|
||||
#312: Also check ReferenceMapTag in concept checks
|
||||
#250: Bugfix in pathSource() and pathTarget()
|
||||
#321: Use pathCopy(from,to) instead of copyPath(to,from)
|
||||
#322: Distribure LEMONConfig.cmake.in
|
||||
#330: Bug fix in map_extender.h
|
||||
#336: Fix the date field comment of graphToEps() output
|
||||
#323: Bug fix in Suurballe
|
||||
#335: Fix clear() function in ExtendFindEnum
|
||||
#337: Use void* as the LPX object pointer
|
||||
#317: Fix (and improve) error message in mip_test.cc
|
||||
Remove unnecessary OsiCbc dependency
|
||||
#356: Allow multiple executions of weighted matching algorithms (#356)
|
||||
|
||||
2009-05-13 Version 1.1 released
|
||||
|
||||
This is the second stable release of the 1.x series. It
|
||||
features a better coverage of the tools available in the 0.x
|
||||
series, a thoroughly reworked LP/MIP interface plus various
|
||||
improvements in the existing tools.
|
||||
|
||||
* Much improved M$ Windows support
|
||||
* Various improvements in the CMAKE build system
|
||||
* Compilation warnings are fixed/suppressed
|
||||
* Support IBM xlC compiler
|
||||
* New algorithms
|
||||
* Connectivity related algorithms (#61)
|
||||
* Euler walks (#65)
|
||||
* Preflow push-relabel max. flow algorithm (#176)
|
||||
* Circulation algorithm (push-relabel based) (#175)
|
||||
* Suurballe algorithm (#47)
|
||||
* Gomory-Hu algorithm (#66)
|
||||
* Hao-Orlin algorithm (#58)
|
||||
* Edmond's maximum cardinality and weighted matching algorithms
|
||||
in general graphs (#48,#265)
|
||||
* Minimum cost arborescence/branching (#60)
|
||||
* Network Simplex min. cost flow algorithm (#234)
|
||||
* New data structures
|
||||
* Full graph structure (#57)
|
||||
* Grid graph structure (#57)
|
||||
* Hypercube graph structure (#57)
|
||||
* Graph adaptors (#67)
|
||||
* ArcSet and EdgeSet classes (#67)
|
||||
* Elevator class (#174)
|
||||
* Other new tools
|
||||
* LP/MIP interface (#44)
|
||||
* Support for GLPK, CPLEX, Soplex, COIN-OR CLP and CBC
|
||||
* Reader for the Nauty file format (#55)
|
||||
* DIMACS readers (#167)
|
||||
* Radix sort algorithms (#72)
|
||||
* RangeIdMap and CrossRefMap (#160)
|
||||
* New command line tools
|
||||
* DIMACS to LGF converter (#182)
|
||||
* lgf-gen - a graph generator (#45)
|
||||
* DIMACS solver utility (#226)
|
||||
* Other code improvements
|
||||
* Lognormal distribution added to Random (#102)
|
||||
* Better (i.e. O(1) time) item counting in SmartGraph (#3)
|
||||
* The standard maps of graphs are guaranteed to be
|
||||
reference maps (#190)
|
||||
* Miscellaneous
|
||||
* Various doc improvements
|
||||
* Improved 0.x -> 1.x converter script
|
||||
|
||||
* Several bugfixes (compared to release 1.0):
|
||||
#170: Bugfix SmartDigraph::split()
|
||||
#171: Bugfix in SmartGraph::restoreSnapshot()
|
||||
#172: Extended test cases for graphs and digraphs
|
||||
#173: Bugfix in Random
|
||||
* operator()s always return a double now
|
||||
* the faulty real<Num>(Num) and real<Num>(Num,Num)
|
||||
have been removed
|
||||
#187: Remove DijkstraWidestPathOperationTraits
|
||||
#61: Bugfix in DfsVisit
|
||||
#193: Bugfix in GraphReader::skipSection()
|
||||
#195: Bugfix in ConEdgeIt()
|
||||
#197: Bugfix in heap unionfind
|
||||
* This bug affects Edmond's general matching algorithms
|
||||
#207: Fix 'make install' without 'make html' using CMAKE
|
||||
#208: Suppress or fix VS2008 compilation warnings
|
||||
----: Update the LEMON icon
|
||||
----: Enable the component-based installer
|
||||
(in installers made by CPACK)
|
||||
----: Set the proper version for CMAKE in the tarballs
|
||||
(made by autotools)
|
||||
----: Minor clarification in the LICENSE file
|
||||
----: Add missing unistd.h include to time_measure.h
|
||||
#204: Compilation bug fixed in graph_to_eps.h with VS2005
|
||||
#214,#215: windows.h should never be included by LEMON headers
|
||||
#230: Build systems check the availability of 'long long' type
|
||||
#229: Default implementation of Tolerance<> is used for integer types
|
||||
#211,#212: Various fixes for compiling on AIX
|
||||
----: Improvements in CMAKE config
|
||||
- docs is installed in share/doc/
|
||||
- detects newer versions of Ghostscript
|
||||
#239: Fix missing 'inline' specifier in time_measure.h
|
||||
#274,#280: Install lemon/config.h
|
||||
#275: Prefix macro names with LEMON_ in lemon/config.h
|
||||
----: Small script for making the release tarballs added
|
||||
----: Minor improvement in unify-sources.sh (a76f55d7d397)
|
||||
|
||||
2009-03-27 LEMON joins to the COIN-OR initiative
|
||||
|
||||
COIN-OR (Computational Infrastructure for Operations Research,
|
||||
http://www.coin-or.org) project is an initiative to spur the
|
||||
development of open-source software for the operations research
|
||||
community.
|
||||
|
||||
2008-10-13 Version 1.0 released
|
||||
|
||||
This is the first stable release of LEMON. Compared to the 0.x
|
||||
release series, it features a considerably smaller but more
|
||||
matured set of tools. The API has also completely revised and
|
||||
changed in several places.
|
||||
|
||||
* The major name changes compared to the 0.x series (see the
|
||||
Migration Guide in the doc for more details)
|
||||
* Graph -> Digraph, UGraph -> Graph
|
||||
* Edge -> Arc, UEdge -> Edge
|
||||
* source(UEdge)/target(UEdge) -> u(Edge)/v(Edge)
|
||||
* Other improvements
|
||||
* Better documentation
|
||||
* Reviewed and cleaned up codebase
|
||||
* CMake based build system (along with the autotools based one)
|
||||
* Contents of the library (ported from 0.x)
|
||||
* Algorithms
|
||||
* breadth-first search (bfs.h)
|
||||
* depth-first search (dfs.h)
|
||||
* Dijkstra's algorithm (dijkstra.h)
|
||||
* Kruskal's algorithm (kruskal.h)
|
||||
* Data structures
|
||||
* graph data structures (list_graph.h, smart_graph.h)
|
||||
* path data structures (path.h)
|
||||
* binary heap data structure (bin_heap.h)
|
||||
* union-find data structures (unionfind.h)
|
||||
* miscellaneous property maps (maps.h)
|
||||
* two dimensional vector and bounding box (dim2.h)
|
||||
* Concepts
|
||||
* graph structure concepts (concepts/digraph.h, concepts/graph.h,
|
||||
concepts/graph_components.h)
|
||||
* concepts for other structures (concepts/heap.h, concepts/maps.h,
|
||||
concepts/path.h)
|
||||
* Tools
|
||||
* Mersenne twister random number generator (random.h)
|
||||
* tools for measuring cpu and wall clock time (time_measure.h)
|
||||
* tools for counting steps and events (counter.h)
|
||||
* tool for parsing command line arguments (arg_parser.h)
|
||||
* tool for visualizing graphs (graph_to_eps.h)
|
||||
* tools for reading and writing data in LEMON Graph Format
|
||||
(lgf_reader.h, lgf_writer.h)
|
||||
* tools to handle the anomalies of calculations with
|
||||
floating point numbers (tolerance.h)
|
||||
* tools to manage RGB colors (color.h)
|
||||
* Infrastructure
|
||||
* extended assertion handling (assert.h)
|
||||
* exception classes and error handling (error.h)
|
||||
* concept checking (concept_check.h)
|
||||
* commonly used mathematical constants (math.h)
|
||||
50
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/README
vendored
Normal file
50
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/README
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
=====================================================================
|
||||
LEMON - a Library for Efficient Modeling and Optimization in Networks
|
||||
=====================================================================
|
||||
|
||||
LEMON is an open source library written in C++. It provides
|
||||
easy-to-use implementations of common data structures and algorithms
|
||||
in the area of optimization and helps implementing new ones. The main
|
||||
focus is on graphs and graph algorithms, thus it is especially
|
||||
suitable for solving design and optimization problems of
|
||||
telecommunication networks. To achieve wide usability its data
|
||||
structures and algorithms provide generic interfaces.
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
LICENSE
|
||||
|
||||
Copying, distribution and modification conditions and terms.
|
||||
|
||||
NEWS
|
||||
|
||||
News and version history.
|
||||
|
||||
INSTALL
|
||||
|
||||
General building and installation instructions.
|
||||
|
||||
lemon/
|
||||
|
||||
Source code of LEMON library.
|
||||
|
||||
doc/
|
||||
|
||||
Documentation of LEMON. The starting page is doc/html/index.html.
|
||||
|
||||
demo/
|
||||
|
||||
Some example programs to make you easier to get familiar with LEMON.
|
||||
|
||||
scripts/
|
||||
|
||||
Scripts that make it easier to develop LEMON.
|
||||
|
||||
test/
|
||||
|
||||
Programs to check the integrity and correctness of LEMON.
|
||||
|
||||
tools/
|
||||
|
||||
Various utilities related to LEMON.
|
||||
110
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/FindCOIN.cmake
vendored
Normal file
110
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/FindCOIN.cmake
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
SET(COIN_ROOT_DIR "" CACHE PATH "COIN root directory")
|
||||
|
||||
FIND_PATH(COIN_INCLUDE_DIR coin/CoinUtilsConfig.h
|
||||
HINTS ${COIN_ROOT_DIR}/include
|
||||
)
|
||||
FIND_LIBRARY(COIN_CBC_LIBRARY
|
||||
NAMES Cbc libCbc
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
FIND_LIBRARY(COIN_CBC_SOLVER_LIBRARY
|
||||
NAMES CbcSolver libCbcSolver
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
FIND_LIBRARY(COIN_CGL_LIBRARY
|
||||
NAMES Cgl libCgl
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
FIND_LIBRARY(COIN_CLP_LIBRARY
|
||||
NAMES Clp libClp
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
FIND_LIBRARY(COIN_COIN_UTILS_LIBRARY
|
||||
NAMES CoinUtils libCoinUtils
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
FIND_LIBRARY(COIN_OSI_LIBRARY
|
||||
NAMES Osi libOsi
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
FIND_LIBRARY(COIN_OSI_CBC_LIBRARY
|
||||
NAMES OsiCbc libOsiCbc
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
FIND_LIBRARY(COIN_OSI_CLP_LIBRARY
|
||||
NAMES OsiClp libOsiClp
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
FIND_LIBRARY(COIN_OSI_VOL_LIBRARY
|
||||
NAMES OsiVol libOsiVol
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
FIND_LIBRARY(COIN_VOL_LIBRARY
|
||||
NAMES Vol libVol
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
|
||||
FIND_LIBRARY(COIN_ZLIB_LIBRARY
|
||||
NAMES z libz
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
FIND_LIBRARY(COIN_BZ2_LIBRARY
|
||||
NAMES bz2 libbz2
|
||||
HINTS ${COIN_ROOT_DIR}/lib/coin
|
||||
HINTS ${COIN_ROOT_DIR}/lib
|
||||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(COIN DEFAULT_MSG
|
||||
COIN_INCLUDE_DIR
|
||||
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
|
||||
)
|
||||
|
||||
IF(COIN_FOUND)
|
||||
SET(COIN_INCLUDE_DIRS ${COIN_INCLUDE_DIR})
|
||||
SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_ZLIB_LIBRARY};${COIN_BZ2_LIBRARY}")
|
||||
IF(COIN_ZLIB_LIBRARY)
|
||||
SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_ZLIB_LIBRARY}")
|
||||
ENDIF(COIN_ZLIB_LIBRARY)
|
||||
IF(COIN_BZ2_LIBRARY)
|
||||
SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_BZ2_LIBRARY}")
|
||||
ENDIF(COIN_BZ2_LIBRARY)
|
||||
SET(COIN_CBC_LIBRARIES "${COIN_CBC_LIBRARY};${COIN_CBC_SOLVER_LIBRARY};${COIN_CGL_LIBRARY};${COIN_OSI_LIBRARY};${COIN_OSI_CBC_LIBRARY};${COIN_OSI_CLP_LIBRARY};${COIN_ZLIB_LIBRARY};${COIN_BZ2_LIBRARY};${COIN_CLP_LIBRARIES}")
|
||||
SET(COIN_LIBRARIES ${COIN_CBC_LIBRARIES})
|
||||
ENDIF(COIN_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
COIN_INCLUDE_DIR
|
||||
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
|
||||
COIN_ZLIB_LIBRARY
|
||||
COIN_BZ2_LIBRARY
|
||||
)
|
||||
55
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/FindGLPK.cmake
vendored
Normal file
55
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/FindGLPK.cmake
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
SET(GLPK_ROOT_DIR "" CACHE PATH "GLPK root directory")
|
||||
|
||||
SET(GLPK_REGKEY "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Glpk;InstallPath]")
|
||||
GET_FILENAME_COMPONENT(GLPK_ROOT_PATH ${GLPK_REGKEY} ABSOLUTE)
|
||||
|
||||
FIND_PATH(GLPK_INCLUDE_DIR
|
||||
glpk.h
|
||||
PATHS ${GLPK_REGKEY}/include
|
||||
HINTS ${GLPK_ROOT_DIR}/include
|
||||
)
|
||||
FIND_LIBRARY(GLPK_LIBRARY
|
||||
glpk
|
||||
PATHS ${GLPK_REGKEY}/lib
|
||||
HINTS ${GLPK_ROOT_DIR}/lib
|
||||
)
|
||||
|
||||
IF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
|
||||
FILE(READ ${GLPK_INCLUDE_DIR}/glpk.h GLPK_GLPK_H)
|
||||
|
||||
STRING(REGEX MATCH "define[ ]+GLP_MAJOR_VERSION[ ]+[0-9]+" GLPK_MAJOR_VERSION_LINE "${GLPK_GLPK_H}")
|
||||
STRING(REGEX REPLACE "define[ ]+GLP_MAJOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MAJOR "${GLPK_MAJOR_VERSION_LINE}")
|
||||
|
||||
STRING(REGEX MATCH "define[ ]+GLP_MINOR_VERSION[ ]+[0-9]+" GLPK_MINOR_VERSION_LINE "${GLPK_GLPK_H}")
|
||||
STRING(REGEX REPLACE "define[ ]+GLP_MINOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MINOR "${GLPK_MINOR_VERSION_LINE}")
|
||||
|
||||
SET(GLPK_VERSION_STRING "${GLPK_VERSION_MAJOR}.${GLPK_VERSION_MINOR}")
|
||||
|
||||
IF(GLPK_FIND_VERSION)
|
||||
IF(GLPK_FIND_VERSION_COUNT GREATER 2)
|
||||
MESSAGE(SEND_ERROR "unexpected version string")
|
||||
ENDIF(GLPK_FIND_VERSION_COUNT GREATER 2)
|
||||
|
||||
MATH(EXPR GLPK_REQUESTED_VERSION "${GLPK_FIND_VERSION_MAJOR}*100 + ${GLPK_FIND_VERSION_MINOR}")
|
||||
MATH(EXPR GLPK_FOUND_VERSION "${GLPK_VERSION_MAJOR}*100 + ${GLPK_VERSION_MINOR}")
|
||||
|
||||
IF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
|
||||
SET(GLPK_PROPER_VERSION_FOUND FALSE)
|
||||
ELSE(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
|
||||
SET(GLPK_PROPER_VERSION_FOUND TRUE)
|
||||
ENDIF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
|
||||
ELSE(GLPK_FIND_VERSION)
|
||||
SET(GLPK_PROPER_VERSION_FOUND TRUE)
|
||||
ENDIF(GLPK_FIND_VERSION)
|
||||
ENDIF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLPK DEFAULT_MSG GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_PROPER_VERSION_FOUND)
|
||||
|
||||
IF(GLPK_FOUND)
|
||||
SET(GLPK_INCLUDE_DIRS ${GLPK_INCLUDE_DIR})
|
||||
SET(GLPK_LIBRARIES ${GLPK_LIBRARY})
|
||||
SET(GLPK_BIN_DIR ${GLPK_ROOT_PATH}/bin)
|
||||
ENDIF(GLPK_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR)
|
||||
10
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/FindGhostscript.cmake
vendored
Normal file
10
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/FindGhostscript.cmake
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PROGRAM(GHOSTSCRIPT_EXECUTABLE
|
||||
NAMES gs gswin32c
|
||||
PATHS "$ENV{ProgramFiles}/gs"
|
||||
PATH_SUFFIXES gs8.61/bin gs8.62/bin gs8.63/bin gs8.64/bin gs8.65/bin
|
||||
DOC "Ghostscript: PostScript and PDF language interpreter and previewer."
|
||||
)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ghostscript DEFAULT_MSG GHOSTSCRIPT_EXECUTABLE)
|
||||
102
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/FindILOG.cmake
vendored
Normal file
102
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/FindILOG.cmake
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
FIND_PATH(ILOG_ROOT_DIR
|
||||
NAMES cplex
|
||||
DOC "CPLEX STUDIO root directory"
|
||||
PATHS /opt/ibm/ILOG /usr/local/ibm/ILOG /usr/local/ILOG /usr/local/ilog
|
||||
PATHS "$ENV{HOME}/ILOG" "$ENV{HOME}/.local/ILOG"
|
||||
PATHS "$ENV{HOME}/ibm/ILOG" "$ENV{HOME}/.local/ibm/ILOG"
|
||||
PATHS "C:/Program Files/IBM/ILOG"
|
||||
PATH_SUFFIXES "CPLEX_Studio126" "CPLEX_Studio125"
|
||||
"CPLEX_Studio124" "CPLEX_Studio123" "CPLEX_Studio122"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
IF(WIN32)
|
||||
IF(MSVC_VERSION STREQUAL "1400")
|
||||
SET(ILOG_WIN_COMPILER "windows_vs2005")
|
||||
ELSEIF(MSVC_VERSION STREQUAL "1500")
|
||||
SET(ILOG_WIN_COMPILER "windows_vs2008")
|
||||
ELSEIF(MSVC_VERSION STREQUAL "1600")
|
||||
SET(ILOG_WIN_COMPILER "windows_vs2010")
|
||||
ELSE()
|
||||
SET(ILOG_WIN_COMPILER "windows_vs2008")
|
||||
ENDIF()
|
||||
IF(CMAKE_CL_64)
|
||||
SET(ILOG_WIN_COMPILER "x64_${ILOG_WIN_COMPILER}")
|
||||
SET(ILOG_WIN_PLATFORM "x64_win32")
|
||||
ELSE()
|
||||
SET(ILOG_WIN_COMPILER "x86_${ILOG_WIN_COMPILER}")
|
||||
SET(ILOG_WIN_PLATFORM "x86_win32")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
FIND_PATH(ILOG_CPLEX_ROOT_DIR
|
||||
NAMES include/ilcplex
|
||||
HINTS ${ILOG_ROOT_DIR}/cplex ${ILOG_ROOT_DIR}/cplex121
|
||||
${ILOG_ROOT_DIR}/cplex122 ${ILOG_ROOT_DIR}/cplex123
|
||||
DOC "CPLEX root directory"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
FIND_PATH(ILOG_CONCERT_ROOT_DIR
|
||||
NAMES include/ilconcert
|
||||
HINTS ${ILOG_ROOT_DIR}/concert ${ILOG_ROOT_DIR}/concert29
|
||||
DOC "CONCERT root directory"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
FIND_PATH(ILOG_CPLEX_INCLUDE_DIR
|
||||
ilcplex/cplex.h
|
||||
HINTS ${ILOG_CPLEX_ROOT_DIR}/include
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
FIND_PATH(ILOG_CONCERT_INCLUDE_DIR
|
||||
ilconcert/ilobasic.h
|
||||
HINTS ${ILOG_CONCERT_ROOT_DIR}/include
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
FIND_LIBRARY(ILOG_CPLEX_LIBRARY
|
||||
cplex cplex121 cplex122 cplex123 cplex124
|
||||
HINTS ${ILOG_CPLEX_ROOT_DIR}/lib/x86_sles10_4.1/static_pic
|
||||
${ILOG_CPLEX_ROOT_DIR}/lib/x86-64_sles10_4.1/static_pic
|
||||
${ILOG_CPLEX_ROOT_DIR}/lib/x86_debian4.0_4.1/static_pic
|
||||
${ILOG_CPLEX_ROOT_DIR}/lib/x86-64_debian4.0_4.1/static_pic
|
||||
${ILOG_CPLEX_ROOT_DIR}/lib/${ILOG_WIN_COMPILER}/stat_mda
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
FIND_LIBRARY(ILOG_CONCERT_LIBRARY
|
||||
concert
|
||||
HINTS ${ILOG_CONCERT_ROOT_DIR}/lib/x86_sles10_4.1/static_pic
|
||||
${ILOG_CONCERT_ROOT_DIR}/lib/x86-64_sles10_4.1/static_pic
|
||||
${ILOG_CONCERT_ROOT_DIR}/lib/x86_debian4.0_4.1/static_pic
|
||||
${ILOG_CONCERT_ROOT_DIR}/lib/x86-64_debian4.0_4.1/static_pic
|
||||
${ILOG_CONCERT_ROOT_DIR}/lib/${ILOG_WIN_COMPILER}/stat_mda
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
FIND_FILE(ILOG_CPLEX_DLL
|
||||
cplex121.dll cplex122.dll cplex123.dll cplex124.dll
|
||||
HINTS ${ILOG_CPLEX_ROOT_DIR}/bin/${ILOG_WIN_PLATFORM}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ILOG
|
||||
DEFAULT_MSG ILOG_CPLEX_LIBRARY ILOG_CPLEX_INCLUDE_DIR
|
||||
)
|
||||
|
||||
IF(ILOG_FOUND)
|
||||
SET(ILOG_INCLUDE_DIRS ${ILOG_CPLEX_INCLUDE_DIR} ${ILOG_CONCERT_INCLUDE_DIR})
|
||||
SET(ILOG_LIBRARIES ${ILOG_CPLEX_LIBRARY} ${ILOG_CONCERT_LIBRARY})
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
# SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
|
||||
SET(ILOG_LIBRARIES ${ILOG_LIBRARIES} "m" "pthread")
|
||||
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
ENDIF(ILOG_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
ILOG_CPLEX_LIBRARY ILOG_CPLEX_INCLUDE_DIR ILOG_CPLEX_DLL
|
||||
ILOG_CONCERT_LIBRARY ILOG_CONCERT_INCLUDE_DIR ILOG_CONCERT_DLL
|
||||
)
|
||||
23
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/FindSOPLEX.cmake
vendored
Normal file
23
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/FindSOPLEX.cmake
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
SET(SOPLEX_ROOT_DIR "" CACHE PATH "SoPlex root directory")
|
||||
|
||||
FIND_PATH(SOPLEX_INCLUDE_DIR
|
||||
soplex.h
|
||||
HINTS ${SOPLEX_ROOT_DIR}/src
|
||||
)
|
||||
FIND_LIBRARY(SOPLEX_LIBRARY
|
||||
soplex
|
||||
HINTS ${SOPLEX_ROOT_DIR}/lib
|
||||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SOPLEX DEFAULT_MSG SOPLEX_LIBRARY SOPLEX_INCLUDE_DIR)
|
||||
|
||||
IF(SOPLEX_FOUND)
|
||||
SET(SOPLEX_INCLUDE_DIRS ${SOPLEX_INCLUDE_DIR})
|
||||
SET(SOPLEX_LIBRARIES ${SOPLEX_LIBRARY})
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
SET(SOPLEX_LIBRARIES "${SOPLEX_LIBRARIES};z")
|
||||
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
ENDIF(SOPLEX_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(SOPLEX_LIBRARY SOPLEX_INCLUDE_DIR)
|
||||
13
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/LEMONConfig.cmake.in
vendored
Normal file
13
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/LEMONConfig.cmake.in
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
SET(LEMON_INCLUDE_DIR "@CMAKE_INSTALL_PREFIX@/include" CACHE PATH "LEMON include directory")
|
||||
SET(LEMON_INCLUDE_DIRS "${LEMON_INCLUDE_DIR}")
|
||||
|
||||
IF(UNIX)
|
||||
SET(LEMON_LIB_NAME "libemon.a")
|
||||
ELSEIF(WIN32)
|
||||
SET(LEMON_LIB_NAME "lemon.lib")
|
||||
ENDIF(UNIX)
|
||||
|
||||
SET(LEMON_LIBRARY "@CMAKE_INSTALL_PREFIX@/lib/${LEMON_LIB_NAME}" CACHE FILEPATH "LEMON library")
|
||||
SET(LEMON_LIBRARIES "${LEMON_LIBRARY}")
|
||||
|
||||
MARK_AS_ADVANCED(LEMON_LIBRARY LEMON_INCLUDE_DIR)
|
||||
BIN
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/nsis/lemon.ico
vendored
Normal file
BIN
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/nsis/lemon.ico
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/nsis/uninstall.ico
vendored
Normal file
BIN
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/nsis/uninstall.ico
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
1
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/version.cmake
vendored
Normal file
1
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/version.cmake
vendored
Normal file
@@ -0,0 +1 @@
|
||||
SET(LEMON_VERSION "1.3.1" CACHE STRING "LEMON version string.")
|
||||
1
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/version.cmake.in
vendored
Normal file
1
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/cmake/version.cmake.in
vendored
Normal file
@@ -0,0 +1 @@
|
||||
SET(LEMON_VERSION "@LEMON_VERSION@" CACHE STRING "LEMON version string.")
|
||||
18
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/contrib/CMakeLists.txt
vendored
Normal file
18
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/contrib/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
INCLUDE_DIRECTORIES(
|
||||
${PROJECT_SOURCE_DIR}
|
||||
${PROJECT_BINARY_DIR}
|
||||
)
|
||||
|
||||
LINK_DIRECTORIES(
|
||||
${PROJECT_BINARY_DIR}/lemon
|
||||
)
|
||||
|
||||
# Uncomment (and adjust) the following two lines. 'myprog' is the name
|
||||
# of the final executable ('.exe' will automatically be added to the
|
||||
# name on Windows) and 'myprog-main.cc' is the source code it is
|
||||
# compiled from. You can add more source files separated by
|
||||
# whitespaces. Moreover, you can add multiple similar blocks if you
|
||||
# want to build more than one executables.
|
||||
|
||||
# ADD_EXECUTABLE(myprog myprog-main.cc)
|
||||
# TARGET_LINK_LIBRARIES(myprog lemon)
|
||||
19
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/demo/CMakeLists.txt
vendored
Normal file
19
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/demo/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
INCLUDE_DIRECTORIES(
|
||||
${PROJECT_SOURCE_DIR}
|
||||
${PROJECT_BINARY_DIR}
|
||||
)
|
||||
|
||||
LINK_DIRECTORIES(
|
||||
${PROJECT_BINARY_DIR}/lemon
|
||||
)
|
||||
|
||||
SET(DEMOS
|
||||
arg_parser_demo
|
||||
graph_to_eps_demo
|
||||
lgf_demo
|
||||
)
|
||||
|
||||
FOREACH(DEMO_NAME ${DEMOS})
|
||||
ADD_EXECUTABLE(${DEMO_NAME} ${DEMO_NAME}.cc)
|
||||
TARGET_LINK_LIBRARIES(${DEMO_NAME} lemon)
|
||||
ENDFOREACH()
|
||||
112
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/demo/arg_parser_demo.cc
vendored
Normal file
112
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/demo/arg_parser_demo.cc
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2010
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
///\ingroup demos
|
||||
///\file
|
||||
///\brief Argument parser demo
|
||||
///
|
||||
/// This example shows how the argument parser can be used.
|
||||
///
|
||||
/// \include arg_parser_demo.cc
|
||||
|
||||
#include <lemon/arg_parser.h>
|
||||
|
||||
using namespace lemon;
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the argument parser
|
||||
ArgParser ap(argc, argv);
|
||||
int i;
|
||||
std::string s;
|
||||
double d = 1.0;
|
||||
bool b, nh;
|
||||
bool g1, g2, g3;
|
||||
|
||||
// Add a mandatory integer option with storage reference
|
||||
ap.refOption("n", "An integer input.", i, true);
|
||||
// Add a double option with storage reference (the default value is 1.0)
|
||||
ap.refOption("val", "A double input.", d);
|
||||
// Add a double option without storage reference (the default value is 3.14)
|
||||
ap.doubleOption("val2", "A double input.", 3.14);
|
||||
// Set synonym for -val option
|
||||
ap.synonym("vals", "val");
|
||||
// Add a string option
|
||||
ap.refOption("name", "A string input.", s);
|
||||
// Add bool options
|
||||
ap.refOption("f", "A switch.", b)
|
||||
.refOption("nohelp", "", nh)
|
||||
.refOption("gra", "Choice A", g1)
|
||||
.refOption("grb", "Choice B", g2)
|
||||
.refOption("grc", "Choice C", g3);
|
||||
// Bundle -gr* options into a group
|
||||
ap.optionGroup("gr", "gra")
|
||||
.optionGroup("gr", "grb")
|
||||
.optionGroup("gr", "grc");
|
||||
// Set the group mandatory
|
||||
ap.mandatoryGroup("gr");
|
||||
// Set the options of the group exclusive (only one option can be given)
|
||||
ap.onlyOneGroup("gr");
|
||||
// Add non-parsed arguments (e.g. input files)
|
||||
ap.other("infile", "The input file.")
|
||||
.other("...");
|
||||
|
||||
// Throw an exception when problems occurs. The default behavior is to
|
||||
// exit(1) on these cases, but this makes Valgrind falsely warn
|
||||
// about memory leaks.
|
||||
ap.throwOnProblems();
|
||||
|
||||
// Perform the parsing process
|
||||
// (in case of any error it terminates the program)
|
||||
// The try {} construct is necessary only if the ap.trowOnProblems()
|
||||
// setting is in use.
|
||||
try {
|
||||
ap.parse();
|
||||
} catch (ArgParserException &) { return 1; }
|
||||
|
||||
// Check each option if it has been given and print its value
|
||||
std::cout << "Parameters of '" << ap.commandName() << "':\n";
|
||||
|
||||
std::cout << " Value of -n: " << i << std::endl;
|
||||
if(ap.given("val")) std::cout << " Value of -val: " << d << std::endl;
|
||||
if(ap.given("val2")) {
|
||||
d = ap["val2"];
|
||||
std::cout << " Value of -val2: " << d << std::endl;
|
||||
}
|
||||
if(ap.given("name")) std::cout << " Value of -name: " << s << std::endl;
|
||||
if(ap.given("f")) std::cout << " -f is given\n";
|
||||
if(ap.given("nohelp")) std::cout << " Value of -nohelp: " << nh << std::endl;
|
||||
if(ap.given("gra")) std::cout << " -gra is given\n";
|
||||
if(ap.given("grb")) std::cout << " -grb is given\n";
|
||||
if(ap.given("grc")) std::cout << " -grc is given\n";
|
||||
|
||||
switch(ap.files().size()) {
|
||||
case 0:
|
||||
std::cout << " No file argument was given.\n";
|
||||
break;
|
||||
case 1:
|
||||
std::cout << " 1 file argument was given. It is:\n";
|
||||
break;
|
||||
default:
|
||||
std::cout << " "
|
||||
<< ap.files().size() << " file arguments were given. They are:\n";
|
||||
}
|
||||
for(unsigned int i=0;i<ap.files().size();++i)
|
||||
std::cout << " '" << ap.files()[i] << "'\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
29
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/demo/digraph.lgf
vendored
Normal file
29
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/demo/digraph.lgf
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
@nodes
|
||||
label
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
@arcs
|
||||
label capacity
|
||||
0 1 0 16
|
||||
0 2 1 12
|
||||
0 3 2 20
|
||||
1 2 3 10
|
||||
1 4 4 10
|
||||
1 5 5 13
|
||||
2 3 6 10
|
||||
2 4 7 8
|
||||
2 6 8 8
|
||||
5 3 9 20
|
||||
3 6 10 25
|
||||
4 7 11 15
|
||||
5 7 12 15
|
||||
6 7 13 18
|
||||
@attributes
|
||||
source 0
|
||||
target 7
|
||||
206
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/demo/graph_to_eps_demo.cc
vendored
Normal file
206
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/demo/graph_to_eps_demo.cc
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
/// \ingroup demos
|
||||
/// \file
|
||||
/// \brief Demo of the graph drawing function \ref graphToEps()
|
||||
///
|
||||
/// This demo program shows examples how to use the function \ref
|
||||
/// graphToEps(). It takes no input but simply creates seven
|
||||
/// <tt>.eps</tt> files demonstrating the capability of \ref
|
||||
/// graphToEps(), and showing how to draw directed graphs,
|
||||
/// how to handle parallel egdes, how to change the properties (like
|
||||
/// color, shape, size, title etc.) of nodes and arcs individually
|
||||
/// using appropriate graph maps.
|
||||
///
|
||||
/// \include graph_to_eps_demo.cc
|
||||
|
||||
#include<lemon/list_graph.h>
|
||||
#include<lemon/graph_to_eps.h>
|
||||
#include<lemon/math.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace lemon;
|
||||
|
||||
int main()
|
||||
{
|
||||
Palette palette;
|
||||
Palette paletteW(true);
|
||||
|
||||
// Create a small digraph
|
||||
ListDigraph g;
|
||||
typedef ListDigraph::Node Node;
|
||||
typedef ListDigraph::NodeIt NodeIt;
|
||||
typedef ListDigraph::Arc Arc;
|
||||
typedef dim2::Point<int> Point;
|
||||
|
||||
Node n1=g.addNode();
|
||||
Node n2=g.addNode();
|
||||
Node n3=g.addNode();
|
||||
Node n4=g.addNode();
|
||||
Node n5=g.addNode();
|
||||
|
||||
ListDigraph::NodeMap<Point> coords(g);
|
||||
ListDigraph::NodeMap<double> sizes(g);
|
||||
ListDigraph::NodeMap<int> colors(g);
|
||||
ListDigraph::NodeMap<int> shapes(g);
|
||||
ListDigraph::ArcMap<int> acolors(g);
|
||||
ListDigraph::ArcMap<int> widths(g);
|
||||
|
||||
coords[n1]=Point(50,50); sizes[n1]=1; colors[n1]=1; shapes[n1]=0;
|
||||
coords[n2]=Point(50,70); sizes[n2]=2; colors[n2]=2; shapes[n2]=2;
|
||||
coords[n3]=Point(70,70); sizes[n3]=1; colors[n3]=3; shapes[n3]=0;
|
||||
coords[n4]=Point(70,50); sizes[n4]=2; colors[n4]=4; shapes[n4]=1;
|
||||
coords[n5]=Point(85,60); sizes[n5]=3; colors[n5]=5; shapes[n5]=2;
|
||||
|
||||
Arc a;
|
||||
|
||||
a=g.addArc(n1,n2); acolors[a]=0; widths[a]=1;
|
||||
a=g.addArc(n2,n3); acolors[a]=0; widths[a]=1;
|
||||
a=g.addArc(n3,n5); acolors[a]=0; widths[a]=3;
|
||||
a=g.addArc(n5,n4); acolors[a]=0; widths[a]=1;
|
||||
a=g.addArc(n4,n1); acolors[a]=0; widths[a]=1;
|
||||
a=g.addArc(n2,n4); acolors[a]=1; widths[a]=2;
|
||||
a=g.addArc(n3,n4); acolors[a]=2; widths[a]=1;
|
||||
|
||||
IdMap<ListDigraph,Node> id(g);
|
||||
|
||||
// Create .eps files showing the digraph with different options
|
||||
cout << "Create 'graph_to_eps_demo_out_1_pure.eps'" << endl;
|
||||
graphToEps(g,"graph_to_eps_demo_out_1_pure.eps").
|
||||
coords(coords).
|
||||
title("Sample .eps figure").
|
||||
copyright("(C) 2003-2009 LEMON Project").
|
||||
run();
|
||||
|
||||
cout << "Create 'graph_to_eps_demo_out_2.eps'" << endl;
|
||||
graphToEps(g,"graph_to_eps_demo_out_2.eps").
|
||||
coords(coords).
|
||||
title("Sample .eps figure").
|
||||
copyright("(C) 2003-2009 LEMON Project").
|
||||
absoluteNodeSizes().absoluteArcWidths().
|
||||
nodeScale(2).nodeSizes(sizes).
|
||||
nodeShapes(shapes).
|
||||
nodeColors(composeMap(palette,colors)).
|
||||
arcColors(composeMap(palette,acolors)).
|
||||
arcWidthScale(.4).arcWidths(widths).
|
||||
nodeTexts(id).nodeTextSize(3).
|
||||
run();
|
||||
|
||||
cout << "Create 'graph_to_eps_demo_out_3_arr.eps'" << endl;
|
||||
graphToEps(g,"graph_to_eps_demo_out_3_arr.eps").
|
||||
title("Sample .eps figure (with arrowheads)").
|
||||
copyright("(C) 2003-2009 LEMON Project").
|
||||
absoluteNodeSizes().absoluteArcWidths().
|
||||
nodeColors(composeMap(palette,colors)).
|
||||
coords(coords).
|
||||
nodeScale(2).nodeSizes(sizes).
|
||||
nodeShapes(shapes).
|
||||
arcColors(composeMap(palette,acolors)).
|
||||
arcWidthScale(.4).arcWidths(widths).
|
||||
nodeTexts(id).nodeTextSize(3).
|
||||
drawArrows().arrowWidth(2).arrowLength(2).
|
||||
run();
|
||||
|
||||
// Add more arcs to the digraph
|
||||
a=g.addArc(n1,n4); acolors[a]=2; widths[a]=1;
|
||||
a=g.addArc(n4,n1); acolors[a]=1; widths[a]=2;
|
||||
|
||||
a=g.addArc(n1,n2); acolors[a]=1; widths[a]=1;
|
||||
a=g.addArc(n1,n2); acolors[a]=2; widths[a]=1;
|
||||
a=g.addArc(n1,n2); acolors[a]=3; widths[a]=1;
|
||||
a=g.addArc(n1,n2); acolors[a]=4; widths[a]=1;
|
||||
a=g.addArc(n1,n2); acolors[a]=5; widths[a]=1;
|
||||
a=g.addArc(n1,n2); acolors[a]=6; widths[a]=1;
|
||||
a=g.addArc(n1,n2); acolors[a]=7; widths[a]=1;
|
||||
|
||||
cout << "Create 'graph_to_eps_demo_out_4_par.eps'" << endl;
|
||||
graphToEps(g,"graph_to_eps_demo_out_4_par.eps").
|
||||
title("Sample .eps figure (parallel arcs)").
|
||||
copyright("(C) 2003-2009 LEMON Project").
|
||||
absoluteNodeSizes().absoluteArcWidths().
|
||||
nodeShapes(shapes).
|
||||
coords(coords).
|
||||
nodeScale(2).nodeSizes(sizes).
|
||||
nodeColors(composeMap(palette,colors)).
|
||||
arcColors(composeMap(palette,acolors)).
|
||||
arcWidthScale(.4).arcWidths(widths).
|
||||
nodeTexts(id).nodeTextSize(3).
|
||||
enableParallel().parArcDist(1.5).
|
||||
run();
|
||||
|
||||
cout << "Create 'graph_to_eps_demo_out_5_par_arr.eps'" << endl;
|
||||
graphToEps(g,"graph_to_eps_demo_out_5_par_arr.eps").
|
||||
title("Sample .eps figure (parallel arcs and arrowheads)").
|
||||
copyright("(C) 2003-2009 LEMON Project").
|
||||
absoluteNodeSizes().absoluteArcWidths().
|
||||
nodeScale(2).nodeSizes(sizes).
|
||||
coords(coords).
|
||||
nodeShapes(shapes).
|
||||
nodeColors(composeMap(palette,colors)).
|
||||
arcColors(composeMap(palette,acolors)).
|
||||
arcWidthScale(.3).arcWidths(widths).
|
||||
nodeTexts(id).nodeTextSize(3).
|
||||
enableParallel().parArcDist(1).
|
||||
drawArrows().arrowWidth(1).arrowLength(1).
|
||||
run();
|
||||
|
||||
cout << "Create 'graph_to_eps_demo_out_6_par_arr_a4.eps'" << endl;
|
||||
graphToEps(g,"graph_to_eps_demo_out_6_par_arr_a4.eps").
|
||||
title("Sample .eps figure (fits to A4)").
|
||||
copyright("(C) 2003-2009 LEMON Project").
|
||||
scaleToA4().
|
||||
absoluteNodeSizes().absoluteArcWidths().
|
||||
nodeScale(2).nodeSizes(sizes).
|
||||
coords(coords).
|
||||
nodeShapes(shapes).
|
||||
nodeColors(composeMap(palette,colors)).
|
||||
arcColors(composeMap(palette,acolors)).
|
||||
arcWidthScale(.3).arcWidths(widths).
|
||||
nodeTexts(id).nodeTextSize(3).
|
||||
enableParallel().parArcDist(1).
|
||||
drawArrows().arrowWidth(1).arrowLength(1).
|
||||
run();
|
||||
|
||||
// Create an .eps file showing the colors of a default Palette
|
||||
ListDigraph h;
|
||||
ListDigraph::NodeMap<int> hcolors(h);
|
||||
ListDigraph::NodeMap<Point> hcoords(h);
|
||||
|
||||
int cols=int(std::sqrt(double(palette.size())));
|
||||
for(int i=0;i<int(paletteW.size());i++) {
|
||||
Node n=h.addNode();
|
||||
hcoords[n]=Point(1+i%cols,1+i/cols);
|
||||
hcolors[n]=i;
|
||||
}
|
||||
|
||||
cout << "Create 'graph_to_eps_demo_out_7_colors.eps'" << endl;
|
||||
graphToEps(h,"graph_to_eps_demo_out_7_colors.eps").
|
||||
scale(60).
|
||||
title("Sample .eps figure (Palette demo)").
|
||||
copyright("(C) 2003-2009 LEMON Project").
|
||||
coords(hcoords).
|
||||
absoluteNodeSizes().absoluteArcWidths().
|
||||
nodeScale(.45).
|
||||
distantColorNodeTexts().
|
||||
nodeTexts(hcolors).nodeTextSize(.6).
|
||||
nodeColors(composeMap(paletteW,hcolors)).
|
||||
run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
70
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/demo/lgf_demo.cc
vendored
Normal file
70
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/demo/lgf_demo.cc
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
///\ingroup demos
|
||||
///\file
|
||||
///\brief Demonstrating graph input and output
|
||||
///
|
||||
/// This program gives an example of how to read and write a digraph
|
||||
/// and additional maps from/to a stream or a file using the
|
||||
/// \ref lgf-format "LGF" format.
|
||||
///
|
||||
/// The \c "digraph.lgf" file:
|
||||
/// \include digraph.lgf
|
||||
///
|
||||
/// And the program which reads it and prints the digraph to the
|
||||
/// standard output:
|
||||
/// \include lgf_demo.cc
|
||||
|
||||
#include <iostream>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/lgf_writer.h>
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
int main() {
|
||||
SmartDigraph g;
|
||||
SmartDigraph::ArcMap<int> cap(g);
|
||||
SmartDigraph::Node s, t;
|
||||
|
||||
try {
|
||||
digraphReader(g, "digraph.lgf"). // read the directed graph into g
|
||||
arcMap("capacity", cap). // read the 'capacity' arc map into cap
|
||||
node("source", s). // read 'source' node to s
|
||||
node("target", t). // read 'target' node to t
|
||||
run();
|
||||
} catch (Exception& error) { // check if there was any error
|
||||
std::cerr << "Error: " << error.what() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cout << "A digraph is read from 'digraph.lgf'." << std::endl;
|
||||
std::cout << "Number of nodes: " << countNodes(g) << std::endl;
|
||||
std::cout << "Number of arcs: " << countArcs(g) << std::endl;
|
||||
|
||||
std::cout << "We can write it to the standard output:" << std::endl;
|
||||
|
||||
digraphWriter(g). // write g to the standard output
|
||||
arcMap("capacity", cap). // write cap into 'capacity'
|
||||
node("source", s). // write s to 'source'
|
||||
node("target", t). // write t to 'target'
|
||||
run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
90
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/CMakeLists.txt
vendored
Normal file
90
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
INCLUDE_DIRECTORIES(
|
||||
${PROJECT_SOURCE_DIR}
|
||||
${PROJECT_BINARY_DIR}
|
||||
)
|
||||
|
||||
CONFIGURE_FILE(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config.h
|
||||
)
|
||||
|
||||
CONFIGURE_FILE(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lemon.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lemon.pc
|
||||
@ONLY
|
||||
)
|
||||
|
||||
SET(LEMON_SOURCES
|
||||
arg_parser.cc
|
||||
base.cc
|
||||
color.cc
|
||||
lp_base.cc
|
||||
lp_skeleton.cc
|
||||
random.cc
|
||||
bits/windows.cc
|
||||
)
|
||||
|
||||
IF(LEMON_HAVE_GLPK)
|
||||
SET(LEMON_SOURCES ${LEMON_SOURCES} glpk.cc)
|
||||
INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIRS})
|
||||
IF(WIN32)
|
||||
INSTALL(FILES ${GLPK_BIN_DIR}/glpk.dll DESTINATION bin)
|
||||
INSTALL(FILES ${GLPK_BIN_DIR}/libltdl3.dll DESTINATION bin)
|
||||
INSTALL(FILES ${GLPK_BIN_DIR}/zlib1.dll DESTINATION bin)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(LEMON_HAVE_CPLEX)
|
||||
SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
|
||||
INCLUDE_DIRECTORIES(${ILOG_INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
|
||||
IF(LEMON_HAVE_CLP)
|
||||
SET(LEMON_SOURCES ${LEMON_SOURCES} clp.cc)
|
||||
INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
|
||||
IF(LEMON_HAVE_CBC)
|
||||
SET(LEMON_SOURCES ${LEMON_SOURCES} cbc.cc)
|
||||
INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
|
||||
IF(LEMON_HAVE_SOPLEX)
|
||||
SET(LEMON_SOURCES ${LEMON_SOURCES} soplex.cc)
|
||||
INCLUDE_DIRECTORIES(${SOPLEX_INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
|
||||
ADD_LIBRARY(lemon ${LEMON_SOURCES})
|
||||
|
||||
TARGET_LINK_LIBRARIES(lemon
|
||||
${GLPK_LIBRARIES} ${COIN_LIBRARIES} ${ILOG_LIBRARIES} ${SOPLEX_LIBRARIES}
|
||||
)
|
||||
|
||||
IF(UNIX)
|
||||
SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon VERSION ${LEMON_VERSION} SOVERSION ${LEMON_VERSION})
|
||||
ENDIF()
|
||||
|
||||
INSTALL(
|
||||
TARGETS lemon
|
||||
ARCHIVE DESTINATION lib
|
||||
LIBRARY DESTINATION lib
|
||||
COMPONENT library
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
DIRECTORY . bits concepts
|
||||
DESTINATION include/lemon
|
||||
COMPONENT headers
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
|
||||
DESTINATION include/lemon
|
||||
COMPONENT headers
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc
|
||||
DESTINATION lib/pkgconfig
|
||||
)
|
||||
3638
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/adaptors.h
vendored
Normal file
3638
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/adaptors.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
473
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/arg_parser.cc
vendored
Normal file
473
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/arg_parser.cc
vendored
Normal file
@@ -0,0 +1,473 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2010
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/arg_parser.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
void ArgParser::_terminate(ArgParserException::Reason reason) const
|
||||
{
|
||||
if(_exit_on_problems)
|
||||
exit(1);
|
||||
else throw(ArgParserException(reason));
|
||||
}
|
||||
|
||||
|
||||
void ArgParser::_showHelp(void *p)
|
||||
{
|
||||
(static_cast<ArgParser*>(p))->showHelp();
|
||||
(static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP);
|
||||
}
|
||||
|
||||
ArgParser::ArgParser(int argc, const char * const *argv)
|
||||
:_argc(argc), _argv(argv), _command_name(argv[0]),
|
||||
_exit_on_problems(true) {
|
||||
funcOption("-help","Print a short help message",_showHelp,this);
|
||||
synonym("help","-help");
|
||||
synonym("h","-help");
|
||||
}
|
||||
|
||||
ArgParser::~ArgParser()
|
||||
{
|
||||
for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
|
||||
if(i->second.self_delete)
|
||||
switch(i->second.type) {
|
||||
case BOOL:
|
||||
delete i->second.bool_p;
|
||||
break;
|
||||
case STRING:
|
||||
delete i->second.string_p;
|
||||
break;
|
||||
case DOUBLE:
|
||||
delete i->second.double_p;
|
||||
break;
|
||||
case INTEGER:
|
||||
delete i->second.int_p;
|
||||
break;
|
||||
case UNKNOWN:
|
||||
break;
|
||||
case FUNC:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ArgParser &ArgParser::intOption(const std::string &name,
|
||||
const std::string &help,
|
||||
int value, bool obl)
|
||||
{
|
||||
ParData p;
|
||||
p.int_p=new int(value);
|
||||
p.self_delete=true;
|
||||
p.help=help;
|
||||
p.type=INTEGER;
|
||||
p.mandatory=obl;
|
||||
_opts[name]=p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::doubleOption(const std::string &name,
|
||||
const std::string &help,
|
||||
double value, bool obl)
|
||||
{
|
||||
ParData p;
|
||||
p.double_p=new double(value);
|
||||
p.self_delete=true;
|
||||
p.help=help;
|
||||
p.type=DOUBLE;
|
||||
p.mandatory=obl;
|
||||
_opts[name]=p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::boolOption(const std::string &name,
|
||||
const std::string &help,
|
||||
bool value, bool obl)
|
||||
{
|
||||
ParData p;
|
||||
p.bool_p=new bool(value);
|
||||
p.self_delete=true;
|
||||
p.help=help;
|
||||
p.type=BOOL;
|
||||
p.mandatory=obl;
|
||||
_opts[name]=p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::stringOption(const std::string &name,
|
||||
const std::string &help,
|
||||
std::string value, bool obl)
|
||||
{
|
||||
ParData p;
|
||||
p.string_p=new std::string(value);
|
||||
p.self_delete=true;
|
||||
p.help=help;
|
||||
p.type=STRING;
|
||||
p.mandatory=obl;
|
||||
_opts[name]=p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::refOption(const std::string &name,
|
||||
const std::string &help,
|
||||
int &ref, bool obl)
|
||||
{
|
||||
ParData p;
|
||||
p.int_p=&ref;
|
||||
p.self_delete=false;
|
||||
p.help=help;
|
||||
p.type=INTEGER;
|
||||
p.mandatory=obl;
|
||||
_opts[name]=p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::refOption(const std::string &name,
|
||||
const std::string &help,
|
||||
double &ref, bool obl)
|
||||
{
|
||||
ParData p;
|
||||
p.double_p=&ref;
|
||||
p.self_delete=false;
|
||||
p.help=help;
|
||||
p.type=DOUBLE;
|
||||
p.mandatory=obl;
|
||||
_opts[name]=p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::refOption(const std::string &name,
|
||||
const std::string &help,
|
||||
bool &ref, bool obl)
|
||||
{
|
||||
ParData p;
|
||||
p.bool_p=&ref;
|
||||
p.self_delete=false;
|
||||
p.help=help;
|
||||
p.type=BOOL;
|
||||
p.mandatory=obl;
|
||||
_opts[name]=p;
|
||||
|
||||
ref = false;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::refOption(const std::string &name,
|
||||
const std::string &help,
|
||||
std::string &ref, bool obl)
|
||||
{
|
||||
ParData p;
|
||||
p.string_p=&ref;
|
||||
p.self_delete=false;
|
||||
p.help=help;
|
||||
p.type=STRING;
|
||||
p.mandatory=obl;
|
||||
_opts[name]=p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::funcOption(const std::string &name,
|
||||
const std::string &help,
|
||||
void (*func)(void *),void *data)
|
||||
{
|
||||
ParData p;
|
||||
p.func_p.p=func;
|
||||
p.func_p.data=data;
|
||||
p.self_delete=false;
|
||||
p.help=help;
|
||||
p.type=FUNC;
|
||||
p.mandatory=false;
|
||||
_opts[name]=p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::optionGroup(const std::string &group,
|
||||
const std::string &opt)
|
||||
{
|
||||
Opts::iterator i = _opts.find(opt);
|
||||
LEMON_ASSERT(i!=_opts.end(), "Unknown option: '"+opt+"'");
|
||||
LEMON_ASSERT(!(i->second.ingroup),
|
||||
"Option already in option group: '"+opt+"'");
|
||||
GroupData &g=_groups[group];
|
||||
g.opts.push_back(opt);
|
||||
i->second.ingroup=true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::onlyOneGroup(const std::string &group)
|
||||
{
|
||||
GroupData &g=_groups[group];
|
||||
g.only_one=true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::synonym(const std::string &syn,
|
||||
const std::string &opt)
|
||||
{
|
||||
Opts::iterator o = _opts.find(opt);
|
||||
LEMON_ASSERT(o!=_opts.end(), "Unknown option: '"+opt+"'");
|
||||
LEMON_ASSERT(_opts.find(syn)==_opts.end(), "Option already used: '"+syn+"'");
|
||||
ParData p;
|
||||
p.help=opt;
|
||||
p.mandatory=false;
|
||||
p.syn=true;
|
||||
_opts[syn]=p;
|
||||
o->second.has_syn=true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::mandatoryGroup(const std::string &group)
|
||||
{
|
||||
GroupData &g=_groups[group];
|
||||
g.mandatory=true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::other(const std::string &name,
|
||||
const std::string &help)
|
||||
{
|
||||
_others_help.push_back(OtherArg(name,help));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ArgParser::show(std::ostream &os,Opts::const_iterator i) const
|
||||
{
|
||||
os << "-" << i->first;
|
||||
if(i->second.has_syn)
|
||||
for(Opts::const_iterator j=_opts.begin();j!=_opts.end();++j)
|
||||
if(j->second.syn&&j->second.help==i->first)
|
||||
os << "|-" << j->first;
|
||||
switch(i->second.type) {
|
||||
case STRING:
|
||||
os << " str";
|
||||
break;
|
||||
case INTEGER:
|
||||
os << " int";
|
||||
break;
|
||||
case DOUBLE:
|
||||
os << " num";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ArgParser::show(std::ostream &os,Groups::const_iterator i) const
|
||||
{
|
||||
GroupData::Opts::const_iterator o=i->second.opts.begin();
|
||||
while(o!=i->second.opts.end()) {
|
||||
show(os,_opts.find(*o));
|
||||
++o;
|
||||
if(o!=i->second.opts.end()) os<<'|';
|
||||
}
|
||||
}
|
||||
|
||||
void ArgParser::showHelp(Opts::const_iterator i) const
|
||||
{
|
||||
if(i->second.help.size()==0||i->second.syn) return;
|
||||
std::cerr << " ";
|
||||
show(std::cerr,i);
|
||||
std::cerr << std::endl;
|
||||
std::cerr << " " << i->second.help << std::endl;
|
||||
}
|
||||
void ArgParser::showHelp(std::vector<ArgParser::OtherArg>::const_iterator i)
|
||||
const
|
||||
{
|
||||
if(i->help.size()==0) return;
|
||||
std::cerr << " " << i->name << std::endl
|
||||
<< " " << i->help << std::endl;
|
||||
}
|
||||
|
||||
void ArgParser::shortHelp() const
|
||||
{
|
||||
const unsigned int LINE_LEN=77;
|
||||
const std::string indent(" ");
|
||||
std::cerr << "Usage:\n " << _command_name;
|
||||
int pos=_command_name.size()+2;
|
||||
for(Groups::const_iterator g=_groups.begin();g!=_groups.end();++g) {
|
||||
std::ostringstream cstr;
|
||||
cstr << ' ';
|
||||
if(!g->second.mandatory) cstr << '[';
|
||||
show(cstr,g);
|
||||
if(!g->second.mandatory) cstr << ']';
|
||||
if(pos+cstr.str().size()>LINE_LEN) {
|
||||
std::cerr << std::endl << indent;
|
||||
pos=indent.size();
|
||||
}
|
||||
std::cerr << cstr.str();
|
||||
pos+=cstr.str().size();
|
||||
}
|
||||
for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i)
|
||||
if(!i->second.ingroup&&!i->second.syn) {
|
||||
std::ostringstream cstr;
|
||||
cstr << ' ';
|
||||
if(!i->second.mandatory) cstr << '[';
|
||||
show(cstr,i);
|
||||
if(!i->second.mandatory) cstr << ']';
|
||||
if(pos+cstr.str().size()>LINE_LEN) {
|
||||
std::cerr << std::endl << indent;
|
||||
pos=indent.size();
|
||||
}
|
||||
std::cerr << cstr.str();
|
||||
pos+=cstr.str().size();
|
||||
}
|
||||
for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
|
||||
i!=_others_help.end();++i)
|
||||
{
|
||||
std::ostringstream cstr;
|
||||
cstr << ' ' << i->name;
|
||||
|
||||
if(pos+cstr.str().size()>LINE_LEN) {
|
||||
std::cerr << std::endl << indent;
|
||||
pos=indent.size();
|
||||
}
|
||||
std::cerr << cstr.str();
|
||||
pos+=cstr.str().size();
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
void ArgParser::showHelp() const
|
||||
{
|
||||
shortHelp();
|
||||
std::cerr << "Where:\n";
|
||||
for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
|
||||
i!=_others_help.end();++i) showHelp(i);
|
||||
for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
|
||||
_terminate(ArgParserException::HELP);
|
||||
}
|
||||
|
||||
|
||||
void ArgParser::unknownOpt(std::string arg) const
|
||||
{
|
||||
std::cerr << "\nUnknown option: " << arg << "\n";
|
||||
std::cerr << "\nType '" << _command_name <<
|
||||
" --help' to obtain a short summary on the usage.\n\n";
|
||||
_terminate(ArgParserException::UNKNOWN_OPT);
|
||||
}
|
||||
|
||||
void ArgParser::requiresValue(std::string arg, OptType t) const
|
||||
{
|
||||
std::cerr << "Argument '" << arg << "' requires a";
|
||||
switch(t) {
|
||||
case STRING:
|
||||
std::cerr << " string";
|
||||
break;
|
||||
case INTEGER:
|
||||
std::cerr << "n integer";
|
||||
break;
|
||||
case DOUBLE:
|
||||
std::cerr << " floating point";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
std::cerr << " value\n\n";
|
||||
showHelp();
|
||||
}
|
||||
|
||||
|
||||
void ArgParser::checkMandatories() const
|
||||
{
|
||||
bool ok=true;
|
||||
for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i)
|
||||
if(i->second.mandatory&&!i->second.set)
|
||||
{
|
||||
if(ok)
|
||||
std::cerr << _command_name
|
||||
<< ": The following mandatory arguments are missing.\n";
|
||||
ok=false;
|
||||
showHelp(i);
|
||||
}
|
||||
for(Groups::const_iterator i=_groups.begin();i!=_groups.end();++i)
|
||||
if(i->second.mandatory||i->second.only_one)
|
||||
{
|
||||
int set=0;
|
||||
for(GroupData::Opts::const_iterator o=i->second.opts.begin();
|
||||
o!=i->second.opts.end();++o)
|
||||
if(_opts.find(*o)->second.set) ++set;
|
||||
if(i->second.mandatory&&!set) {
|
||||
std::cerr << _command_name <<
|
||||
": At least one of the following arguments is mandatory.\n";
|
||||
ok=false;
|
||||
for(GroupData::Opts::const_iterator o=i->second.opts.begin();
|
||||
o!=i->second.opts.end();++o)
|
||||
showHelp(_opts.find(*o));
|
||||
}
|
||||
if(i->second.only_one&&set>1) {
|
||||
std::cerr << _command_name <<
|
||||
": At most one of the following arguments can be given.\n";
|
||||
ok=false;
|
||||
for(GroupData::Opts::const_iterator o=i->second.opts.begin();
|
||||
o!=i->second.opts.end();++o)
|
||||
showHelp(_opts.find(*o));
|
||||
}
|
||||
}
|
||||
if(!ok) {
|
||||
std::cerr << "\nType '" << _command_name <<
|
||||
" --help' to obtain a short summary on the usage.\n\n";
|
||||
_terminate(ArgParserException::INVALID_OPT);
|
||||
}
|
||||
}
|
||||
|
||||
ArgParser &ArgParser::parse()
|
||||
{
|
||||
for(int ar=1; ar<_argc; ++ar) {
|
||||
std::string arg(_argv[ar]);
|
||||
if (arg[0] != '-' || arg.size() == 1) {
|
||||
_file_args.push_back(arg);
|
||||
}
|
||||
else {
|
||||
Opts::iterator i = _opts.find(arg.substr(1));
|
||||
if(i==_opts.end()) unknownOpt(arg);
|
||||
else {
|
||||
if(i->second.syn) i=_opts.find(i->second.help);
|
||||
ParData &p(i->second);
|
||||
if (p.type==BOOL) *p.bool_p=true;
|
||||
else if (p.type==FUNC) p.func_p.p(p.func_p.data);
|
||||
else if(++ar==_argc) requiresValue(arg, p.type);
|
||||
else {
|
||||
std::string val(_argv[ar]);
|
||||
std::istringstream vals(val);
|
||||
switch(p.type) {
|
||||
case STRING:
|
||||
*p.string_p=val;
|
||||
break;
|
||||
case INTEGER:
|
||||
vals >> *p.int_p;
|
||||
break;
|
||||
case DOUBLE:
|
||||
vals >> *p.double_p;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(p.type!=STRING&&(!vals||!vals.eof()))
|
||||
requiresValue(arg, p.type);
|
||||
}
|
||||
p.set = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
checkMandatories();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
||||
440
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/arg_parser.h
vendored
Normal file
440
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/arg_parser.h
vendored
Normal file
@@ -0,0 +1,440 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2010
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_ARG_PARSER_H
|
||||
#define LEMON_ARG_PARSER_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <lemon/assert.h>
|
||||
|
||||
///\ingroup misc
|
||||
///\file
|
||||
///\brief A tool to parse command line arguments.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
///Exception used by ArgParser
|
||||
|
||||
///Exception used by ArgParser.
|
||||
///
|
||||
class ArgParserException : public Exception {
|
||||
public:
|
||||
/// Reasons for failure
|
||||
|
||||
/// Reasons for failure.
|
||||
///
|
||||
enum Reason {
|
||||
HELP, ///< <tt>--help</tt> option was given.
|
||||
UNKNOWN_OPT, ///< Unknown option was given.
|
||||
INVALID_OPT ///< Invalid combination of options.
|
||||
};
|
||||
|
||||
private:
|
||||
Reason _reason;
|
||||
|
||||
public:
|
||||
///Constructor
|
||||
ArgParserException(Reason r) throw() : _reason(r) {}
|
||||
///Virtual destructor
|
||||
virtual ~ArgParserException() throw() {}
|
||||
///A short description of the exception
|
||||
virtual const char* what() const throw() {
|
||||
switch(_reason)
|
||||
{
|
||||
case HELP:
|
||||
return "lemon::ArgParseException: ask for help";
|
||||
break;
|
||||
case UNKNOWN_OPT:
|
||||
return "lemon::ArgParseException: unknown option";
|
||||
break;
|
||||
case INVALID_OPT:
|
||||
return "lemon::ArgParseException: invalid combination of options";
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
///Return the reason for the failure
|
||||
Reason reason() const {return _reason; }
|
||||
};
|
||||
|
||||
|
||||
///Command line arguments parser
|
||||
|
||||
///\ingroup misc
|
||||
///Command line arguments parser.
|
||||
///
|
||||
///For a complete example see the \ref arg_parser_demo.cc demo file.
|
||||
class ArgParser {
|
||||
|
||||
static void _showHelp(void *p);
|
||||
protected:
|
||||
|
||||
int _argc;
|
||||
const char * const *_argv;
|
||||
|
||||
enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
|
||||
|
||||
class ParData {
|
||||
public:
|
||||
union {
|
||||
bool *bool_p;
|
||||
int *int_p;
|
||||
double *double_p;
|
||||
std::string *string_p;
|
||||
struct {
|
||||
void (*p)(void *);
|
||||
void *data;
|
||||
} func_p;
|
||||
|
||||
};
|
||||
std::string help;
|
||||
bool mandatory;
|
||||
OptType type;
|
||||
bool set;
|
||||
bool ingroup;
|
||||
bool has_syn;
|
||||
bool syn;
|
||||
bool self_delete;
|
||||
ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
|
||||
has_syn(false), syn(false), self_delete(false) {}
|
||||
};
|
||||
|
||||
typedef std::map<std::string,ParData> Opts;
|
||||
Opts _opts;
|
||||
|
||||
class GroupData
|
||||
{
|
||||
public:
|
||||
typedef std::list<std::string> Opts;
|
||||
Opts opts;
|
||||
bool only_one;
|
||||
bool mandatory;
|
||||
GroupData() :only_one(false), mandatory(false) {}
|
||||
};
|
||||
|
||||
typedef std::map<std::string,GroupData> Groups;
|
||||
Groups _groups;
|
||||
|
||||
struct OtherArg
|
||||
{
|
||||
std::string name;
|
||||
std::string help;
|
||||
OtherArg(std::string n, std::string h) :name(n), help(h) {}
|
||||
|
||||
};
|
||||
|
||||
std::vector<OtherArg> _others_help;
|
||||
std::vector<std::string> _file_args;
|
||||
std::string _command_name;
|
||||
|
||||
|
||||
private:
|
||||
//Bind a function to an option.
|
||||
|
||||
//\param name The name of the option. The leading '-' must be omitted.
|
||||
//\param help A help string.
|
||||
//\retval func The function to be called when the option is given. It
|
||||
// must be of type "void f(void *)"
|
||||
//\param data Data to be passed to \c func
|
||||
ArgParser &funcOption(const std::string &name,
|
||||
const std::string &help,
|
||||
void (*func)(void *),void *data);
|
||||
|
||||
bool _exit_on_problems;
|
||||
|
||||
void _terminate(ArgParserException::Reason reason) const;
|
||||
|
||||
public:
|
||||
|
||||
///Constructor
|
||||
ArgParser(int argc, const char * const *argv);
|
||||
|
||||
~ArgParser();
|
||||
|
||||
///\name Options
|
||||
///
|
||||
|
||||
///@{
|
||||
|
||||
///Add a new integer type option
|
||||
|
||||
///Add a new integer type option.
|
||||
///\param name The name of the option. The leading '-' must be omitted.
|
||||
///\param help A help string.
|
||||
///\param value A default value for the option.
|
||||
///\param obl Indicate if the option is mandatory.
|
||||
ArgParser &intOption(const std::string &name,
|
||||
const std::string &help,
|
||||
int value=0, bool obl=false);
|
||||
|
||||
///Add a new floating point type option
|
||||
|
||||
///Add a new floating point type option.
|
||||
///\param name The name of the option. The leading '-' must be omitted.
|
||||
///\param help A help string.
|
||||
///\param value A default value for the option.
|
||||
///\param obl Indicate if the option is mandatory.
|
||||
ArgParser &doubleOption(const std::string &name,
|
||||
const std::string &help,
|
||||
double value=0, bool obl=false);
|
||||
|
||||
///Add a new bool type option
|
||||
|
||||
///Add a new bool type option.
|
||||
///\param name The name of the option. The leading '-' must be omitted.
|
||||
///\param help A help string.
|
||||
///\param value A default value for the option.
|
||||
///\param obl Indicate if the option is mandatory.
|
||||
///\note A mandatory bool obtion is of very little use.
|
||||
ArgParser &boolOption(const std::string &name,
|
||||
const std::string &help,
|
||||
bool value=false, bool obl=false);
|
||||
|
||||
///Add a new string type option
|
||||
|
||||
///Add a new string type option.
|
||||
///\param name The name of the option. The leading '-' must be omitted.
|
||||
///\param help A help string.
|
||||
///\param value A default value for the option.
|
||||
///\param obl Indicate if the option is mandatory.
|
||||
ArgParser &stringOption(const std::string &name,
|
||||
const std::string &help,
|
||||
std::string value="", bool obl=false);
|
||||
|
||||
///Give help string for non-parsed arguments.
|
||||
|
||||
///With this function you can give help string for non-parsed arguments.
|
||||
///The parameter \c name will be printed in the short usage line, while
|
||||
///\c help gives a more detailed description.
|
||||
ArgParser &other(const std::string &name,
|
||||
const std::string &help="");
|
||||
|
||||
///@}
|
||||
|
||||
///\name Options with External Storage
|
||||
///Using this functions, the value of the option will be directly written
|
||||
///into a variable once the option appears in the command line.
|
||||
|
||||
///@{
|
||||
|
||||
///Add a new integer type option with a storage reference
|
||||
|
||||
///Add a new integer type option with a storage reference.
|
||||
///\param name The name of the option. The leading '-' must be omitted.
|
||||
///\param help A help string.
|
||||
///\param obl Indicate if the option is mandatory.
|
||||
///\retval ref The value of the argument will be written to this variable.
|
||||
ArgParser &refOption(const std::string &name,
|
||||
const std::string &help,
|
||||
int &ref, bool obl=false);
|
||||
|
||||
///Add a new floating type option with a storage reference
|
||||
|
||||
///Add a new floating type option with a storage reference.
|
||||
///\param name The name of the option. The leading '-' must be omitted.
|
||||
///\param help A help string.
|
||||
///\param obl Indicate if the option is mandatory.
|
||||
///\retval ref The value of the argument will be written to this variable.
|
||||
ArgParser &refOption(const std::string &name,
|
||||
const std::string &help,
|
||||
double &ref, bool obl=false);
|
||||
|
||||
///Add a new bool type option with a storage reference
|
||||
|
||||
///Add a new bool type option with a storage reference.
|
||||
///\param name The name of the option. The leading '-' must be omitted.
|
||||
///\param help A help string.
|
||||
///\param obl Indicate if the option is mandatory.
|
||||
///\retval ref The value of the argument will be written to this variable.
|
||||
///\note A mandatory bool obtion is of very little use.
|
||||
ArgParser &refOption(const std::string &name,
|
||||
const std::string &help,
|
||||
bool &ref, bool obl=false);
|
||||
|
||||
///Add a new string type option with a storage reference
|
||||
|
||||
///Add a new string type option with a storage reference.
|
||||
///\param name The name of the option. The leading '-' must be omitted.
|
||||
///\param help A help string.
|
||||
///\param obl Indicate if the option is mandatory.
|
||||
///\retval ref The value of the argument will be written to this variable.
|
||||
ArgParser &refOption(const std::string &name,
|
||||
const std::string &help,
|
||||
std::string &ref, bool obl=false);
|
||||
|
||||
///@}
|
||||
|
||||
///\name Option Groups and Synonyms
|
||||
///
|
||||
|
||||
///@{
|
||||
|
||||
///Bundle some options into a group
|
||||
|
||||
/// You can group some option by calling this function repeatedly for each
|
||||
/// option to be grouped with the same groupname.
|
||||
///\param group The group name.
|
||||
///\param opt The option name.
|
||||
ArgParser &optionGroup(const std::string &group,
|
||||
const std::string &opt);
|
||||
|
||||
///Make the members of a group exclusive
|
||||
|
||||
///If you call this function for a group, than at most one of them can be
|
||||
///given at the same time.
|
||||
ArgParser &onlyOneGroup(const std::string &group);
|
||||
|
||||
///Make a group mandatory
|
||||
|
||||
///Using this function, at least one of the members of \c group
|
||||
///must be given.
|
||||
ArgParser &mandatoryGroup(const std::string &group);
|
||||
|
||||
///Create synonym to an option
|
||||
|
||||
///With this function you can create a synonym \c syn of the
|
||||
///option \c opt.
|
||||
ArgParser &synonym(const std::string &syn,
|
||||
const std::string &opt);
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
void show(std::ostream &os,Opts::const_iterator i) const;
|
||||
void show(std::ostream &os,Groups::const_iterator i) const;
|
||||
void showHelp(Opts::const_iterator i) const;
|
||||
void showHelp(std::vector<OtherArg>::const_iterator i) const;
|
||||
|
||||
void unknownOpt(std::string arg) const;
|
||||
|
||||
void requiresValue(std::string arg, OptType t) const;
|
||||
void checkMandatories() const;
|
||||
|
||||
void shortHelp() const;
|
||||
void showHelp() const;
|
||||
public:
|
||||
|
||||
///Start the parsing process
|
||||
ArgParser &parse();
|
||||
|
||||
/// Synonym for parse()
|
||||
ArgParser &run()
|
||||
{
|
||||
return parse();
|
||||
}
|
||||
|
||||
///Give back the command name (the 0th argument)
|
||||
const std::string &commandName() const { return _command_name; }
|
||||
|
||||
///Check if an opion has been given to the command.
|
||||
bool given(std::string op) const
|
||||
{
|
||||
Opts::const_iterator i = _opts.find(op);
|
||||
return i!=_opts.end()?i->second.set:false;
|
||||
}
|
||||
|
||||
|
||||
///Magic type for operator[]
|
||||
|
||||
///This is the type of the return value of ArgParser::operator[]().
|
||||
///It automatically converts to \c int, \c double, \c bool or
|
||||
///\c std::string if the type of the option matches, which is checked
|
||||
///with an \ref LEMON_ASSERT "assertion" (i.e. it performs runtime
|
||||
///type checking).
|
||||
class RefType
|
||||
{
|
||||
const ArgParser &_parser;
|
||||
std::string _name;
|
||||
public:
|
||||
///\e
|
||||
RefType(const ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
|
||||
///\e
|
||||
operator bool()
|
||||
{
|
||||
Opts::const_iterator i = _parser._opts.find(_name);
|
||||
LEMON_ASSERT(i!=_parser._opts.end(),
|
||||
std::string()+"Unkown option: '"+_name+"'");
|
||||
LEMON_ASSERT(i->second.type==ArgParser::BOOL,
|
||||
std::string()+"'"+_name+"' is a bool option");
|
||||
return *(i->second.bool_p);
|
||||
}
|
||||
///\e
|
||||
operator std::string()
|
||||
{
|
||||
Opts::const_iterator i = _parser._opts.find(_name);
|
||||
LEMON_ASSERT(i!=_parser._opts.end(),
|
||||
std::string()+"Unkown option: '"+_name+"'");
|
||||
LEMON_ASSERT(i->second.type==ArgParser::STRING,
|
||||
std::string()+"'"+_name+"' is a string option");
|
||||
return *(i->second.string_p);
|
||||
}
|
||||
///\e
|
||||
operator double()
|
||||
{
|
||||
Opts::const_iterator i = _parser._opts.find(_name);
|
||||
LEMON_ASSERT(i!=_parser._opts.end(),
|
||||
std::string()+"Unkown option: '"+_name+"'");
|
||||
LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
|
||||
i->second.type==ArgParser::INTEGER,
|
||||
std::string()+"'"+_name+"' is a floating point option");
|
||||
return i->second.type==ArgParser::DOUBLE ?
|
||||
*(i->second.double_p) : *(i->second.int_p);
|
||||
}
|
||||
///\e
|
||||
operator int()
|
||||
{
|
||||
Opts::const_iterator i = _parser._opts.find(_name);
|
||||
LEMON_ASSERT(i!=_parser._opts.end(),
|
||||
std::string()+"Unkown option: '"+_name+"'");
|
||||
LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
|
||||
std::string()+"'"+_name+"' is an integer option");
|
||||
return *(i->second.int_p);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
///Give back the value of an option
|
||||
|
||||
///Give back the value of an option.
|
||||
///\sa RefType
|
||||
RefType operator[](const std::string &n) const
|
||||
{
|
||||
return RefType(*this, n);
|
||||
}
|
||||
|
||||
///Give back the non-option type arguments.
|
||||
|
||||
///Give back a reference to a vector consisting of the program arguments
|
||||
///not starting with a '-' character.
|
||||
const std::vector<std::string> &files() const { return _file_args; }
|
||||
|
||||
///Throw instead of exit in case of problems
|
||||
void throwOnProblems()
|
||||
{
|
||||
_exit_on_problems=false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LEMON_ARG_PARSER_H
|
||||
214
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/assert.h
vendored
Normal file
214
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/assert.h
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_ASSERT_H
|
||||
#define LEMON_ASSERT_H
|
||||
|
||||
/// \ingroup exceptions
|
||||
/// \file
|
||||
/// \brief Extended assertion handling
|
||||
|
||||
#include <lemon/error.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
inline void assert_fail_abort(const char *file, int line,
|
||||
const char *function, const char* message,
|
||||
const char *assertion)
|
||||
{
|
||||
std::cerr << file << ":" << line << ": ";
|
||||
if (function)
|
||||
std::cerr << function << ": ";
|
||||
std::cerr << message;
|
||||
if (assertion)
|
||||
std::cerr << " (assertion '" << assertion << "' failed)";
|
||||
std::cerr << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
namespace _assert_bits {
|
||||
|
||||
|
||||
inline const char* cstringify(const std::string& str) {
|
||||
return str.c_str();
|
||||
}
|
||||
|
||||
inline const char* cstringify(const char* str) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // LEMON_ASSERT_H
|
||||
|
||||
#undef LEMON_ASSERT
|
||||
#undef LEMON_DEBUG
|
||||
|
||||
#if (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \
|
||||
(defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
|
||||
#error "LEMON assertion system is not set properly"
|
||||
#endif
|
||||
|
||||
#if ((defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \
|
||||
(defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \
|
||||
defined(LEMON_ENABLE_ASSERTS)) && \
|
||||
(defined(LEMON_DISABLE_ASSERTS) || \
|
||||
defined(NDEBUG))
|
||||
#error "LEMON assertion system is not set properly"
|
||||
#endif
|
||||
|
||||
|
||||
#if defined LEMON_ASSERT_ABORT
|
||||
# undef LEMON_ASSERT_HANDLER
|
||||
# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
|
||||
#elif defined LEMON_ASSERT_CUSTOM
|
||||
# undef LEMON_ASSERT_HANDLER
|
||||
# ifndef LEMON_CUSTOM_ASSERT_HANDLER
|
||||
# error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
|
||||
# endif
|
||||
# define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
|
||||
#elif defined LEMON_DISABLE_ASSERTS
|
||||
# undef LEMON_ASSERT_HANDLER
|
||||
#elif defined NDEBUG
|
||||
# undef LEMON_ASSERT_HANDLER
|
||||
#else
|
||||
# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
|
||||
#endif
|
||||
|
||||
#ifndef LEMON_FUNCTION_NAME
|
||||
# if defined __GNUC__
|
||||
# define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
|
||||
# elif defined _MSC_VER
|
||||
# define LEMON_FUNCTION_NAME (__FUNCSIG__)
|
||||
# elif __STDC_VERSION__ >= 199901L
|
||||
# define LEMON_FUNCTION_NAME (__func__)
|
||||
# else
|
||||
# define LEMON_FUNCTION_NAME ("<unknown>")
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef DOXYGEN
|
||||
|
||||
/// \ingroup exceptions
|
||||
///
|
||||
/// \brief Macro for assertion with customizable message
|
||||
///
|
||||
/// Macro for assertion with customizable message.
|
||||
/// \param exp An expression that must be convertible to \c bool. If it is \c
|
||||
/// false, then an assertion is raised. The concrete behaviour depends on the
|
||||
/// settings of the assertion system.
|
||||
/// \param msg A <tt>const char*</tt> parameter, which can be used to provide
|
||||
/// information about the circumstances of the failed assertion.
|
||||
///
|
||||
/// The assertions are enabled in the default behaviour.
|
||||
/// You can disable them with the following code:
|
||||
/// \code
|
||||
/// #define LEMON_DISABLE_ASSERTS
|
||||
/// \endcode
|
||||
/// or with compilation parameters:
|
||||
/// \code
|
||||
/// g++ -DLEMON_DISABLE_ASSERTS
|
||||
/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
|
||||
/// \endcode
|
||||
/// The checking is also disabled when the standard macro \c NDEBUG is defined.
|
||||
///
|
||||
/// As a default behaviour the failed assertion prints a short log message to
|
||||
/// the standard error and aborts the execution.
|
||||
///
|
||||
/// However, the following modes can be used in the assertion system:
|
||||
/// - \c LEMON_ASSERT_ABORT The failed assertion prints a short log message to
|
||||
/// the standard error and aborts the program. It is the default behaviour.
|
||||
/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
|
||||
/// function.
|
||||
/// \code
|
||||
/// void custom_assert_handler(const char* file, int line,
|
||||
/// const char* function, const char* message,
|
||||
/// const char* assertion);
|
||||
/// \endcode
|
||||
/// The name of the function should be defined as the \c
|
||||
/// LEMON_CUSTOM_ASSERT_HANDLER macro name.
|
||||
/// \code
|
||||
/// #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
|
||||
/// \endcode
|
||||
/// Whenever an assertion is occured, the custom assertion
|
||||
/// handler is called with appropiate parameters.
|
||||
///
|
||||
/// The assertion mode can also be changed within one compilation unit.
|
||||
/// If the macros are redefined with other settings and the
|
||||
/// \ref lemon/assert.h "assert.h" file is reincluded, then the
|
||||
/// behaviour is changed appropiately to the new settings.
|
||||
# define LEMON_ASSERT(exp, msg) \
|
||||
(static_cast<void> (!!(exp) ? 0 : ( \
|
||||
LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
|
||||
LEMON_FUNCTION_NAME, \
|
||||
::lemon::_assert_bits::cstringify(msg), #exp), 0)))
|
||||
|
||||
/// \ingroup exceptions
|
||||
///
|
||||
/// \brief Macro for internal assertions
|
||||
///
|
||||
/// Macro for internal assertions, it is used in the library to check
|
||||
/// the consistency of results of algorithms, several pre- and
|
||||
/// postconditions and invariants. The checking is disabled by
|
||||
/// default, but it can be turned on with the macro \c
|
||||
/// LEMON_ENABLE_DEBUG.
|
||||
/// \code
|
||||
/// #define LEMON_ENABLE_DEBUG
|
||||
/// \endcode
|
||||
/// or with compilation parameters:
|
||||
/// \code
|
||||
/// g++ -DLEMON_ENABLE_DEBUG
|
||||
/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
|
||||
/// \endcode
|
||||
///
|
||||
/// This macro works like the \c LEMON_ASSERT macro, therefore the
|
||||
/// current behaviour depends on the settings of \c LEMON_ASSERT
|
||||
/// macro.
|
||||
///
|
||||
/// \see LEMON_ASSERT
|
||||
# define LEMON_DEBUG(exp, msg) \
|
||||
(static_cast<void> (!!(exp) ? 0 : ( \
|
||||
LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
|
||||
LEMON_FUNCTION_NAME, \
|
||||
::lemon::_assert_bits::cstringify(msg), #exp), 0)))
|
||||
|
||||
#else
|
||||
|
||||
# ifndef LEMON_ASSERT_HANDLER
|
||||
# define LEMON_ASSERT(exp, msg) (static_cast<void>(0))
|
||||
# define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
|
||||
# else
|
||||
# define LEMON_ASSERT(exp, msg) \
|
||||
(static_cast<void> (!!(exp) ? 0 : ( \
|
||||
LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
|
||||
LEMON_FUNCTION_NAME, \
|
||||
::lemon::_assert_bits::cstringify(msg), \
|
||||
#exp), 0)))
|
||||
# if defined LEMON_ENABLE_DEBUG
|
||||
# define LEMON_DEBUG(exp, msg) \
|
||||
(static_cast<void> (!!(exp) ? 0 : ( \
|
||||
LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
|
||||
LEMON_FUNCTION_NAME, \
|
||||
::lemon::_assert_bits::cstringify(msg), \
|
||||
#exp), 0)))
|
||||
# else
|
||||
# define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif
|
||||
37
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/base.cc
vendored
Normal file
37
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/base.cc
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
///\file
|
||||
///\brief Some basic non-inline functions and static global data.
|
||||
|
||||
#include<lemon/tolerance.h>
|
||||
#include<lemon/core.h>
|
||||
#include<lemon/time_measure.h>
|
||||
namespace lemon {
|
||||
|
||||
float Tolerance<float>::def_epsilon = static_cast<float>(1e-4);
|
||||
double Tolerance<double>::def_epsilon = 1e-10;
|
||||
long double Tolerance<long double>::def_epsilon = 1e-14;
|
||||
|
||||
#ifndef LEMON_ONLY_TEMPLATES
|
||||
const Invalid INVALID = Invalid();
|
||||
#endif
|
||||
|
||||
TimeStamp::Format TimeStamp::_format = TimeStamp::NORMAL;
|
||||
|
||||
} //namespace lemon
|
||||
1116
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bellman_ford.h
vendored
Normal file
1116
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bellman_ford.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1754
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bfs.h
vendored
Normal file
1754
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bfs.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
347
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bin_heap.h
vendored
Normal file
347
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bin_heap.h
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BIN_HEAP_H
|
||||
#define LEMON_BIN_HEAP_H
|
||||
|
||||
///\ingroup heaps
|
||||
///\file
|
||||
///\brief Binary heap implementation.
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \ingroup heaps
|
||||
///
|
||||
/// \brief Binary heap data structure.
|
||||
///
|
||||
/// This class implements the \e binary \e heap data structure.
|
||||
/// It fully conforms to the \ref concepts::Heap "heap concept".
|
||||
///
|
||||
/// \tparam PR Type of the priorities of the items.
|
||||
/// \tparam IM A read-writable item map with \c int values, used
|
||||
/// internally to handle the cross references.
|
||||
/// \tparam CMP A functor class for comparing the priorities.
|
||||
/// The default is \c std::less<PR>.
|
||||
#ifdef DOXYGEN
|
||||
template <typename PR, typename IM, typename CMP>
|
||||
#else
|
||||
template <typename PR, typename IM, typename CMP = std::less<PR> >
|
||||
#endif
|
||||
class BinHeap {
|
||||
public:
|
||||
|
||||
/// Type of the item-int map.
|
||||
typedef IM ItemIntMap;
|
||||
/// Type of the priorities.
|
||||
typedef PR Prio;
|
||||
/// Type of the items stored in the heap.
|
||||
typedef typename ItemIntMap::Key Item;
|
||||
/// Type of the item-priority pairs.
|
||||
typedef std::pair<Item,Prio> Pair;
|
||||
/// Functor type for comparing the priorities.
|
||||
typedef CMP Compare;
|
||||
|
||||
/// \brief Type to represent the states of the items.
|
||||
///
|
||||
/// Each item has a state associated to it. It can be "in heap",
|
||||
/// "pre-heap" or "post-heap". The latter two are indifferent from the
|
||||
/// heap's point of view, but may be useful to the user.
|
||||
///
|
||||
/// The item-int map must be initialized in such way that it assigns
|
||||
/// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
|
||||
enum State {
|
||||
IN_HEAP = 0, ///< = 0.
|
||||
PRE_HEAP = -1, ///< = -1.
|
||||
POST_HEAP = -2 ///< = -2.
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<Pair> _data;
|
||||
Compare _comp;
|
||||
ItemIntMap &_iim;
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to the items.
|
||||
/// It is used internally to handle the cross references.
|
||||
/// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
explicit BinHeap(ItemIntMap &map) : _iim(map) {}
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to the items.
|
||||
/// It is used internally to handle the cross references.
|
||||
/// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
/// \param comp The function object used for comparing the priorities.
|
||||
BinHeap(ItemIntMap &map, const Compare &comp)
|
||||
: _iim(map), _comp(comp) {}
|
||||
|
||||
|
||||
/// \brief The number of items stored in the heap.
|
||||
///
|
||||
/// This function returns the number of items stored in the heap.
|
||||
int size() const { return _data.size(); }
|
||||
|
||||
/// \brief Check if the heap is empty.
|
||||
///
|
||||
/// This function returns \c true if the heap is empty.
|
||||
bool empty() const { return _data.empty(); }
|
||||
|
||||
/// \brief Make the heap empty.
|
||||
///
|
||||
/// This functon makes the heap empty.
|
||||
/// It does not change the cross reference map. If you want to reuse
|
||||
/// a heap that is not surely empty, you should first clear it and
|
||||
/// then you should set the cross reference map to \c PRE_HEAP
|
||||
/// for each item.
|
||||
void clear() {
|
||||
_data.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
static int parent(int i) { return (i-1)/2; }
|
||||
|
||||
static int secondChild(int i) { return 2*i+2; }
|
||||
bool less(const Pair &p1, const Pair &p2) const {
|
||||
return _comp(p1.second, p2.second);
|
||||
}
|
||||
|
||||
int bubbleUp(int hole, Pair p) {
|
||||
int par = parent(hole);
|
||||
while( hole>0 && less(p,_data[par]) ) {
|
||||
move(_data[par],hole);
|
||||
hole = par;
|
||||
par = parent(hole);
|
||||
}
|
||||
move(p, hole);
|
||||
return hole;
|
||||
}
|
||||
|
||||
int bubbleDown(int hole, Pair p, int length) {
|
||||
int child = secondChild(hole);
|
||||
while(child < length) {
|
||||
if( less(_data[child-1], _data[child]) ) {
|
||||
--child;
|
||||
}
|
||||
if( !less(_data[child], p) )
|
||||
goto ok;
|
||||
move(_data[child], hole);
|
||||
hole = child;
|
||||
child = secondChild(hole);
|
||||
}
|
||||
child--;
|
||||
if( child<length && less(_data[child], p) ) {
|
||||
move(_data[child], hole);
|
||||
hole=child;
|
||||
}
|
||||
ok:
|
||||
move(p, hole);
|
||||
return hole;
|
||||
}
|
||||
|
||||
void move(const Pair &p, int i) {
|
||||
_data[i] = p;
|
||||
_iim.set(p.first, i);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Insert a pair of item and priority into the heap.
|
||||
///
|
||||
/// This function inserts \c p.first to the heap with priority
|
||||
/// \c p.second.
|
||||
/// \param p The pair to insert.
|
||||
/// \pre \c p.first must not be stored in the heap.
|
||||
void push(const Pair &p) {
|
||||
int n = _data.size();
|
||||
_data.resize(n+1);
|
||||
bubbleUp(n, p);
|
||||
}
|
||||
|
||||
/// \brief Insert an item into the heap with the given priority.
|
||||
///
|
||||
/// This function inserts the given item into the heap with the
|
||||
/// given priority.
|
||||
/// \param i The item to insert.
|
||||
/// \param p The priority of the item.
|
||||
/// \pre \e i must not be stored in the heap.
|
||||
void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
|
||||
|
||||
/// \brief Return the item having minimum priority.
|
||||
///
|
||||
/// This function returns the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Item top() const {
|
||||
return _data[0].first;
|
||||
}
|
||||
|
||||
/// \brief The minimum priority.
|
||||
///
|
||||
/// This function returns the minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Prio prio() const {
|
||||
return _data[0].second;
|
||||
}
|
||||
|
||||
/// \brief Remove the item having minimum priority.
|
||||
///
|
||||
/// This function removes the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
void pop() {
|
||||
int n = _data.size()-1;
|
||||
_iim.set(_data[0].first, POST_HEAP);
|
||||
if (n > 0) {
|
||||
bubbleDown(0, _data[n], n);
|
||||
}
|
||||
_data.pop_back();
|
||||
}
|
||||
|
||||
/// \brief Remove the given item from the heap.
|
||||
///
|
||||
/// This function removes the given item from the heap if it is
|
||||
/// already stored.
|
||||
/// \param i The item to delete.
|
||||
/// \pre \e i must be in the heap.
|
||||
void erase(const Item &i) {
|
||||
int h = _iim[i];
|
||||
int n = _data.size()-1;
|
||||
_iim.set(_data[h].first, POST_HEAP);
|
||||
if( h < n ) {
|
||||
if ( bubbleUp(h, _data[n]) == h) {
|
||||
bubbleDown(h, _data[n], n);
|
||||
}
|
||||
}
|
||||
_data.pop_back();
|
||||
}
|
||||
|
||||
/// \brief The priority of the given item.
|
||||
///
|
||||
/// This function returns the priority of the given item.
|
||||
/// \param i The item.
|
||||
/// \pre \e i must be in the heap.
|
||||
Prio operator[](const Item &i) const {
|
||||
int idx = _iim[i];
|
||||
return _data[idx].second;
|
||||
}
|
||||
|
||||
/// \brief Set the priority of an item or insert it, if it is
|
||||
/// not stored in the heap.
|
||||
///
|
||||
/// This method sets the priority of the given item if it is
|
||||
/// already stored in the heap. Otherwise it inserts the given
|
||||
/// item into the heap with the given priority.
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
void set(const Item &i, const Prio &p) {
|
||||
int idx = _iim[i];
|
||||
if( idx < 0 ) {
|
||||
push(i,p);
|
||||
}
|
||||
else if( _comp(p, _data[idx].second) ) {
|
||||
bubbleUp(idx, Pair(i,p));
|
||||
}
|
||||
else {
|
||||
bubbleDown(idx, Pair(i,p), _data.size());
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Decrease the priority of an item to the given value.
|
||||
///
|
||||
/// This function decreases the priority of an item to the given value.
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
/// \pre \e i must be stored in the heap with priority at least \e p.
|
||||
void decrease(const Item &i, const Prio &p) {
|
||||
int idx = _iim[i];
|
||||
bubbleUp(idx, Pair(i,p));
|
||||
}
|
||||
|
||||
/// \brief Increase the priority of an item to the given value.
|
||||
///
|
||||
/// This function increases the priority of an item to the given value.
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
/// \pre \e i must be stored in the heap with priority at most \e p.
|
||||
void increase(const Item &i, const Prio &p) {
|
||||
int idx = _iim[i];
|
||||
bubbleDown(idx, Pair(i,p), _data.size());
|
||||
}
|
||||
|
||||
/// \brief Return the state of an item.
|
||||
///
|
||||
/// This method returns \c PRE_HEAP if the given item has never
|
||||
/// been in the heap, \c IN_HEAP if it is in the heap at the moment,
|
||||
/// and \c POST_HEAP otherwise.
|
||||
/// In the latter case it is possible that the item will get back
|
||||
/// to the heap again.
|
||||
/// \param i The item.
|
||||
State state(const Item &i) const {
|
||||
int s = _iim[i];
|
||||
if( s>=0 )
|
||||
s=0;
|
||||
return State(s);
|
||||
}
|
||||
|
||||
/// \brief Set the state of an item in the heap.
|
||||
///
|
||||
/// This function sets the state of the given item in the heap.
|
||||
/// It can be used to manually clear the heap when it is important
|
||||
/// to achive better time complexity.
|
||||
/// \param i The item.
|
||||
/// \param st The state. It should not be \c IN_HEAP.
|
||||
void state(const Item& i, State st) {
|
||||
switch (st) {
|
||||
case POST_HEAP:
|
||||
case PRE_HEAP:
|
||||
if (state(i) == IN_HEAP) {
|
||||
erase(i);
|
||||
}
|
||||
_iim[i] = st;
|
||||
break;
|
||||
case IN_HEAP:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Replace an item in the heap.
|
||||
///
|
||||
/// This function replaces item \c i with item \c j.
|
||||
/// Item \c i must be in the heap, while \c j must be out of the heap.
|
||||
/// After calling this method, item \c i will be out of the
|
||||
/// heap and \c j will be in the heap with the same prioriority
|
||||
/// as item \c i had before.
|
||||
void replace(const Item& i, const Item& j) {
|
||||
int idx = _iim[i];
|
||||
_iim.set(i, _iim[j]);
|
||||
_iim.set(j, idx);
|
||||
_data[idx].first = j;
|
||||
}
|
||||
|
||||
}; // class BinHeap
|
||||
|
||||
} // namespace lemon
|
||||
|
||||
#endif // LEMON_BIN_HEAP_H
|
||||
445
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/binomial_heap.h
vendored
Normal file
445
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/binomial_heap.h
vendored
Normal file
@@ -0,0 +1,445 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2010
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BINOMIAL_HEAP_H
|
||||
#define LEMON_BINOMIAL_HEAP_H
|
||||
|
||||
///\file
|
||||
///\ingroup heaps
|
||||
///\brief Binomial Heap implementation.
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <lemon/math.h>
|
||||
#include <lemon/counter.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \ingroup heaps
|
||||
///
|
||||
///\brief Binomial heap data structure.
|
||||
///
|
||||
/// This class implements the \e binomial \e heap data structure.
|
||||
/// It fully conforms to the \ref concepts::Heap "heap concept".
|
||||
///
|
||||
/// The methods \ref increase() and \ref erase() are not efficient
|
||||
/// in a binomial heap. In case of many calls of these operations,
|
||||
/// it is better to use other heap structure, e.g. \ref BinHeap
|
||||
/// "binary heap".
|
||||
///
|
||||
/// \tparam PR Type of the priorities of the items.
|
||||
/// \tparam IM A read-writable item map with \c int values, used
|
||||
/// internally to handle the cross references.
|
||||
/// \tparam CMP A functor class for comparing the priorities.
|
||||
/// The default is \c std::less<PR>.
|
||||
#ifdef DOXYGEN
|
||||
template <typename PR, typename IM, typename CMP>
|
||||
#else
|
||||
template <typename PR, typename IM, typename CMP = std::less<PR> >
|
||||
#endif
|
||||
class BinomialHeap {
|
||||
public:
|
||||
/// Type of the item-int map.
|
||||
typedef IM ItemIntMap;
|
||||
/// Type of the priorities.
|
||||
typedef PR Prio;
|
||||
/// Type of the items stored in the heap.
|
||||
typedef typename ItemIntMap::Key Item;
|
||||
/// Functor type for comparing the priorities.
|
||||
typedef CMP Compare;
|
||||
|
||||
/// \brief Type to represent the states of the items.
|
||||
///
|
||||
/// Each item has a state associated to it. It can be "in heap",
|
||||
/// "pre-heap" or "post-heap". The latter two are indifferent from the
|
||||
/// heap's point of view, but may be useful to the user.
|
||||
///
|
||||
/// The item-int map must be initialized in such way that it assigns
|
||||
/// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
|
||||
enum State {
|
||||
IN_HEAP = 0, ///< = 0.
|
||||
PRE_HEAP = -1, ///< = -1.
|
||||
POST_HEAP = -2 ///< = -2.
|
||||
};
|
||||
|
||||
private:
|
||||
class Store;
|
||||
|
||||
std::vector<Store> _data;
|
||||
int _min, _head;
|
||||
ItemIntMap &_iim;
|
||||
Compare _comp;
|
||||
int _num_items;
|
||||
|
||||
public:
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to the items.
|
||||
/// It is used internally to handle the cross references.
|
||||
/// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
explicit BinomialHeap(ItemIntMap &map)
|
||||
: _min(0), _head(-1), _iim(map), _num_items(0) {}
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to the items.
|
||||
/// It is used internally to handle the cross references.
|
||||
/// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
/// \param comp The function object used for comparing the priorities.
|
||||
BinomialHeap(ItemIntMap &map, const Compare &comp)
|
||||
: _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
|
||||
|
||||
/// \brief The number of items stored in the heap.
|
||||
///
|
||||
/// This function returns the number of items stored in the heap.
|
||||
int size() const { return _num_items; }
|
||||
|
||||
/// \brief Check if the heap is empty.
|
||||
///
|
||||
/// This function returns \c true if the heap is empty.
|
||||
bool empty() const { return _num_items==0; }
|
||||
|
||||
/// \brief Make the heap empty.
|
||||
///
|
||||
/// This functon makes the heap empty.
|
||||
/// It does not change the cross reference map. If you want to reuse
|
||||
/// a heap that is not surely empty, you should first clear it and
|
||||
/// then you should set the cross reference map to \c PRE_HEAP
|
||||
/// for each item.
|
||||
void clear() {
|
||||
_data.clear(); _min=0; _num_items=0; _head=-1;
|
||||
}
|
||||
|
||||
/// \brief Set the priority of an item or insert it, if it is
|
||||
/// not stored in the heap.
|
||||
///
|
||||
/// This method sets the priority of the given item if it is
|
||||
/// already stored in the heap. Otherwise it inserts the given
|
||||
/// item into the heap with the given priority.
|
||||
/// \param item The item.
|
||||
/// \param value The priority.
|
||||
void set (const Item& item, const Prio& value) {
|
||||
int i=_iim[item];
|
||||
if ( i >= 0 && _data[i].in ) {
|
||||
if ( _comp(value, _data[i].prio) ) decrease(item, value);
|
||||
if ( _comp(_data[i].prio, value) ) increase(item, value);
|
||||
} else push(item, value);
|
||||
}
|
||||
|
||||
/// \brief Insert an item into the heap with the given priority.
|
||||
///
|
||||
/// This function inserts the given item into the heap with the
|
||||
/// given priority.
|
||||
/// \param item The item to insert.
|
||||
/// \param value The priority of the item.
|
||||
/// \pre \e item must not be stored in the heap.
|
||||
void push (const Item& item, const Prio& value) {
|
||||
int i=_iim[item];
|
||||
if ( i<0 ) {
|
||||
int s=_data.size();
|
||||
_iim.set( item,s );
|
||||
Store st;
|
||||
st.name=item;
|
||||
st.prio=value;
|
||||
_data.push_back(st);
|
||||
i=s;
|
||||
}
|
||||
else {
|
||||
_data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
|
||||
_data[i].degree=0;
|
||||
_data[i].in=true;
|
||||
_data[i].prio=value;
|
||||
}
|
||||
|
||||
if( 0==_num_items ) {
|
||||
_head=i;
|
||||
_min=i;
|
||||
} else {
|
||||
merge(i);
|
||||
if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
|
||||
}
|
||||
++_num_items;
|
||||
}
|
||||
|
||||
/// \brief Return the item having minimum priority.
|
||||
///
|
||||
/// This function returns the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Item top() const { return _data[_min].name; }
|
||||
|
||||
/// \brief The minimum priority.
|
||||
///
|
||||
/// This function returns the minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Prio prio() const { return _data[_min].prio; }
|
||||
|
||||
/// \brief The priority of the given item.
|
||||
///
|
||||
/// This function returns the priority of the given item.
|
||||
/// \param item The item.
|
||||
/// \pre \e item must be in the heap.
|
||||
const Prio& operator[](const Item& item) const {
|
||||
return _data[_iim[item]].prio;
|
||||
}
|
||||
|
||||
/// \brief Remove the item having minimum priority.
|
||||
///
|
||||
/// This function removes the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
void pop() {
|
||||
_data[_min].in=false;
|
||||
|
||||
int head_child=-1;
|
||||
if ( _data[_min].child!=-1 ) {
|
||||
int child=_data[_min].child;
|
||||
int neighb;
|
||||
while( child!=-1 ) {
|
||||
neighb=_data[child].right_neighbor;
|
||||
_data[child].parent=-1;
|
||||
_data[child].right_neighbor=head_child;
|
||||
head_child=child;
|
||||
child=neighb;
|
||||
}
|
||||
}
|
||||
|
||||
if ( _data[_head].right_neighbor==-1 ) {
|
||||
// there was only one root
|
||||
_head=head_child;
|
||||
}
|
||||
else {
|
||||
// there were more roots
|
||||
if( _head!=_min ) { unlace(_min); }
|
||||
else { _head=_data[_head].right_neighbor; }
|
||||
merge(head_child);
|
||||
}
|
||||
_min=findMin();
|
||||
--_num_items;
|
||||
}
|
||||
|
||||
/// \brief Remove the given item from the heap.
|
||||
///
|
||||
/// This function removes the given item from the heap if it is
|
||||
/// already stored.
|
||||
/// \param item The item to delete.
|
||||
/// \pre \e item must be in the heap.
|
||||
void erase (const Item& item) {
|
||||
int i=_iim[item];
|
||||
if ( i >= 0 && _data[i].in ) {
|
||||
decrease( item, _data[_min].prio-1 );
|
||||
pop();
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Decrease the priority of an item to the given value.
|
||||
///
|
||||
/// This function decreases the priority of an item to the given value.
|
||||
/// \param item The item.
|
||||
/// \param value The priority.
|
||||
/// \pre \e item must be stored in the heap with priority at least \e value.
|
||||
void decrease (Item item, const Prio& value) {
|
||||
int i=_iim[item];
|
||||
int p=_data[i].parent;
|
||||
_data[i].prio=value;
|
||||
|
||||
while( p!=-1 && _comp(value, _data[p].prio) ) {
|
||||
_data[i].name=_data[p].name;
|
||||
_data[i].prio=_data[p].prio;
|
||||
_data[p].name=item;
|
||||
_data[p].prio=value;
|
||||
_iim[_data[i].name]=i;
|
||||
i=p;
|
||||
p=_data[p].parent;
|
||||
}
|
||||
_iim[item]=i;
|
||||
if ( _comp(value, _data[_min].prio) ) _min=i;
|
||||
}
|
||||
|
||||
/// \brief Increase the priority of an item to the given value.
|
||||
///
|
||||
/// This function increases the priority of an item to the given value.
|
||||
/// \param item The item.
|
||||
/// \param value The priority.
|
||||
/// \pre \e item must be stored in the heap with priority at most \e value.
|
||||
void increase (Item item, const Prio& value) {
|
||||
erase(item);
|
||||
push(item, value);
|
||||
}
|
||||
|
||||
/// \brief Return the state of an item.
|
||||
///
|
||||
/// This method returns \c PRE_HEAP if the given item has never
|
||||
/// been in the heap, \c IN_HEAP if it is in the heap at the moment,
|
||||
/// and \c POST_HEAP otherwise.
|
||||
/// In the latter case it is possible that the item will get back
|
||||
/// to the heap again.
|
||||
/// \param item The item.
|
||||
State state(const Item &item) const {
|
||||
int i=_iim[item];
|
||||
if( i>=0 ) {
|
||||
if ( _data[i].in ) i=0;
|
||||
else i=-2;
|
||||
}
|
||||
return State(i);
|
||||
}
|
||||
|
||||
/// \brief Set the state of an item in the heap.
|
||||
///
|
||||
/// This function sets the state of the given item in the heap.
|
||||
/// It can be used to manually clear the heap when it is important
|
||||
/// to achive better time complexity.
|
||||
/// \param i The item.
|
||||
/// \param st The state. It should not be \c IN_HEAP.
|
||||
void state(const Item& i, State st) {
|
||||
switch (st) {
|
||||
case POST_HEAP:
|
||||
case PRE_HEAP:
|
||||
if (state(i) == IN_HEAP) {
|
||||
erase(i);
|
||||
}
|
||||
_iim[i] = st;
|
||||
break;
|
||||
case IN_HEAP:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Find the minimum of the roots
|
||||
int findMin() {
|
||||
if( _head!=-1 ) {
|
||||
int min_loc=_head, min_val=_data[_head].prio;
|
||||
for( int x=_data[_head].right_neighbor; x!=-1;
|
||||
x=_data[x].right_neighbor ) {
|
||||
if( _comp( _data[x].prio,min_val ) ) {
|
||||
min_val=_data[x].prio;
|
||||
min_loc=x;
|
||||
}
|
||||
}
|
||||
return min_loc;
|
||||
}
|
||||
else return -1;
|
||||
}
|
||||
|
||||
// Merge the heap with another heap starting at the given position
|
||||
void merge(int a) {
|
||||
if( _head==-1 || a==-1 ) return;
|
||||
if( _data[a].right_neighbor==-1 &&
|
||||
_data[a].degree<=_data[_head].degree ) {
|
||||
_data[a].right_neighbor=_head;
|
||||
_head=a;
|
||||
} else {
|
||||
interleave(a);
|
||||
}
|
||||
if( _data[_head].right_neighbor==-1 ) return;
|
||||
|
||||
int x=_head;
|
||||
int x_prev=-1, x_next=_data[x].right_neighbor;
|
||||
while( x_next!=-1 ) {
|
||||
if( _data[x].degree!=_data[x_next].degree ||
|
||||
( _data[x_next].right_neighbor!=-1 &&
|
||||
_data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
|
||||
x_prev=x;
|
||||
x=x_next;
|
||||
}
|
||||
else {
|
||||
if( _comp(_data[x_next].prio,_data[x].prio) ) {
|
||||
if( x_prev==-1 ) {
|
||||
_head=x_next;
|
||||
} else {
|
||||
_data[x_prev].right_neighbor=x_next;
|
||||
}
|
||||
fuse(x,x_next);
|
||||
x=x_next;
|
||||
}
|
||||
else {
|
||||
_data[x].right_neighbor=_data[x_next].right_neighbor;
|
||||
fuse(x_next,x);
|
||||
}
|
||||
}
|
||||
x_next=_data[x].right_neighbor;
|
||||
}
|
||||
}
|
||||
|
||||
// Interleave the elements of the given list into the list of the roots
|
||||
void interleave(int a) {
|
||||
int p=_head, q=a;
|
||||
int curr=_data.size();
|
||||
_data.push_back(Store());
|
||||
|
||||
while( p!=-1 || q!=-1 ) {
|
||||
if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
|
||||
_data[curr].right_neighbor=p;
|
||||
curr=p;
|
||||
p=_data[p].right_neighbor;
|
||||
}
|
||||
else {
|
||||
_data[curr].right_neighbor=q;
|
||||
curr=q;
|
||||
q=_data[q].right_neighbor;
|
||||
}
|
||||
}
|
||||
|
||||
_head=_data.back().right_neighbor;
|
||||
_data.pop_back();
|
||||
}
|
||||
|
||||
// Lace node a under node b
|
||||
void fuse(int a, int b) {
|
||||
_data[a].parent=b;
|
||||
_data[a].right_neighbor=_data[b].child;
|
||||
_data[b].child=a;
|
||||
|
||||
++_data[b].degree;
|
||||
}
|
||||
|
||||
// Unlace node a (if it has siblings)
|
||||
void unlace(int a) {
|
||||
int neighb=_data[a].right_neighbor;
|
||||
int other=_head;
|
||||
|
||||
while( _data[other].right_neighbor!=a )
|
||||
other=_data[other].right_neighbor;
|
||||
_data[other].right_neighbor=neighb;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class Store {
|
||||
friend class BinomialHeap;
|
||||
|
||||
Item name;
|
||||
int parent;
|
||||
int right_neighbor;
|
||||
int child;
|
||||
int degree;
|
||||
bool in;
|
||||
Prio prio;
|
||||
|
||||
Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
|
||||
in(true) {}
|
||||
};
|
||||
};
|
||||
|
||||
} //namespace lemon
|
||||
|
||||
#endif //LEMON_BINOMIAL_HEAP_H
|
||||
|
||||
472
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/alteration_notifier.h
vendored
Normal file
472
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/alteration_notifier.h
vendored
Normal file
@@ -0,0 +1,472 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_ALTERATION_NOTIFIER_H
|
||||
#define LEMON_BITS_ALTERATION_NOTIFIER_H
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/bits/lock.h>
|
||||
|
||||
//\ingroup graphbits
|
||||
//\file
|
||||
//\brief Observer notifier for graph alteration observers.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
// \ingroup graphbits
|
||||
//
|
||||
// \brief Notifier class to notify observes about alterations in
|
||||
// a container.
|
||||
//
|
||||
// The simple graphs can be refered as two containers: a node container
|
||||
// and an edge container. But they do not store values directly, they
|
||||
// are just key continars for more value containers, which are the
|
||||
// node and edge maps.
|
||||
//
|
||||
// The node and edge sets of the graphs can be changed as we add or erase
|
||||
// nodes and edges in the graph. LEMON would like to handle easily
|
||||
// that the node and edge maps should contain values for all nodes or
|
||||
// edges. If we want to check on every indicing if the map contains
|
||||
// the current indicing key that cause a drawback in the performance
|
||||
// in the library. We use another solution: we notify all maps about
|
||||
// an alteration in the graph, which cause only drawback on the
|
||||
// alteration of the graph.
|
||||
//
|
||||
// This class provides an interface to a node or edge container.
|
||||
// The first() and next() member functions make possible
|
||||
// to iterate on the keys of the container.
|
||||
// The id() function returns an integer id for each key.
|
||||
// The maxId() function gives back an upper bound of the ids.
|
||||
//
|
||||
// For the proper functonality of this class, we should notify it
|
||||
// about each alteration in the container. The alterations have four type:
|
||||
// add(), erase(), build() and clear(). The add() and
|
||||
// erase() signal that only one or few items added or erased to or
|
||||
// from the graph. If all items are erased from the graph or if a new graph
|
||||
// is built from an empty graph, then it can be signaled with the
|
||||
// clear() and build() members. Important rule that if we erase items
|
||||
// from graphs we should first signal the alteration and after that erase
|
||||
// them from the container, on the other way on item addition we should
|
||||
// first extend the container and just after that signal the alteration.
|
||||
//
|
||||
// The alteration can be observed with a class inherited from the
|
||||
// ObserverBase nested class. The signals can be handled with
|
||||
// overriding the virtual functions defined in the base class. The
|
||||
// observer base can be attached to the notifier with the
|
||||
// attach() member and can be detached with detach() function. The
|
||||
// alteration handlers should not call any function which signals
|
||||
// an other alteration in the same notifier and should not
|
||||
// detach any observer from the notifier.
|
||||
//
|
||||
// Alteration observers try to be exception safe. If an add() or
|
||||
// a clear() function throws an exception then the remaining
|
||||
// observeres will not be notified and the fulfilled additions will
|
||||
// be rolled back by calling the erase() or clear() functions.
|
||||
// Hence erase() and clear() should not throw exception.
|
||||
// Actullay, they can throw only \ref ImmediateDetach exception,
|
||||
// which detach the observer from the notifier.
|
||||
//
|
||||
// There are some cases, when the alteration observing is not completly
|
||||
// reliable. If we want to carry out the node degree in the graph
|
||||
// as in the \ref InDegMap and we use the reverseArc(), then it cause
|
||||
// unreliable functionality. Because the alteration observing signals
|
||||
// only erasing and adding but not the reversing, it will stores bad
|
||||
// degrees. Apart form that the subgraph adaptors cannot even signal
|
||||
// the alterations because just a setting in the filter map can modify
|
||||
// the graph and this cannot be watched in any way.
|
||||
//
|
||||
// \param _Container The container which is observed.
|
||||
// \param _Item The item type which is obserbved.
|
||||
|
||||
template <typename _Container, typename _Item>
|
||||
class AlterationNotifier {
|
||||
public:
|
||||
|
||||
typedef True Notifier;
|
||||
|
||||
typedef _Container Container;
|
||||
typedef _Item Item;
|
||||
|
||||
// \brief Exception which can be called from clear() and
|
||||
// erase().
|
||||
//
|
||||
// From the clear() and erase() function only this
|
||||
// exception is allowed to throw. The exception immediatly
|
||||
// detaches the current observer from the notifier. Because the
|
||||
// clear() and erase() should not throw other exceptions
|
||||
// it can be used to invalidate the observer.
|
||||
struct ImmediateDetach {};
|
||||
|
||||
// \brief ObserverBase is the base class for the observers.
|
||||
//
|
||||
// ObserverBase is the abstract base class for the observers.
|
||||
// It will be notified about an item was inserted into or
|
||||
// erased from the graph.
|
||||
//
|
||||
// The observer interface contains some pure virtual functions
|
||||
// to override. The add() and erase() functions are
|
||||
// to notify the oberver when one item is added or erased.
|
||||
//
|
||||
// The build() and clear() members are to notify the observer
|
||||
// about the container is built from an empty container or
|
||||
// is cleared to an empty container.
|
||||
class ObserverBase {
|
||||
protected:
|
||||
typedef AlterationNotifier Notifier;
|
||||
|
||||
friend class AlterationNotifier;
|
||||
|
||||
// \brief Default constructor.
|
||||
//
|
||||
// Default constructor for ObserverBase.
|
||||
ObserverBase() : _notifier(0) {}
|
||||
|
||||
// \brief Constructor which attach the observer into notifier.
|
||||
//
|
||||
// Constructor which attach the observer into notifier.
|
||||
ObserverBase(AlterationNotifier& nf) {
|
||||
attach(nf);
|
||||
}
|
||||
|
||||
// \brief Constructor which attach the obserever to the same notifier.
|
||||
//
|
||||
// Constructor which attach the obserever to the same notifier as
|
||||
// the other observer is attached to.
|
||||
ObserverBase(const ObserverBase& copy) {
|
||||
if (copy.attached()) {
|
||||
attach(*copy.notifier());
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Destructor
|
||||
virtual ~ObserverBase() {
|
||||
if (attached()) {
|
||||
detach();
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Attaches the observer into an AlterationNotifier.
|
||||
//
|
||||
// This member attaches the observer into an AlterationNotifier.
|
||||
void attach(AlterationNotifier& nf) {
|
||||
nf.attach(*this);
|
||||
}
|
||||
|
||||
// \brief Detaches the observer into an AlterationNotifier.
|
||||
//
|
||||
// This member detaches the observer from an AlterationNotifier.
|
||||
void detach() {
|
||||
_notifier->detach(*this);
|
||||
}
|
||||
|
||||
// \brief Gives back a pointer to the notifier which the map
|
||||
// attached into.
|
||||
//
|
||||
// This function gives back a pointer to the notifier which the map
|
||||
// attached into.
|
||||
Notifier* notifier() const { return const_cast<Notifier*>(_notifier); }
|
||||
|
||||
// Gives back true when the observer is attached into a notifier.
|
||||
bool attached() const { return _notifier != 0; }
|
||||
|
||||
private:
|
||||
|
||||
ObserverBase& operator=(const ObserverBase& copy);
|
||||
|
||||
protected:
|
||||
|
||||
Notifier* _notifier;
|
||||
typename std::list<ObserverBase*>::iterator _index;
|
||||
|
||||
// \brief The member function to notificate the observer about an
|
||||
// item is added to the container.
|
||||
//
|
||||
// The add() member function notificates the observer about an item
|
||||
// is added to the container. It have to be overrided in the
|
||||
// subclasses.
|
||||
virtual void add(const Item&) = 0;
|
||||
|
||||
// \brief The member function to notificate the observer about
|
||||
// more item is added to the container.
|
||||
//
|
||||
// The add() member function notificates the observer about more item
|
||||
// is added to the container. It have to be overrided in the
|
||||
// subclasses.
|
||||
virtual void add(const std::vector<Item>& items) = 0;
|
||||
|
||||
// \brief The member function to notificate the observer about an
|
||||
// item is erased from the container.
|
||||
//
|
||||
// The erase() member function notificates the observer about an
|
||||
// item is erased from the container. It have to be overrided in
|
||||
// the subclasses.
|
||||
virtual void erase(const Item&) = 0;
|
||||
|
||||
// \brief The member function to notificate the observer about
|
||||
// more item is erased from the container.
|
||||
//
|
||||
// The erase() member function notificates the observer about more item
|
||||
// is erased from the container. It have to be overrided in the
|
||||
// subclasses.
|
||||
virtual void erase(const std::vector<Item>& items) = 0;
|
||||
|
||||
// \brief The member function to notificate the observer about the
|
||||
// container is built.
|
||||
//
|
||||
// The build() member function notificates the observer about the
|
||||
// container is built from an empty container. It have to be
|
||||
// overrided in the subclasses.
|
||||
virtual void build() = 0;
|
||||
|
||||
// \brief The member function to notificate the observer about all
|
||||
// items are erased from the container.
|
||||
//
|
||||
// The clear() member function notificates the observer about all
|
||||
// items are erased from the container. It have to be overrided in
|
||||
// the subclasses.
|
||||
virtual void clear() = 0;
|
||||
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
const Container* container;
|
||||
|
||||
typedef std::list<ObserverBase*> Observers;
|
||||
Observers _observers;
|
||||
lemon::bits::Lock _lock;
|
||||
|
||||
public:
|
||||
|
||||
// \brief Default constructor.
|
||||
//
|
||||
// The default constructor of the AlterationNotifier.
|
||||
// It creates an empty notifier.
|
||||
AlterationNotifier()
|
||||
: container(0) {}
|
||||
|
||||
// \brief Constructor.
|
||||
//
|
||||
// Constructor with the observed container parameter.
|
||||
AlterationNotifier(const Container& _container)
|
||||
: container(&_container) {}
|
||||
|
||||
// \brief Copy Constructor of the AlterationNotifier.
|
||||
//
|
||||
// Copy constructor of the AlterationNotifier.
|
||||
// It creates only an empty notifier because the copiable
|
||||
// notifier's observers have to be registered still into that notifier.
|
||||
AlterationNotifier(const AlterationNotifier& _notifier)
|
||||
: container(_notifier.container) {}
|
||||
|
||||
// \brief Destructor.
|
||||
//
|
||||
// Destructor of the AlterationNotifier.
|
||||
~AlterationNotifier() {
|
||||
typename Observers::iterator it;
|
||||
for (it = _observers.begin(); it != _observers.end(); ++it) {
|
||||
(*it)->_notifier = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Sets the container.
|
||||
//
|
||||
// Sets the container.
|
||||
void setContainer(const Container& _container) {
|
||||
container = &_container;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
AlterationNotifier& operator=(const AlterationNotifier&);
|
||||
|
||||
public:
|
||||
|
||||
// \brief First item in the container.
|
||||
//
|
||||
// Returns the first item in the container. It is
|
||||
// for start the iteration on the container.
|
||||
void first(Item& item) const {
|
||||
container->first(item);
|
||||
}
|
||||
|
||||
// \brief Next item in the container.
|
||||
//
|
||||
// Returns the next item in the container. It is
|
||||
// for iterate on the container.
|
||||
void next(Item& item) const {
|
||||
container->next(item);
|
||||
}
|
||||
|
||||
// \brief Returns the id of the item.
|
||||
//
|
||||
// Returns the id of the item provided by the container.
|
||||
int id(const Item& item) const {
|
||||
return container->id(item);
|
||||
}
|
||||
|
||||
// \brief Returns the maximum id of the container.
|
||||
//
|
||||
// Returns the maximum id of the container.
|
||||
int maxId() const {
|
||||
return container->maxId(Item());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void attach(ObserverBase& observer) {
|
||||
_lock.lock();
|
||||
observer._index = _observers.insert(_observers.begin(), &observer);
|
||||
observer._notifier = this;
|
||||
_lock.unlock();
|
||||
}
|
||||
|
||||
void detach(ObserverBase& observer) {
|
||||
_lock.lock();
|
||||
_observers.erase(observer._index);
|
||||
observer._index = _observers.end();
|
||||
observer._notifier = 0;
|
||||
_lock.unlock();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// \brief Notifies all the registed observers about an item added to
|
||||
// the container.
|
||||
//
|
||||
// It notifies all the registed observers about an item added to
|
||||
// the container.
|
||||
void add(const Item& item) {
|
||||
typename Observers::reverse_iterator it;
|
||||
try {
|
||||
for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
|
||||
(*it)->add(item);
|
||||
}
|
||||
} catch (...) {
|
||||
typename Observers::iterator jt;
|
||||
for (jt = it.base(); jt != _observers.end(); ++jt) {
|
||||
(*jt)->erase(item);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Notifies all the registed observers about more item added to
|
||||
// the container.
|
||||
//
|
||||
// It notifies all the registed observers about more item added to
|
||||
// the container.
|
||||
void add(const std::vector<Item>& items) {
|
||||
typename Observers::reverse_iterator it;
|
||||
try {
|
||||
for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
|
||||
(*it)->add(items);
|
||||
}
|
||||
} catch (...) {
|
||||
typename Observers::iterator jt;
|
||||
for (jt = it.base(); jt != _observers.end(); ++jt) {
|
||||
(*jt)->erase(items);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Notifies all the registed observers about an item erased from
|
||||
// the container.
|
||||
//
|
||||
// It notifies all the registed observers about an item erased from
|
||||
// the container.
|
||||
void erase(const Item& item) throw() {
|
||||
typename Observers::iterator it = _observers.begin();
|
||||
while (it != _observers.end()) {
|
||||
try {
|
||||
(*it)->erase(item);
|
||||
++it;
|
||||
} catch (const ImmediateDetach&) {
|
||||
(*it)->_index = _observers.end();
|
||||
(*it)->_notifier = 0;
|
||||
it = _observers.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Notifies all the registed observers about more item erased
|
||||
// from the container.
|
||||
//
|
||||
// It notifies all the registed observers about more item erased from
|
||||
// the container.
|
||||
void erase(const std::vector<Item>& items) {
|
||||
typename Observers::iterator it = _observers.begin();
|
||||
while (it != _observers.end()) {
|
||||
try {
|
||||
(*it)->erase(items);
|
||||
++it;
|
||||
} catch (const ImmediateDetach&) {
|
||||
(*it)->_index = _observers.end();
|
||||
(*it)->_notifier = 0;
|
||||
it = _observers.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Notifies all the registed observers about the container is
|
||||
// built.
|
||||
//
|
||||
// Notifies all the registed observers about the container is built
|
||||
// from an empty container.
|
||||
void build() {
|
||||
typename Observers::reverse_iterator it;
|
||||
try {
|
||||
for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
|
||||
(*it)->build();
|
||||
}
|
||||
} catch (...) {
|
||||
typename Observers::iterator jt;
|
||||
for (jt = it.base(); jt != _observers.end(); ++jt) {
|
||||
(*jt)->clear();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Notifies all the registed observers about all items are
|
||||
// erased.
|
||||
//
|
||||
// Notifies all the registed observers about all items are erased
|
||||
// from the container.
|
||||
void clear() {
|
||||
typename Observers::iterator it = _observers.begin();
|
||||
while (it != _observers.end()) {
|
||||
try {
|
||||
(*it)->clear();
|
||||
++it;
|
||||
} catch (const ImmediateDetach&) {
|
||||
(*it)->_index = _observers.end();
|
||||
(*it)->_notifier = 0;
|
||||
it = _observers.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
351
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/array_map.h
vendored
Normal file
351
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/array_map.h
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_ARRAY_MAP_H
|
||||
#define LEMON_BITS_ARRAY_MAP_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <lemon/bits/traits.h>
|
||||
#include <lemon/bits/alteration_notifier.h>
|
||||
#include <lemon/concept_check.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
|
||||
// \ingroup graphbits
|
||||
// \file
|
||||
// \brief Graph map based on the array storage.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
// \ingroup graphbits
|
||||
//
|
||||
// \brief Graph map based on the array storage.
|
||||
//
|
||||
// The ArrayMap template class is graph map structure that automatically
|
||||
// updates the map when a key is added to or erased from the graph.
|
||||
// This map uses the allocators to implement the container functionality.
|
||||
//
|
||||
// The template parameters are the Graph, the current Item type and
|
||||
// the Value type of the map.
|
||||
template <typename _Graph, typename _Item, typename _Value>
|
||||
class ArrayMap
|
||||
: public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
|
||||
public:
|
||||
// The graph type.
|
||||
typedef _Graph GraphType;
|
||||
// The item type.
|
||||
typedef _Item Item;
|
||||
// The reference map tag.
|
||||
typedef True ReferenceMapTag;
|
||||
|
||||
// The key type of the map.
|
||||
typedef _Item Key;
|
||||
// The value type of the map.
|
||||
typedef _Value Value;
|
||||
|
||||
// The const reference type of the map.
|
||||
typedef const _Value& ConstReference;
|
||||
// The reference type of the map.
|
||||
typedef _Value& Reference;
|
||||
|
||||
// The map type.
|
||||
typedef ArrayMap Map;
|
||||
|
||||
// The notifier type.
|
||||
typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
|
||||
|
||||
private:
|
||||
|
||||
// The MapBase of the Map which imlements the core regisitry function.
|
||||
typedef typename Notifier::ObserverBase Parent;
|
||||
|
||||
typedef std::allocator<Value> Allocator;
|
||||
|
||||
public:
|
||||
|
||||
// \brief Graph initialized map constructor.
|
||||
//
|
||||
// Graph initialized map constructor.
|
||||
explicit ArrayMap(const GraphType& graph) {
|
||||
Parent::attach(graph.notifier(Item()));
|
||||
allocate_memory();
|
||||
Notifier* nf = Parent::notifier();
|
||||
Item it;
|
||||
for (nf->first(it); it != INVALID; nf->next(it)) {
|
||||
int id = nf->id(it);;
|
||||
std::allocator_traits<Allocator>::construct(allocator, &(values[id]), Value());
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Constructor to use default value to initialize the map.
|
||||
//
|
||||
// It constructs a map and initialize all of the the map.
|
||||
ArrayMap(const GraphType& graph, const Value& value) {
|
||||
Parent::attach(graph.notifier(Item()));
|
||||
allocate_memory();
|
||||
Notifier* nf = Parent::notifier();
|
||||
Item it;
|
||||
for (nf->first(it); it != INVALID; nf->next(it)) {
|
||||
int id = nf->id(it);;
|
||||
allocator.construct(&(values[id]), value);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// \brief Constructor to copy a map of the same map type.
|
||||
//
|
||||
// Constructor to copy a map of the same map type.
|
||||
ArrayMap(const ArrayMap& copy) : Parent() {
|
||||
if (copy.attached()) {
|
||||
attach(*copy.notifier());
|
||||
}
|
||||
capacity = copy.capacity;
|
||||
if (capacity == 0) return;
|
||||
values = allocator.allocate(capacity);
|
||||
Notifier* nf = Parent::notifier();
|
||||
Item it;
|
||||
for (nf->first(it); it != INVALID; nf->next(it)) {
|
||||
int id = nf->id(it);;
|
||||
allocator.construct(&(values[id]), copy.values[id]);
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Assign operator.
|
||||
//
|
||||
// This operator assigns for each item in the map the
|
||||
// value mapped to the same item in the copied map.
|
||||
// The parameter map should be indiced with the same
|
||||
// itemset because this assign operator does not change
|
||||
// the container of the map.
|
||||
ArrayMap& operator=(const ArrayMap& cmap) {
|
||||
return operator=<ArrayMap>(cmap);
|
||||
}
|
||||
|
||||
|
||||
// \brief Template assign operator.
|
||||
//
|
||||
// The given parameter should conform to the ReadMap
|
||||
// concecpt and could be indiced by the current item set of
|
||||
// the NodeMap. In this case the value for each item
|
||||
// is assigned by the value of the given ReadMap.
|
||||
template <typename CMap>
|
||||
ArrayMap& operator=(const CMap& cmap) {
|
||||
checkConcept<concepts::ReadMap<Key, _Value>, CMap>();
|
||||
const typename Parent::Notifier* nf = Parent::notifier();
|
||||
Item it;
|
||||
for (nf->first(it); it != INVALID; nf->next(it)) {
|
||||
set(it, cmap[it]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
// \brief The destructor of the map.
|
||||
//
|
||||
// The destructor of the map.
|
||||
virtual ~ArrayMap() {
|
||||
if (attached()) {
|
||||
clear();
|
||||
detach();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
using Parent::attach;
|
||||
using Parent::detach;
|
||||
using Parent::attached;
|
||||
|
||||
public:
|
||||
|
||||
// \brief The subscript operator.
|
||||
//
|
||||
// The subscript operator. The map can be subscripted by the
|
||||
// actual keys of the graph.
|
||||
Value& operator[](const Key& key) {
|
||||
int id = Parent::notifier()->id(key);
|
||||
return values[id];
|
||||
}
|
||||
|
||||
// \brief The const subscript operator.
|
||||
//
|
||||
// The const subscript operator. The map can be subscripted by the
|
||||
// actual keys of the graph.
|
||||
const Value& operator[](const Key& key) const {
|
||||
int id = Parent::notifier()->id(key);
|
||||
return values[id];
|
||||
}
|
||||
|
||||
// \brief Setter function of the map.
|
||||
//
|
||||
// Setter function of the map. Equivalent with map[key] = val.
|
||||
// This is a compatibility feature with the not dereferable maps.
|
||||
void set(const Key& key, const Value& val) {
|
||||
(*this)[key] = val;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// \brief Adds a new key to the map.
|
||||
//
|
||||
// It adds a new key to the map. It is called by the observer notifier
|
||||
// and it overrides the add() member function of the observer base.
|
||||
virtual void add(const Key& key) {
|
||||
Notifier* nf = Parent::notifier();
|
||||
int id = nf->id(key);
|
||||
if (id >= capacity) {
|
||||
int new_capacity = (capacity == 0 ? 1 : capacity);
|
||||
while (new_capacity <= id) {
|
||||
new_capacity <<= 1;
|
||||
}
|
||||
Value* new_values = allocator.allocate(new_capacity);
|
||||
Item it;
|
||||
for (nf->first(it); it != INVALID; nf->next(it)) {
|
||||
int jd = nf->id(it);;
|
||||
if (id != jd) {
|
||||
std::allocator_traits<Allocator>::construct(allocator, &(new_values[jd]), values[jd]);
|
||||
std::allocator_traits<Allocator>::destroy(allocator, &(values[jd]));
|
||||
}
|
||||
}
|
||||
if (capacity != 0) allocator.deallocate(values, capacity);
|
||||
values = new_values;
|
||||
capacity = new_capacity;
|
||||
}
|
||||
std::allocator_traits<Allocator>::construct(allocator, &(values[id]), Value());
|
||||
}
|
||||
|
||||
// \brief Adds more new keys to the map.
|
||||
//
|
||||
// It adds more new keys to the map. It is called by the observer notifier
|
||||
// and it overrides the add() member function of the observer base.
|
||||
virtual void add(const std::vector<Key>& keys) {
|
||||
Notifier* nf = Parent::notifier();
|
||||
int max_id = -1;
|
||||
for (int i = 0; i < int(keys.size()); ++i) {
|
||||
int id = nf->id(keys[i]);
|
||||
if (id > max_id) {
|
||||
max_id = id;
|
||||
}
|
||||
}
|
||||
if (max_id >= capacity) {
|
||||
int new_capacity = (capacity == 0 ? 1 : capacity);
|
||||
while (new_capacity <= max_id) {
|
||||
new_capacity <<= 1;
|
||||
}
|
||||
Value* new_values = allocator.allocate(new_capacity);
|
||||
Item it;
|
||||
for (nf->first(it); it != INVALID; nf->next(it)) {
|
||||
int id = nf->id(it);
|
||||
bool found = false;
|
||||
for (int i = 0; i < int(keys.size()); ++i) {
|
||||
int jd = nf->id(keys[i]);
|
||||
if (id == jd) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) continue;
|
||||
std::allocator_traits<Allocator>::construct(allocator, &(new_values[id]), values[id]);
|
||||
std::allocator_traits<Allocator>::destroy(allocator, &(values[id]));
|
||||
}
|
||||
if (capacity != 0) allocator.deallocate(values, capacity);
|
||||
values = new_values;
|
||||
capacity = new_capacity;
|
||||
}
|
||||
for (int i = 0; i < int(keys.size()); ++i) {
|
||||
int id = nf->id(keys[i]);
|
||||
std::allocator_traits<Allocator>::construct(allocator, &(values[id]), Value());
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Erase a key from the map.
|
||||
//
|
||||
// Erase a key from the map. It is called by the observer notifier
|
||||
// and it overrides the erase() member function of the observer base.
|
||||
virtual void erase(const Key& key) {
|
||||
int id = Parent::notifier()->id(key);
|
||||
std::allocator_traits<Allocator>::destroy(allocator, &(values[id]));
|
||||
}
|
||||
|
||||
// \brief Erase more keys from the map.
|
||||
//
|
||||
// Erase more keys from the map. It is called by the observer notifier
|
||||
// and it overrides the erase() member function of the observer base.
|
||||
virtual void erase(const std::vector<Key>& keys) {
|
||||
for (int i = 0; i < int(keys.size()); ++i) {
|
||||
int id = Parent::notifier()->id(keys[i]);
|
||||
std::allocator_traits<Allocator>::destroy(allocator, &(values[id]));
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Builds the map.
|
||||
//
|
||||
// It builds the map. It is called by the observer notifier
|
||||
// and it overrides the build() member function of the observer base.
|
||||
virtual void build() {
|
||||
Notifier* nf = Parent::notifier();
|
||||
allocate_memory();
|
||||
Item it;
|
||||
for (nf->first(it); it != INVALID; nf->next(it)) {
|
||||
int id = nf->id(it);;
|
||||
std::allocator_traits<Allocator>::construct(allocator, &(values[id]), Value());
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Clear the map.
|
||||
//
|
||||
// It erase all items from the map. It is called by the observer notifier
|
||||
// and it overrides the clear() member function of the observer base.
|
||||
virtual void clear() {
|
||||
Notifier* nf = Parent::notifier();
|
||||
if (capacity != 0) {
|
||||
Item it;
|
||||
for (nf->first(it); it != INVALID; nf->next(it)) {
|
||||
int id = nf->id(it);
|
||||
std::allocator_traits<Allocator>::destroy(allocator, &(values[id]));
|
||||
}
|
||||
allocator.deallocate(values, capacity);
|
||||
capacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void allocate_memory() {
|
||||
int max_id = Parent::notifier()->maxId();
|
||||
if (max_id == -1) {
|
||||
capacity = 0;
|
||||
values = 0;
|
||||
return;
|
||||
}
|
||||
capacity = 1;
|
||||
while (capacity <= max_id) {
|
||||
capacity <<= 1;
|
||||
}
|
||||
values = allocator.allocate(capacity);
|
||||
}
|
||||
|
||||
int capacity;
|
||||
Value* values;
|
||||
Allocator allocator;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
174
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/bezier.h
vendored
Normal file
174
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/bezier.h
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BEZIER_H
|
||||
#define LEMON_BEZIER_H
|
||||
|
||||
//\ingroup misc
|
||||
//\file
|
||||
//\brief Classes to compute with Bezier curves.
|
||||
//
|
||||
//Up to now this file is used internally by \ref graph_to_eps.h
|
||||
|
||||
#include<lemon/dim2.h>
|
||||
|
||||
namespace lemon {
|
||||
namespace dim2 {
|
||||
|
||||
class BezierBase {
|
||||
public:
|
||||
typedef lemon::dim2::Point<double> Point;
|
||||
protected:
|
||||
static Point conv(Point x,Point y,double t) {return (1-t)*x+t*y;}
|
||||
};
|
||||
|
||||
class Bezier1 : public BezierBase
|
||||
{
|
||||
public:
|
||||
Point p1,p2;
|
||||
|
||||
Bezier1() {}
|
||||
Bezier1(Point _p1, Point _p2) :p1(_p1), p2(_p2) {}
|
||||
|
||||
Point operator()(double t) const
|
||||
{
|
||||
// return conv(conv(p1,p2,t),conv(p2,p3,t),t);
|
||||
return conv(p1,p2,t);
|
||||
}
|
||||
Bezier1 before(double t) const
|
||||
{
|
||||
return Bezier1(p1,conv(p1,p2,t));
|
||||
}
|
||||
|
||||
Bezier1 after(double t) const
|
||||
{
|
||||
return Bezier1(conv(p1,p2,t),p2);
|
||||
}
|
||||
|
||||
Bezier1 revert() const { return Bezier1(p2,p1);}
|
||||
Bezier1 operator()(double a,double b) const { return before(b).after(a/b); }
|
||||
Point grad() const { return p2-p1; }
|
||||
Point norm() const { return rot90(p2-p1); }
|
||||
Point grad(double) const { return grad(); }
|
||||
Point norm(double t) const { return rot90(grad(t)); }
|
||||
};
|
||||
|
||||
class Bezier2 : public BezierBase
|
||||
{
|
||||
public:
|
||||
Point p1,p2,p3;
|
||||
|
||||
Bezier2() {}
|
||||
Bezier2(Point _p1, Point _p2, Point _p3) :p1(_p1), p2(_p2), p3(_p3) {}
|
||||
Bezier2(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,.5)), p3(b.p2) {}
|
||||
Point operator()(double t) const
|
||||
{
|
||||
// return conv(conv(p1,p2,t),conv(p2,p3,t),t);
|
||||
return ((1-t)*(1-t))*p1+(2*(1-t)*t)*p2+(t*t)*p3;
|
||||
}
|
||||
Bezier2 before(double t) const
|
||||
{
|
||||
Point q(conv(p1,p2,t));
|
||||
Point r(conv(p2,p3,t));
|
||||
return Bezier2(p1,q,conv(q,r,t));
|
||||
}
|
||||
|
||||
Bezier2 after(double t) const
|
||||
{
|
||||
Point q(conv(p1,p2,t));
|
||||
Point r(conv(p2,p3,t));
|
||||
return Bezier2(conv(q,r,t),r,p3);
|
||||
}
|
||||
Bezier2 revert() const { return Bezier2(p3,p2,p1);}
|
||||
Bezier2 operator()(double a,double b) const { return before(b).after(a/b); }
|
||||
Bezier1 grad() const { return Bezier1(2.0*(p2-p1),2.0*(p3-p2)); }
|
||||
Bezier1 norm() const { return Bezier1(2.0*rot90(p2-p1),2.0*rot90(p3-p2)); }
|
||||
Point grad(double t) const { return grad()(t); }
|
||||
Point norm(double t) const { return rot90(grad(t)); }
|
||||
};
|
||||
|
||||
class Bezier3 : public BezierBase
|
||||
{
|
||||
public:
|
||||
Point p1,p2,p3,p4;
|
||||
|
||||
Bezier3() {}
|
||||
Bezier3(Point _p1, Point _p2, Point _p3, Point _p4)
|
||||
: p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
|
||||
Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)),
|
||||
p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {}
|
||||
Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)),
|
||||
p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {}
|
||||
|
||||
Point operator()(double t) const
|
||||
{
|
||||
// return Bezier2(conv(p1,p2,t),conv(p2,p3,t),conv(p3,p4,t))(t);
|
||||
return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+
|
||||
(3*t*t*(1-t))*p3+(t*t*t)*p4;
|
||||
}
|
||||
Bezier3 before(double t) const
|
||||
{
|
||||
Point p(conv(p1,p2,t));
|
||||
Point q(conv(p2,p3,t));
|
||||
Point r(conv(p3,p4,t));
|
||||
Point a(conv(p,q,t));
|
||||
Point b(conv(q,r,t));
|
||||
Point c(conv(a,b,t));
|
||||
return Bezier3(p1,p,a,c);
|
||||
}
|
||||
|
||||
Bezier3 after(double t) const
|
||||
{
|
||||
Point p(conv(p1,p2,t));
|
||||
Point q(conv(p2,p3,t));
|
||||
Point r(conv(p3,p4,t));
|
||||
Point a(conv(p,q,t));
|
||||
Point b(conv(q,r,t));
|
||||
Point c(conv(a,b,t));
|
||||
return Bezier3(c,b,r,p4);
|
||||
}
|
||||
Bezier3 revert() const { return Bezier3(p4,p3,p2,p1);}
|
||||
Bezier3 operator()(double a,double b) const { return before(b).after(a/b); }
|
||||
Bezier2 grad() const { return Bezier2(3.0*(p2-p1),3.0*(p3-p2),3.0*(p4-p3)); }
|
||||
Bezier2 norm() const { return Bezier2(3.0*rot90(p2-p1),
|
||||
3.0*rot90(p3-p2),
|
||||
3.0*rot90(p4-p3)); }
|
||||
Point grad(double t) const { return grad()(t); }
|
||||
Point norm(double t) const { return rot90(grad(t)); }
|
||||
|
||||
template<class R,class F,class S,class D>
|
||||
R recSplit(F &_f,const S &_s,D _d) const
|
||||
{
|
||||
const Point a=(p1+p2)/2;
|
||||
const Point b=(p2+p3)/2;
|
||||
const Point c=(p3+p4)/2;
|
||||
const Point d=(a+b)/2;
|
||||
const Point e=(b+c)/2;
|
||||
// const Point f=(d+e)/2;
|
||||
R f1=_f(Bezier3(p1,a,d,e),_d);
|
||||
R f2=_f(Bezier3(e,d,c,p4),_d);
|
||||
return _s(f1,f2);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
} //END OF NAMESPACE dim2
|
||||
} //END OF NAMESPACE lemon
|
||||
|
||||
#endif // LEMON_BEZIER_H
|
||||
182
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/default_map.h
vendored
Normal file
182
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/default_map.h
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_DEFAULT_MAP_H
|
||||
#define LEMON_BITS_DEFAULT_MAP_H
|
||||
|
||||
#include <lemon/config.h>
|
||||
#include <lemon/bits/array_map.h>
|
||||
#include <lemon/bits/vector_map.h>
|
||||
//#include <lemon/bits/debug_map.h>
|
||||
|
||||
//\ingroup graphbits
|
||||
//\file
|
||||
//\brief Graph maps that construct and destruct their elements dynamically.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
|
||||
//#ifndef LEMON_USE_DEBUG_MAP
|
||||
|
||||
template <typename _Graph, typename _Item, typename _Value>
|
||||
struct DefaultMapSelector {
|
||||
typedef ArrayMap<_Graph, _Item, _Value> Map;
|
||||
};
|
||||
|
||||
// bool
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, bool> {
|
||||
typedef VectorMap<_Graph, _Item, bool> Map;
|
||||
};
|
||||
|
||||
// char
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, char> {
|
||||
typedef VectorMap<_Graph, _Item, char> Map;
|
||||
};
|
||||
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, signed char> {
|
||||
typedef VectorMap<_Graph, _Item, signed char> Map;
|
||||
};
|
||||
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, unsigned char> {
|
||||
typedef VectorMap<_Graph, _Item, unsigned char> Map;
|
||||
};
|
||||
|
||||
|
||||
// int
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, signed int> {
|
||||
typedef VectorMap<_Graph, _Item, signed int> Map;
|
||||
};
|
||||
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, unsigned int> {
|
||||
typedef VectorMap<_Graph, _Item, unsigned int> Map;
|
||||
};
|
||||
|
||||
|
||||
// short
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, signed short> {
|
||||
typedef VectorMap<_Graph, _Item, signed short> Map;
|
||||
};
|
||||
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, unsigned short> {
|
||||
typedef VectorMap<_Graph, _Item, unsigned short> Map;
|
||||
};
|
||||
|
||||
|
||||
// long
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, signed long> {
|
||||
typedef VectorMap<_Graph, _Item, signed long> Map;
|
||||
};
|
||||
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, unsigned long> {
|
||||
typedef VectorMap<_Graph, _Item, unsigned long> Map;
|
||||
};
|
||||
|
||||
|
||||
#if defined LEMON_HAVE_LONG_LONG
|
||||
|
||||
// long long
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, signed long long> {
|
||||
typedef VectorMap<_Graph, _Item, signed long long> Map;
|
||||
};
|
||||
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, unsigned long long> {
|
||||
typedef VectorMap<_Graph, _Item, unsigned long long> Map;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// float
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, float> {
|
||||
typedef VectorMap<_Graph, _Item, float> Map;
|
||||
};
|
||||
|
||||
|
||||
// double
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, double> {
|
||||
typedef VectorMap<_Graph, _Item, double> Map;
|
||||
};
|
||||
|
||||
|
||||
// long double
|
||||
template <typename _Graph, typename _Item>
|
||||
struct DefaultMapSelector<_Graph, _Item, long double> {
|
||||
typedef VectorMap<_Graph, _Item, long double> Map;
|
||||
};
|
||||
|
||||
|
||||
// pointer
|
||||
template <typename _Graph, typename _Item, typename _Ptr>
|
||||
struct DefaultMapSelector<_Graph, _Item, _Ptr*> {
|
||||
typedef VectorMap<_Graph, _Item, _Ptr*> Map;
|
||||
};
|
||||
|
||||
// #else
|
||||
|
||||
// template <typename _Graph, typename _Item, typename _Value>
|
||||
// struct DefaultMapSelector {
|
||||
// typedef DebugMap<_Graph, _Item, _Value> Map;
|
||||
// };
|
||||
|
||||
// #endif
|
||||
|
||||
// DefaultMap class
|
||||
template <typename _Graph, typename _Item, typename _Value>
|
||||
class DefaultMap
|
||||
: public DefaultMapSelector<_Graph, _Item, _Value>::Map {
|
||||
typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
|
||||
|
||||
public:
|
||||
typedef DefaultMap<_Graph, _Item, _Value> Map;
|
||||
|
||||
typedef typename Parent::GraphType GraphType;
|
||||
typedef typename Parent::Value Value;
|
||||
|
||||
explicit DefaultMap(const GraphType& graph) : Parent(graph) {}
|
||||
DefaultMap(const GraphType& graph, const Value& value)
|
||||
: Parent(graph, value) {}
|
||||
|
||||
DefaultMap& operator=(const DefaultMap& cmap) {
|
||||
return operator=<DefaultMap>(cmap);
|
||||
}
|
||||
|
||||
template <typename CMap>
|
||||
DefaultMap& operator=(const CMap& cmap) {
|
||||
Parent::operator=(cmap);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
627
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/edge_set_extender.h
vendored
Normal file
627
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/edge_set_extender.h
vendored
Normal file
@@ -0,0 +1,627 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_EDGE_SET_EXTENDER_H
|
||||
#define LEMON_BITS_EDGE_SET_EXTENDER_H
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/error.h>
|
||||
#include <lemon/bits/default_map.h>
|
||||
#include <lemon/bits/map_extender.h>
|
||||
|
||||
//\ingroup digraphbits
|
||||
//\file
|
||||
//\brief Extenders for the arc set types
|
||||
namespace lemon {
|
||||
|
||||
// \ingroup digraphbits
|
||||
//
|
||||
// \brief Extender for the ArcSets
|
||||
template <typename Base>
|
||||
class ArcSetExtender : public Base {
|
||||
typedef Base Parent;
|
||||
|
||||
public:
|
||||
|
||||
typedef ArcSetExtender Digraph;
|
||||
|
||||
// Base extensions
|
||||
|
||||
typedef typename Parent::Node Node;
|
||||
typedef typename Parent::Arc Arc;
|
||||
|
||||
int maxId(Node) const {
|
||||
return Parent::maxNodeId();
|
||||
}
|
||||
|
||||
int maxId(Arc) const {
|
||||
return Parent::maxArcId();
|
||||
}
|
||||
|
||||
Node fromId(int id, Node) const {
|
||||
return Parent::nodeFromId(id);
|
||||
}
|
||||
|
||||
Arc fromId(int id, Arc) const {
|
||||
return Parent::arcFromId(id);
|
||||
}
|
||||
|
||||
Node oppositeNode(const Node &n, const Arc &e) const {
|
||||
if (n == Parent::source(e))
|
||||
return Parent::target(e);
|
||||
else if(n==Parent::target(e))
|
||||
return Parent::source(e);
|
||||
else
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
|
||||
// Alteration notifier extensions
|
||||
|
||||
// The arc observer registry.
|
||||
typedef AlterationNotifier<ArcSetExtender, Arc> ArcNotifier;
|
||||
|
||||
protected:
|
||||
|
||||
mutable ArcNotifier arc_notifier;
|
||||
|
||||
public:
|
||||
|
||||
using Parent::notifier;
|
||||
|
||||
// Gives back the arc alteration notifier.
|
||||
ArcNotifier& notifier(Arc) const {
|
||||
return arc_notifier;
|
||||
}
|
||||
|
||||
// Iterable extensions
|
||||
|
||||
class NodeIt : public Node {
|
||||
const Digraph* digraph;
|
||||
public:
|
||||
|
||||
NodeIt() {}
|
||||
|
||||
NodeIt(Invalid i) : Node(i) { }
|
||||
|
||||
explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
|
||||
_graph.first(static_cast<Node&>(*this));
|
||||
}
|
||||
|
||||
NodeIt(const Digraph& _graph, const Node& node)
|
||||
: Node(node), digraph(&_graph) {}
|
||||
|
||||
NodeIt& operator++() {
|
||||
digraph->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ArcIt : public Arc {
|
||||
const Digraph* digraph;
|
||||
public:
|
||||
|
||||
ArcIt() { }
|
||||
|
||||
ArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
|
||||
_graph.first(static_cast<Arc&>(*this));
|
||||
}
|
||||
|
||||
ArcIt(const Digraph& _graph, const Arc& e) :
|
||||
Arc(e), digraph(&_graph) { }
|
||||
|
||||
ArcIt& operator++() {
|
||||
digraph->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class OutArcIt : public Arc {
|
||||
const Digraph* digraph;
|
||||
public:
|
||||
|
||||
OutArcIt() { }
|
||||
|
||||
OutArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
OutArcIt(const Digraph& _graph, const Node& node)
|
||||
: digraph(&_graph) {
|
||||
_graph.firstOut(*this, node);
|
||||
}
|
||||
|
||||
OutArcIt(const Digraph& _graph, const Arc& arc)
|
||||
: Arc(arc), digraph(&_graph) {}
|
||||
|
||||
OutArcIt& operator++() {
|
||||
digraph->nextOut(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class InArcIt : public Arc {
|
||||
const Digraph* digraph;
|
||||
public:
|
||||
|
||||
InArcIt() { }
|
||||
|
||||
InArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
InArcIt(const Digraph& _graph, const Node& node)
|
||||
: digraph(&_graph) {
|
||||
_graph.firstIn(*this, node);
|
||||
}
|
||||
|
||||
InArcIt(const Digraph& _graph, const Arc& arc) :
|
||||
Arc(arc), digraph(&_graph) {}
|
||||
|
||||
InArcIt& operator++() {
|
||||
digraph->nextIn(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// \brief Base node of the iterator
|
||||
//
|
||||
// Returns the base node (ie. the source in this case) of the iterator
|
||||
Node baseNode(const OutArcIt &e) const {
|
||||
return Parent::source(static_cast<const Arc&>(e));
|
||||
}
|
||||
// \brief Running node of the iterator
|
||||
//
|
||||
// Returns the running node (ie. the target in this case) of the
|
||||
// iterator
|
||||
Node runningNode(const OutArcIt &e) const {
|
||||
return Parent::target(static_cast<const Arc&>(e));
|
||||
}
|
||||
|
||||
// \brief Base node of the iterator
|
||||
//
|
||||
// Returns the base node (ie. the target in this case) of the iterator
|
||||
Node baseNode(const InArcIt &e) const {
|
||||
return Parent::target(static_cast<const Arc&>(e));
|
||||
}
|
||||
// \brief Running node of the iterator
|
||||
//
|
||||
// Returns the running node (ie. the source in this case) of the
|
||||
// iterator
|
||||
Node runningNode(const InArcIt &e) const {
|
||||
return Parent::source(static_cast<const Arc&>(e));
|
||||
}
|
||||
|
||||
using Parent::first;
|
||||
|
||||
// Mappable extension
|
||||
|
||||
template <typename _Value>
|
||||
class ArcMap
|
||||
: public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
|
||||
typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
|
||||
|
||||
public:
|
||||
explicit ArcMap(const Digraph& _g)
|
||||
: Parent(_g) {}
|
||||
ArcMap(const Digraph& _g, const _Value& _v)
|
||||
: Parent(_g, _v) {}
|
||||
|
||||
ArcMap& operator=(const ArcMap& cmap) {
|
||||
return operator=<ArcMap>(cmap);
|
||||
}
|
||||
|
||||
template <typename CMap>
|
||||
ArcMap& operator=(const CMap& cmap) {
|
||||
Parent::operator=(cmap);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Alteration extension
|
||||
|
||||
Arc addArc(const Node& from, const Node& to) {
|
||||
Arc arc = Parent::addArc(from, to);
|
||||
notifier(Arc()).add(arc);
|
||||
return arc;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
notifier(Arc()).clear();
|
||||
Parent::clear();
|
||||
}
|
||||
|
||||
void erase(const Arc& arc) {
|
||||
notifier(Arc()).erase(arc);
|
||||
Parent::erase(arc);
|
||||
}
|
||||
|
||||
ArcSetExtender() {
|
||||
arc_notifier.setContainer(*this);
|
||||
}
|
||||
|
||||
~ArcSetExtender() {
|
||||
arc_notifier.clear();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// \ingroup digraphbits
|
||||
//
|
||||
// \brief Extender for the EdgeSets
|
||||
template <typename Base>
|
||||
class EdgeSetExtender : public Base {
|
||||
typedef Base Parent;
|
||||
|
||||
public:
|
||||
|
||||
typedef EdgeSetExtender Graph;
|
||||
|
||||
typedef True UndirectedTag;
|
||||
|
||||
typedef typename Parent::Node Node;
|
||||
typedef typename Parent::Arc Arc;
|
||||
typedef typename Parent::Edge Edge;
|
||||
|
||||
int maxId(Node) const {
|
||||
return Parent::maxNodeId();
|
||||
}
|
||||
|
||||
int maxId(Arc) const {
|
||||
return Parent::maxArcId();
|
||||
}
|
||||
|
||||
int maxId(Edge) const {
|
||||
return Parent::maxEdgeId();
|
||||
}
|
||||
|
||||
Node fromId(int id, Node) const {
|
||||
return Parent::nodeFromId(id);
|
||||
}
|
||||
|
||||
Arc fromId(int id, Arc) const {
|
||||
return Parent::arcFromId(id);
|
||||
}
|
||||
|
||||
Edge fromId(int id, Edge) const {
|
||||
return Parent::edgeFromId(id);
|
||||
}
|
||||
|
||||
Node oppositeNode(const Node &n, const Edge &e) const {
|
||||
if( n == Parent::u(e))
|
||||
return Parent::v(e);
|
||||
else if( n == Parent::v(e))
|
||||
return Parent::u(e);
|
||||
else
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
Arc oppositeArc(const Arc &e) const {
|
||||
return Parent::direct(e, !Parent::direction(e));
|
||||
}
|
||||
|
||||
using Parent::direct;
|
||||
Arc direct(const Edge &e, const Node &s) const {
|
||||
return Parent::direct(e, Parent::u(e) == s);
|
||||
}
|
||||
|
||||
typedef AlterationNotifier<EdgeSetExtender, Arc> ArcNotifier;
|
||||
typedef AlterationNotifier<EdgeSetExtender, Edge> EdgeNotifier;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
mutable ArcNotifier arc_notifier;
|
||||
mutable EdgeNotifier edge_notifier;
|
||||
|
||||
public:
|
||||
|
||||
using Parent::notifier;
|
||||
|
||||
ArcNotifier& notifier(Arc) const {
|
||||
return arc_notifier;
|
||||
}
|
||||
|
||||
EdgeNotifier& notifier(Edge) const {
|
||||
return edge_notifier;
|
||||
}
|
||||
|
||||
|
||||
class NodeIt : public Node {
|
||||
const Graph* graph;
|
||||
public:
|
||||
|
||||
NodeIt() {}
|
||||
|
||||
NodeIt(Invalid i) : Node(i) { }
|
||||
|
||||
explicit NodeIt(const Graph& _graph) : graph(&_graph) {
|
||||
_graph.first(static_cast<Node&>(*this));
|
||||
}
|
||||
|
||||
NodeIt(const Graph& _graph, const Node& node)
|
||||
: Node(node), graph(&_graph) {}
|
||||
|
||||
NodeIt& operator++() {
|
||||
graph->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ArcIt : public Arc {
|
||||
const Graph* graph;
|
||||
public:
|
||||
|
||||
ArcIt() { }
|
||||
|
||||
ArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
explicit ArcIt(const Graph& _graph) : graph(&_graph) {
|
||||
_graph.first(static_cast<Arc&>(*this));
|
||||
}
|
||||
|
||||
ArcIt(const Graph& _graph, const Arc& e) :
|
||||
Arc(e), graph(&_graph) { }
|
||||
|
||||
ArcIt& operator++() {
|
||||
graph->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class OutArcIt : public Arc {
|
||||
const Graph* graph;
|
||||
public:
|
||||
|
||||
OutArcIt() { }
|
||||
|
||||
OutArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
OutArcIt(const Graph& _graph, const Node& node)
|
||||
: graph(&_graph) {
|
||||
_graph.firstOut(*this, node);
|
||||
}
|
||||
|
||||
OutArcIt(const Graph& _graph, const Arc& arc)
|
||||
: Arc(arc), graph(&_graph) {}
|
||||
|
||||
OutArcIt& operator++() {
|
||||
graph->nextOut(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class InArcIt : public Arc {
|
||||
const Graph* graph;
|
||||
public:
|
||||
|
||||
InArcIt() { }
|
||||
|
||||
InArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
InArcIt(const Graph& _graph, const Node& node)
|
||||
: graph(&_graph) {
|
||||
_graph.firstIn(*this, node);
|
||||
}
|
||||
|
||||
InArcIt(const Graph& _graph, const Arc& arc) :
|
||||
Arc(arc), graph(&_graph) {}
|
||||
|
||||
InArcIt& operator++() {
|
||||
graph->nextIn(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class EdgeIt : public Parent::Edge {
|
||||
const Graph* graph;
|
||||
public:
|
||||
|
||||
EdgeIt() { }
|
||||
|
||||
EdgeIt(Invalid i) : Edge(i) { }
|
||||
|
||||
explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
|
||||
_graph.first(static_cast<Edge&>(*this));
|
||||
}
|
||||
|
||||
EdgeIt(const Graph& _graph, const Edge& e) :
|
||||
Edge(e), graph(&_graph) { }
|
||||
|
||||
EdgeIt& operator++() {
|
||||
graph->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class IncEdgeIt : public Parent::Edge {
|
||||
friend class EdgeSetExtender;
|
||||
const Graph* graph;
|
||||
bool direction;
|
||||
public:
|
||||
|
||||
IncEdgeIt() { }
|
||||
|
||||
IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
|
||||
|
||||
IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
|
||||
_graph.firstInc(*this, direction, n);
|
||||
}
|
||||
|
||||
IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
|
||||
: graph(&_graph), Edge(ue) {
|
||||
direction = (_graph.source(ue) == n);
|
||||
}
|
||||
|
||||
IncEdgeIt& operator++() {
|
||||
graph->nextInc(*this, direction);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// \brief Base node of the iterator
|
||||
//
|
||||
// Returns the base node (ie. the source in this case) of the iterator
|
||||
Node baseNode(const OutArcIt &e) const {
|
||||
return Parent::source(static_cast<const Arc&>(e));
|
||||
}
|
||||
// \brief Running node of the iterator
|
||||
//
|
||||
// Returns the running node (ie. the target in this case) of the
|
||||
// iterator
|
||||
Node runningNode(const OutArcIt &e) const {
|
||||
return Parent::target(static_cast<const Arc&>(e));
|
||||
}
|
||||
|
||||
// \brief Base node of the iterator
|
||||
//
|
||||
// Returns the base node (ie. the target in this case) of the iterator
|
||||
Node baseNode(const InArcIt &e) const {
|
||||
return Parent::target(static_cast<const Arc&>(e));
|
||||
}
|
||||
// \brief Running node of the iterator
|
||||
//
|
||||
// Returns the running node (ie. the source in this case) of the
|
||||
// iterator
|
||||
Node runningNode(const InArcIt &e) const {
|
||||
return Parent::source(static_cast<const Arc&>(e));
|
||||
}
|
||||
|
||||
// Base node of the iterator
|
||||
//
|
||||
// Returns the base node of the iterator
|
||||
Node baseNode(const IncEdgeIt &e) const {
|
||||
return e.direction ? this->u(e) : this->v(e);
|
||||
}
|
||||
// Running node of the iterator
|
||||
//
|
||||
// Returns the running node of the iterator
|
||||
Node runningNode(const IncEdgeIt &e) const {
|
||||
return e.direction ? this->v(e) : this->u(e);
|
||||
}
|
||||
|
||||
|
||||
template <typename _Value>
|
||||
class ArcMap
|
||||
: public MapExtender<DefaultMap<Graph, Arc, _Value> > {
|
||||
typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
|
||||
|
||||
public:
|
||||
explicit ArcMap(const Graph& _g)
|
||||
: Parent(_g) {}
|
||||
ArcMap(const Graph& _g, const _Value& _v)
|
||||
: Parent(_g, _v) {}
|
||||
|
||||
ArcMap& operator=(const ArcMap& cmap) {
|
||||
return operator=<ArcMap>(cmap);
|
||||
}
|
||||
|
||||
template <typename CMap>
|
||||
ArcMap& operator=(const CMap& cmap) {
|
||||
Parent::operator=(cmap);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <typename _Value>
|
||||
class EdgeMap
|
||||
: public MapExtender<DefaultMap<Graph, Edge, _Value> > {
|
||||
typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
|
||||
|
||||
public:
|
||||
explicit EdgeMap(const Graph& _g)
|
||||
: Parent(_g) {}
|
||||
|
||||
EdgeMap(const Graph& _g, const _Value& _v)
|
||||
: Parent(_g, _v) {}
|
||||
|
||||
EdgeMap& operator=(const EdgeMap& cmap) {
|
||||
return operator=<EdgeMap>(cmap);
|
||||
}
|
||||
|
||||
template <typename CMap>
|
||||
EdgeMap& operator=(const CMap& cmap) {
|
||||
Parent::operator=(cmap);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Alteration extension
|
||||
|
||||
Edge addEdge(const Node& from, const Node& to) {
|
||||
Edge edge = Parent::addEdge(from, to);
|
||||
notifier(Edge()).add(edge);
|
||||
std::vector<Arc> arcs;
|
||||
arcs.push_back(Parent::direct(edge, true));
|
||||
arcs.push_back(Parent::direct(edge, false));
|
||||
notifier(Arc()).add(arcs);
|
||||
return edge;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
notifier(Arc()).clear();
|
||||
notifier(Edge()).clear();
|
||||
Parent::clear();
|
||||
}
|
||||
|
||||
void erase(const Edge& edge) {
|
||||
std::vector<Arc> arcs;
|
||||
arcs.push_back(Parent::direct(edge, true));
|
||||
arcs.push_back(Parent::direct(edge, false));
|
||||
notifier(Arc()).erase(arcs);
|
||||
notifier(Edge()).erase(edge);
|
||||
Parent::erase(edge);
|
||||
}
|
||||
|
||||
|
||||
EdgeSetExtender() {
|
||||
arc_notifier.setContainer(*this);
|
||||
edge_notifier.setContainer(*this);
|
||||
}
|
||||
|
||||
~EdgeSetExtender() {
|
||||
edge_notifier.clear();
|
||||
arc_notifier.clear();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
131
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/enable_if.h
vendored
Normal file
131
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/enable_if.h
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
// This file contains a modified version of the enable_if library from BOOST.
|
||||
// See the appropriate copyright notice below.
|
||||
|
||||
// Boost enable_if library
|
||||
|
||||
// Copyright 2003 (c) The Trustees of Indiana University.
|
||||
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
|
||||
// Jeremiah Willcock (jewillco at osl.iu.edu)
|
||||
// Andrew Lumsdaine (lums at osl.iu.edu)
|
||||
|
||||
|
||||
#ifndef LEMON_BITS_ENABLE_IF_H
|
||||
#define LEMON_BITS_ENABLE_IF_H
|
||||
|
||||
//\file
|
||||
//\brief Miscellaneous basic utilities
|
||||
|
||||
namespace lemon
|
||||
{
|
||||
|
||||
// Basic type for defining "tags". A "YES" condition for \c enable_if.
|
||||
|
||||
// Basic type for defining "tags". A "YES" condition for \c enable_if.
|
||||
//
|
||||
//\sa False
|
||||
struct True {
|
||||
//\e
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
// Basic type for defining "tags". A "NO" condition for \c enable_if.
|
||||
|
||||
// Basic type for defining "tags". A "NO" condition for \c enable_if.
|
||||
//
|
||||
//\sa True
|
||||
struct False {
|
||||
//\e
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct Wrap {
|
||||
const T &value;
|
||||
Wrap(const T &t) : value(t) {}
|
||||
};
|
||||
|
||||
/**************** dummy class to avoid ambiguity ****************/
|
||||
|
||||
template<int T> struct dummy { dummy(int) {} };
|
||||
|
||||
/**************** enable_if from BOOST ****************/
|
||||
|
||||
template <typename Type, typename T = void>
|
||||
struct exists {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
|
||||
template <bool B, class T = void>
|
||||
struct enable_if_c {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct enable_if_c<false, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct enable_if : public enable_if_c<Cond::value, T> {};
|
||||
|
||||
template <bool B, class T>
|
||||
struct lazy_enable_if_c {
|
||||
typedef typename T::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct lazy_enable_if_c<false, T> {};
|
||||
|
||||
template <class Cond, class T>
|
||||
struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
|
||||
|
||||
|
||||
template <bool B, class T = void>
|
||||
struct disable_if_c {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct disable_if_c<true, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct disable_if : public disable_if_c<Cond::value, T> {};
|
||||
|
||||
template <bool B, class T>
|
||||
struct lazy_disable_if_c {
|
||||
typedef typename T::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct lazy_disable_if_c<true, T> {};
|
||||
|
||||
template <class Cond, class T>
|
||||
struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
|
||||
|
||||
} // namespace lemon
|
||||
|
||||
#endif
|
||||
401
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/graph_adaptor_extender.h
vendored
Normal file
401
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/graph_adaptor_extender.h
vendored
Normal file
@@ -0,0 +1,401 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
|
||||
#define LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/error.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
template <typename _Digraph>
|
||||
class DigraphAdaptorExtender : public _Digraph {
|
||||
typedef _Digraph Parent;
|
||||
|
||||
public:
|
||||
|
||||
typedef _Digraph Digraph;
|
||||
typedef DigraphAdaptorExtender Adaptor;
|
||||
|
||||
// Base extensions
|
||||
|
||||
typedef typename Parent::Node Node;
|
||||
typedef typename Parent::Arc Arc;
|
||||
|
||||
int maxId(Node) const {
|
||||
return Parent::maxNodeId();
|
||||
}
|
||||
|
||||
int maxId(Arc) const {
|
||||
return Parent::maxArcId();
|
||||
}
|
||||
|
||||
Node fromId(int id, Node) const {
|
||||
return Parent::nodeFromId(id);
|
||||
}
|
||||
|
||||
Arc fromId(int id, Arc) const {
|
||||
return Parent::arcFromId(id);
|
||||
}
|
||||
|
||||
Node oppositeNode(const Node &n, const Arc &e) const {
|
||||
if (n == Parent::source(e))
|
||||
return Parent::target(e);
|
||||
else if(n==Parent::target(e))
|
||||
return Parent::source(e);
|
||||
else
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
class NodeIt : public Node {
|
||||
const Adaptor* _adaptor;
|
||||
public:
|
||||
|
||||
NodeIt() {}
|
||||
|
||||
NodeIt(Invalid i) : Node(i) { }
|
||||
|
||||
explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
|
||||
_adaptor->first(static_cast<Node&>(*this));
|
||||
}
|
||||
|
||||
NodeIt(const Adaptor& adaptor, const Node& node)
|
||||
: Node(node), _adaptor(&adaptor) {}
|
||||
|
||||
NodeIt& operator++() {
|
||||
_adaptor->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ArcIt : public Arc {
|
||||
const Adaptor* _adaptor;
|
||||
public:
|
||||
|
||||
ArcIt() { }
|
||||
|
||||
ArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
|
||||
_adaptor->first(static_cast<Arc&>(*this));
|
||||
}
|
||||
|
||||
ArcIt(const Adaptor& adaptor, const Arc& e) :
|
||||
Arc(e), _adaptor(&adaptor) { }
|
||||
|
||||
ArcIt& operator++() {
|
||||
_adaptor->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class OutArcIt : public Arc {
|
||||
const Adaptor* _adaptor;
|
||||
public:
|
||||
|
||||
OutArcIt() { }
|
||||
|
||||
OutArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
OutArcIt(const Adaptor& adaptor, const Node& node)
|
||||
: _adaptor(&adaptor) {
|
||||
_adaptor->firstOut(*this, node);
|
||||
}
|
||||
|
||||
OutArcIt(const Adaptor& adaptor, const Arc& arc)
|
||||
: Arc(arc), _adaptor(&adaptor) {}
|
||||
|
||||
OutArcIt& operator++() {
|
||||
_adaptor->nextOut(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class InArcIt : public Arc {
|
||||
const Adaptor* _adaptor;
|
||||
public:
|
||||
|
||||
InArcIt() { }
|
||||
|
||||
InArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
InArcIt(const Adaptor& adaptor, const Node& node)
|
||||
: _adaptor(&adaptor) {
|
||||
_adaptor->firstIn(*this, node);
|
||||
}
|
||||
|
||||
InArcIt(const Adaptor& adaptor, const Arc& arc) :
|
||||
Arc(arc), _adaptor(&adaptor) {}
|
||||
|
||||
InArcIt& operator++() {
|
||||
_adaptor->nextIn(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Node baseNode(const OutArcIt &e) const {
|
||||
return Parent::source(e);
|
||||
}
|
||||
Node runningNode(const OutArcIt &e) const {
|
||||
return Parent::target(e);
|
||||
}
|
||||
|
||||
Node baseNode(const InArcIt &e) const {
|
||||
return Parent::target(e);
|
||||
}
|
||||
Node runningNode(const InArcIt &e) const {
|
||||
return Parent::source(e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename _Graph>
|
||||
class GraphAdaptorExtender : public _Graph {
|
||||
typedef _Graph Parent;
|
||||
|
||||
public:
|
||||
|
||||
typedef _Graph Graph;
|
||||
typedef GraphAdaptorExtender Adaptor;
|
||||
|
||||
typedef True UndirectedTag;
|
||||
|
||||
typedef typename Parent::Node Node;
|
||||
typedef typename Parent::Arc Arc;
|
||||
typedef typename Parent::Edge Edge;
|
||||
|
||||
// Graph extension
|
||||
|
||||
int maxId(Node) const {
|
||||
return Parent::maxNodeId();
|
||||
}
|
||||
|
||||
int maxId(Arc) const {
|
||||
return Parent::maxArcId();
|
||||
}
|
||||
|
||||
int maxId(Edge) const {
|
||||
return Parent::maxEdgeId();
|
||||
}
|
||||
|
||||
Node fromId(int id, Node) const {
|
||||
return Parent::nodeFromId(id);
|
||||
}
|
||||
|
||||
Arc fromId(int id, Arc) const {
|
||||
return Parent::arcFromId(id);
|
||||
}
|
||||
|
||||
Edge fromId(int id, Edge) const {
|
||||
return Parent::edgeFromId(id);
|
||||
}
|
||||
|
||||
Node oppositeNode(const Node &n, const Edge &e) const {
|
||||
if( n == Parent::u(e))
|
||||
return Parent::v(e);
|
||||
else if( n == Parent::v(e))
|
||||
return Parent::u(e);
|
||||
else
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
Arc oppositeArc(const Arc &a) const {
|
||||
return Parent::direct(a, !Parent::direction(a));
|
||||
}
|
||||
|
||||
using Parent::direct;
|
||||
Arc direct(const Edge &e, const Node &s) const {
|
||||
return Parent::direct(e, Parent::u(e) == s);
|
||||
}
|
||||
|
||||
|
||||
class NodeIt : public Node {
|
||||
const Adaptor* _adaptor;
|
||||
public:
|
||||
|
||||
NodeIt() {}
|
||||
|
||||
NodeIt(Invalid i) : Node(i) { }
|
||||
|
||||
explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
|
||||
_adaptor->first(static_cast<Node&>(*this));
|
||||
}
|
||||
|
||||
NodeIt(const Adaptor& adaptor, const Node& node)
|
||||
: Node(node), _adaptor(&adaptor) {}
|
||||
|
||||
NodeIt& operator++() {
|
||||
_adaptor->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ArcIt : public Arc {
|
||||
const Adaptor* _adaptor;
|
||||
public:
|
||||
|
||||
ArcIt() { }
|
||||
|
||||
ArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
|
||||
_adaptor->first(static_cast<Arc&>(*this));
|
||||
}
|
||||
|
||||
ArcIt(const Adaptor& adaptor, const Arc& e) :
|
||||
Arc(e), _adaptor(&adaptor) { }
|
||||
|
||||
ArcIt& operator++() {
|
||||
_adaptor->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class OutArcIt : public Arc {
|
||||
const Adaptor* _adaptor;
|
||||
public:
|
||||
|
||||
OutArcIt() { }
|
||||
|
||||
OutArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
OutArcIt(const Adaptor& adaptor, const Node& node)
|
||||
: _adaptor(&adaptor) {
|
||||
_adaptor->firstOut(*this, node);
|
||||
}
|
||||
|
||||
OutArcIt(const Adaptor& adaptor, const Arc& arc)
|
||||
: Arc(arc), _adaptor(&adaptor) {}
|
||||
|
||||
OutArcIt& operator++() {
|
||||
_adaptor->nextOut(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class InArcIt : public Arc {
|
||||
const Adaptor* _adaptor;
|
||||
public:
|
||||
|
||||
InArcIt() { }
|
||||
|
||||
InArcIt(Invalid i) : Arc(i) { }
|
||||
|
||||
InArcIt(const Adaptor& adaptor, const Node& node)
|
||||
: _adaptor(&adaptor) {
|
||||
_adaptor->firstIn(*this, node);
|
||||
}
|
||||
|
||||
InArcIt(const Adaptor& adaptor, const Arc& arc) :
|
||||
Arc(arc), _adaptor(&adaptor) {}
|
||||
|
||||
InArcIt& operator++() {
|
||||
_adaptor->nextIn(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class EdgeIt : public Parent::Edge {
|
||||
const Adaptor* _adaptor;
|
||||
public:
|
||||
|
||||
EdgeIt() { }
|
||||
|
||||
EdgeIt(Invalid i) : Edge(i) { }
|
||||
|
||||
explicit EdgeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
|
||||
_adaptor->first(static_cast<Edge&>(*this));
|
||||
}
|
||||
|
||||
EdgeIt(const Adaptor& adaptor, const Edge& e) :
|
||||
Edge(e), _adaptor(&adaptor) { }
|
||||
|
||||
EdgeIt& operator++() {
|
||||
_adaptor->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class IncEdgeIt : public Edge {
|
||||
friend class GraphAdaptorExtender;
|
||||
const Adaptor* _adaptor;
|
||||
bool direction;
|
||||
public:
|
||||
|
||||
IncEdgeIt() { }
|
||||
|
||||
IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
|
||||
|
||||
IncEdgeIt(const Adaptor& adaptor, const Node &n) : _adaptor(&adaptor) {
|
||||
_adaptor->firstInc(static_cast<Edge&>(*this), direction, n);
|
||||
}
|
||||
|
||||
IncEdgeIt(const Adaptor& adaptor, const Edge &e, const Node &n)
|
||||
: _adaptor(&adaptor), Edge(e) {
|
||||
direction = (_adaptor->u(e) == n);
|
||||
}
|
||||
|
||||
IncEdgeIt& operator++() {
|
||||
_adaptor->nextInc(*this, direction);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
Node baseNode(const OutArcIt &a) const {
|
||||
return Parent::source(a);
|
||||
}
|
||||
Node runningNode(const OutArcIt &a) const {
|
||||
return Parent::target(a);
|
||||
}
|
||||
|
||||
Node baseNode(const InArcIt &a) const {
|
||||
return Parent::target(a);
|
||||
}
|
||||
Node runningNode(const InArcIt &a) const {
|
||||
return Parent::source(a);
|
||||
}
|
||||
|
||||
Node baseNode(const IncEdgeIt &e) const {
|
||||
return e.direction ? Parent::u(e) : Parent::v(e);
|
||||
}
|
||||
Node runningNode(const IncEdgeIt &e) const {
|
||||
return e.direction ? Parent::v(e) : Parent::u(e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
1332
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/graph_extender.h
vendored
Normal file
1332
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/graph_extender.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
65
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/lock.h
vendored
Normal file
65
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/lock.h
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_LOCK_H
|
||||
#define LEMON_BITS_LOCK_H
|
||||
|
||||
#include <lemon/config.h>
|
||||
#if defined(LEMON_USE_PTHREAD)
|
||||
#include <pthread.h>
|
||||
#elif defined(LEMON_USE_WIN32_THREADS)
|
||||
#include <lemon/bits/windows.h>
|
||||
#endif
|
||||
|
||||
namespace lemon {
|
||||
namespace bits {
|
||||
|
||||
#if defined(LEMON_USE_PTHREAD)
|
||||
class Lock {
|
||||
public:
|
||||
Lock() {
|
||||
pthread_mutex_init(&_lock, 0);
|
||||
}
|
||||
~Lock() {
|
||||
pthread_mutex_destroy(&_lock);
|
||||
}
|
||||
void lock() {
|
||||
pthread_mutex_lock(&_lock);
|
||||
}
|
||||
void unlock() {
|
||||
pthread_mutex_unlock(&_lock);
|
||||
}
|
||||
|
||||
private:
|
||||
pthread_mutex_t _lock;
|
||||
};
|
||||
#elif defined(LEMON_USE_WIN32_THREADS)
|
||||
class Lock : public WinLock {};
|
||||
#else
|
||||
class Lock {
|
||||
public:
|
||||
Lock() {}
|
||||
~Lock() {}
|
||||
void lock() {}
|
||||
void unlock() {}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
332
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/map_extender.h
vendored
Normal file
332
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/map_extender.h
vendored
Normal file
@@ -0,0 +1,332 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_MAP_EXTENDER_H
|
||||
#define LEMON_BITS_MAP_EXTENDER_H
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include <lemon/bits/traits.h>
|
||||
|
||||
#include <lemon/concept_check.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
|
||||
//\file
|
||||
//\brief Extenders for iterable maps.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
// \ingroup graphbits
|
||||
//
|
||||
// \brief Extender for maps
|
||||
template <typename _Map>
|
||||
class MapExtender : public _Map {
|
||||
typedef _Map Parent;
|
||||
typedef typename Parent::GraphType GraphType;
|
||||
|
||||
public:
|
||||
|
||||
typedef MapExtender Map;
|
||||
typedef typename Parent::Key Item;
|
||||
|
||||
typedef typename Parent::Key Key;
|
||||
typedef typename Parent::Value Value;
|
||||
typedef typename Parent::Reference Reference;
|
||||
typedef typename Parent::ConstReference ConstReference;
|
||||
|
||||
typedef typename Parent::ReferenceMapTag ReferenceMapTag;
|
||||
|
||||
class MapIt;
|
||||
class ConstMapIt;
|
||||
|
||||
friend class MapIt;
|
||||
friend class ConstMapIt;
|
||||
|
||||
public:
|
||||
|
||||
MapExtender(const GraphType& graph)
|
||||
: Parent(graph) {}
|
||||
|
||||
MapExtender(const GraphType& graph, const Value& value)
|
||||
: Parent(graph, value) {}
|
||||
|
||||
private:
|
||||
MapExtender& operator=(const MapExtender& cmap) {
|
||||
return operator=<MapExtender>(cmap);
|
||||
}
|
||||
|
||||
template <typename CMap>
|
||||
MapExtender& operator=(const CMap& cmap) {
|
||||
Parent::operator=(cmap);
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
class MapIt : public Item {
|
||||
typedef Item Parent;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename Map::Value Value;
|
||||
|
||||
MapIt() : map(NULL) {}
|
||||
|
||||
MapIt(Invalid i) : Parent(i), map(NULL) {}
|
||||
|
||||
explicit MapIt(Map& _map) : map(&_map) {
|
||||
map->notifier()->first(*this);
|
||||
}
|
||||
|
||||
MapIt(const Map& _map, const Item& item)
|
||||
: Parent(item), map(&_map) {}
|
||||
|
||||
MapIt& operator++() {
|
||||
map->notifier()->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
typename MapTraits<Map>::ConstReturnValue operator*() const {
|
||||
return (*map)[*this];
|
||||
}
|
||||
|
||||
typename MapTraits<Map>::ReturnValue operator*() {
|
||||
return (*map)[*this];
|
||||
}
|
||||
|
||||
void set(const Value& value) {
|
||||
map->set(*this, value);
|
||||
}
|
||||
|
||||
protected:
|
||||
Map* map;
|
||||
|
||||
};
|
||||
|
||||
class ConstMapIt : public Item {
|
||||
typedef Item Parent;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename Map::Value Value;
|
||||
|
||||
ConstMapIt() : map(NULL) {}
|
||||
|
||||
ConstMapIt(Invalid i) : Parent(i), map(NULL) {}
|
||||
|
||||
explicit ConstMapIt(Map& _map) : map(&_map) {
|
||||
map->notifier()->first(*this);
|
||||
}
|
||||
|
||||
ConstMapIt(const Map& _map, const Item& item)
|
||||
: Parent(item), map(_map) {}
|
||||
|
||||
ConstMapIt& operator++() {
|
||||
map->notifier()->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
typename MapTraits<Map>::ConstReturnValue operator*() const {
|
||||
return map[*this];
|
||||
}
|
||||
|
||||
protected:
|
||||
const Map* map;
|
||||
};
|
||||
|
||||
class ItemIt : public Item {
|
||||
typedef Item Parent;
|
||||
|
||||
public:
|
||||
ItemIt() : map(NULL) {}
|
||||
|
||||
|
||||
ItemIt(Invalid i) : Parent(i), map(NULL) {}
|
||||
|
||||
explicit ItemIt(Map& _map) : map(&_map) {
|
||||
map->notifier()->first(*this);
|
||||
}
|
||||
|
||||
ItemIt(const Map& _map, const Item& item)
|
||||
: Parent(item), map(&_map) {}
|
||||
|
||||
ItemIt& operator++() {
|
||||
map->notifier()->next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
const Map* map;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// \ingroup graphbits
|
||||
//
|
||||
// \brief Extender for maps which use a subset of the items.
|
||||
template <typename _Graph, typename _Map>
|
||||
class SubMapExtender : public _Map {
|
||||
typedef _Map Parent;
|
||||
typedef _Graph GraphType;
|
||||
|
||||
public:
|
||||
|
||||
typedef SubMapExtender Map;
|
||||
typedef typename Parent::Key Item;
|
||||
|
||||
typedef typename Parent::Key Key;
|
||||
typedef typename Parent::Value Value;
|
||||
typedef typename Parent::Reference Reference;
|
||||
typedef typename Parent::ConstReference ConstReference;
|
||||
|
||||
typedef typename Parent::ReferenceMapTag ReferenceMapTag;
|
||||
|
||||
class MapIt;
|
||||
class ConstMapIt;
|
||||
|
||||
friend class MapIt;
|
||||
friend class ConstMapIt;
|
||||
|
||||
public:
|
||||
|
||||
SubMapExtender(const GraphType& _graph)
|
||||
: Parent(_graph), graph(_graph) {}
|
||||
|
||||
SubMapExtender(const GraphType& _graph, const Value& _value)
|
||||
: Parent(_graph, _value), graph(_graph) {}
|
||||
|
||||
private:
|
||||
SubMapExtender& operator=(const SubMapExtender& cmap) {
|
||||
return operator=<MapExtender>(cmap);
|
||||
}
|
||||
|
||||
template <typename CMap>
|
||||
SubMapExtender& operator=(const CMap& cmap) {
|
||||
checkConcept<concepts::ReadMap<Key, Value>, CMap>();
|
||||
Item it;
|
||||
for (graph.first(it); it != INVALID; graph.next(it)) {
|
||||
Parent::set(it, cmap[it]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
class MapIt : public Item {
|
||||
typedef Item Parent;
|
||||
|
||||
public:
|
||||
typedef typename Map::Value Value;
|
||||
|
||||
MapIt() : map(NULL) {}
|
||||
|
||||
MapIt(Invalid i) : Parent(i), map(NULL) { }
|
||||
|
||||
explicit MapIt(Map& _map) : map(&_map) {
|
||||
map->graph.first(*this);
|
||||
}
|
||||
|
||||
MapIt(const Map& _map, const Item& item)
|
||||
: Parent(item), map(&_map) {}
|
||||
|
||||
MapIt& operator++() {
|
||||
map->graph.next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
typename MapTraits<Map>::ConstReturnValue operator*() const {
|
||||
return (*map)[*this];
|
||||
}
|
||||
|
||||
typename MapTraits<Map>::ReturnValue operator*() {
|
||||
return (*map)[*this];
|
||||
}
|
||||
|
||||
void set(const Value& value) {
|
||||
map->set(*this, value);
|
||||
}
|
||||
|
||||
protected:
|
||||
Map* map;
|
||||
|
||||
};
|
||||
|
||||
class ConstMapIt : public Item {
|
||||
typedef Item Parent;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename Map::Value Value;
|
||||
|
||||
ConstMapIt() : map(NULL) {}
|
||||
|
||||
ConstMapIt(Invalid i) : Parent(i), map(NULL) { }
|
||||
|
||||
explicit ConstMapIt(Map& _map) : map(&_map) {
|
||||
map->graph.first(*this);
|
||||
}
|
||||
|
||||
ConstMapIt(const Map& _map, const Item& item)
|
||||
: Parent(item), map(&_map) {}
|
||||
|
||||
ConstMapIt& operator++() {
|
||||
map->graph.next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
typename MapTraits<Map>::ConstReturnValue operator*() const {
|
||||
return (*map)[*this];
|
||||
}
|
||||
|
||||
protected:
|
||||
const Map* map;
|
||||
};
|
||||
|
||||
class ItemIt : public Item {
|
||||
typedef Item Parent;
|
||||
|
||||
public:
|
||||
ItemIt() : map(NULL) {}
|
||||
|
||||
|
||||
ItemIt(Invalid i) : Parent(i), map(NULL) { }
|
||||
|
||||
explicit ItemIt(Map& _map) : map(&_map) {
|
||||
map->graph.first(*this);
|
||||
}
|
||||
|
||||
ItemIt(const Map& _map, const Item& item)
|
||||
: Parent(item), map(&_map) {}
|
||||
|
||||
ItemIt& operator++() {
|
||||
map->graph.next(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
const Map* map;
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
const GraphType& graph;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
177
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/path_dump.h
vendored
Normal file
177
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/path_dump.h
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_PATH_DUMP_H
|
||||
#define LEMON_BITS_PATH_DUMP_H
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/concept_check.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
template <typename _Digraph, typename _PredMap>
|
||||
class PredMapPath {
|
||||
public:
|
||||
typedef True RevPathTag;
|
||||
|
||||
typedef _Digraph Digraph;
|
||||
typedef typename Digraph::Arc Arc;
|
||||
typedef _PredMap PredMap;
|
||||
|
||||
PredMapPath(const Digraph& _digraph, const PredMap& _predMap,
|
||||
typename Digraph::Node _target)
|
||||
: digraph(_digraph), predMap(_predMap), target(_target) {}
|
||||
|
||||
int length() const {
|
||||
int len = 0;
|
||||
typename Digraph::Node node = target;
|
||||
typename Digraph::Arc arc;
|
||||
while ((arc = predMap[node]) != INVALID) {
|
||||
node = digraph.source(arc);
|
||||
++len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return predMap[target] == INVALID;
|
||||
}
|
||||
|
||||
class RevArcIt {
|
||||
public:
|
||||
RevArcIt() {}
|
||||
RevArcIt(Invalid) : path(0), current(INVALID) {}
|
||||
RevArcIt(const PredMapPath& _path)
|
||||
: path(&_path), current(_path.target) {
|
||||
if (path->predMap[current] == INVALID) current = INVALID;
|
||||
}
|
||||
|
||||
operator const typename Digraph::Arc() const {
|
||||
return path->predMap[current];
|
||||
}
|
||||
|
||||
RevArcIt& operator++() {
|
||||
current = path->digraph.source(path->predMap[current]);
|
||||
if (path->predMap[current] == INVALID) current = INVALID;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const RevArcIt& e) const {
|
||||
return current == e.current;
|
||||
}
|
||||
|
||||
bool operator!=(const RevArcIt& e) const {
|
||||
return current != e.current;
|
||||
}
|
||||
|
||||
bool operator<(const RevArcIt& e) const {
|
||||
return current < e.current;
|
||||
}
|
||||
|
||||
private:
|
||||
const PredMapPath* path;
|
||||
typename Digraph::Node current;
|
||||
};
|
||||
|
||||
private:
|
||||
const Digraph& digraph;
|
||||
const PredMap& predMap;
|
||||
typename Digraph::Node target;
|
||||
};
|
||||
|
||||
|
||||
template <typename _Digraph, typename _PredMatrixMap>
|
||||
class PredMatrixMapPath {
|
||||
public:
|
||||
typedef True RevPathTag;
|
||||
|
||||
typedef _Digraph Digraph;
|
||||
typedef typename Digraph::Arc Arc;
|
||||
typedef _PredMatrixMap PredMatrixMap;
|
||||
|
||||
PredMatrixMapPath(const Digraph& _digraph,
|
||||
const PredMatrixMap& _predMatrixMap,
|
||||
typename Digraph::Node _source,
|
||||
typename Digraph::Node _target)
|
||||
: digraph(_digraph), predMatrixMap(_predMatrixMap),
|
||||
source(_source), target(_target) {}
|
||||
|
||||
int length() const {
|
||||
int len = 0;
|
||||
typename Digraph::Node node = target;
|
||||
typename Digraph::Arc arc;
|
||||
while ((arc = predMatrixMap(source, node)) != INVALID) {
|
||||
node = digraph.source(arc);
|
||||
++len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return predMatrixMap(source, target) == INVALID;
|
||||
}
|
||||
|
||||
class RevArcIt {
|
||||
public:
|
||||
RevArcIt() {}
|
||||
RevArcIt(Invalid) : path(0), current(INVALID) {}
|
||||
RevArcIt(const PredMatrixMapPath& _path)
|
||||
: path(&_path), current(_path.target) {
|
||||
if (path->predMatrixMap(path->source, current) == INVALID)
|
||||
current = INVALID;
|
||||
}
|
||||
|
||||
operator const typename Digraph::Arc() const {
|
||||
return path->predMatrixMap(path->source, current);
|
||||
}
|
||||
|
||||
RevArcIt& operator++() {
|
||||
current =
|
||||
path->digraph.source(path->predMatrixMap(path->source, current));
|
||||
if (path->predMatrixMap(path->source, current) == INVALID)
|
||||
current = INVALID;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const RevArcIt& e) const {
|
||||
return current == e.current;
|
||||
}
|
||||
|
||||
bool operator!=(const RevArcIt& e) const {
|
||||
return current != e.current;
|
||||
}
|
||||
|
||||
bool operator<(const RevArcIt& e) const {
|
||||
return current < e.current;
|
||||
}
|
||||
|
||||
private:
|
||||
const PredMatrixMapPath* path;
|
||||
typename Digraph::Node current;
|
||||
};
|
||||
|
||||
private:
|
||||
const Digraph& digraph;
|
||||
const PredMatrixMap& predMatrixMap;
|
||||
typename Digraph::Node source;
|
||||
typename Digraph::Node target;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
194
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/solver_bits.h
vendored
Normal file
194
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/solver_bits.h
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_SOLVER_BITS_H
|
||||
#define LEMON_BITS_SOLVER_BITS_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
namespace _solver_bits {
|
||||
|
||||
class VarIndex {
|
||||
private:
|
||||
struct ItemT {
|
||||
int prev, next;
|
||||
int index;
|
||||
};
|
||||
std::vector<ItemT> items;
|
||||
int first_item, last_item, first_free_item;
|
||||
|
||||
std::vector<int> cross;
|
||||
|
||||
public:
|
||||
|
||||
VarIndex()
|
||||
: first_item(-1), last_item(-1), first_free_item(-1) {
|
||||
}
|
||||
|
||||
void clear() {
|
||||
first_item = -1;
|
||||
last_item = -1;
|
||||
first_free_item = -1;
|
||||
items.clear();
|
||||
cross.clear();
|
||||
}
|
||||
|
||||
int addIndex(int idx) {
|
||||
int n;
|
||||
if (first_free_item == -1) {
|
||||
n = items.size();
|
||||
items.push_back(ItemT());
|
||||
} else {
|
||||
n = first_free_item;
|
||||
first_free_item = items[n].next;
|
||||
if (first_free_item != -1) {
|
||||
items[first_free_item].prev = -1;
|
||||
}
|
||||
}
|
||||
items[n].index = idx;
|
||||
if (static_cast<int>(cross.size()) <= idx) {
|
||||
cross.resize(idx + 1, -1);
|
||||
}
|
||||
cross[idx] = n;
|
||||
|
||||
items[n].prev = last_item;
|
||||
items[n].next = -1;
|
||||
if (last_item != -1) {
|
||||
items[last_item].next = n;
|
||||
} else {
|
||||
first_item = n;
|
||||
}
|
||||
last_item = n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int addIndex(int idx, int n) {
|
||||
while (n >= static_cast<int>(items.size())) {
|
||||
items.push_back(ItemT());
|
||||
items.back().prev = -1;
|
||||
items.back().next = first_free_item;
|
||||
if (first_free_item != -1) {
|
||||
items[first_free_item].prev = items.size() - 1;
|
||||
}
|
||||
first_free_item = items.size() - 1;
|
||||
}
|
||||
if (items[n].next != -1) {
|
||||
items[items[n].next].prev = items[n].prev;
|
||||
}
|
||||
if (items[n].prev != -1) {
|
||||
items[items[n].prev].next = items[n].next;
|
||||
} else {
|
||||
first_free_item = items[n].next;
|
||||
}
|
||||
|
||||
items[n].index = idx;
|
||||
if (static_cast<int>(cross.size()) <= idx) {
|
||||
cross.resize(idx + 1, -1);
|
||||
}
|
||||
cross[idx] = n;
|
||||
|
||||
items[n].prev = last_item;
|
||||
items[n].next = -1;
|
||||
if (last_item != -1) {
|
||||
items[last_item].next = n;
|
||||
} else {
|
||||
first_item = n;
|
||||
}
|
||||
last_item = n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void eraseIndex(int idx) {
|
||||
int n = cross[idx];
|
||||
|
||||
if (items[n].prev != -1) {
|
||||
items[items[n].prev].next = items[n].next;
|
||||
} else {
|
||||
first_item = items[n].next;
|
||||
}
|
||||
if (items[n].next != -1) {
|
||||
items[items[n].next].prev = items[n].prev;
|
||||
} else {
|
||||
last_item = items[n].prev;
|
||||
}
|
||||
|
||||
if (first_free_item != -1) {
|
||||
items[first_free_item].prev = n;
|
||||
}
|
||||
items[n].next = first_free_item;
|
||||
items[n].prev = -1;
|
||||
first_free_item = n;
|
||||
|
||||
while (!cross.empty() && cross.back() == -1) {
|
||||
cross.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
int maxIndex() const {
|
||||
return cross.size() - 1;
|
||||
}
|
||||
|
||||
void shiftIndices(int idx) {
|
||||
for (int i = idx + 1; i < static_cast<int>(cross.size()); ++i) {
|
||||
cross[i - 1] = cross[i];
|
||||
if (cross[i] != -1) {
|
||||
--items[cross[i]].index;
|
||||
}
|
||||
}
|
||||
cross.back() = -1;
|
||||
cross.pop_back();
|
||||
while (!cross.empty() && cross.back() == -1) {
|
||||
cross.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void relocateIndex(int idx, int jdx) {
|
||||
cross[idx] = cross[jdx];
|
||||
items[cross[jdx]].index = idx;
|
||||
cross[jdx] = -1;
|
||||
|
||||
while (!cross.empty() && cross.back() == -1) {
|
||||
cross.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
int operator[](int idx) const {
|
||||
return cross[idx];
|
||||
}
|
||||
|
||||
int operator()(int fdx) const {
|
||||
return items[fdx].index;
|
||||
}
|
||||
|
||||
void firstItem(int& fdx) const {
|
||||
fdx = first_item;
|
||||
}
|
||||
|
||||
void nextItem(int& fdx) const {
|
||||
fdx = items[fdx].next;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
388
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/traits.h
vendored
Normal file
388
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/traits.h
vendored
Normal file
@@ -0,0 +1,388 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_TRAITS_H
|
||||
#define LEMON_BITS_TRAITS_H
|
||||
|
||||
//\file
|
||||
//\brief Traits for graphs and maps
|
||||
//
|
||||
|
||||
#include <lemon/bits/enable_if.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
struct InvalidType {};
|
||||
|
||||
template <typename GR, typename _Item>
|
||||
class ItemSetTraits {};
|
||||
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct NodeNotifierIndicator {
|
||||
typedef InvalidType Type;
|
||||
};
|
||||
template <typename GR>
|
||||
struct NodeNotifierIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::NodeNotifier::Notifier, void>::type
|
||||
> {
|
||||
typedef typename GR::NodeNotifier Type;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
class ItemSetTraits<GR, typename GR::Node> {
|
||||
public:
|
||||
|
||||
typedef GR Graph;
|
||||
typedef GR Digraph;
|
||||
|
||||
typedef typename GR::Node Item;
|
||||
typedef typename GR::NodeIt ItemIt;
|
||||
|
||||
typedef typename NodeNotifierIndicator<GR>::Type ItemNotifier;
|
||||
|
||||
template <typename V>
|
||||
class Map : public GR::template NodeMap<V> {
|
||||
typedef typename GR::template NodeMap<V> Parent;
|
||||
|
||||
public:
|
||||
typedef typename GR::template NodeMap<V> Type;
|
||||
typedef typename Parent::Value Value;
|
||||
|
||||
Map(const GR& _digraph) : Parent(_digraph) {}
|
||||
Map(const GR& _digraph, const Value& _value)
|
||||
: Parent(_digraph, _value) {}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct ArcNotifierIndicator {
|
||||
typedef InvalidType Type;
|
||||
};
|
||||
template <typename GR>
|
||||
struct ArcNotifierIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::ArcNotifier::Notifier, void>::type
|
||||
> {
|
||||
typedef typename GR::ArcNotifier Type;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
class ItemSetTraits<GR, typename GR::Arc> {
|
||||
public:
|
||||
|
||||
typedef GR Graph;
|
||||
typedef GR Digraph;
|
||||
|
||||
typedef typename GR::Arc Item;
|
||||
typedef typename GR::ArcIt ItemIt;
|
||||
|
||||
typedef typename ArcNotifierIndicator<GR>::Type ItemNotifier;
|
||||
|
||||
template <typename V>
|
||||
class Map : public GR::template ArcMap<V> {
|
||||
typedef typename GR::template ArcMap<V> Parent;
|
||||
|
||||
public:
|
||||
typedef typename GR::template ArcMap<V> Type;
|
||||
typedef typename Parent::Value Value;
|
||||
|
||||
Map(const GR& _digraph) : Parent(_digraph) {}
|
||||
Map(const GR& _digraph, const Value& _value)
|
||||
: Parent(_digraph, _value) {}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct EdgeNotifierIndicator {
|
||||
typedef InvalidType Type;
|
||||
};
|
||||
template <typename GR>
|
||||
struct EdgeNotifierIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::EdgeNotifier::Notifier, void>::type
|
||||
> {
|
||||
typedef typename GR::EdgeNotifier Type;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
class ItemSetTraits<GR, typename GR::Edge> {
|
||||
public:
|
||||
|
||||
typedef GR Graph;
|
||||
typedef GR Digraph;
|
||||
|
||||
typedef typename GR::Edge Item;
|
||||
typedef typename GR::EdgeIt ItemIt;
|
||||
|
||||
typedef typename EdgeNotifierIndicator<GR>::Type ItemNotifier;
|
||||
|
||||
template <typename V>
|
||||
class Map : public GR::template EdgeMap<V> {
|
||||
typedef typename GR::template EdgeMap<V> Parent;
|
||||
|
||||
public:
|
||||
typedef typename GR::template EdgeMap<V> Type;
|
||||
typedef typename Parent::Value Value;
|
||||
|
||||
Map(const GR& _digraph) : Parent(_digraph) {}
|
||||
Map(const GR& _digraph, const Value& _value)
|
||||
: Parent(_digraph, _value) {}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct RedNodeNotifierIndicator {
|
||||
typedef InvalidType Type;
|
||||
};
|
||||
template <typename GR>
|
||||
struct RedNodeNotifierIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::RedNodeNotifier::Notifier, void>::type
|
||||
> {
|
||||
typedef typename GR::RedNodeNotifier Type;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
class ItemSetTraits<GR, typename GR::RedNode> {
|
||||
public:
|
||||
|
||||
typedef GR BpGraph;
|
||||
typedef GR Graph;
|
||||
typedef GR Digraph;
|
||||
|
||||
typedef typename GR::RedNode Item;
|
||||
typedef typename GR::RedNodeIt ItemIt;
|
||||
|
||||
typedef typename RedNodeNotifierIndicator<GR>::Type ItemNotifier;
|
||||
|
||||
template <typename V>
|
||||
class Map : public GR::template RedNodeMap<V> {
|
||||
typedef typename GR::template RedNodeMap<V> Parent;
|
||||
|
||||
public:
|
||||
typedef typename GR::template RedNodeMap<V> Type;
|
||||
typedef typename Parent::Value Value;
|
||||
|
||||
Map(const GR& _bpgraph) : Parent(_bpgraph) {}
|
||||
Map(const GR& _bpgraph, const Value& _value)
|
||||
: Parent(_bpgraph, _value) {}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct BlueNodeNotifierIndicator {
|
||||
typedef InvalidType Type;
|
||||
};
|
||||
template <typename GR>
|
||||
struct BlueNodeNotifierIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::BlueNodeNotifier::Notifier, void>::type
|
||||
> {
|
||||
typedef typename GR::BlueNodeNotifier Type;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
class ItemSetTraits<GR, typename GR::BlueNode> {
|
||||
public:
|
||||
|
||||
typedef GR BpGraph;
|
||||
typedef GR Graph;
|
||||
typedef GR Digraph;
|
||||
|
||||
typedef typename GR::BlueNode Item;
|
||||
typedef typename GR::BlueNodeIt ItemIt;
|
||||
|
||||
typedef typename BlueNodeNotifierIndicator<GR>::Type ItemNotifier;
|
||||
|
||||
template <typename V>
|
||||
class Map : public GR::template BlueNodeMap<V> {
|
||||
typedef typename GR::template BlueNodeMap<V> Parent;
|
||||
|
||||
public:
|
||||
typedef typename GR::template BlueNodeMap<V> Type;
|
||||
typedef typename Parent::Value Value;
|
||||
|
||||
Map(const GR& _bpgraph) : Parent(_bpgraph) {}
|
||||
Map(const GR& _bpgraph, const Value& _value)
|
||||
: Parent(_bpgraph, _value) {}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template <typename Map, typename Enable = void>
|
||||
struct MapTraits {
|
||||
typedef False ReferenceMapTag;
|
||||
|
||||
typedef typename Map::Key Key;
|
||||
typedef typename Map::Value Value;
|
||||
|
||||
typedef Value ConstReturnValue;
|
||||
typedef Value ReturnValue;
|
||||
};
|
||||
|
||||
template <typename Map>
|
||||
struct MapTraits<
|
||||
Map, typename enable_if<typename Map::ReferenceMapTag, void>::type >
|
||||
{
|
||||
typedef True ReferenceMapTag;
|
||||
|
||||
typedef typename Map::Key Key;
|
||||
typedef typename Map::Value Value;
|
||||
|
||||
typedef typename Map::ConstReference ConstReturnValue;
|
||||
typedef typename Map::Reference ReturnValue;
|
||||
|
||||
typedef typename Map::ConstReference ConstReference;
|
||||
typedef typename Map::Reference Reference;
|
||||
};
|
||||
|
||||
template <typename MatrixMap, typename Enable = void>
|
||||
struct MatrixMapTraits {
|
||||
typedef False ReferenceMapTag;
|
||||
|
||||
typedef typename MatrixMap::FirstKey FirstKey;
|
||||
typedef typename MatrixMap::SecondKey SecondKey;
|
||||
typedef typename MatrixMap::Value Value;
|
||||
|
||||
typedef Value ConstReturnValue;
|
||||
typedef Value ReturnValue;
|
||||
};
|
||||
|
||||
template <typename MatrixMap>
|
||||
struct MatrixMapTraits<
|
||||
MatrixMap, typename enable_if<typename MatrixMap::ReferenceMapTag,
|
||||
void>::type >
|
||||
{
|
||||
typedef True ReferenceMapTag;
|
||||
|
||||
typedef typename MatrixMap::FirstKey FirstKey;
|
||||
typedef typename MatrixMap::SecondKey SecondKey;
|
||||
typedef typename MatrixMap::Value Value;
|
||||
|
||||
typedef typename MatrixMap::ConstReference ConstReturnValue;
|
||||
typedef typename MatrixMap::Reference ReturnValue;
|
||||
|
||||
typedef typename MatrixMap::ConstReference ConstReference;
|
||||
typedef typename MatrixMap::Reference Reference;
|
||||
};
|
||||
|
||||
// Indicators for the tags
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct NodeNumTagIndicator {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
struct NodeNumTagIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::NodeNumTag, void>::type
|
||||
> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct ArcNumTagIndicator {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
struct ArcNumTagIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::ArcNumTag, void>::type
|
||||
> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct EdgeNumTagIndicator {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
struct EdgeNumTagIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::EdgeNumTag, void>::type
|
||||
> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct FindArcTagIndicator {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
struct FindArcTagIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::FindArcTag, void>::type
|
||||
> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct FindEdgeTagIndicator {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
struct FindEdgeTagIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::FindEdgeTag, void>::type
|
||||
> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct UndirectedTagIndicator {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
struct UndirectedTagIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::UndirectedTag, void>::type
|
||||
> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename GR, typename Enable = void>
|
||||
struct BuildTagIndicator {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename GR>
|
||||
struct BuildTagIndicator<
|
||||
GR,
|
||||
typename enable_if<typename GR::BuildTag, void>::type
|
||||
> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
494
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/variant.h
vendored
Normal file
494
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/variant.h
vendored
Normal file
@@ -0,0 +1,494 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_VARIANT_H
|
||||
#define LEMON_BITS_VARIANT_H
|
||||
|
||||
#include <lemon/assert.h>
|
||||
|
||||
// \file
|
||||
// \brief Variant types
|
||||
|
||||
namespace lemon {
|
||||
|
||||
namespace _variant_bits {
|
||||
|
||||
template <int left, int right>
|
||||
struct CTMax {
|
||||
static const int value = left < right ? right : left;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
// \brief Simple Variant type for two types
|
||||
//
|
||||
// Simple Variant type for two types. The Variant type is a type-safe
|
||||
// union. C++ has strong limitations for using unions, for
|
||||
// example you cannot store a type with non-default constructor or
|
||||
// destructor in a union. This class always knowns the current
|
||||
// state of the variant and it cares for the proper construction
|
||||
// and destruction.
|
||||
template <typename _First, typename _Second>
|
||||
class BiVariant {
|
||||
public:
|
||||
|
||||
// \brief The \c First type.
|
||||
typedef _First First;
|
||||
// \brief The \c Second type.
|
||||
typedef _Second Second;
|
||||
|
||||
// \brief Constructor
|
||||
//
|
||||
// This constructor initalizes to the default value of the \c First
|
||||
// type.
|
||||
BiVariant() {
|
||||
flag = true;
|
||||
new(reinterpret_cast<First*>(data)) First();
|
||||
}
|
||||
|
||||
// \brief Constructor
|
||||
//
|
||||
// This constructor initalizes to the given value of the \c First
|
||||
// type.
|
||||
BiVariant(const First& f) {
|
||||
flag = true;
|
||||
new(reinterpret_cast<First*>(data)) First(f);
|
||||
}
|
||||
|
||||
// \brief Constructor
|
||||
//
|
||||
// This constructor initalizes to the given value of the \c
|
||||
// Second type.
|
||||
BiVariant(const Second& s) {
|
||||
flag = false;
|
||||
new(reinterpret_cast<Second*>(data)) Second(s);
|
||||
}
|
||||
|
||||
// \brief Copy constructor
|
||||
//
|
||||
// Copy constructor
|
||||
BiVariant(const BiVariant& bivariant) {
|
||||
flag = bivariant.flag;
|
||||
if (flag) {
|
||||
new(reinterpret_cast<First*>(data)) First(bivariant.first());
|
||||
} else {
|
||||
new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Destrcutor
|
||||
//
|
||||
// Destructor
|
||||
~BiVariant() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
// \brief Set to the default value of the \c First type.
|
||||
//
|
||||
// This function sets the variant to the default value of the \c
|
||||
// First type.
|
||||
BiVariant& setFirst() {
|
||||
destroy();
|
||||
flag = true;
|
||||
new(reinterpret_cast<First*>(data)) First();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// \brief Set to the given value of the \c First type.
|
||||
//
|
||||
// This function sets the variant to the given value of the \c
|
||||
// First type.
|
||||
BiVariant& setFirst(const First& f) {
|
||||
destroy();
|
||||
flag = true;
|
||||
new(reinterpret_cast<First*>(data)) First(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// \brief Set to the default value of the \c Second type.
|
||||
//
|
||||
// This function sets the variant to the default value of the \c
|
||||
// Second type.
|
||||
BiVariant& setSecond() {
|
||||
destroy();
|
||||
flag = false;
|
||||
new(reinterpret_cast<Second*>(data)) Second();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// \brief Set to the given value of the \c Second type.
|
||||
//
|
||||
// This function sets the variant to the given value of the \c
|
||||
// Second type.
|
||||
BiVariant& setSecond(const Second& s) {
|
||||
destroy();
|
||||
flag = false;
|
||||
new(reinterpret_cast<Second*>(data)) Second(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// \brief Operator form of the \c setFirst()
|
||||
BiVariant& operator=(const First& f) {
|
||||
return setFirst(f);
|
||||
}
|
||||
|
||||
// \brief Operator form of the \c setSecond()
|
||||
BiVariant& operator=(const Second& s) {
|
||||
return setSecond(s);
|
||||
}
|
||||
|
||||
// \brief Assign operator
|
||||
BiVariant& operator=(const BiVariant& bivariant) {
|
||||
if (this == &bivariant) return *this;
|
||||
destroy();
|
||||
flag = bivariant.flag;
|
||||
if (flag) {
|
||||
new(reinterpret_cast<First*>(data)) First(bivariant.first());
|
||||
} else {
|
||||
new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// \brief Reference to the value
|
||||
//
|
||||
// Reference to the value of the \c First type.
|
||||
// \pre The BiVariant should store value of \c First type.
|
||||
First& first() {
|
||||
LEMON_DEBUG(flag, "Variant wrong state");
|
||||
return *reinterpret_cast<First*>(data);
|
||||
}
|
||||
|
||||
// \brief Const reference to the value
|
||||
//
|
||||
// Const reference to the value of the \c First type.
|
||||
// \pre The BiVariant should store value of \c First type.
|
||||
const First& first() const {
|
||||
LEMON_DEBUG(flag, "Variant wrong state");
|
||||
return *reinterpret_cast<const First*>(data);
|
||||
}
|
||||
|
||||
// \brief Operator form of the \c first()
|
||||
operator First&() { return first(); }
|
||||
// \brief Operator form of the const \c first()
|
||||
operator const First&() const { return first(); }
|
||||
|
||||
// \brief Reference to the value
|
||||
//
|
||||
// Reference to the value of the \c Second type.
|
||||
// \pre The BiVariant should store value of \c Second type.
|
||||
Second& second() {
|
||||
LEMON_DEBUG(!flag, "Variant wrong state");
|
||||
return *reinterpret_cast<Second*>(data);
|
||||
}
|
||||
|
||||
// \brief Const reference to the value
|
||||
//
|
||||
// Const reference to the value of the \c Second type.
|
||||
// \pre The BiVariant should store value of \c Second type.
|
||||
const Second& second() const {
|
||||
LEMON_DEBUG(!flag, "Variant wrong state");
|
||||
return *reinterpret_cast<const Second*>(data);
|
||||
}
|
||||
|
||||
// \brief Operator form of the \c second()
|
||||
operator Second&() { return second(); }
|
||||
// \brief Operator form of the const \c second()
|
||||
operator const Second&() const { return second(); }
|
||||
|
||||
// \brief %True when the variant is in the first state
|
||||
//
|
||||
// %True when the variant stores value of the \c First type.
|
||||
bool firstState() const { return flag; }
|
||||
|
||||
// \brief %True when the variant is in the second state
|
||||
//
|
||||
// %True when the variant stores value of the \c Second type.
|
||||
bool secondState() const { return !flag; }
|
||||
|
||||
private:
|
||||
|
||||
void destroy() {
|
||||
if (flag) {
|
||||
reinterpret_cast<First*>(data)->~First();
|
||||
} else {
|
||||
reinterpret_cast<Second*>(data)->~Second();
|
||||
}
|
||||
}
|
||||
|
||||
char data[_variant_bits::CTMax<sizeof(First), sizeof(Second)>::value];
|
||||
bool flag;
|
||||
};
|
||||
|
||||
namespace _variant_bits {
|
||||
|
||||
template <int _idx, typename _TypeMap>
|
||||
struct Memory {
|
||||
|
||||
typedef typename _TypeMap::template Map<_idx>::Type Current;
|
||||
|
||||
static void destroy(int index, char* place) {
|
||||
if (index == _idx) {
|
||||
reinterpret_cast<Current*>(place)->~Current();
|
||||
} else {
|
||||
Memory<_idx - 1, _TypeMap>::destroy(index, place);
|
||||
}
|
||||
}
|
||||
|
||||
static void copy(int index, char* to, const char* from) {
|
||||
if (index == _idx) {
|
||||
new (reinterpret_cast<Current*>(to))
|
||||
Current(reinterpret_cast<const Current*>(from));
|
||||
} else {
|
||||
Memory<_idx - 1, _TypeMap>::copy(index, to, from);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename _TypeMap>
|
||||
struct Memory<-1, _TypeMap> {
|
||||
|
||||
static void destroy(int, char*) {
|
||||
LEMON_DEBUG(false, "Variant wrong index.");
|
||||
}
|
||||
|
||||
static void copy(int, char*, const char*) {
|
||||
LEMON_DEBUG(false, "Variant wrong index.");
|
||||
}
|
||||
};
|
||||
|
||||
template <int _idx, typename _TypeMap>
|
||||
struct Size {
|
||||
static const int value =
|
||||
CTMax<sizeof(typename _TypeMap::template Map<_idx>::Type),
|
||||
Size<_idx - 1, _TypeMap>::value>::value;
|
||||
};
|
||||
|
||||
template <typename _TypeMap>
|
||||
struct Size<0, _TypeMap> {
|
||||
static const int value =
|
||||
sizeof(typename _TypeMap::template Map<0>::Type);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// \brief Variant type
|
||||
//
|
||||
// Simple Variant type. The Variant type is a type-safe union.
|
||||
// C++ has strong limitations for using unions, for example you
|
||||
// cannot store type with non-default constructor or destructor in
|
||||
// a union. This class always knowns the current state of the
|
||||
// variant and it cares for the proper construction and
|
||||
// destruction.
|
||||
//
|
||||
// \param _num The number of the types which can be stored in the
|
||||
// variant type.
|
||||
// \param _TypeMap This class describes the types of the Variant. The
|
||||
// _TypeMap::Map<index>::Type should be a valid type for each index
|
||||
// in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper
|
||||
// class to define such type mappings up to 10 types.
|
||||
//
|
||||
// And the usage of the class:
|
||||
//\code
|
||||
// typedef Variant<3, VariantTypeMap<int, std::string, double> > MyVariant;
|
||||
// MyVariant var;
|
||||
// var.set<0>(12);
|
||||
// std::cout << var.get<0>() << std::endl;
|
||||
// var.set<1>("alpha");
|
||||
// std::cout << var.get<1>() << std::endl;
|
||||
// var.set<2>(0.75);
|
||||
// std::cout << var.get<2>() << std::endl;
|
||||
//\endcode
|
||||
//
|
||||
// The result of course:
|
||||
//\code
|
||||
// 12
|
||||
// alpha
|
||||
// 0.75
|
||||
//\endcode
|
||||
template <int _num, typename _TypeMap>
|
||||
class Variant {
|
||||
public:
|
||||
|
||||
static const int num = _num;
|
||||
|
||||
typedef _TypeMap TypeMap;
|
||||
|
||||
// \brief Constructor
|
||||
//
|
||||
// This constructor initalizes to the default value of the \c type
|
||||
// with 0 index.
|
||||
Variant() {
|
||||
flag = 0;
|
||||
new(reinterpret_cast<typename TypeMap::template Map<0>::Type*>(data))
|
||||
typename TypeMap::template Map<0>::Type();
|
||||
}
|
||||
|
||||
|
||||
// \brief Copy constructor
|
||||
//
|
||||
// Copy constructor
|
||||
Variant(const Variant& variant) {
|
||||
flag = variant.flag;
|
||||
_variant_bits::Memory<num - 1, TypeMap>::copy(flag, data, variant.data);
|
||||
}
|
||||
|
||||
// \brief Assign operator
|
||||
//
|
||||
// Assign operator
|
||||
Variant& operator=(const Variant& variant) {
|
||||
if (this == &variant) return *this;
|
||||
_variant_bits::Memory<num - 1, TypeMap>::
|
||||
destroy(flag, data);
|
||||
flag = variant.flag;
|
||||
_variant_bits::Memory<num - 1, TypeMap>::
|
||||
copy(flag, data, variant.data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// \brief Destrcutor
|
||||
//
|
||||
// Destructor
|
||||
~Variant() {
|
||||
_variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
|
||||
}
|
||||
|
||||
// \brief Set to the default value of the type with \c _idx index.
|
||||
//
|
||||
// This function sets the variant to the default value of the
|
||||
// type with \c _idx index.
|
||||
template <int _idx>
|
||||
Variant& set() {
|
||||
_variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
|
||||
flag = _idx;
|
||||
new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
|
||||
typename TypeMap::template Map<_idx>::Type();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// \brief Set to the given value of the type with \c _idx index.
|
||||
//
|
||||
// This function sets the variant to the given value of the type
|
||||
// with \c _idx index.
|
||||
template <int _idx>
|
||||
Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) {
|
||||
_variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
|
||||
flag = _idx;
|
||||
new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
|
||||
typename TypeMap::template Map<_idx>::Type(init);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// \brief Gets the current value of the type with \c _idx index.
|
||||
//
|
||||
// Gets the current value of the type with \c _idx index.
|
||||
template <int _idx>
|
||||
const typename TypeMap::template Map<_idx>::Type& get() const {
|
||||
LEMON_DEBUG(_idx == flag, "Variant wrong index");
|
||||
return *reinterpret_cast<const typename TypeMap::
|
||||
template Map<_idx>::Type*>(data);
|
||||
}
|
||||
|
||||
// \brief Gets the current value of the type with \c _idx index.
|
||||
//
|
||||
// Gets the current value of the type with \c _idx index.
|
||||
template <int _idx>
|
||||
typename _TypeMap::template Map<_idx>::Type& get() {
|
||||
LEMON_DEBUG(_idx == flag, "Variant wrong index");
|
||||
return *reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>
|
||||
(data);
|
||||
}
|
||||
|
||||
// \brief Returns the current state of the variant.
|
||||
//
|
||||
// Returns the current state of the variant.
|
||||
int state() const {
|
||||
return flag;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char data[_variant_bits::Size<num - 1, TypeMap>::value];
|
||||
int flag;
|
||||
};
|
||||
|
||||
namespace _variant_bits {
|
||||
|
||||
template <int _index, typename _List>
|
||||
struct Get {
|
||||
typedef typename Get<_index - 1, typename _List::Next>::Type Type;
|
||||
};
|
||||
|
||||
template <typename _List>
|
||||
struct Get<0, _List> {
|
||||
typedef typename _List::Type Type;
|
||||
};
|
||||
|
||||
struct List {};
|
||||
|
||||
template <typename _Type, typename _List>
|
||||
struct Insert {
|
||||
typedef _List Next;
|
||||
typedef _Type Type;
|
||||
};
|
||||
|
||||
template <int _idx, typename _T0, typename _T1, typename _T2,
|
||||
typename _T3, typename _T4, typename _T5, typename _T6,
|
||||
typename _T7, typename _T8, typename _T9>
|
||||
struct Mapper {
|
||||
typedef List L10;
|
||||
typedef Insert<_T9, L10> L9;
|
||||
typedef Insert<_T8, L9> L8;
|
||||
typedef Insert<_T7, L8> L7;
|
||||
typedef Insert<_T6, L7> L6;
|
||||
typedef Insert<_T5, L6> L5;
|
||||
typedef Insert<_T4, L5> L4;
|
||||
typedef Insert<_T3, L4> L3;
|
||||
typedef Insert<_T2, L3> L2;
|
||||
typedef Insert<_T1, L2> L1;
|
||||
typedef Insert<_T0, L1> L0;
|
||||
typedef typename Get<_idx, L0>::Type Type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// \brief Helper class for Variant
|
||||
//
|
||||
// Helper class to define type mappings for Variant. This class
|
||||
// converts the template parameters to be mappable by integer.
|
||||
// \see Variant
|
||||
template <
|
||||
typename _T0,
|
||||
typename _T1 = void, typename _T2 = void, typename _T3 = void,
|
||||
typename _T4 = void, typename _T5 = void, typename _T6 = void,
|
||||
typename _T7 = void, typename _T8 = void, typename _T9 = void>
|
||||
struct VariantTypeMap {
|
||||
template <int _idx>
|
||||
struct Map {
|
||||
typedef typename _variant_bits::
|
||||
Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type
|
||||
Type;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
244
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/vector_map.h
vendored
Normal file
244
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/vector_map.h
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_VECTOR_MAP_H
|
||||
#define LEMON_BITS_VECTOR_MAP_H
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/bits/alteration_notifier.h>
|
||||
|
||||
#include <lemon/concept_check.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
|
||||
//\ingroup graphbits
|
||||
//
|
||||
//\file
|
||||
//\brief Vector based graph maps.
|
||||
namespace lemon {
|
||||
|
||||
// \ingroup graphbits
|
||||
//
|
||||
// \brief Graph map based on the std::vector storage.
|
||||
//
|
||||
// The VectorMap template class is graph map structure that automatically
|
||||
// updates the map when a key is added to or erased from the graph.
|
||||
// This map type uses std::vector to store the values.
|
||||
//
|
||||
// \tparam _Graph The graph this map is attached to.
|
||||
// \tparam _Item The item type of the graph items.
|
||||
// \tparam _Value The value type of the map.
|
||||
template <typename _Graph, typename _Item, typename _Value>
|
||||
class VectorMap
|
||||
: public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
|
||||
private:
|
||||
|
||||
// The container type of the map.
|
||||
typedef std::vector<_Value> Container;
|
||||
|
||||
public:
|
||||
|
||||
// The graph type of the map.
|
||||
typedef _Graph GraphType;
|
||||
// The item type of the map.
|
||||
typedef _Item Item;
|
||||
// The reference map tag.
|
||||
typedef True ReferenceMapTag;
|
||||
|
||||
// The key type of the map.
|
||||
typedef _Item Key;
|
||||
// The value type of the map.
|
||||
typedef _Value Value;
|
||||
|
||||
// The notifier type.
|
||||
typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
|
||||
|
||||
// The map type.
|
||||
typedef VectorMap Map;
|
||||
|
||||
// The reference type of the map;
|
||||
typedef typename Container::reference Reference;
|
||||
// The const reference type of the map;
|
||||
typedef typename Container::const_reference ConstReference;
|
||||
|
||||
private:
|
||||
|
||||
// The base class of the map.
|
||||
typedef typename Notifier::ObserverBase Parent;
|
||||
|
||||
public:
|
||||
|
||||
// \brief Constructor to attach the new map into the notifier.
|
||||
//
|
||||
// It constructs a map and attachs it into the notifier.
|
||||
// It adds all the items of the graph to the map.
|
||||
VectorMap(const GraphType& graph) {
|
||||
Parent::attach(graph.notifier(Item()));
|
||||
container.resize(Parent::notifier()->maxId() + 1);
|
||||
}
|
||||
|
||||
// \brief Constructor uses given value to initialize the map.
|
||||
//
|
||||
// It constructs a map uses a given value to initialize the map.
|
||||
// It adds all the items of the graph to the map.
|
||||
VectorMap(const GraphType& graph, const Value& value) {
|
||||
Parent::attach(graph.notifier(Item()));
|
||||
container.resize(Parent::notifier()->maxId() + 1, value);
|
||||
}
|
||||
|
||||
private:
|
||||
// \brief Copy constructor
|
||||
//
|
||||
// Copy constructor.
|
||||
VectorMap(const VectorMap& _copy) : Parent() {
|
||||
if (_copy.attached()) {
|
||||
Parent::attach(*_copy.notifier());
|
||||
container = _copy.container;
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Assign operator.
|
||||
//
|
||||
// This operator assigns for each item in the map the
|
||||
// value mapped to the same item in the copied map.
|
||||
// The parameter map should be indiced with the same
|
||||
// itemset because this assign operator does not change
|
||||
// the container of the map.
|
||||
VectorMap& operator=(const VectorMap& cmap) {
|
||||
return operator=<VectorMap>(cmap);
|
||||
}
|
||||
|
||||
|
||||
// \brief Template assign operator.
|
||||
//
|
||||
// The given parameter should conform to the ReadMap
|
||||
// concecpt and could be indiced by the current item set of
|
||||
// the NodeMap. In this case the value for each item
|
||||
// is assigned by the value of the given ReadMap.
|
||||
template <typename CMap>
|
||||
VectorMap& operator=(const CMap& cmap) {
|
||||
checkConcept<concepts::ReadMap<Key, _Value>, CMap>();
|
||||
const typename Parent::Notifier* nf = Parent::notifier();
|
||||
Item it;
|
||||
for (nf->first(it); it != INVALID; nf->next(it)) {
|
||||
set(it, cmap[it]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// \brief The subcript operator.
|
||||
//
|
||||
// The subscript operator. The map can be subscripted by the
|
||||
// actual items of the graph.
|
||||
Reference operator[](const Key& key) {
|
||||
return container[Parent::notifier()->id(key)];
|
||||
}
|
||||
|
||||
// \brief The const subcript operator.
|
||||
//
|
||||
// The const subscript operator. The map can be subscripted by the
|
||||
// actual items of the graph.
|
||||
ConstReference operator[](const Key& key) const {
|
||||
return container[Parent::notifier()->id(key)];
|
||||
}
|
||||
|
||||
|
||||
// \brief The setter function of the map.
|
||||
//
|
||||
// It the same as operator[](key) = value expression.
|
||||
void set(const Key& key, const Value& value) {
|
||||
(*this)[key] = value;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// \brief Adds a new key to the map.
|
||||
//
|
||||
// It adds a new key to the map. It is called by the observer notifier
|
||||
// and it overrides the add() member function of the observer base.
|
||||
virtual void add(const Key& key) {
|
||||
int id = Parent::notifier()->id(key);
|
||||
if (id >= int(container.size())) {
|
||||
container.resize(id + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Adds more new keys to the map.
|
||||
//
|
||||
// It adds more new keys to the map. It is called by the observer notifier
|
||||
// and it overrides the add() member function of the observer base.
|
||||
virtual void add(const std::vector<Key>& keys) {
|
||||
int max = container.size() - 1;
|
||||
for (int i = 0; i < int(keys.size()); ++i) {
|
||||
int id = Parent::notifier()->id(keys[i]);
|
||||
if (id >= max) {
|
||||
max = id;
|
||||
}
|
||||
}
|
||||
container.resize(max + 1);
|
||||
}
|
||||
|
||||
// \brief Erase a key from the map.
|
||||
//
|
||||
// Erase a key from the map. It is called by the observer notifier
|
||||
// and it overrides the erase() member function of the observer base.
|
||||
virtual void erase(const Key& key) {
|
||||
container[Parent::notifier()->id(key)] = Value();
|
||||
}
|
||||
|
||||
// \brief Erase more keys from the map.
|
||||
//
|
||||
// It erases more keys from the map. It is called by the observer notifier
|
||||
// and it overrides the erase() member function of the observer base.
|
||||
virtual void erase(const std::vector<Key>& keys) {
|
||||
for (int i = 0; i < int(keys.size()); ++i) {
|
||||
container[Parent::notifier()->id(keys[i])] = Value();
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Build the map.
|
||||
//
|
||||
// It builds the map. It is called by the observer notifier
|
||||
// and it overrides the build() member function of the observer base.
|
||||
virtual void build() {
|
||||
int size = Parent::notifier()->maxId() + 1;
|
||||
container.reserve(size);
|
||||
container.resize(size);
|
||||
}
|
||||
|
||||
// \brief Clear the map.
|
||||
//
|
||||
// It erases all items from the map. It is called by the observer notifier
|
||||
// and it overrides the clear() member function of the observer base.
|
||||
virtual void clear() {
|
||||
container.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Container container;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
166
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/windows.cc
vendored
Normal file
166
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/windows.cc
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
///\file
|
||||
///\brief Some basic non-inline functions and static global data.
|
||||
|
||||
#include<lemon/bits/windows.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#ifdef UNICODE
|
||||
#undef UNICODE
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#ifdef LOCALE_INVARIANT
|
||||
#define MY_LOCALE LOCALE_INVARIANT
|
||||
#else
|
||||
#define MY_LOCALE LOCALE_NEUTRAL
|
||||
#endif
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <ctime>
|
||||
#ifndef WIN32
|
||||
#include <sys/times.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
|
||||
namespace lemon {
|
||||
namespace bits {
|
||||
void getWinProcTimes(double &rtime,
|
||||
double &utime, double &stime,
|
||||
double &cutime, double &cstime)
|
||||
{
|
||||
#ifdef WIN32
|
||||
static const double ch = 4294967296.0e-7;
|
||||
static const double cl = 1.0e-7;
|
||||
|
||||
FILETIME system;
|
||||
GetSystemTimeAsFileTime(&system);
|
||||
rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
|
||||
|
||||
FILETIME create, exit, kernel, user;
|
||||
if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
|
||||
utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
|
||||
stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
|
||||
cutime = 0;
|
||||
cstime = 0;
|
||||
} else {
|
||||
rtime = 0;
|
||||
utime = 0;
|
||||
stime = 0;
|
||||
cutime = 0;
|
||||
cstime = 0;
|
||||
}
|
||||
#else
|
||||
timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
|
||||
|
||||
tms ts;
|
||||
double tck=sysconf(_SC_CLK_TCK);
|
||||
times(&ts);
|
||||
utime=ts.tms_utime/tck;
|
||||
stime=ts.tms_stime/tck;
|
||||
cutime=ts.tms_cutime/tck;
|
||||
cstime=ts.tms_cstime/tck;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string getWinFormattedDate()
|
||||
{
|
||||
std::ostringstream os;
|
||||
#ifdef WIN32
|
||||
SYSTEMTIME time;
|
||||
GetSystemTime(&time);
|
||||
char buf1[11], buf2[9], buf3[5];
|
||||
if (GetDateFormat(MY_LOCALE, 0, &time,
|
||||
("ddd MMM dd"), buf1, 11) &&
|
||||
GetTimeFormat(MY_LOCALE, 0, &time,
|
||||
("HH':'mm':'ss"), buf2, 9) &&
|
||||
GetDateFormat(MY_LOCALE, 0, &time,
|
||||
("yyyy"), buf3, 5)) {
|
||||
os << buf1 << ' ' << buf2 << ' ' << buf3;
|
||||
}
|
||||
else os << "unknown";
|
||||
#else
|
||||
timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
|
||||
char cbuf[26];
|
||||
ctime_r(&tv.tv_sec,cbuf);
|
||||
os << cbuf;
|
||||
#endif
|
||||
return os.str();
|
||||
}
|
||||
|
||||
int getWinRndSeed()
|
||||
{
|
||||
#ifdef WIN32
|
||||
FILETIME time;
|
||||
GetSystemTimeAsFileTime(&time);
|
||||
return GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime;
|
||||
#else
|
||||
timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
return getpid() + tv.tv_sec + tv.tv_usec;
|
||||
#endif
|
||||
}
|
||||
|
||||
WinLock::WinLock() {
|
||||
#ifdef WIN32
|
||||
CRITICAL_SECTION *lock = new CRITICAL_SECTION;
|
||||
InitializeCriticalSection(lock);
|
||||
_repr = lock;
|
||||
#else
|
||||
_repr = 0; //Just to avoid 'unused variable' warning with clang
|
||||
#endif
|
||||
}
|
||||
|
||||
WinLock::~WinLock() {
|
||||
#ifdef WIN32
|
||||
CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
|
||||
DeleteCriticalSection(lock);
|
||||
delete lock;
|
||||
#endif
|
||||
}
|
||||
|
||||
void WinLock::lock() {
|
||||
#ifdef WIN32
|
||||
CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
|
||||
EnterCriticalSection(lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void WinLock::unlock() {
|
||||
#ifdef WIN32
|
||||
CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
|
||||
LeaveCriticalSection(lock);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
44
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/windows.h
vendored
Normal file
44
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/windows.h
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BITS_WINDOWS_H
|
||||
#define LEMON_BITS_WINDOWS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace lemon {
|
||||
namespace bits {
|
||||
void getWinProcTimes(double &rtime,
|
||||
double &utime, double &stime,
|
||||
double &cutime, double &cstime);
|
||||
std::string getWinFormattedDate();
|
||||
int getWinRndSeed();
|
||||
|
||||
class WinLock {
|
||||
public:
|
||||
WinLock();
|
||||
~WinLock();
|
||||
void lock();
|
||||
void unlock();
|
||||
private:
|
||||
void *_repr;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
594
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bucket_heap.h
vendored
Normal file
594
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/bucket_heap.h
vendored
Normal file
@@ -0,0 +1,594 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2010
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_BUCKET_HEAP_H
|
||||
#define LEMON_BUCKET_HEAP_H
|
||||
|
||||
///\ingroup heaps
|
||||
///\file
|
||||
///\brief Bucket heap implementation.
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
namespace _bucket_heap_bits {
|
||||
|
||||
template <bool MIN>
|
||||
struct DirectionTraits {
|
||||
static bool less(int left, int right) {
|
||||
return left < right;
|
||||
}
|
||||
static void increase(int& value) {
|
||||
++value;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DirectionTraits<false> {
|
||||
static bool less(int left, int right) {
|
||||
return left > right;
|
||||
}
|
||||
static void increase(int& value) {
|
||||
--value;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// \ingroup heaps
|
||||
///
|
||||
/// \brief Bucket heap data structure.
|
||||
///
|
||||
/// This class implements the \e bucket \e heap data structure.
|
||||
/// It practically conforms to the \ref concepts::Heap "heap concept",
|
||||
/// but it has some limitations.
|
||||
///
|
||||
/// The bucket heap is a very simple structure. It can store only
|
||||
/// \c int priorities and it maintains a list of items for each priority
|
||||
/// in the range <tt>[0..C)</tt>. So it should only be used when the
|
||||
/// priorities are small. It is not intended to use as a Dijkstra heap.
|
||||
///
|
||||
/// \tparam IM A read-writable item map with \c int values, used
|
||||
/// internally to handle the cross references.
|
||||
/// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
|
||||
/// The default is \e min-heap. If this parameter is set to \c false,
|
||||
/// then the comparison is reversed, so the top(), prio() and pop()
|
||||
/// functions deal with the item having maximum priority instead of the
|
||||
/// minimum.
|
||||
///
|
||||
/// \sa SimpleBucketHeap
|
||||
template <typename IM, bool MIN = true>
|
||||
class BucketHeap {
|
||||
|
||||
public:
|
||||
|
||||
/// Type of the item-int map.
|
||||
typedef IM ItemIntMap;
|
||||
/// Type of the priorities.
|
||||
typedef int Prio;
|
||||
/// Type of the items stored in the heap.
|
||||
typedef typename ItemIntMap::Key Item;
|
||||
/// Type of the item-priority pairs.
|
||||
typedef std::pair<Item,Prio> Pair;
|
||||
|
||||
private:
|
||||
|
||||
typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Type to represent the states of the items.
|
||||
///
|
||||
/// Each item has a state associated to it. It can be "in heap",
|
||||
/// "pre-heap" or "post-heap". The latter two are indifferent from the
|
||||
/// heap's point of view, but may be useful to the user.
|
||||
///
|
||||
/// The item-int map must be initialized in such way that it assigns
|
||||
/// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
|
||||
enum State {
|
||||
IN_HEAP = 0, ///< = 0.
|
||||
PRE_HEAP = -1, ///< = -1.
|
||||
POST_HEAP = -2 ///< = -2.
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to the items.
|
||||
/// It is used internally to handle the cross references.
|
||||
/// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
|
||||
|
||||
/// \brief The number of items stored in the heap.
|
||||
///
|
||||
/// This function returns the number of items stored in the heap.
|
||||
int size() const { return _data.size(); }
|
||||
|
||||
/// \brief Check if the heap is empty.
|
||||
///
|
||||
/// This function returns \c true if the heap is empty.
|
||||
bool empty() const { return _data.empty(); }
|
||||
|
||||
/// \brief Make the heap empty.
|
||||
///
|
||||
/// This functon makes the heap empty.
|
||||
/// It does not change the cross reference map. If you want to reuse
|
||||
/// a heap that is not surely empty, you should first clear it and
|
||||
/// then you should set the cross reference map to \c PRE_HEAP
|
||||
/// for each item.
|
||||
void clear() {
|
||||
_data.clear(); _first.clear(); _minimum = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void relocateLast(int idx) {
|
||||
if (idx + 1 < int(_data.size())) {
|
||||
_data[idx] = _data.back();
|
||||
if (_data[idx].prev != -1) {
|
||||
_data[_data[idx].prev].next = idx;
|
||||
} else {
|
||||
_first[_data[idx].value] = idx;
|
||||
}
|
||||
if (_data[idx].next != -1) {
|
||||
_data[_data[idx].next].prev = idx;
|
||||
}
|
||||
_iim[_data[idx].item] = idx;
|
||||
}
|
||||
_data.pop_back();
|
||||
}
|
||||
|
||||
void unlace(int idx) {
|
||||
if (_data[idx].prev != -1) {
|
||||
_data[_data[idx].prev].next = _data[idx].next;
|
||||
} else {
|
||||
_first[_data[idx].value] = _data[idx].next;
|
||||
}
|
||||
if (_data[idx].next != -1) {
|
||||
_data[_data[idx].next].prev = _data[idx].prev;
|
||||
}
|
||||
}
|
||||
|
||||
void lace(int idx) {
|
||||
if (int(_first.size()) <= _data[idx].value) {
|
||||
_first.resize(_data[idx].value + 1, -1);
|
||||
}
|
||||
_data[idx].next = _first[_data[idx].value];
|
||||
if (_data[idx].next != -1) {
|
||||
_data[_data[idx].next].prev = idx;
|
||||
}
|
||||
_first[_data[idx].value] = idx;
|
||||
_data[idx].prev = -1;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Insert a pair of item and priority into the heap.
|
||||
///
|
||||
/// This function inserts \c p.first to the heap with priority
|
||||
/// \c p.second.
|
||||
/// \param p The pair to insert.
|
||||
/// \pre \c p.first must not be stored in the heap.
|
||||
void push(const Pair& p) {
|
||||
push(p.first, p.second);
|
||||
}
|
||||
|
||||
/// \brief Insert an item into the heap with the given priority.
|
||||
///
|
||||
/// This function inserts the given item into the heap with the
|
||||
/// given priority.
|
||||
/// \param i The item to insert.
|
||||
/// \param p The priority of the item.
|
||||
/// \pre \e i must not be stored in the heap.
|
||||
void push(const Item &i, const Prio &p) {
|
||||
int idx = _data.size();
|
||||
_iim[i] = idx;
|
||||
_data.push_back(BucketItem(i, p));
|
||||
lace(idx);
|
||||
if (Direction::less(p, _minimum)) {
|
||||
_minimum = p;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Return the item having minimum priority.
|
||||
///
|
||||
/// This function returns the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Item top() const {
|
||||
while (_first[_minimum] == -1) {
|
||||
Direction::increase(_minimum);
|
||||
}
|
||||
return _data[_first[_minimum]].item;
|
||||
}
|
||||
|
||||
/// \brief The minimum priority.
|
||||
///
|
||||
/// This function returns the minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Prio prio() const {
|
||||
while (_first[_minimum] == -1) {
|
||||
Direction::increase(_minimum);
|
||||
}
|
||||
return _minimum;
|
||||
}
|
||||
|
||||
/// \brief Remove the item having minimum priority.
|
||||
///
|
||||
/// This function removes the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
void pop() {
|
||||
while (_first[_minimum] == -1) {
|
||||
Direction::increase(_minimum);
|
||||
}
|
||||
int idx = _first[_minimum];
|
||||
_iim[_data[idx].item] = -2;
|
||||
unlace(idx);
|
||||
relocateLast(idx);
|
||||
}
|
||||
|
||||
/// \brief Remove the given item from the heap.
|
||||
///
|
||||
/// This function removes the given item from the heap if it is
|
||||
/// already stored.
|
||||
/// \param i The item to delete.
|
||||
/// \pre \e i must be in the heap.
|
||||
void erase(const Item &i) {
|
||||
int idx = _iim[i];
|
||||
_iim[_data[idx].item] = -2;
|
||||
unlace(idx);
|
||||
relocateLast(idx);
|
||||
}
|
||||
|
||||
/// \brief The priority of the given item.
|
||||
///
|
||||
/// This function returns the priority of the given item.
|
||||
/// \param i The item.
|
||||
/// \pre \e i must be in the heap.
|
||||
Prio operator[](const Item &i) const {
|
||||
int idx = _iim[i];
|
||||
return _data[idx].value;
|
||||
}
|
||||
|
||||
/// \brief Set the priority of an item or insert it, if it is
|
||||
/// not stored in the heap.
|
||||
///
|
||||
/// This method sets the priority of the given item if it is
|
||||
/// already stored in the heap. Otherwise it inserts the given
|
||||
/// item into the heap with the given priority.
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
void set(const Item &i, const Prio &p) {
|
||||
int idx = _iim[i];
|
||||
if (idx < 0) {
|
||||
push(i, p);
|
||||
} else if (Direction::less(p, _data[idx].value)) {
|
||||
decrease(i, p);
|
||||
} else {
|
||||
increase(i, p);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Decrease the priority of an item to the given value.
|
||||
///
|
||||
/// This function decreases the priority of an item to the given value.
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
/// \pre \e i must be stored in the heap with priority at least \e p.
|
||||
void decrease(const Item &i, const Prio &p) {
|
||||
int idx = _iim[i];
|
||||
unlace(idx);
|
||||
_data[idx].value = p;
|
||||
if (Direction::less(p, _minimum)) {
|
||||
_minimum = p;
|
||||
}
|
||||
lace(idx);
|
||||
}
|
||||
|
||||
/// \brief Increase the priority of an item to the given value.
|
||||
///
|
||||
/// This function increases the priority of an item to the given value.
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
/// \pre \e i must be stored in the heap with priority at most \e p.
|
||||
void increase(const Item &i, const Prio &p) {
|
||||
int idx = _iim[i];
|
||||
unlace(idx);
|
||||
_data[idx].value = p;
|
||||
lace(idx);
|
||||
}
|
||||
|
||||
/// \brief Return the state of an item.
|
||||
///
|
||||
/// This method returns \c PRE_HEAP if the given item has never
|
||||
/// been in the heap, \c IN_HEAP if it is in the heap at the moment,
|
||||
/// and \c POST_HEAP otherwise.
|
||||
/// In the latter case it is possible that the item will get back
|
||||
/// to the heap again.
|
||||
/// \param i The item.
|
||||
State state(const Item &i) const {
|
||||
int idx = _iim[i];
|
||||
if (idx >= 0) idx = 0;
|
||||
return State(idx);
|
||||
}
|
||||
|
||||
/// \brief Set the state of an item in the heap.
|
||||
///
|
||||
/// This function sets the state of the given item in the heap.
|
||||
/// It can be used to manually clear the heap when it is important
|
||||
/// to achive better time complexity.
|
||||
/// \param i The item.
|
||||
/// \param st The state. It should not be \c IN_HEAP.
|
||||
void state(const Item& i, State st) {
|
||||
switch (st) {
|
||||
case POST_HEAP:
|
||||
case PRE_HEAP:
|
||||
if (state(i) == IN_HEAP) {
|
||||
erase(i);
|
||||
}
|
||||
_iim[i] = st;
|
||||
break;
|
||||
case IN_HEAP:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
struct BucketItem {
|
||||
BucketItem(const Item& _item, int _value)
|
||||
: item(_item), value(_value) {}
|
||||
|
||||
Item item;
|
||||
int value;
|
||||
|
||||
int prev, next;
|
||||
};
|
||||
|
||||
ItemIntMap& _iim;
|
||||
std::vector<int> _first;
|
||||
std::vector<BucketItem> _data;
|
||||
mutable int _minimum;
|
||||
|
||||
}; // class BucketHeap
|
||||
|
||||
/// \ingroup heaps
|
||||
///
|
||||
/// \brief Simplified bucket heap data structure.
|
||||
///
|
||||
/// This class implements a simplified \e bucket \e heap data
|
||||
/// structure. It does not provide some functionality, but it is
|
||||
/// faster and simpler than BucketHeap. The main difference is
|
||||
/// that BucketHeap stores a doubly-linked list for each key while
|
||||
/// this class stores only simply-linked lists. It supports erasing
|
||||
/// only for the item having minimum priority and it does not support
|
||||
/// key increasing and decreasing.
|
||||
///
|
||||
/// Note that this implementation does not conform to the
|
||||
/// \ref concepts::Heap "heap concept" due to the lack of some
|
||||
/// functionality.
|
||||
///
|
||||
/// \tparam IM A read-writable item map with \c int values, used
|
||||
/// internally to handle the cross references.
|
||||
/// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
|
||||
/// The default is \e min-heap. If this parameter is set to \c false,
|
||||
/// then the comparison is reversed, so the top(), prio() and pop()
|
||||
/// functions deal with the item having maximum priority instead of the
|
||||
/// minimum.
|
||||
///
|
||||
/// \sa BucketHeap
|
||||
template <typename IM, bool MIN = true >
|
||||
class SimpleBucketHeap {
|
||||
|
||||
public:
|
||||
|
||||
/// Type of the item-int map.
|
||||
typedef IM ItemIntMap;
|
||||
/// Type of the priorities.
|
||||
typedef int Prio;
|
||||
/// Type of the items stored in the heap.
|
||||
typedef typename ItemIntMap::Key Item;
|
||||
/// Type of the item-priority pairs.
|
||||
typedef std::pair<Item,Prio> Pair;
|
||||
|
||||
private:
|
||||
|
||||
typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Type to represent the states of the items.
|
||||
///
|
||||
/// Each item has a state associated to it. It can be "in heap",
|
||||
/// "pre-heap" or "post-heap". The latter two are indifferent from the
|
||||
/// heap's point of view, but may be useful to the user.
|
||||
///
|
||||
/// The item-int map must be initialized in such way that it assigns
|
||||
/// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
|
||||
enum State {
|
||||
IN_HEAP = 0, ///< = 0.
|
||||
PRE_HEAP = -1, ///< = -1.
|
||||
POST_HEAP = -2 ///< = -2.
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to the items.
|
||||
/// It is used internally to handle the cross references.
|
||||
/// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
explicit SimpleBucketHeap(ItemIntMap &map)
|
||||
: _iim(map), _free(-1), _num(0), _minimum(0) {}
|
||||
|
||||
/// \brief The number of items stored in the heap.
|
||||
///
|
||||
/// This function returns the number of items stored in the heap.
|
||||
int size() const { return _num; }
|
||||
|
||||
/// \brief Check if the heap is empty.
|
||||
///
|
||||
/// This function returns \c true if the heap is empty.
|
||||
bool empty() const { return _num == 0; }
|
||||
|
||||
/// \brief Make the heap empty.
|
||||
///
|
||||
/// This functon makes the heap empty.
|
||||
/// It does not change the cross reference map. If you want to reuse
|
||||
/// a heap that is not surely empty, you should first clear it and
|
||||
/// then you should set the cross reference map to \c PRE_HEAP
|
||||
/// for each item.
|
||||
void clear() {
|
||||
_data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
|
||||
}
|
||||
|
||||
/// \brief Insert a pair of item and priority into the heap.
|
||||
///
|
||||
/// This function inserts \c p.first to the heap with priority
|
||||
/// \c p.second.
|
||||
/// \param p The pair to insert.
|
||||
/// \pre \c p.first must not be stored in the heap.
|
||||
void push(const Pair& p) {
|
||||
push(p.first, p.second);
|
||||
}
|
||||
|
||||
/// \brief Insert an item into the heap with the given priority.
|
||||
///
|
||||
/// This function inserts the given item into the heap with the
|
||||
/// given priority.
|
||||
/// \param i The item to insert.
|
||||
/// \param p The priority of the item.
|
||||
/// \pre \e i must not be stored in the heap.
|
||||
void push(const Item &i, const Prio &p) {
|
||||
int idx;
|
||||
if (_free == -1) {
|
||||
idx = _data.size();
|
||||
_data.push_back(BucketItem(i));
|
||||
} else {
|
||||
idx = _free;
|
||||
_free = _data[idx].next;
|
||||
_data[idx].item = i;
|
||||
}
|
||||
_iim[i] = idx;
|
||||
if (p >= int(_first.size())) _first.resize(p + 1, -1);
|
||||
_data[idx].next = _first[p];
|
||||
_first[p] = idx;
|
||||
if (Direction::less(p, _minimum)) {
|
||||
_minimum = p;
|
||||
}
|
||||
++_num;
|
||||
}
|
||||
|
||||
/// \brief Return the item having minimum priority.
|
||||
///
|
||||
/// This function returns the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Item top() const {
|
||||
while (_first[_minimum] == -1) {
|
||||
Direction::increase(_minimum);
|
||||
}
|
||||
return _data[_first[_minimum]].item;
|
||||
}
|
||||
|
||||
/// \brief The minimum priority.
|
||||
///
|
||||
/// This function returns the minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Prio prio() const {
|
||||
while (_first[_minimum] == -1) {
|
||||
Direction::increase(_minimum);
|
||||
}
|
||||
return _minimum;
|
||||
}
|
||||
|
||||
/// \brief Remove the item having minimum priority.
|
||||
///
|
||||
/// This function removes the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
void pop() {
|
||||
while (_first[_minimum] == -1) {
|
||||
Direction::increase(_minimum);
|
||||
}
|
||||
int idx = _first[_minimum];
|
||||
_iim[_data[idx].item] = -2;
|
||||
_first[_minimum] = _data[idx].next;
|
||||
_data[idx].next = _free;
|
||||
_free = idx;
|
||||
--_num;
|
||||
}
|
||||
|
||||
/// \brief The priority of the given item.
|
||||
///
|
||||
/// This function returns the priority of the given item.
|
||||
/// \param i The item.
|
||||
/// \pre \e i must be in the heap.
|
||||
/// \warning This operator is not a constant time function because
|
||||
/// it scans the whole data structure to find the proper value.
|
||||
Prio operator[](const Item &i) const {
|
||||
for (int k = 0; k < int(_first.size()); ++k) {
|
||||
int idx = _first[k];
|
||||
while (idx != -1) {
|
||||
if (_data[idx].item == i) {
|
||||
return k;
|
||||
}
|
||||
idx = _data[idx].next;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// \brief Return the state of an item.
|
||||
///
|
||||
/// This method returns \c PRE_HEAP if the given item has never
|
||||
/// been in the heap, \c IN_HEAP if it is in the heap at the moment,
|
||||
/// and \c POST_HEAP otherwise.
|
||||
/// In the latter case it is possible that the item will get back
|
||||
/// to the heap again.
|
||||
/// \param i The item.
|
||||
State state(const Item &i) const {
|
||||
int idx = _iim[i];
|
||||
if (idx >= 0) idx = 0;
|
||||
return State(idx);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
struct BucketItem {
|
||||
BucketItem(const Item& _item)
|
||||
: item(_item) {}
|
||||
|
||||
Item item;
|
||||
int next;
|
||||
};
|
||||
|
||||
ItemIntMap& _iim;
|
||||
std::vector<int> _first;
|
||||
std::vector<BucketItem> _data;
|
||||
int _free, _num;
|
||||
mutable int _minimum;
|
||||
|
||||
}; // class SimpleBucketHeap
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
1014
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/capacity_scaling.h
vendored
Normal file
1014
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/capacity_scaling.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
460
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cbc.cc
vendored
Normal file
460
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cbc.cc
vendored
Normal file
@@ -0,0 +1,460 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
///\file
|
||||
///\brief Implementation of the CBC MIP solver interface.
|
||||
|
||||
#include "cbc.h"
|
||||
|
||||
#include <coin/CoinModel.hpp>
|
||||
#include <coin/CbcModel.hpp>
|
||||
#include <coin/OsiSolverInterface.hpp>
|
||||
|
||||
#include "coin/OsiClpSolverInterface.hpp"
|
||||
|
||||
#include "coin/CbcCutGenerator.hpp"
|
||||
#include "coin/CbcHeuristicLocal.hpp"
|
||||
#include "coin/CbcHeuristicGreedy.hpp"
|
||||
#include "coin/CbcHeuristicFPump.hpp"
|
||||
#include "coin/CbcHeuristicRINS.hpp"
|
||||
|
||||
#include "coin/CglGomory.hpp"
|
||||
#include "coin/CglProbing.hpp"
|
||||
#include "coin/CglKnapsackCover.hpp"
|
||||
#include "coin/CglOddHole.hpp"
|
||||
#include "coin/CglClique.hpp"
|
||||
#include "coin/CglFlowCover.hpp"
|
||||
#include "coin/CglMixedIntegerRounding.hpp"
|
||||
|
||||
#include "coin/CbcHeuristic.hpp"
|
||||
|
||||
namespace lemon {
|
||||
|
||||
CbcMip::CbcMip() {
|
||||
_prob = new CoinModel();
|
||||
_prob->setProblemName("LEMON");
|
||||
_osi_solver = 0;
|
||||
_cbc_model = 0;
|
||||
messageLevel(MESSAGE_NOTHING);
|
||||
}
|
||||
|
||||
CbcMip::CbcMip(const CbcMip& other) {
|
||||
_prob = new CoinModel(*other._prob);
|
||||
_prob->setProblemName("LEMON");
|
||||
_osi_solver = 0;
|
||||
_cbc_model = 0;
|
||||
messageLevel(MESSAGE_NOTHING);
|
||||
}
|
||||
|
||||
CbcMip::~CbcMip() {
|
||||
delete _prob;
|
||||
if (_osi_solver) delete _osi_solver;
|
||||
if (_cbc_model) delete _cbc_model;
|
||||
}
|
||||
|
||||
const char* CbcMip::_solverName() const { return "CbcMip"; }
|
||||
|
||||
int CbcMip::_addCol() {
|
||||
_prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0, 0, false);
|
||||
return _prob->numberColumns() - 1;
|
||||
}
|
||||
|
||||
CbcMip* CbcMip::newSolver() const {
|
||||
CbcMip* newlp = new CbcMip;
|
||||
return newlp;
|
||||
}
|
||||
|
||||
CbcMip* CbcMip::cloneSolver() const {
|
||||
CbcMip* copylp = new CbcMip(*this);
|
||||
return copylp;
|
||||
}
|
||||
|
||||
int CbcMip::_addRow() {
|
||||
_prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
|
||||
return _prob->numberRows() - 1;
|
||||
}
|
||||
|
||||
int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
|
||||
std::vector<int> indexes;
|
||||
std::vector<Value> values;
|
||||
|
||||
for(ExprIterator it = b; it != e; ++it) {
|
||||
indexes.push_back(it->first);
|
||||
values.push_back(it->second);
|
||||
}
|
||||
|
||||
_prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
|
||||
return _prob->numberRows() - 1;
|
||||
}
|
||||
|
||||
void CbcMip::_eraseCol(int i) {
|
||||
_prob->deleteColumn(i);
|
||||
}
|
||||
|
||||
void CbcMip::_eraseRow(int i) {
|
||||
_prob->deleteRow(i);
|
||||
}
|
||||
|
||||
void CbcMip::_eraseColId(int i) {
|
||||
cols.eraseIndex(i);
|
||||
}
|
||||
|
||||
void CbcMip::_eraseRowId(int i) {
|
||||
rows.eraseIndex(i);
|
||||
}
|
||||
|
||||
void CbcMip::_getColName(int c, std::string& name) const {
|
||||
name = _prob->getColumnName(c);
|
||||
}
|
||||
|
||||
void CbcMip::_setColName(int c, const std::string& name) {
|
||||
_prob->setColumnName(c, name.c_str());
|
||||
}
|
||||
|
||||
int CbcMip::_colByName(const std::string& name) const {
|
||||
return _prob->column(name.c_str());
|
||||
}
|
||||
|
||||
void CbcMip::_getRowName(int r, std::string& name) const {
|
||||
name = _prob->getRowName(r);
|
||||
}
|
||||
|
||||
void CbcMip::_setRowName(int r, const std::string& name) {
|
||||
_prob->setRowName(r, name.c_str());
|
||||
}
|
||||
|
||||
int CbcMip::_rowByName(const std::string& name) const {
|
||||
return _prob->row(name.c_str());
|
||||
}
|
||||
|
||||
void CbcMip::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
|
||||
for (ExprIterator it = b; it != e; ++it) {
|
||||
_prob->setElement(i, it->first, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void CbcMip::_getRowCoeffs(int ix, InsertIterator b) const {
|
||||
int length = _prob->numberRows();
|
||||
|
||||
std::vector<int> indices(length);
|
||||
std::vector<Value> values(length);
|
||||
|
||||
length = _prob->getRow(ix, &indices[0], &values[0]);
|
||||
|
||||
for (int i = 0; i < length; ++i) {
|
||||
*b = std::make_pair(indices[i], values[i]);
|
||||
++b;
|
||||
}
|
||||
}
|
||||
|
||||
void CbcMip::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
|
||||
for (ExprIterator it = b; it != e; ++it) {
|
||||
_prob->setElement(it->first, ix, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void CbcMip::_getColCoeffs(int ix, InsertIterator b) const {
|
||||
int length = _prob->numberColumns();
|
||||
|
||||
std::vector<int> indices(length);
|
||||
std::vector<Value> values(length);
|
||||
|
||||
length = _prob->getColumn(ix, &indices[0], &values[0]);
|
||||
|
||||
for (int i = 0; i < length; ++i) {
|
||||
*b = std::make_pair(indices[i], values[i]);
|
||||
++b;
|
||||
}
|
||||
}
|
||||
|
||||
void CbcMip::_setCoeff(int ix, int jx, Value value) {
|
||||
_prob->setElement(ix, jx, value);
|
||||
}
|
||||
|
||||
CbcMip::Value CbcMip::_getCoeff(int ix, int jx) const {
|
||||
return _prob->getElement(ix, jx);
|
||||
}
|
||||
|
||||
|
||||
void CbcMip::_setColLowerBound(int i, Value lo) {
|
||||
LEMON_ASSERT(lo != INF, "Invalid bound");
|
||||
_prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
|
||||
}
|
||||
|
||||
CbcMip::Value CbcMip::_getColLowerBound(int i) const {
|
||||
double val = _prob->getColumnLower(i);
|
||||
return val == - COIN_DBL_MAX ? - INF : val;
|
||||
}
|
||||
|
||||
void CbcMip::_setColUpperBound(int i, Value up) {
|
||||
LEMON_ASSERT(up != -INF, "Invalid bound");
|
||||
_prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
|
||||
}
|
||||
|
||||
CbcMip::Value CbcMip::_getColUpperBound(int i) const {
|
||||
double val = _prob->getColumnUpper(i);
|
||||
return val == COIN_DBL_MAX ? INF : val;
|
||||
}
|
||||
|
||||
void CbcMip::_setRowLowerBound(int i, Value lo) {
|
||||
LEMON_ASSERT(lo != INF, "Invalid bound");
|
||||
_prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
|
||||
}
|
||||
|
||||
CbcMip::Value CbcMip::_getRowLowerBound(int i) const {
|
||||
double val = _prob->getRowLower(i);
|
||||
return val == - COIN_DBL_MAX ? - INF : val;
|
||||
}
|
||||
|
||||
void CbcMip::_setRowUpperBound(int i, Value up) {
|
||||
LEMON_ASSERT(up != -INF, "Invalid bound");
|
||||
_prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
|
||||
}
|
||||
|
||||
CbcMip::Value CbcMip::_getRowUpperBound(int i) const {
|
||||
double val = _prob->getRowUpper(i);
|
||||
return val == COIN_DBL_MAX ? INF : val;
|
||||
}
|
||||
|
||||
void CbcMip::_setObjCoeffs(ExprIterator b, ExprIterator e) {
|
||||
int num = _prob->numberColumns();
|
||||
for (int i = 0; i < num; ++i) {
|
||||
_prob->setColumnObjective(i, 0.0);
|
||||
}
|
||||
for (ExprIterator it = b; it != e; ++it) {
|
||||
_prob->setColumnObjective(it->first, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void CbcMip::_getObjCoeffs(InsertIterator b) const {
|
||||
int num = _prob->numberColumns();
|
||||
for (int i = 0; i < num; ++i) {
|
||||
Value coef = _prob->getColumnObjective(i);
|
||||
if (coef != 0.0) {
|
||||
*b = std::make_pair(i, coef);
|
||||
++b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CbcMip::_setObjCoeff(int i, Value obj_coef) {
|
||||
_prob->setColumnObjective(i, obj_coef);
|
||||
}
|
||||
|
||||
CbcMip::Value CbcMip::_getObjCoeff(int i) const {
|
||||
return _prob->getColumnObjective(i);
|
||||
}
|
||||
|
||||
CbcMip::SolveExitStatus CbcMip::_solve() {
|
||||
|
||||
if (_osi_solver) {
|
||||
delete _osi_solver;
|
||||
}
|
||||
_osi_solver = new OsiClpSolverInterface();
|
||||
|
||||
_osi_solver->loadFromCoinModel(*_prob);
|
||||
|
||||
if (_cbc_model) {
|
||||
delete _cbc_model;
|
||||
}
|
||||
_cbc_model= new CbcModel(*_osi_solver);
|
||||
|
||||
_osi_solver->messageHandler()->setLogLevel(_message_level);
|
||||
_cbc_model->setLogLevel(_message_level);
|
||||
|
||||
_cbc_model->initialSolve();
|
||||
_cbc_model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
|
||||
|
||||
if (!_cbc_model->isInitialSolveAbandoned() &&
|
||||
_cbc_model->isInitialSolveProvenOptimal() &&
|
||||
!_cbc_model->isInitialSolveProvenPrimalInfeasible() &&
|
||||
!_cbc_model->isInitialSolveProvenDualInfeasible()) {
|
||||
|
||||
CglProbing generator1;
|
||||
generator1.setUsingObjective(true);
|
||||
generator1.setMaxPass(3);
|
||||
generator1.setMaxProbe(100);
|
||||
generator1.setMaxLook(50);
|
||||
generator1.setRowCuts(3);
|
||||
_cbc_model->addCutGenerator(&generator1, -1, "Probing");
|
||||
|
||||
CglGomory generator2;
|
||||
generator2.setLimit(300);
|
||||
_cbc_model->addCutGenerator(&generator2, -1, "Gomory");
|
||||
|
||||
CglKnapsackCover generator3;
|
||||
_cbc_model->addCutGenerator(&generator3, -1, "Knapsack");
|
||||
|
||||
CglOddHole generator4;
|
||||
generator4.setMinimumViolation(0.005);
|
||||
generator4.setMinimumViolationPer(0.00002);
|
||||
generator4.setMaximumEntries(200);
|
||||
_cbc_model->addCutGenerator(&generator4, -1, "OddHole");
|
||||
|
||||
CglClique generator5;
|
||||
generator5.setStarCliqueReport(false);
|
||||
generator5.setRowCliqueReport(false);
|
||||
_cbc_model->addCutGenerator(&generator5, -1, "Clique");
|
||||
|
||||
CglMixedIntegerRounding mixedGen;
|
||||
_cbc_model->addCutGenerator(&mixedGen, -1, "MixedIntegerRounding");
|
||||
|
||||
CglFlowCover flowGen;
|
||||
_cbc_model->addCutGenerator(&flowGen, -1, "FlowCover");
|
||||
|
||||
OsiClpSolverInterface* osiclp =
|
||||
dynamic_cast<OsiClpSolverInterface*>(_cbc_model->solver());
|
||||
if (osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500) {
|
||||
osiclp->setupForRepeatedUse(2, 0);
|
||||
}
|
||||
|
||||
CbcRounding heuristic1(*_cbc_model);
|
||||
heuristic1.setWhen(3);
|
||||
_cbc_model->addHeuristic(&heuristic1);
|
||||
|
||||
CbcHeuristicLocal heuristic2(*_cbc_model);
|
||||
heuristic2.setWhen(3);
|
||||
_cbc_model->addHeuristic(&heuristic2);
|
||||
|
||||
CbcHeuristicGreedyCover heuristic3(*_cbc_model);
|
||||
heuristic3.setAlgorithm(11);
|
||||
heuristic3.setWhen(3);
|
||||
_cbc_model->addHeuristic(&heuristic3);
|
||||
|
||||
CbcHeuristicFPump heuristic4(*_cbc_model);
|
||||
heuristic4.setWhen(3);
|
||||
_cbc_model->addHeuristic(&heuristic4);
|
||||
|
||||
CbcHeuristicRINS heuristic5(*_cbc_model);
|
||||
heuristic5.setWhen(3);
|
||||
_cbc_model->addHeuristic(&heuristic5);
|
||||
|
||||
if (_cbc_model->getNumCols() < 500) {
|
||||
_cbc_model->setMaximumCutPassesAtRoot(-100);
|
||||
} else if (_cbc_model->getNumCols() < 5000) {
|
||||
_cbc_model->setMaximumCutPassesAtRoot(100);
|
||||
} else {
|
||||
_cbc_model->setMaximumCutPassesAtRoot(20);
|
||||
}
|
||||
|
||||
if (_cbc_model->getNumCols() < 5000) {
|
||||
_cbc_model->setNumberStrong(10);
|
||||
}
|
||||
|
||||
_cbc_model->solver()->setIntParam(OsiMaxNumIterationHotStart, 100);
|
||||
_cbc_model->branchAndBound();
|
||||
}
|
||||
|
||||
if (_cbc_model->isAbandoned()) {
|
||||
return UNSOLVED;
|
||||
} else {
|
||||
return SOLVED;
|
||||
}
|
||||
}
|
||||
|
||||
CbcMip::Value CbcMip::_getSol(int i) const {
|
||||
return _cbc_model->getColSolution()[i];
|
||||
}
|
||||
|
||||
CbcMip::Value CbcMip::_getSolValue() const {
|
||||
return _cbc_model->getObjValue();
|
||||
}
|
||||
|
||||
CbcMip::ProblemType CbcMip::_getType() const {
|
||||
if (_cbc_model->isProvenOptimal()) {
|
||||
return OPTIMAL;
|
||||
} else if (_cbc_model->isContinuousUnbounded()) {
|
||||
return UNBOUNDED;
|
||||
}
|
||||
return FEASIBLE;
|
||||
}
|
||||
|
||||
void CbcMip::_setSense(Sense sense) {
|
||||
switch (sense) {
|
||||
case MIN:
|
||||
_prob->setOptimizationDirection(1.0);
|
||||
break;
|
||||
case MAX:
|
||||
_prob->setOptimizationDirection(- 1.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CbcMip::Sense CbcMip::_getSense() const {
|
||||
if (_prob->optimizationDirection() > 0.0) {
|
||||
return MIN;
|
||||
} else if (_prob->optimizationDirection() < 0.0) {
|
||||
return MAX;
|
||||
} else {
|
||||
LEMON_ASSERT(false, "Wrong sense");
|
||||
return CbcMip::Sense();
|
||||
}
|
||||
}
|
||||
|
||||
void CbcMip::_setColType(int i, CbcMip::ColTypes col_type) {
|
||||
switch (col_type){
|
||||
case INTEGER:
|
||||
_prob->setInteger(i);
|
||||
break;
|
||||
case REAL:
|
||||
_prob->setContinuous(i);
|
||||
break;
|
||||
default:;
|
||||
LEMON_ASSERT(false, "Wrong sense");
|
||||
}
|
||||
}
|
||||
|
||||
CbcMip::ColTypes CbcMip::_getColType(int i) const {
|
||||
return _prob->getColumnIsInteger(i) ? INTEGER : REAL;
|
||||
}
|
||||
|
||||
void CbcMip::_clear() {
|
||||
delete _prob;
|
||||
if (_osi_solver) {
|
||||
delete _osi_solver;
|
||||
_osi_solver = 0;
|
||||
}
|
||||
if (_cbc_model) {
|
||||
delete _cbc_model;
|
||||
_cbc_model = 0;
|
||||
}
|
||||
|
||||
_prob = new CoinModel();
|
||||
}
|
||||
|
||||
void CbcMip::_messageLevel(MessageLevel level) {
|
||||
switch (level) {
|
||||
case MESSAGE_NOTHING:
|
||||
_message_level = 0;
|
||||
break;
|
||||
case MESSAGE_ERROR:
|
||||
_message_level = 1;
|
||||
break;
|
||||
case MESSAGE_WARNING:
|
||||
_message_level = 1;
|
||||
break;
|
||||
case MESSAGE_NORMAL:
|
||||
_message_level = 2;
|
||||
break;
|
||||
case MESSAGE_VERBOSE:
|
||||
_message_level = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} //END OF NAMESPACE LEMON
|
||||
129
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cbc.h
vendored
Normal file
129
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cbc.h
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_CBC_H
|
||||
#define LEMON_CBC_H
|
||||
|
||||
///\file
|
||||
///\brief Header of the LEMON-CBC mip solver interface.
|
||||
///\ingroup lp_group
|
||||
|
||||
#include <lemon/lp_base.h>
|
||||
|
||||
class CoinModel;
|
||||
class OsiSolverInterface;
|
||||
class CbcModel;
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \brief Interface for the CBC MIP solver
|
||||
///
|
||||
/// This class implements an interface for the CBC MIP solver.
|
||||
///\ingroup lp_group
|
||||
class CbcMip : public MipSolver {
|
||||
protected:
|
||||
|
||||
CoinModel *_prob;
|
||||
OsiSolverInterface *_osi_solver;
|
||||
CbcModel *_cbc_model;
|
||||
|
||||
public:
|
||||
|
||||
/// \e
|
||||
CbcMip();
|
||||
/// \e
|
||||
CbcMip(const CbcMip&);
|
||||
/// \e
|
||||
~CbcMip();
|
||||
/// \e
|
||||
virtual CbcMip* newSolver() const;
|
||||
/// \e
|
||||
virtual CbcMip* cloneSolver() const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual const char* _solverName() const;
|
||||
|
||||
virtual int _addCol();
|
||||
virtual int _addRow();
|
||||
virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
|
||||
|
||||
virtual void _eraseCol(int i);
|
||||
virtual void _eraseRow(int i);
|
||||
|
||||
virtual void _eraseColId(int i);
|
||||
virtual void _eraseRowId(int i);
|
||||
|
||||
virtual void _getColName(int col, std::string& name) const;
|
||||
virtual void _setColName(int col, const std::string& name);
|
||||
virtual int _colByName(const std::string& name) const;
|
||||
|
||||
virtual void _getRowName(int row, std::string& name) const;
|
||||
virtual void _setRowName(int row, const std::string& name);
|
||||
virtual int _rowByName(const std::string& name) const;
|
||||
|
||||
virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
|
||||
virtual void _getRowCoeffs(int i, InsertIterator b) const;
|
||||
|
||||
virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
|
||||
virtual void _getColCoeffs(int i, InsertIterator b) const;
|
||||
|
||||
virtual void _setCoeff(int row, int col, Value value);
|
||||
virtual Value _getCoeff(int row, int col) const;
|
||||
|
||||
virtual void _setColLowerBound(int i, Value value);
|
||||
virtual Value _getColLowerBound(int i) const;
|
||||
virtual void _setColUpperBound(int i, Value value);
|
||||
virtual Value _getColUpperBound(int i) const;
|
||||
|
||||
virtual void _setRowLowerBound(int i, Value value);
|
||||
virtual Value _getRowLowerBound(int i) const;
|
||||
virtual void _setRowUpperBound(int i, Value value);
|
||||
virtual Value _getRowUpperBound(int i) const;
|
||||
|
||||
virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
|
||||
virtual void _getObjCoeffs(InsertIterator b) const;
|
||||
|
||||
virtual void _setObjCoeff(int i, Value obj_coef);
|
||||
virtual Value _getObjCoeff(int i) const;
|
||||
|
||||
virtual void _setSense(Sense sense);
|
||||
virtual Sense _getSense() const;
|
||||
|
||||
virtual ColTypes _getColType(int col) const;
|
||||
virtual void _setColType(int col, ColTypes col_type);
|
||||
|
||||
virtual SolveExitStatus _solve();
|
||||
virtual ProblemType _getType() const;
|
||||
virtual Value _getSol(int i) const;
|
||||
virtual Value _getSolValue() const;
|
||||
|
||||
virtual void _clear();
|
||||
|
||||
virtual void _messageLevel(MessageLevel level);
|
||||
void _applyMessageLevel();
|
||||
|
||||
int _message_level;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
254
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/christofides_tsp.h
vendored
Normal file
254
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/christofides_tsp.h
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_CHRISTOFIDES_TSP_H
|
||||
#define LEMON_CHRISTOFIDES_TSP_H
|
||||
|
||||
/// \ingroup tsp
|
||||
/// \file
|
||||
/// \brief Christofides algorithm for symmetric TSP
|
||||
|
||||
#include <lemon/full_graph.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/kruskal.h>
|
||||
#include <lemon/matching.h>
|
||||
#include <lemon/euler.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \ingroup tsp
|
||||
///
|
||||
/// \brief Christofides algorithm for symmetric TSP.
|
||||
///
|
||||
/// ChristofidesTsp implements Christofides' heuristic for solving
|
||||
/// symmetric \ref tsp "TSP".
|
||||
///
|
||||
/// This a well-known approximation method for the TSP problem with
|
||||
/// metric cost function.
|
||||
/// It has a guaranteed approximation factor of 3/2 (i.e. it finds a tour
|
||||
/// whose total cost is at most 3/2 of the optimum), but it usually
|
||||
/// provides better solutions in practice.
|
||||
/// This implementation runs in O(n<sup>3</sup>log(n)) time.
|
||||
///
|
||||
/// The algorithm starts with a \ref spantree "minimum cost spanning tree" and
|
||||
/// finds a \ref MaxWeightedPerfectMatching "minimum cost perfect matching"
|
||||
/// in the subgraph induced by the nodes that have odd degree in the
|
||||
/// spanning tree.
|
||||
/// Finally, it constructs the tour from the \ref EulerIt "Euler traversal"
|
||||
/// of the union of the spanning tree and the matching.
|
||||
/// During this last step, the algorithm simply skips the visited nodes
|
||||
/// (i.e. creates shortcuts) assuming that the triangle inequality holds
|
||||
/// for the cost function.
|
||||
///
|
||||
/// \tparam CM Type of the cost map.
|
||||
///
|
||||
/// \warning CM::Value must be a signed number type.
|
||||
template <typename CM>
|
||||
class ChristofidesTsp
|
||||
{
|
||||
public:
|
||||
|
||||
/// Type of the cost map
|
||||
typedef CM CostMap;
|
||||
/// Type of the edge costs
|
||||
typedef typename CM::Value Cost;
|
||||
|
||||
private:
|
||||
|
||||
GRAPH_TYPEDEFS(FullGraph);
|
||||
|
||||
const FullGraph &_gr;
|
||||
const CostMap &_cost;
|
||||
std::vector<Node> _path;
|
||||
Cost _sum;
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constructor
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param gr The \ref FullGraph "full graph" the algorithm runs on.
|
||||
/// \param cost The cost map.
|
||||
ChristofidesTsp(const FullGraph &gr, const CostMap &cost)
|
||||
: _gr(gr), _cost(cost) {}
|
||||
|
||||
/// \name Execution Control
|
||||
/// @{
|
||||
|
||||
/// \brief Runs the algorithm.
|
||||
///
|
||||
/// This function runs the algorithm.
|
||||
///
|
||||
/// \return The total cost of the found tour.
|
||||
Cost run() {
|
||||
_path.clear();
|
||||
|
||||
if (_gr.nodeNum() == 0) return _sum = 0;
|
||||
else if (_gr.nodeNum() == 1) {
|
||||
_path.push_back(_gr(0));
|
||||
return _sum = 0;
|
||||
}
|
||||
else if (_gr.nodeNum() == 2) {
|
||||
_path.push_back(_gr(0));
|
||||
_path.push_back(_gr(1));
|
||||
return _sum = 2 * _cost[_gr.edge(_gr(0), _gr(1))];
|
||||
}
|
||||
|
||||
// Compute min. cost spanning tree
|
||||
std::vector<Edge> tree;
|
||||
kruskal(_gr, _cost, std::back_inserter(tree));
|
||||
|
||||
FullGraph::NodeMap<int> deg(_gr, 0);
|
||||
for (int i = 0; i != int(tree.size()); ++i) {
|
||||
Edge e = tree[i];
|
||||
++deg[_gr.u(e)];
|
||||
++deg[_gr.v(e)];
|
||||
}
|
||||
|
||||
// Copy the induced subgraph of odd nodes
|
||||
std::vector<Node> odd_nodes;
|
||||
for (NodeIt u(_gr); u != INVALID; ++u) {
|
||||
if (deg[u] % 2 == 1) odd_nodes.push_back(u);
|
||||
}
|
||||
|
||||
SmartGraph sgr;
|
||||
SmartGraph::EdgeMap<Cost> scost(sgr);
|
||||
for (int i = 0; i != int(odd_nodes.size()); ++i) {
|
||||
sgr.addNode();
|
||||
}
|
||||
for (int i = 0; i != int(odd_nodes.size()); ++i) {
|
||||
for (int j = 0; j != int(odd_nodes.size()); ++j) {
|
||||
if (j == i) continue;
|
||||
SmartGraph::Edge e =
|
||||
sgr.addEdge(sgr.nodeFromId(i), sgr.nodeFromId(j));
|
||||
scost[e] = -_cost[_gr.edge(odd_nodes[i], odd_nodes[j])];
|
||||
}
|
||||
}
|
||||
|
||||
// Compute min. cost perfect matching
|
||||
MaxWeightedPerfectMatching<SmartGraph, SmartGraph::EdgeMap<Cost> >
|
||||
mwpm(sgr, scost);
|
||||
mwpm.run();
|
||||
|
||||
for (SmartGraph::EdgeIt e(sgr); e != INVALID; ++e) {
|
||||
if (mwpm.matching(e)) {
|
||||
tree.push_back( _gr.edge(odd_nodes[sgr.id(sgr.u(e))],
|
||||
odd_nodes[sgr.id(sgr.v(e))]) );
|
||||
}
|
||||
}
|
||||
|
||||
// Join the spanning tree and the matching
|
||||
sgr.clear();
|
||||
for (int i = 0; i != _gr.nodeNum(); ++i) {
|
||||
sgr.addNode();
|
||||
}
|
||||
for (int i = 0; i != int(tree.size()); ++i) {
|
||||
int ui = _gr.id(_gr.u(tree[i])),
|
||||
vi = _gr.id(_gr.v(tree[i]));
|
||||
sgr.addEdge(sgr.nodeFromId(ui), sgr.nodeFromId(vi));
|
||||
}
|
||||
|
||||
// Compute the tour from the Euler traversal
|
||||
SmartGraph::NodeMap<bool> visited(sgr, false);
|
||||
for (EulerIt<SmartGraph> e(sgr); e != INVALID; ++e) {
|
||||
SmartGraph::Node n = sgr.target(e);
|
||||
if (!visited[n]) {
|
||||
_path.push_back(_gr(sgr.id(n)));
|
||||
visited[n] = true;
|
||||
}
|
||||
}
|
||||
|
||||
_sum = _cost[_gr.edge(_path.back(), _path.front())];
|
||||
for (int i = 0; i < int(_path.size())-1; ++i) {
|
||||
_sum += _cost[_gr.edge(_path[i], _path[i+1])];
|
||||
}
|
||||
|
||||
return _sum;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Query Functions
|
||||
/// @{
|
||||
|
||||
/// \brief The total cost of the found tour.
|
||||
///
|
||||
/// This function returns the total cost of the found tour.
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
Cost tourCost() const {
|
||||
return _sum;
|
||||
}
|
||||
|
||||
/// \brief Returns a const reference to the node sequence of the
|
||||
/// found tour.
|
||||
///
|
||||
/// This function returns a const reference to a vector
|
||||
/// that stores the node sequence of the found tour.
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
const std::vector<Node>& tourNodes() const {
|
||||
return _path;
|
||||
}
|
||||
|
||||
/// \brief Gives back the node sequence of the found tour.
|
||||
///
|
||||
/// This function copies the node sequence of the found tour into
|
||||
/// an STL container through the given output iterator. The
|
||||
/// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
|
||||
/// For example,
|
||||
/// \code
|
||||
/// std::vector<FullGraph::Node> nodes(countNodes(graph));
|
||||
/// tsp.tourNodes(nodes.begin());
|
||||
/// \endcode
|
||||
/// or
|
||||
/// \code
|
||||
/// std::list<FullGraph::Node> nodes;
|
||||
/// tsp.tourNodes(std::back_inserter(nodes));
|
||||
/// \endcode
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
template <typename Iterator>
|
||||
void tourNodes(Iterator out) const {
|
||||
std::copy(_path.begin(), _path.end(), out);
|
||||
}
|
||||
|
||||
/// \brief Gives back the found tour as a path.
|
||||
///
|
||||
/// This function copies the found tour as a list of arcs/edges into
|
||||
/// the given \ref lemon::concepts::Path "path structure".
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
template <typename Path>
|
||||
void tour(Path &path) const {
|
||||
path.clear();
|
||||
for (int i = 0; i < int(_path.size()) - 1; ++i) {
|
||||
path.addBack(_gr.arc(_path[i], _path[i+1]));
|
||||
}
|
||||
if (int(_path.size()) >= 2) {
|
||||
path.addBack(_gr.arc(_path.back(), _path.front()));
|
||||
}
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
}; // namespace lemon
|
||||
|
||||
#endif
|
||||
807
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/circulation.h
vendored
Normal file
807
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/circulation.h
vendored
Normal file
@@ -0,0 +1,807 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_CIRCULATION_H
|
||||
#define LEMON_CIRCULATION_H
|
||||
|
||||
#include <lemon/tolerance.h>
|
||||
#include <lemon/elevator.h>
|
||||
#include <limits>
|
||||
|
||||
///\ingroup max_flow
|
||||
///\file
|
||||
///\brief Push-relabel algorithm for finding a feasible circulation.
|
||||
///
|
||||
namespace lemon {
|
||||
|
||||
/// \brief Default traits class of Circulation class.
|
||||
///
|
||||
/// Default traits class of Circulation class.
|
||||
///
|
||||
/// \tparam GR Type of the digraph the algorithm runs on.
|
||||
/// \tparam LM The type of the lower bound map.
|
||||
/// \tparam UM The type of the upper bound (capacity) map.
|
||||
/// \tparam SM The type of the supply map.
|
||||
template <typename GR, typename LM,
|
||||
typename UM, typename SM>
|
||||
struct CirculationDefaultTraits {
|
||||
|
||||
/// \brief The type of the digraph the algorithm runs on.
|
||||
typedef GR Digraph;
|
||||
|
||||
/// \brief The type of the lower bound map.
|
||||
///
|
||||
/// The type of the map that stores the lower bounds on the arcs.
|
||||
/// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
|
||||
typedef LM LowerMap;
|
||||
|
||||
/// \brief The type of the upper bound (capacity) map.
|
||||
///
|
||||
/// The type of the map that stores the upper bounds (capacities)
|
||||
/// on the arcs.
|
||||
/// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
|
||||
typedef UM UpperMap;
|
||||
|
||||
/// \brief The type of supply map.
|
||||
///
|
||||
/// The type of the map that stores the signed supply values of the
|
||||
/// nodes.
|
||||
/// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
|
||||
typedef SM SupplyMap;
|
||||
|
||||
/// \brief The type of the flow and supply values.
|
||||
typedef typename SupplyMap::Value Value;
|
||||
|
||||
/// \brief The type of the map that stores the flow values.
|
||||
///
|
||||
/// The type of the map that stores the flow values.
|
||||
/// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
|
||||
/// concept.
|
||||
#ifdef DOXYGEN
|
||||
typedef GR::ArcMap<Value> FlowMap;
|
||||
#else
|
||||
typedef typename Digraph::template ArcMap<Value> FlowMap;
|
||||
#endif
|
||||
|
||||
/// \brief Instantiates a FlowMap.
|
||||
///
|
||||
/// This function instantiates a \ref FlowMap.
|
||||
/// \param digraph The digraph for which we would like to define
|
||||
/// the flow map.
|
||||
static FlowMap* createFlowMap(const Digraph& digraph) {
|
||||
return new FlowMap(digraph);
|
||||
}
|
||||
|
||||
/// \brief The elevator type used by the algorithm.
|
||||
///
|
||||
/// The elevator type used by the algorithm.
|
||||
///
|
||||
/// \sa Elevator, LinkedElevator
|
||||
#ifdef DOXYGEN
|
||||
typedef lemon::Elevator<GR, GR::Node> Elevator;
|
||||
#else
|
||||
typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
|
||||
#endif
|
||||
|
||||
/// \brief Instantiates an Elevator.
|
||||
///
|
||||
/// This function instantiates an \ref Elevator.
|
||||
/// \param digraph The digraph for which we would like to define
|
||||
/// the elevator.
|
||||
/// \param max_level The maximum level of the elevator.
|
||||
static Elevator* createElevator(const Digraph& digraph, int max_level) {
|
||||
return new Elevator(digraph, max_level);
|
||||
}
|
||||
|
||||
/// \brief The tolerance used by the algorithm
|
||||
///
|
||||
/// The tolerance used by the algorithm to handle inexact computation.
|
||||
typedef lemon::Tolerance<Value> Tolerance;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Push-relabel algorithm for the network circulation problem.
|
||||
|
||||
\ingroup max_flow
|
||||
This class implements a push-relabel algorithm for the \e network
|
||||
\e circulation problem.
|
||||
It is to find a feasible circulation when lower and upper bounds
|
||||
are given for the flow values on the arcs and lower bounds are
|
||||
given for the difference between the outgoing and incoming flow
|
||||
at the nodes.
|
||||
|
||||
The exact formulation of this problem is the following.
|
||||
Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
|
||||
\f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
|
||||
upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
|
||||
holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
|
||||
denotes the signed supply values of the nodes.
|
||||
If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
|
||||
supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
|
||||
\f$-sup(u)\f$ demand.
|
||||
A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
|
||||
solution of the following problem.
|
||||
|
||||
\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
|
||||
\geq sup(u) \quad \forall u\in V, \f]
|
||||
\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
|
||||
|
||||
The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
|
||||
zero or negative in order to have a feasible solution (since the sum
|
||||
of the expressions on the left-hand side of the inequalities is zero).
|
||||
It means that the total demand must be greater or equal to the total
|
||||
supply and all the supplies have to be carried out from the supply nodes,
|
||||
but there could be demands that are not satisfied.
|
||||
If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
|
||||
constraints have to be satisfied with equality, i.e. all demands
|
||||
have to be satisfied and all supplies have to be used.
|
||||
|
||||
If you need the opposite inequalities in the supply/demand constraints
|
||||
(i.e. the total demand is less than the total supply and all the demands
|
||||
have to be satisfied while there could be supplies that are not used),
|
||||
then you could easily transform the problem to the above form by reversing
|
||||
the direction of the arcs and taking the negative of the supply values
|
||||
(e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
|
||||
|
||||
This algorithm either calculates a feasible circulation, or provides
|
||||
a \ref barrier() "barrier", which prooves that a feasible soultion
|
||||
cannot exist.
|
||||
|
||||
Note that this algorithm also provides a feasible solution for the
|
||||
\ref min_cost_flow "minimum cost flow problem".
|
||||
|
||||
\tparam GR The type of the digraph the algorithm runs on.
|
||||
\tparam LM The type of the lower bound map. The default
|
||||
map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
|
||||
\tparam UM The type of the upper bound (capacity) map.
|
||||
The default map type is \c LM.
|
||||
\tparam SM The type of the supply map. The default map type is
|
||||
\ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
|
||||
\tparam TR The traits class that defines various types used by the
|
||||
algorithm. By default, it is \ref CirculationDefaultTraits
|
||||
"CirculationDefaultTraits<GR, LM, UM, SM>".
|
||||
In most cases, this parameter should not be set directly,
|
||||
consider to use the named template parameters instead.
|
||||
*/
|
||||
#ifdef DOXYGEN
|
||||
template< typename GR,
|
||||
typename LM,
|
||||
typename UM,
|
||||
typename SM,
|
||||
typename TR >
|
||||
#else
|
||||
template< typename GR,
|
||||
typename LM = typename GR::template ArcMap<int>,
|
||||
typename UM = LM,
|
||||
typename SM = typename GR::template NodeMap<typename UM::Value>,
|
||||
typename TR = CirculationDefaultTraits<GR, LM, UM, SM> >
|
||||
#endif
|
||||
class Circulation {
|
||||
public:
|
||||
|
||||
/// \brief The \ref lemon::CirculationDefaultTraits "traits class"
|
||||
/// of the algorithm.
|
||||
typedef TR Traits;
|
||||
///The type of the digraph the algorithm runs on.
|
||||
typedef typename Traits::Digraph Digraph;
|
||||
///The type of the flow and supply values.
|
||||
typedef typename Traits::Value Value;
|
||||
|
||||
///The type of the lower bound map.
|
||||
typedef typename Traits::LowerMap LowerMap;
|
||||
///The type of the upper bound (capacity) map.
|
||||
typedef typename Traits::UpperMap UpperMap;
|
||||
///The type of the supply map.
|
||||
typedef typename Traits::SupplyMap SupplyMap;
|
||||
///The type of the flow map.
|
||||
typedef typename Traits::FlowMap FlowMap;
|
||||
|
||||
///The type of the elevator.
|
||||
typedef typename Traits::Elevator Elevator;
|
||||
///The type of the tolerance.
|
||||
typedef typename Traits::Tolerance Tolerance;
|
||||
|
||||
private:
|
||||
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
const Digraph &_g;
|
||||
int _node_num;
|
||||
|
||||
const LowerMap *_lo;
|
||||
const UpperMap *_up;
|
||||
const SupplyMap *_supply;
|
||||
|
||||
FlowMap *_flow;
|
||||
bool _local_flow;
|
||||
|
||||
Elevator* _level;
|
||||
bool _local_level;
|
||||
|
||||
typedef typename Digraph::template NodeMap<Value> ExcessMap;
|
||||
ExcessMap* _excess;
|
||||
|
||||
Tolerance _tol;
|
||||
int _el;
|
||||
|
||||
public:
|
||||
|
||||
typedef Circulation Create;
|
||||
|
||||
///\name Named Template Parameters
|
||||
|
||||
///@{
|
||||
|
||||
template <typename T>
|
||||
struct SetFlowMapTraits : public Traits {
|
||||
typedef T FlowMap;
|
||||
static FlowMap *createFlowMap(const Digraph&) {
|
||||
LEMON_ASSERT(false, "FlowMap is not initialized");
|
||||
return 0; // ignore warnings
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief \ref named-templ-param "Named parameter" for setting
|
||||
/// FlowMap type
|
||||
///
|
||||
/// \ref named-templ-param "Named parameter" for setting FlowMap
|
||||
/// type.
|
||||
template <typename T>
|
||||
struct SetFlowMap
|
||||
: public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
|
||||
SetFlowMapTraits<T> > {
|
||||
typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
|
||||
SetFlowMapTraits<T> > Create;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct SetElevatorTraits : public Traits {
|
||||
typedef T Elevator;
|
||||
static Elevator *createElevator(const Digraph&, int) {
|
||||
LEMON_ASSERT(false, "Elevator is not initialized");
|
||||
return 0; // ignore warnings
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief \ref named-templ-param "Named parameter" for setting
|
||||
/// Elevator type
|
||||
///
|
||||
/// \ref named-templ-param "Named parameter" for setting Elevator
|
||||
/// type. If this named parameter is used, then an external
|
||||
/// elevator object must be passed to the algorithm using the
|
||||
/// \ref elevator(Elevator&) "elevator()" function before calling
|
||||
/// \ref run() or \ref init().
|
||||
/// \sa SetStandardElevator
|
||||
template <typename T>
|
||||
struct SetElevator
|
||||
: public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
|
||||
SetElevatorTraits<T> > {
|
||||
typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
|
||||
SetElevatorTraits<T> > Create;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct SetStandardElevatorTraits : public Traits {
|
||||
typedef T Elevator;
|
||||
static Elevator *createElevator(const Digraph& digraph, int max_level) {
|
||||
return new Elevator(digraph, max_level);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief \ref named-templ-param "Named parameter" for setting
|
||||
/// Elevator type with automatic allocation
|
||||
///
|
||||
/// \ref named-templ-param "Named parameter" for setting Elevator
|
||||
/// type with automatic allocation.
|
||||
/// The Elevator should have standard constructor interface to be
|
||||
/// able to automatically created by the algorithm (i.e. the
|
||||
/// digraph and the maximum level should be passed to it).
|
||||
/// However, an external elevator object could also be passed to the
|
||||
/// algorithm with the \ref elevator(Elevator&) "elevator()" function
|
||||
/// before calling \ref run() or \ref init().
|
||||
/// \sa SetElevator
|
||||
template <typename T>
|
||||
struct SetStandardElevator
|
||||
: public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
|
||||
SetStandardElevatorTraits<T> > {
|
||||
typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
|
||||
SetStandardElevatorTraits<T> > Create;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
protected:
|
||||
|
||||
Circulation() {}
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor.
|
||||
|
||||
/// The constructor of the class.
|
||||
///
|
||||
/// \param graph The digraph the algorithm runs on.
|
||||
/// \param lower The lower bounds for the flow values on the arcs.
|
||||
/// \param upper The upper bounds (capacities) for the flow values
|
||||
/// on the arcs.
|
||||
/// \param supply The signed supply values of the nodes.
|
||||
Circulation(const Digraph &graph, const LowerMap &lower,
|
||||
const UpperMap &upper, const SupplyMap &supply)
|
||||
: _g(graph), _lo(&lower), _up(&upper), _supply(&supply),
|
||||
_flow(NULL), _local_flow(false), _level(NULL), _local_level(false),
|
||||
_excess(NULL) {}
|
||||
|
||||
/// Destructor.
|
||||
~Circulation() {
|
||||
destroyStructures();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
bool checkBoundMaps() {
|
||||
for (ArcIt e(_g);e!=INVALID;++e) {
|
||||
if (_tol.less((*_up)[e], (*_lo)[e])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void createStructures() {
|
||||
_node_num = _el = countNodes(_g);
|
||||
|
||||
if (!_flow) {
|
||||
_flow = Traits::createFlowMap(_g);
|
||||
_local_flow = true;
|
||||
}
|
||||
if (!_level) {
|
||||
_level = Traits::createElevator(_g, _node_num);
|
||||
_local_level = true;
|
||||
}
|
||||
if (!_excess) {
|
||||
_excess = new ExcessMap(_g);
|
||||
}
|
||||
}
|
||||
|
||||
void destroyStructures() {
|
||||
if (_local_flow) {
|
||||
delete _flow;
|
||||
}
|
||||
if (_local_level) {
|
||||
delete _level;
|
||||
}
|
||||
if (_excess) {
|
||||
delete _excess;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// Sets the lower bound map.
|
||||
|
||||
/// Sets the lower bound map.
|
||||
/// \return <tt>(*this)</tt>
|
||||
Circulation& lowerMap(const LowerMap& map) {
|
||||
_lo = ↦
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Sets the upper bound (capacity) map.
|
||||
|
||||
/// Sets the upper bound (capacity) map.
|
||||
/// \return <tt>(*this)</tt>
|
||||
Circulation& upperMap(const UpperMap& map) {
|
||||
_up = ↦
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Sets the supply map.
|
||||
|
||||
/// Sets the supply map.
|
||||
/// \return <tt>(*this)</tt>
|
||||
Circulation& supplyMap(const SupplyMap& map) {
|
||||
_supply = ↦
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Sets the flow map.
|
||||
///
|
||||
/// Sets the flow map.
|
||||
/// If you don't use this function before calling \ref run() or
|
||||
/// \ref init(), an instance will be allocated automatically.
|
||||
/// The destructor deallocates this automatically allocated map,
|
||||
/// of course.
|
||||
/// \return <tt>(*this)</tt>
|
||||
Circulation& flowMap(FlowMap& map) {
|
||||
if (_local_flow) {
|
||||
delete _flow;
|
||||
_local_flow = false;
|
||||
}
|
||||
_flow = ↦
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Sets the elevator used by algorithm.
|
||||
///
|
||||
/// Sets the elevator used by algorithm.
|
||||
/// If you don't use this function before calling \ref run() or
|
||||
/// \ref init(), an instance will be allocated automatically.
|
||||
/// The destructor deallocates this automatically allocated elevator,
|
||||
/// of course.
|
||||
/// \return <tt>(*this)</tt>
|
||||
Circulation& elevator(Elevator& elevator) {
|
||||
if (_local_level) {
|
||||
delete _level;
|
||||
_local_level = false;
|
||||
}
|
||||
_level = &elevator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Returns a const reference to the elevator.
|
||||
///
|
||||
/// Returns a const reference to the elevator.
|
||||
///
|
||||
/// \pre Either \ref run() or \ref init() must be called before
|
||||
/// using this function.
|
||||
const Elevator& elevator() const {
|
||||
return *_level;
|
||||
}
|
||||
|
||||
/// \brief Sets the tolerance used by the algorithm.
|
||||
///
|
||||
/// Sets the tolerance object used by the algorithm.
|
||||
/// \return <tt>(*this)</tt>
|
||||
Circulation& tolerance(const Tolerance& tolerance) {
|
||||
_tol = tolerance;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Returns a const reference to the tolerance.
|
||||
///
|
||||
/// Returns a const reference to the tolerance object used by
|
||||
/// the algorithm.
|
||||
const Tolerance& tolerance() const {
|
||||
return _tol;
|
||||
}
|
||||
|
||||
/// \name Execution Control
|
||||
/// The simplest way to execute the algorithm is to call \ref run().\n
|
||||
/// If you need better control on the initial solution or the execution,
|
||||
/// you have to call one of the \ref init() functions first, then
|
||||
/// the \ref start() function.
|
||||
|
||||
///@{
|
||||
|
||||
/// Initializes the internal data structures.
|
||||
|
||||
/// Initializes the internal data structures and sets all flow values
|
||||
/// to the lower bound.
|
||||
void init()
|
||||
{
|
||||
LEMON_DEBUG(checkBoundMaps(),
|
||||
"Upper bounds must be greater or equal to the lower bounds");
|
||||
|
||||
createStructures();
|
||||
|
||||
for(NodeIt n(_g);n!=INVALID;++n) {
|
||||
(*_excess)[n] = (*_supply)[n];
|
||||
}
|
||||
|
||||
for (ArcIt e(_g);e!=INVALID;++e) {
|
||||
_flow->set(e, (*_lo)[e]);
|
||||
(*_excess)[_g.target(e)] += (*_flow)[e];
|
||||
(*_excess)[_g.source(e)] -= (*_flow)[e];
|
||||
}
|
||||
|
||||
// global relabeling tested, but in general case it provides
|
||||
// worse performance for random digraphs
|
||||
_level->initStart();
|
||||
for(NodeIt n(_g);n!=INVALID;++n)
|
||||
_level->initAddItem(n);
|
||||
_level->initFinish();
|
||||
for(NodeIt n(_g);n!=INVALID;++n)
|
||||
if(_tol.positive((*_excess)[n]))
|
||||
_level->activate(n);
|
||||
}
|
||||
|
||||
/// Initializes the internal data structures using a greedy approach.
|
||||
|
||||
/// Initializes the internal data structures using a greedy approach
|
||||
/// to construct the initial solution.
|
||||
void greedyInit()
|
||||
{
|
||||
LEMON_DEBUG(checkBoundMaps(),
|
||||
"Upper bounds must be greater or equal to the lower bounds");
|
||||
|
||||
createStructures();
|
||||
|
||||
for(NodeIt n(_g);n!=INVALID;++n) {
|
||||
(*_excess)[n] = (*_supply)[n];
|
||||
}
|
||||
|
||||
for (ArcIt e(_g);e!=INVALID;++e) {
|
||||
if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
|
||||
_flow->set(e, (*_up)[e]);
|
||||
(*_excess)[_g.target(e)] += (*_up)[e];
|
||||
(*_excess)[_g.source(e)] -= (*_up)[e];
|
||||
} else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
|
||||
_flow->set(e, (*_lo)[e]);
|
||||
(*_excess)[_g.target(e)] += (*_lo)[e];
|
||||
(*_excess)[_g.source(e)] -= (*_lo)[e];
|
||||
} else {
|
||||
Value fc = -(*_excess)[_g.target(e)];
|
||||
_flow->set(e, fc);
|
||||
(*_excess)[_g.target(e)] = 0;
|
||||
(*_excess)[_g.source(e)] -= fc;
|
||||
}
|
||||
}
|
||||
|
||||
_level->initStart();
|
||||
for(NodeIt n(_g);n!=INVALID;++n)
|
||||
_level->initAddItem(n);
|
||||
_level->initFinish();
|
||||
for(NodeIt n(_g);n!=INVALID;++n)
|
||||
if(_tol.positive((*_excess)[n]))
|
||||
_level->activate(n);
|
||||
}
|
||||
|
||||
///Executes the algorithm
|
||||
|
||||
///This function executes the algorithm.
|
||||
///
|
||||
///\return \c true if a feasible circulation is found.
|
||||
///
|
||||
///\sa barrier()
|
||||
///\sa barrierMap()
|
||||
bool start()
|
||||
{
|
||||
|
||||
Node act;
|
||||
while((act=_level->highestActive())!=INVALID) {
|
||||
int actlevel=(*_level)[act];
|
||||
int mlevel=_node_num;
|
||||
Value exc=(*_excess)[act];
|
||||
|
||||
for(OutArcIt e(_g,act);e!=INVALID; ++e) {
|
||||
Node v = _g.target(e);
|
||||
Value fc=(*_up)[e]-(*_flow)[e];
|
||||
if(!_tol.positive(fc)) continue;
|
||||
if((*_level)[v]<actlevel) {
|
||||
if(!_tol.less(fc, exc)) {
|
||||
_flow->set(e, (*_flow)[e] + exc);
|
||||
(*_excess)[v] += exc;
|
||||
if(!_level->active(v) && _tol.positive((*_excess)[v]))
|
||||
_level->activate(v);
|
||||
(*_excess)[act] = 0;
|
||||
_level->deactivate(act);
|
||||
goto next_l;
|
||||
}
|
||||
else {
|
||||
_flow->set(e, (*_up)[e]);
|
||||
(*_excess)[v] += fc;
|
||||
if(!_level->active(v) && _tol.positive((*_excess)[v]))
|
||||
_level->activate(v);
|
||||
exc-=fc;
|
||||
}
|
||||
}
|
||||
else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
|
||||
}
|
||||
for(InArcIt e(_g,act);e!=INVALID; ++e) {
|
||||
Node v = _g.source(e);
|
||||
Value fc=(*_flow)[e]-(*_lo)[e];
|
||||
if(!_tol.positive(fc)) continue;
|
||||
if((*_level)[v]<actlevel) {
|
||||
if(!_tol.less(fc, exc)) {
|
||||
_flow->set(e, (*_flow)[e] - exc);
|
||||
(*_excess)[v] += exc;
|
||||
if(!_level->active(v) && _tol.positive((*_excess)[v]))
|
||||
_level->activate(v);
|
||||
(*_excess)[act] = 0;
|
||||
_level->deactivate(act);
|
||||
goto next_l;
|
||||
}
|
||||
else {
|
||||
_flow->set(e, (*_lo)[e]);
|
||||
(*_excess)[v] += fc;
|
||||
if(!_level->active(v) && _tol.positive((*_excess)[v]))
|
||||
_level->activate(v);
|
||||
exc-=fc;
|
||||
}
|
||||
}
|
||||
else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
|
||||
}
|
||||
|
||||
(*_excess)[act] = exc;
|
||||
if(!_tol.positive(exc)) _level->deactivate(act);
|
||||
else if(mlevel==_node_num) {
|
||||
_level->liftHighestActiveToTop();
|
||||
_el = _node_num;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
_level->liftHighestActive(mlevel+1);
|
||||
if(_level->onLevel(actlevel)==0) {
|
||||
_el = actlevel;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
next_l:
|
||||
;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Runs the algorithm.
|
||||
|
||||
/// This function runs the algorithm.
|
||||
///
|
||||
/// \return \c true if a feasible circulation is found.
|
||||
///
|
||||
/// \note Apart from the return value, c.run() is just a shortcut of
|
||||
/// the following code.
|
||||
/// \code
|
||||
/// c.greedyInit();
|
||||
/// c.start();
|
||||
/// \endcode
|
||||
bool run() {
|
||||
greedyInit();
|
||||
return start();
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Query Functions
|
||||
/// The results of the circulation algorithm can be obtained using
|
||||
/// these functions.\n
|
||||
/// Either \ref run() or \ref start() should be called before
|
||||
/// using them.
|
||||
|
||||
///@{
|
||||
|
||||
/// \brief Returns the flow value on the given arc.
|
||||
///
|
||||
/// Returns the flow value on the given arc.
|
||||
///
|
||||
/// \pre Either \ref run() or \ref init() must be called before
|
||||
/// using this function.
|
||||
Value flow(const Arc& arc) const {
|
||||
return (*_flow)[arc];
|
||||
}
|
||||
|
||||
/// \brief Returns a const reference to the flow map.
|
||||
///
|
||||
/// Returns a const reference to the arc map storing the found flow.
|
||||
///
|
||||
/// \pre Either \ref run() or \ref init() must be called before
|
||||
/// using this function.
|
||||
const FlowMap& flowMap() const {
|
||||
return *_flow;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Returns \c true if the given node is in a barrier.
|
||||
|
||||
Barrier is a set \e B of nodes for which
|
||||
|
||||
\f[ \sum_{uv\in A: u\in B} upper(uv) -
|
||||
\sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f]
|
||||
|
||||
holds. The existence of a set with this property prooves that a
|
||||
feasible circualtion cannot exist.
|
||||
|
||||
This function returns \c true if the given node is in the found
|
||||
barrier. If a feasible circulation is found, the function
|
||||
gives back \c false for every node.
|
||||
|
||||
\pre Either \ref run() or \ref init() must be called before
|
||||
using this function.
|
||||
|
||||
\sa barrierMap()
|
||||
\sa checkBarrier()
|
||||
*/
|
||||
bool barrier(const Node& node) const
|
||||
{
|
||||
return (*_level)[node] >= _el;
|
||||
}
|
||||
|
||||
/// \brief Gives back a barrier.
|
||||
///
|
||||
/// This function sets \c bar to the characteristic vector of the
|
||||
/// found barrier. \c bar should be a \ref concepts::WriteMap "writable"
|
||||
/// node map with \c bool (or convertible) value type.
|
||||
///
|
||||
/// If a feasible circulation is found, the function gives back an
|
||||
/// empty set, so \c bar[v] will be \c false for all nodes \c v.
|
||||
///
|
||||
/// \note This function calls \ref barrier() for each node,
|
||||
/// so it runs in O(n) time.
|
||||
///
|
||||
/// \pre Either \ref run() or \ref init() must be called before
|
||||
/// using this function.
|
||||
///
|
||||
/// \sa barrier()
|
||||
/// \sa checkBarrier()
|
||||
template<class BarrierMap>
|
||||
void barrierMap(BarrierMap &bar) const
|
||||
{
|
||||
for(NodeIt n(_g);n!=INVALID;++n)
|
||||
bar.set(n, (*_level)[n] >= _el);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Checker Functions
|
||||
/// The feasibility of the results can be checked using
|
||||
/// these functions.\n
|
||||
/// Either \ref run() or \ref start() should be called before
|
||||
/// using them.
|
||||
|
||||
///@{
|
||||
|
||||
///Check if the found flow is a feasible circulation
|
||||
|
||||
///Check if the found flow is a feasible circulation,
|
||||
///
|
||||
bool checkFlow() const {
|
||||
for(ArcIt e(_g);e!=INVALID;++e)
|
||||
if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
|
||||
for(NodeIt n(_g);n!=INVALID;++n)
|
||||
{
|
||||
Value dif=-(*_supply)[n];
|
||||
for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
|
||||
for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
|
||||
if(_tol.negative(dif)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///Check whether or not the last execution provides a barrier
|
||||
|
||||
///Check whether or not the last execution provides a barrier.
|
||||
///\sa barrier()
|
||||
///\sa barrierMap()
|
||||
bool checkBarrier() const
|
||||
{
|
||||
Value delta=0;
|
||||
Value inf_cap = std::numeric_limits<Value>::has_infinity ?
|
||||
std::numeric_limits<Value>::infinity() :
|
||||
std::numeric_limits<Value>::max();
|
||||
for(NodeIt n(_g);n!=INVALID;++n)
|
||||
if(barrier(n))
|
||||
delta-=(*_supply)[n];
|
||||
for(ArcIt e(_g);e!=INVALID;++e)
|
||||
{
|
||||
Node s=_g.source(e);
|
||||
Node t=_g.target(e);
|
||||
if(barrier(s)&&!barrier(t)) {
|
||||
if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
|
||||
delta+=(*_up)[e];
|
||||
}
|
||||
else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
|
||||
}
|
||||
return _tol.negative(delta);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
464
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/clp.cc
vendored
Normal file
464
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/clp.cc
vendored
Normal file
@@ -0,0 +1,464 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/clp.h>
|
||||
#include <coin/ClpSimplex.hpp>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
ClpLp::ClpLp() {
|
||||
_prob = new ClpSimplex();
|
||||
_init_temporals();
|
||||
messageLevel(MESSAGE_NOTHING);
|
||||
}
|
||||
|
||||
ClpLp::ClpLp(const ClpLp& other) {
|
||||
_prob = new ClpSimplex(*other._prob);
|
||||
rows = other.rows;
|
||||
cols = other.cols;
|
||||
_init_temporals();
|
||||
messageLevel(MESSAGE_NOTHING);
|
||||
}
|
||||
|
||||
ClpLp::~ClpLp() {
|
||||
delete _prob;
|
||||
_clear_temporals();
|
||||
}
|
||||
|
||||
void ClpLp::_init_temporals() {
|
||||
_primal_ray = 0;
|
||||
_dual_ray = 0;
|
||||
}
|
||||
|
||||
void ClpLp::_clear_temporals() {
|
||||
if (_primal_ray) {
|
||||
delete[] _primal_ray;
|
||||
_primal_ray = 0;
|
||||
}
|
||||
if (_dual_ray) {
|
||||
delete[] _dual_ray;
|
||||
_dual_ray = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ClpLp* ClpLp::newSolver() const {
|
||||
ClpLp* newlp = new ClpLp;
|
||||
return newlp;
|
||||
}
|
||||
|
||||
ClpLp* ClpLp::cloneSolver() const {
|
||||
ClpLp* copylp = new ClpLp(*this);
|
||||
return copylp;
|
||||
}
|
||||
|
||||
const char* ClpLp::_solverName() const { return "ClpLp"; }
|
||||
|
||||
int ClpLp::_addCol() {
|
||||
_prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0);
|
||||
return _prob->numberColumns() - 1;
|
||||
}
|
||||
|
||||
int ClpLp::_addRow() {
|
||||
_prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
|
||||
return _prob->numberRows() - 1;
|
||||
}
|
||||
|
||||
int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
|
||||
std::vector<int> indexes;
|
||||
std::vector<Value> values;
|
||||
|
||||
for(ExprIterator it = b; it != e; ++it) {
|
||||
indexes.push_back(it->first);
|
||||
values.push_back(it->second);
|
||||
}
|
||||
|
||||
_prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
|
||||
return _prob->numberRows() - 1;
|
||||
}
|
||||
|
||||
|
||||
void ClpLp::_eraseCol(int c) {
|
||||
_col_names_ref.erase(_prob->getColumnName(c));
|
||||
_prob->deleteColumns(1, &c);
|
||||
}
|
||||
|
||||
void ClpLp::_eraseRow(int r) {
|
||||
_row_names_ref.erase(_prob->getRowName(r));
|
||||
_prob->deleteRows(1, &r);
|
||||
}
|
||||
|
||||
void ClpLp::_eraseColId(int i) {
|
||||
cols.eraseIndex(i);
|
||||
cols.shiftIndices(i);
|
||||
}
|
||||
|
||||
void ClpLp::_eraseRowId(int i) {
|
||||
rows.eraseIndex(i);
|
||||
rows.shiftIndices(i);
|
||||
}
|
||||
|
||||
void ClpLp::_getColName(int c, std::string& name) const {
|
||||
name = _prob->getColumnName(c);
|
||||
}
|
||||
|
||||
void ClpLp::_setColName(int c, const std::string& name) {
|
||||
_prob->setColumnName(c, const_cast<std::string&>(name));
|
||||
_col_names_ref[name] = c;
|
||||
}
|
||||
|
||||
int ClpLp::_colByName(const std::string& name) const {
|
||||
std::map<std::string, int>::const_iterator it = _col_names_ref.find(name);
|
||||
return it != _col_names_ref.end() ? it->second : -1;
|
||||
}
|
||||
|
||||
void ClpLp::_getRowName(int r, std::string& name) const {
|
||||
name = _prob->getRowName(r);
|
||||
}
|
||||
|
||||
void ClpLp::_setRowName(int r, const std::string& name) {
|
||||
_prob->setRowName(r, const_cast<std::string&>(name));
|
||||
_row_names_ref[name] = r;
|
||||
}
|
||||
|
||||
int ClpLp::_rowByName(const std::string& name) const {
|
||||
std::map<std::string, int>::const_iterator it = _row_names_ref.find(name);
|
||||
return it != _row_names_ref.end() ? it->second : -1;
|
||||
}
|
||||
|
||||
|
||||
void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) {
|
||||
std::map<int, Value> coeffs;
|
||||
|
||||
int n = _prob->clpMatrix()->getNumCols();
|
||||
|
||||
const int* indices = _prob->clpMatrix()->getIndices();
|
||||
const double* elements = _prob->clpMatrix()->getElements();
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
|
||||
CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
|
||||
|
||||
const int* it = std::lower_bound(indices + begin, indices + end, ix);
|
||||
if (it != indices + end && *it == ix && elements[it - indices] != 0.0) {
|
||||
coeffs[i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
for (ExprIterator it = b; it != e; ++it) {
|
||||
coeffs[it->first] = it->second;
|
||||
}
|
||||
|
||||
for (std::map<int, Value>::iterator it = coeffs.begin();
|
||||
it != coeffs.end(); ++it) {
|
||||
_prob->modifyCoefficient(ix, it->first, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void ClpLp::_getRowCoeffs(int ix, InsertIterator b) const {
|
||||
int n = _prob->clpMatrix()->getNumCols();
|
||||
|
||||
const int* indices = _prob->clpMatrix()->getIndices();
|
||||
const double* elements = _prob->clpMatrix()->getElements();
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
|
||||
CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
|
||||
|
||||
const int* it = std::lower_bound(indices + begin, indices + end, ix);
|
||||
if (it != indices + end && *it == ix) {
|
||||
*b = std::make_pair(i, elements[it - indices]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClpLp::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
|
||||
std::map<int, Value> coeffs;
|
||||
|
||||
CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
|
||||
CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
|
||||
|
||||
const int* indices = _prob->clpMatrix()->getIndices();
|
||||
const double* elements = _prob->clpMatrix()->getElements();
|
||||
|
||||
for (CoinBigIndex i = begin; i != end; ++i) {
|
||||
if (elements[i] != 0.0) {
|
||||
coeffs[indices[i]] = 0.0;
|
||||
}
|
||||
}
|
||||
for (ExprIterator it = b; it != e; ++it) {
|
||||
coeffs[it->first] = it->second;
|
||||
}
|
||||
for (std::map<int, Value>::iterator it = coeffs.begin();
|
||||
it != coeffs.end(); ++it) {
|
||||
_prob->modifyCoefficient(it->first, ix, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void ClpLp::_getColCoeffs(int ix, InsertIterator b) const {
|
||||
CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
|
||||
CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
|
||||
|
||||
const int* indices = _prob->clpMatrix()->getIndices();
|
||||
const double* elements = _prob->clpMatrix()->getElements();
|
||||
|
||||
for (CoinBigIndex i = begin; i != end; ++i) {
|
||||
*b = std::make_pair(indices[i], elements[i]);
|
||||
++b;
|
||||
}
|
||||
}
|
||||
|
||||
void ClpLp::_setCoeff(int ix, int jx, Value value) {
|
||||
_prob->modifyCoefficient(ix, jx, value);
|
||||
}
|
||||
|
||||
ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const {
|
||||
CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
|
||||
CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
|
||||
|
||||
const int* indices = _prob->clpMatrix()->getIndices();
|
||||
const double* elements = _prob->clpMatrix()->getElements();
|
||||
|
||||
const int* it = std::lower_bound(indices + begin, indices + end, jx);
|
||||
if (it != indices + end && *it == jx) {
|
||||
return elements[it - indices];
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void ClpLp::_setColLowerBound(int i, Value lo) {
|
||||
_prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
|
||||
}
|
||||
|
||||
ClpLp::Value ClpLp::_getColLowerBound(int i) const {
|
||||
double val = _prob->getColLower()[i];
|
||||
return val == - COIN_DBL_MAX ? - INF : val;
|
||||
}
|
||||
|
||||
void ClpLp::_setColUpperBound(int i, Value up) {
|
||||
_prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
|
||||
}
|
||||
|
||||
ClpLp::Value ClpLp::_getColUpperBound(int i) const {
|
||||
double val = _prob->getColUpper()[i];
|
||||
return val == COIN_DBL_MAX ? INF : val;
|
||||
}
|
||||
|
||||
void ClpLp::_setRowLowerBound(int i, Value lo) {
|
||||
_prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
|
||||
}
|
||||
|
||||
ClpLp::Value ClpLp::_getRowLowerBound(int i) const {
|
||||
double val = _prob->getRowLower()[i];
|
||||
return val == - COIN_DBL_MAX ? - INF : val;
|
||||
}
|
||||
|
||||
void ClpLp::_setRowUpperBound(int i, Value up) {
|
||||
_prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
|
||||
}
|
||||
|
||||
ClpLp::Value ClpLp::_getRowUpperBound(int i) const {
|
||||
double val = _prob->getRowUpper()[i];
|
||||
return val == COIN_DBL_MAX ? INF : val;
|
||||
}
|
||||
|
||||
void ClpLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
|
||||
int num = _prob->clpMatrix()->getNumCols();
|
||||
for (int i = 0; i < num; ++i) {
|
||||
_prob->setObjectiveCoefficient(i, 0.0);
|
||||
}
|
||||
for (ExprIterator it = b; it != e; ++it) {
|
||||
_prob->setObjectiveCoefficient(it->first, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void ClpLp::_getObjCoeffs(InsertIterator b) const {
|
||||
int num = _prob->clpMatrix()->getNumCols();
|
||||
for (int i = 0; i < num; ++i) {
|
||||
Value coef = _prob->getObjCoefficients()[i];
|
||||
if (coef != 0.0) {
|
||||
*b = std::make_pair(i, coef);
|
||||
++b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClpLp::_setObjCoeff(int i, Value obj_coef) {
|
||||
_prob->setObjectiveCoefficient(i, obj_coef);
|
||||
}
|
||||
|
||||
ClpLp::Value ClpLp::_getObjCoeff(int i) const {
|
||||
return _prob->getObjCoefficients()[i];
|
||||
}
|
||||
|
||||
ClpLp::SolveExitStatus ClpLp::_solve() {
|
||||
return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
|
||||
}
|
||||
|
||||
ClpLp::SolveExitStatus ClpLp::solvePrimal() {
|
||||
return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
|
||||
}
|
||||
|
||||
ClpLp::SolveExitStatus ClpLp::solveDual() {
|
||||
return _prob->dual() >= 0 ? SOLVED : UNSOLVED;
|
||||
}
|
||||
|
||||
ClpLp::SolveExitStatus ClpLp::solveBarrier() {
|
||||
return _prob->barrier() >= 0 ? SOLVED : UNSOLVED;
|
||||
}
|
||||
|
||||
ClpLp::Value ClpLp::_getPrimal(int i) const {
|
||||
return _prob->primalColumnSolution()[i];
|
||||
}
|
||||
ClpLp::Value ClpLp::_getPrimalValue() const {
|
||||
return _prob->objectiveValue();
|
||||
}
|
||||
|
||||
ClpLp::Value ClpLp::_getDual(int i) const {
|
||||
return _prob->dualRowSolution()[i];
|
||||
}
|
||||
|
||||
ClpLp::Value ClpLp::_getPrimalRay(int i) const {
|
||||
if (!_primal_ray) {
|
||||
_primal_ray = _prob->unboundedRay();
|
||||
LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided");
|
||||
}
|
||||
return _primal_ray[i];
|
||||
}
|
||||
|
||||
ClpLp::Value ClpLp::_getDualRay(int i) const {
|
||||
if (!_dual_ray) {
|
||||
_dual_ray = _prob->infeasibilityRay();
|
||||
LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided");
|
||||
}
|
||||
return _dual_ray[i];
|
||||
}
|
||||
|
||||
ClpLp::VarStatus ClpLp::_getColStatus(int i) const {
|
||||
switch (_prob->getColumnStatus(i)) {
|
||||
case ClpSimplex::basic:
|
||||
return BASIC;
|
||||
case ClpSimplex::isFree:
|
||||
return FREE;
|
||||
case ClpSimplex::atUpperBound:
|
||||
return UPPER;
|
||||
case ClpSimplex::atLowerBound:
|
||||
return LOWER;
|
||||
case ClpSimplex::isFixed:
|
||||
return FIXED;
|
||||
case ClpSimplex::superBasic:
|
||||
return FREE;
|
||||
default:
|
||||
LEMON_ASSERT(false, "Wrong column status");
|
||||
return VarStatus();
|
||||
}
|
||||
}
|
||||
|
||||
ClpLp::VarStatus ClpLp::_getRowStatus(int i) const {
|
||||
switch (_prob->getColumnStatus(i)) {
|
||||
case ClpSimplex::basic:
|
||||
return BASIC;
|
||||
case ClpSimplex::isFree:
|
||||
return FREE;
|
||||
case ClpSimplex::atUpperBound:
|
||||
return UPPER;
|
||||
case ClpSimplex::atLowerBound:
|
||||
return LOWER;
|
||||
case ClpSimplex::isFixed:
|
||||
return FIXED;
|
||||
case ClpSimplex::superBasic:
|
||||
return FREE;
|
||||
default:
|
||||
LEMON_ASSERT(false, "Wrong row status");
|
||||
return VarStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ClpLp::ProblemType ClpLp::_getPrimalType() const {
|
||||
if (_prob->isProvenOptimal()) {
|
||||
return OPTIMAL;
|
||||
} else if (_prob->isProvenPrimalInfeasible()) {
|
||||
return INFEASIBLE;
|
||||
} else if (_prob->isProvenDualInfeasible()) {
|
||||
return UNBOUNDED;
|
||||
} else {
|
||||
return UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
ClpLp::ProblemType ClpLp::_getDualType() const {
|
||||
if (_prob->isProvenOptimal()) {
|
||||
return OPTIMAL;
|
||||
} else if (_prob->isProvenDualInfeasible()) {
|
||||
return INFEASIBLE;
|
||||
} else if (_prob->isProvenPrimalInfeasible()) {
|
||||
return INFEASIBLE;
|
||||
} else {
|
||||
return UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
void ClpLp::_setSense(ClpLp::Sense sense) {
|
||||
switch (sense) {
|
||||
case MIN:
|
||||
_prob->setOptimizationDirection(1);
|
||||
break;
|
||||
case MAX:
|
||||
_prob->setOptimizationDirection(-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ClpLp::Sense ClpLp::_getSense() const {
|
||||
double dir = _prob->optimizationDirection();
|
||||
if (dir > 0.0) {
|
||||
return MIN;
|
||||
} else {
|
||||
return MAX;
|
||||
}
|
||||
}
|
||||
|
||||
void ClpLp::_clear() {
|
||||
delete _prob;
|
||||
_prob = new ClpSimplex();
|
||||
_col_names_ref.clear();
|
||||
_clear_temporals();
|
||||
}
|
||||
|
||||
void ClpLp::_messageLevel(MessageLevel level) {
|
||||
switch (level) {
|
||||
case MESSAGE_NOTHING:
|
||||
_prob->setLogLevel(0);
|
||||
break;
|
||||
case MESSAGE_ERROR:
|
||||
_prob->setLogLevel(1);
|
||||
break;
|
||||
case MESSAGE_WARNING:
|
||||
_prob->setLogLevel(2);
|
||||
break;
|
||||
case MESSAGE_NORMAL:
|
||||
_prob->setLogLevel(3);
|
||||
break;
|
||||
case MESSAGE_VERBOSE:
|
||||
_prob->setLogLevel(4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} //END OF NAMESPACE LEMON
|
||||
164
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/clp.h
vendored
Normal file
164
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/clp.h
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_CLP_H
|
||||
#define LEMON_CLP_H
|
||||
|
||||
///\file
|
||||
///\brief Header of the LEMON-CLP lp solver interface.
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <lemon/lp_base.h>
|
||||
|
||||
class ClpSimplex;
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \ingroup lp_group
|
||||
///
|
||||
/// \brief Interface for the CLP solver
|
||||
///
|
||||
/// This class implements an interface for the Clp LP solver. The
|
||||
/// Clp library is an object oriented lp solver library developed at
|
||||
/// the IBM. The CLP is part of the COIN-OR package and it can be
|
||||
/// used with Common Public License.
|
||||
class ClpLp : public LpSolver {
|
||||
protected:
|
||||
|
||||
ClpSimplex* _prob;
|
||||
|
||||
std::map<std::string, int> _col_names_ref;
|
||||
std::map<std::string, int> _row_names_ref;
|
||||
|
||||
public:
|
||||
|
||||
/// \e
|
||||
ClpLp();
|
||||
/// \e
|
||||
ClpLp(const ClpLp&);
|
||||
/// \e
|
||||
~ClpLp();
|
||||
|
||||
/// \e
|
||||
virtual ClpLp* newSolver() const;
|
||||
/// \e
|
||||
virtual ClpLp* cloneSolver() const;
|
||||
|
||||
protected:
|
||||
|
||||
mutable double* _primal_ray;
|
||||
mutable double* _dual_ray;
|
||||
|
||||
void _init_temporals();
|
||||
void _clear_temporals();
|
||||
|
||||
protected:
|
||||
|
||||
virtual const char* _solverName() const;
|
||||
|
||||
virtual int _addCol();
|
||||
virtual int _addRow();
|
||||
virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
|
||||
|
||||
virtual void _eraseCol(int i);
|
||||
virtual void _eraseRow(int i);
|
||||
|
||||
virtual void _eraseColId(int i);
|
||||
virtual void _eraseRowId(int i);
|
||||
|
||||
virtual void _getColName(int col, std::string& name) const;
|
||||
virtual void _setColName(int col, const std::string& name);
|
||||
virtual int _colByName(const std::string& name) const;
|
||||
|
||||
virtual void _getRowName(int row, std::string& name) const;
|
||||
virtual void _setRowName(int row, const std::string& name);
|
||||
virtual int _rowByName(const std::string& name) const;
|
||||
|
||||
virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
|
||||
virtual void _getRowCoeffs(int i, InsertIterator b) const;
|
||||
|
||||
virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
|
||||
virtual void _getColCoeffs(int i, InsertIterator b) const;
|
||||
|
||||
virtual void _setCoeff(int row, int col, Value value);
|
||||
virtual Value _getCoeff(int row, int col) const;
|
||||
|
||||
virtual void _setColLowerBound(int i, Value value);
|
||||
virtual Value _getColLowerBound(int i) const;
|
||||
virtual void _setColUpperBound(int i, Value value);
|
||||
virtual Value _getColUpperBound(int i) const;
|
||||
|
||||
virtual void _setRowLowerBound(int i, Value value);
|
||||
virtual Value _getRowLowerBound(int i) const;
|
||||
virtual void _setRowUpperBound(int i, Value value);
|
||||
virtual Value _getRowUpperBound(int i) const;
|
||||
|
||||
virtual void _setObjCoeffs(ExprIterator, ExprIterator);
|
||||
virtual void _getObjCoeffs(InsertIterator) const;
|
||||
|
||||
virtual void _setObjCoeff(int i, Value obj_coef);
|
||||
virtual Value _getObjCoeff(int i) const;
|
||||
|
||||
virtual void _setSense(Sense sense);
|
||||
virtual Sense _getSense() const;
|
||||
|
||||
virtual SolveExitStatus _solve();
|
||||
|
||||
virtual Value _getPrimal(int i) const;
|
||||
virtual Value _getDual(int i) const;
|
||||
|
||||
virtual Value _getPrimalValue() const;
|
||||
|
||||
virtual Value _getPrimalRay(int i) const;
|
||||
virtual Value _getDualRay(int i) const;
|
||||
|
||||
virtual VarStatus _getColStatus(int i) const;
|
||||
virtual VarStatus _getRowStatus(int i) const;
|
||||
|
||||
virtual ProblemType _getPrimalType() const;
|
||||
virtual ProblemType _getDualType() const;
|
||||
|
||||
virtual void _clear();
|
||||
|
||||
virtual void _messageLevel(MessageLevel);
|
||||
|
||||
public:
|
||||
|
||||
///Solves LP with primal simplex method.
|
||||
SolveExitStatus solvePrimal();
|
||||
|
||||
///Solves LP with dual simplex method.
|
||||
SolveExitStatus solveDual();
|
||||
|
||||
///Solves LP with barrier method.
|
||||
SolveExitStatus solveBarrier();
|
||||
|
||||
///Returns the constraint identifier understood by CLP.
|
||||
int clpRow(Row r) const { return rows(id(r)); }
|
||||
|
||||
///Returns the variable identifier understood by CLP.
|
||||
int clpCol(Col c) const { return cols(id(c)); }
|
||||
|
||||
};
|
||||
|
||||
} //END OF NAMESPACE LEMON
|
||||
|
||||
#endif //LEMON_CLP_H
|
||||
|
||||
44
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/color.cc
vendored
Normal file
44
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/color.cc
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
///\file
|
||||
///\brief Color constants
|
||||
|
||||
#include<lemon/color.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
const Color WHITE(1,1,1);
|
||||
|
||||
const Color BLACK(0,0,0);
|
||||
const Color RED(1,0,0);
|
||||
const Color GREEN(0,1,0);
|
||||
const Color BLUE(0,0,1);
|
||||
const Color YELLOW(1,1,0);
|
||||
const Color MAGENTA(1,0,1);
|
||||
const Color CYAN(0,1,1);
|
||||
|
||||
const Color GREY(0,0,0);
|
||||
const Color DARK_RED(.5,0,0);
|
||||
const Color DARK_GREEN(0,.5,0);
|
||||
const Color DARK_BLUE(0,0,.5);
|
||||
const Color DARK_YELLOW(.5,.5,0);
|
||||
const Color DARK_MAGENTA(.5,0,.5);
|
||||
const Color DARK_CYAN(0,.5,.5);
|
||||
|
||||
} //namespace lemon
|
||||
204
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/color.h
vendored
Normal file
204
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/color.h
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_COLOR_H
|
||||
#define LEMON_COLOR_H
|
||||
|
||||
#include<vector>
|
||||
#include<lemon/math.h>
|
||||
#include<lemon/maps.h>
|
||||
|
||||
|
||||
///\ingroup misc
|
||||
///\file
|
||||
///\brief Tools to manage RGB colors.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
|
||||
/// \addtogroup misc
|
||||
/// @{
|
||||
|
||||
///Data structure representing RGB colors.
|
||||
|
||||
///Data structure representing RGB colors.
|
||||
class Color
|
||||
{
|
||||
double _r,_g,_b;
|
||||
public:
|
||||
///Default constructor
|
||||
Color() {}
|
||||
///Constructor
|
||||
Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
|
||||
///Set the red component
|
||||
double & red() {return _r;}
|
||||
///Return the red component
|
||||
const double & red() const {return _r;}
|
||||
///Set the green component
|
||||
double & green() {return _g;}
|
||||
///Return the green component
|
||||
const double & green() const {return _g;}
|
||||
///Set the blue component
|
||||
double & blue() {return _b;}
|
||||
///Return the blue component
|
||||
const double & blue() const {return _b;}
|
||||
///Set the color components
|
||||
void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
|
||||
};
|
||||
|
||||
/// White color constant
|
||||
extern const Color WHITE;
|
||||
/// Black color constant
|
||||
extern const Color BLACK;
|
||||
/// Red color constant
|
||||
extern const Color RED;
|
||||
/// Green color constant
|
||||
extern const Color GREEN;
|
||||
/// Blue color constant
|
||||
extern const Color BLUE;
|
||||
/// Yellow color constant
|
||||
extern const Color YELLOW;
|
||||
/// Magenta color constant
|
||||
extern const Color MAGENTA;
|
||||
/// Cyan color constant
|
||||
extern const Color CYAN;
|
||||
/// Grey color constant
|
||||
extern const Color GREY;
|
||||
/// Dark red color constant
|
||||
extern const Color DARK_RED;
|
||||
/// Dark green color constant
|
||||
extern const Color DARK_GREEN;
|
||||
/// Drak blue color constant
|
||||
extern const Color DARK_BLUE;
|
||||
/// Dark yellow color constant
|
||||
extern const Color DARK_YELLOW;
|
||||
/// Dark magenta color constant
|
||||
extern const Color DARK_MAGENTA;
|
||||
/// Dark cyan color constant
|
||||
extern const Color DARK_CYAN;
|
||||
|
||||
///Map <tt>int</tt>s to different <tt>Color</tt>s
|
||||
|
||||
///This map assigns one of the predefined \ref Color "Color"s to
|
||||
///each <tt>int</tt>. It is possible to change the colors as well as
|
||||
///their number. The integer range is cyclically mapped to the
|
||||
///provided set of colors.
|
||||
///
|
||||
///This is a true \ref concepts::ReferenceMap "reference map", so
|
||||
///you can also change the actual colors.
|
||||
|
||||
class Palette : public MapBase<int,Color>
|
||||
{
|
||||
std::vector<Color> colors;
|
||||
public:
|
||||
///Constructor
|
||||
|
||||
///Constructor.
|
||||
///\param have_white Indicates whether white is among the
|
||||
///provided initial colors (\c true) or not (\c false). If it is true,
|
||||
///white will be assigned to \c 0.
|
||||
///\param num The number of the allocated colors. If it is \c -1,
|
||||
///the default color configuration is set up (26 color plus optionaly the
|
||||
///white). If \c num is less then 26/27 then the default color
|
||||
///list is cut. Otherwise the color list is filled repeatedly with
|
||||
///the default color list. (The colors can be changed later on.)
|
||||
Palette(bool have_white=false,int num=-1)
|
||||
{
|
||||
if (num==0) return;
|
||||
do {
|
||||
if(have_white) colors.push_back(Color(1,1,1));
|
||||
|
||||
colors.push_back(Color(0,0,0));
|
||||
colors.push_back(Color(1,0,0));
|
||||
colors.push_back(Color(0,1,0));
|
||||
colors.push_back(Color(0,0,1));
|
||||
colors.push_back(Color(1,1,0));
|
||||
colors.push_back(Color(1,0,1));
|
||||
colors.push_back(Color(0,1,1));
|
||||
|
||||
colors.push_back(Color(.5,0,0));
|
||||
colors.push_back(Color(0,.5,0));
|
||||
colors.push_back(Color(0,0,.5));
|
||||
colors.push_back(Color(.5,.5,0));
|
||||
colors.push_back(Color(.5,0,.5));
|
||||
colors.push_back(Color(0,.5,.5));
|
||||
|
||||
colors.push_back(Color(.5,.5,.5));
|
||||
colors.push_back(Color(1,.5,.5));
|
||||
colors.push_back(Color(.5,1,.5));
|
||||
colors.push_back(Color(.5,.5,1));
|
||||
colors.push_back(Color(1,1,.5));
|
||||
colors.push_back(Color(1,.5,1));
|
||||
colors.push_back(Color(.5,1,1));
|
||||
|
||||
colors.push_back(Color(1,.5,0));
|
||||
colors.push_back(Color(.5,1,0));
|
||||
colors.push_back(Color(1,0,.5));
|
||||
colors.push_back(Color(0,1,.5));
|
||||
colors.push_back(Color(0,.5,1));
|
||||
colors.push_back(Color(.5,0,1));
|
||||
} while(int(colors.size())<num);
|
||||
if(num>=0) colors.resize(num);
|
||||
}
|
||||
///\e
|
||||
Color &operator[](int i)
|
||||
{
|
||||
return colors[i%colors.size()];
|
||||
}
|
||||
///\e
|
||||
const Color &operator[](int i) const
|
||||
{
|
||||
return colors[i%colors.size()];
|
||||
}
|
||||
///\e
|
||||
void set(int i,const Color &c)
|
||||
{
|
||||
colors[i%colors.size()]=c;
|
||||
}
|
||||
///Adds a new color to the end of the color list.
|
||||
void add(const Color &c)
|
||||
{
|
||||
colors.push_back(c);
|
||||
}
|
||||
|
||||
///Sets the number of the existing colors.
|
||||
void resize(int s) { colors.resize(s);}
|
||||
///Returns the number of the existing colors.
|
||||
int size() const { return int(colors.size());}
|
||||
};
|
||||
|
||||
///Returns a visibly distinct \ref Color
|
||||
|
||||
///Returns a \ref Color which is as different from the given parameter
|
||||
///as it is possible.
|
||||
inline Color distantColor(const Color &c)
|
||||
{
|
||||
return Color(c.red()<.5?1:0,c.green()<.5?1:0,c.blue()<.5?1:0);
|
||||
}
|
||||
///Returns black for light colors and white for the dark ones.
|
||||
|
||||
///Returns black for light colors and white for the dark ones.
|
||||
inline Color distantBW(const Color &c){
|
||||
return (.2125*c.red()+.7154*c.green()+.0721*c.blue())<.5 ? WHITE : BLACK;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
} //END OF NAMESPACE LEMON
|
||||
|
||||
#endif // LEMON_COLOR_H
|
||||
77
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concept_check.h
vendored
Normal file
77
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concept_check.h
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
// The contents of this file was inspired by the concept checking
|
||||
// utility of the BOOST library (http://www.boost.org).
|
||||
|
||||
///\file
|
||||
///\brief Basic utilities for concept checking.
|
||||
///
|
||||
|
||||
#ifndef LEMON_CONCEPT_CHECK_H
|
||||
#define LEMON_CONCEPT_CHECK_H
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/*
|
||||
"inline" is used for ignore_unused_variable_warning()
|
||||
and function_requires() to make sure there is no
|
||||
overtarget with g++.
|
||||
*/
|
||||
|
||||
template <class T> inline void ignore_unused_variable_warning(const T&) { }
|
||||
template <class T1, class T2>
|
||||
inline void ignore_unused_variable_warning(const T1&, const T2&) { }
|
||||
template <class T1, class T2, class T3>
|
||||
inline void ignore_unused_variable_warning(const T1&, const T2&,
|
||||
const T3&) { }
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
inline void ignore_unused_variable_warning(const T1&, const T2&,
|
||||
const T3&, const T4&) { }
|
||||
template <class T1, class T2, class T3, class T4, class T5>
|
||||
inline void ignore_unused_variable_warning(const T1&, const T2&,
|
||||
const T3&, const T4&,
|
||||
const T5&) { }
|
||||
template <class T1, class T2, class T3, class T4, class T5, class T6>
|
||||
inline void ignore_unused_variable_warning(const T1&, const T2&,
|
||||
const T3&, const T4&,
|
||||
const T5&, const T6&) { }
|
||||
|
||||
///\e
|
||||
template <class Concept>
|
||||
inline void function_requires()
|
||||
{
|
||||
#if !defined(NDEBUG)
|
||||
void (Concept::*x)() = & Concept::constraints;
|
||||
::lemon::ignore_unused_variable_warning(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
///\e
|
||||
template <typename Concept, typename Type>
|
||||
inline void checkConcept() {
|
||||
#if !defined(NDEBUG)
|
||||
typedef typename Concept::template Constraints<Type> ConceptCheck;
|
||||
void (ConceptCheck::*x)() = & ConceptCheck::constraints;
|
||||
::lemon::ignore_unused_variable_warning(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace lemon
|
||||
|
||||
#endif // LEMON_CONCEPT_CHECK_H
|
||||
1029
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/bpgraph.h
vendored
Normal file
1029
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/bpgraph.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
491
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/digraph.h
vendored
Normal file
491
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/digraph.h
vendored
Normal file
@@ -0,0 +1,491 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_CONCEPTS_DIGRAPH_H
|
||||
#define LEMON_CONCEPTS_DIGRAPH_H
|
||||
|
||||
///\ingroup graph_concepts
|
||||
///\file
|
||||
///\brief The concept of directed graphs.
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
#include <lemon/concept_check.h>
|
||||
#include <lemon/concepts/graph_components.h>
|
||||
|
||||
namespace lemon {
|
||||
namespace concepts {
|
||||
|
||||
/// \ingroup graph_concepts
|
||||
///
|
||||
/// \brief Class describing the concept of directed graphs.
|
||||
///
|
||||
/// This class describes the common interface of all directed
|
||||
/// graphs (digraphs).
|
||||
///
|
||||
/// Like all concept classes, it only provides an interface
|
||||
/// without any sensible implementation. So any general algorithm for
|
||||
/// directed graphs should compile with this class, but it will not
|
||||
/// run properly, of course.
|
||||
/// An actual digraph implementation like \ref ListDigraph or
|
||||
/// \ref SmartDigraph may have additional functionality.
|
||||
///
|
||||
/// \sa Graph
|
||||
class Digraph {
|
||||
private:
|
||||
/// Diraphs are \e not copy constructible. Use DigraphCopy instead.
|
||||
Digraph(const Digraph &) {}
|
||||
/// \brief Assignment of a digraph to another one is \e not allowed.
|
||||
/// Use DigraphCopy instead.
|
||||
void operator=(const Digraph &) {}
|
||||
|
||||
public:
|
||||
/// Default constructor.
|
||||
Digraph() { }
|
||||
|
||||
/// The node type of the digraph
|
||||
|
||||
/// This class identifies a node of the digraph. It also serves
|
||||
/// as a base class of the node iterators,
|
||||
/// thus they convert to this type.
|
||||
class Node {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the object to an undefined value.
|
||||
Node() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
Node(const Node&) { }
|
||||
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the object to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
Node(Invalid) { }
|
||||
/// Equality operator
|
||||
|
||||
/// Equality operator.
|
||||
///
|
||||
/// Two iterators are equal if and only if they point to the
|
||||
/// same object or both are \c INVALID.
|
||||
bool operator==(Node) const { return true; }
|
||||
|
||||
/// Inequality operator
|
||||
|
||||
/// Inequality operator.
|
||||
bool operator!=(Node) const { return true; }
|
||||
|
||||
/// Artificial ordering operator.
|
||||
|
||||
/// Artificial ordering operator.
|
||||
///
|
||||
/// \note This operator only has to define some strict ordering of
|
||||
/// the nodes; this order has nothing to do with the iteration
|
||||
/// ordering of the nodes.
|
||||
bool operator<(Node) const { return false; }
|
||||
};
|
||||
|
||||
/// Iterator class for the nodes.
|
||||
|
||||
/// This iterator goes through each node of the digraph.
|
||||
/// Its usage is quite simple, for example, you can count the number
|
||||
/// of nodes in a digraph \c g of type \c %Digraph like this:
|
||||
///\code
|
||||
/// int count=0;
|
||||
/// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
|
||||
///\endcode
|
||||
class NodeIt : public Node {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the iterator to an undefined value.
|
||||
NodeIt() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
NodeIt(const NodeIt& n) : Node(n) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the iterator to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
NodeIt(Invalid) { }
|
||||
/// Sets the iterator to the first node.
|
||||
|
||||
/// Sets the iterator to the first node of the given digraph.
|
||||
///
|
||||
explicit NodeIt(const Digraph&) { }
|
||||
/// Sets the iterator to the given node.
|
||||
|
||||
/// Sets the iterator to the given node of the given digraph.
|
||||
///
|
||||
NodeIt(const Digraph&, const Node&) { }
|
||||
/// Next node.
|
||||
|
||||
/// Assign the iterator to the next node.
|
||||
///
|
||||
NodeIt& operator++() { return *this; }
|
||||
};
|
||||
|
||||
|
||||
/// The arc type of the digraph
|
||||
|
||||
/// This class identifies an arc of the digraph. It also serves
|
||||
/// as a base class of the arc iterators,
|
||||
/// thus they will convert to this type.
|
||||
class Arc {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the object to an undefined value.
|
||||
Arc() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
Arc(const Arc&) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the object to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
Arc(Invalid) { }
|
||||
/// Equality operator
|
||||
|
||||
/// Equality operator.
|
||||
///
|
||||
/// Two iterators are equal if and only if they point to the
|
||||
/// same object or both are \c INVALID.
|
||||
bool operator==(Arc) const { return true; }
|
||||
/// Inequality operator
|
||||
|
||||
/// Inequality operator.
|
||||
bool operator!=(Arc) const { return true; }
|
||||
|
||||
/// Artificial ordering operator.
|
||||
|
||||
/// Artificial ordering operator.
|
||||
///
|
||||
/// \note This operator only has to define some strict ordering of
|
||||
/// the arcs; this order has nothing to do with the iteration
|
||||
/// ordering of the arcs.
|
||||
bool operator<(Arc) const { return false; }
|
||||
};
|
||||
|
||||
/// Iterator class for the outgoing arcs of a node.
|
||||
|
||||
/// This iterator goes trough the \e outgoing arcs of a certain node
|
||||
/// of a digraph.
|
||||
/// Its usage is quite simple, for example, you can count the number
|
||||
/// of outgoing arcs of a node \c n
|
||||
/// in a digraph \c g of type \c %Digraph as follows.
|
||||
///\code
|
||||
/// int count=0;
|
||||
/// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
|
||||
///\endcode
|
||||
class OutArcIt : public Arc {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the iterator to an undefined value.
|
||||
OutArcIt() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
OutArcIt(const OutArcIt& e) : Arc(e) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the iterator to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
OutArcIt(Invalid) { }
|
||||
/// Sets the iterator to the first outgoing arc.
|
||||
|
||||
/// Sets the iterator to the first outgoing arc of the given node.
|
||||
///
|
||||
OutArcIt(const Digraph&, const Node&) { }
|
||||
/// Sets the iterator to the given arc.
|
||||
|
||||
/// Sets the iterator to the given arc of the given digraph.
|
||||
///
|
||||
OutArcIt(const Digraph&, const Arc&) { }
|
||||
/// Next outgoing arc
|
||||
|
||||
/// Assign the iterator to the next
|
||||
/// outgoing arc of the corresponding node.
|
||||
OutArcIt& operator++() { return *this; }
|
||||
};
|
||||
|
||||
/// Iterator class for the incoming arcs of a node.
|
||||
|
||||
/// This iterator goes trough the \e incoming arcs of a certain node
|
||||
/// of a digraph.
|
||||
/// Its usage is quite simple, for example, you can count the number
|
||||
/// of incoming arcs of a node \c n
|
||||
/// in a digraph \c g of type \c %Digraph as follows.
|
||||
///\code
|
||||
/// int count=0;
|
||||
/// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
|
||||
///\endcode
|
||||
class InArcIt : public Arc {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the iterator to an undefined value.
|
||||
InArcIt() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
InArcIt(const InArcIt& e) : Arc(e) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the iterator to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
InArcIt(Invalid) { }
|
||||
/// Sets the iterator to the first incoming arc.
|
||||
|
||||
/// Sets the iterator to the first incoming arc of the given node.
|
||||
///
|
||||
InArcIt(const Digraph&, const Node&) { }
|
||||
/// Sets the iterator to the given arc.
|
||||
|
||||
/// Sets the iterator to the given arc of the given digraph.
|
||||
///
|
||||
InArcIt(const Digraph&, const Arc&) { }
|
||||
/// Next incoming arc
|
||||
|
||||
/// Assign the iterator to the next
|
||||
/// incoming arc of the corresponding node.
|
||||
InArcIt& operator++() { return *this; }
|
||||
};
|
||||
|
||||
/// Iterator class for the arcs.
|
||||
|
||||
/// This iterator goes through each arc of the digraph.
|
||||
/// Its usage is quite simple, for example, you can count the number
|
||||
/// of arcs in a digraph \c g of type \c %Digraph as follows:
|
||||
///\code
|
||||
/// int count=0;
|
||||
/// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count;
|
||||
///\endcode
|
||||
class ArcIt : public Arc {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the iterator to an undefined value.
|
||||
ArcIt() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
ArcIt(const ArcIt& e) : Arc(e) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the iterator to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
ArcIt(Invalid) { }
|
||||
/// Sets the iterator to the first arc.
|
||||
|
||||
/// Sets the iterator to the first arc of the given digraph.
|
||||
///
|
||||
explicit ArcIt(const Digraph& g) {
|
||||
::lemon::ignore_unused_variable_warning(g);
|
||||
}
|
||||
/// Sets the iterator to the given arc.
|
||||
|
||||
/// Sets the iterator to the given arc of the given digraph.
|
||||
///
|
||||
ArcIt(const Digraph&, const Arc&) { }
|
||||
/// Next arc
|
||||
|
||||
/// Assign the iterator to the next arc.
|
||||
///
|
||||
ArcIt& operator++() { return *this; }
|
||||
};
|
||||
|
||||
/// \brief The source node of the arc.
|
||||
///
|
||||
/// Returns the source node of the given arc.
|
||||
Node source(Arc) const { return INVALID; }
|
||||
|
||||
/// \brief The target node of the arc.
|
||||
///
|
||||
/// Returns the target node of the given arc.
|
||||
Node target(Arc) const { return INVALID; }
|
||||
|
||||
/// \brief The ID of the node.
|
||||
///
|
||||
/// Returns the ID of the given node.
|
||||
int id(Node) const { return -1; }
|
||||
|
||||
/// \brief The ID of the arc.
|
||||
///
|
||||
/// Returns the ID of the given arc.
|
||||
int id(Arc) const { return -1; }
|
||||
|
||||
/// \brief The node with the given ID.
|
||||
///
|
||||
/// Returns the node with the given ID.
|
||||
/// \pre The argument should be a valid node ID in the digraph.
|
||||
Node nodeFromId(int) const { return INVALID; }
|
||||
|
||||
/// \brief The arc with the given ID.
|
||||
///
|
||||
/// Returns the arc with the given ID.
|
||||
/// \pre The argument should be a valid arc ID in the digraph.
|
||||
Arc arcFromId(int) const { return INVALID; }
|
||||
|
||||
/// \brief An upper bound on the node IDs.
|
||||
///
|
||||
/// Returns an upper bound on the node IDs.
|
||||
int maxNodeId() const { return -1; }
|
||||
|
||||
/// \brief An upper bound on the arc IDs.
|
||||
///
|
||||
/// Returns an upper bound on the arc IDs.
|
||||
int maxArcId() const { return -1; }
|
||||
|
||||
void first(Node&) const {}
|
||||
void next(Node&) const {}
|
||||
|
||||
void first(Arc&) const {}
|
||||
void next(Arc&) const {}
|
||||
|
||||
|
||||
void firstIn(Arc&, const Node&) const {}
|
||||
void nextIn(Arc&) const {}
|
||||
|
||||
void firstOut(Arc&, const Node&) const {}
|
||||
void nextOut(Arc&) const {}
|
||||
|
||||
// The second parameter is dummy.
|
||||
Node fromId(int, Node) const { return INVALID; }
|
||||
// The second parameter is dummy.
|
||||
Arc fromId(int, Arc) const { return INVALID; }
|
||||
|
||||
// Dummy parameter.
|
||||
int maxId(Node) const { return -1; }
|
||||
// Dummy parameter.
|
||||
int maxId(Arc) const { return -1; }
|
||||
|
||||
/// \brief The opposite node on the arc.
|
||||
///
|
||||
/// Returns the opposite node on the given arc.
|
||||
Node oppositeNode(Node, Arc) const { return INVALID; }
|
||||
|
||||
/// \brief The base node of the iterator.
|
||||
///
|
||||
/// Returns the base node of the given outgoing arc iterator
|
||||
/// (i.e. the source node of the corresponding arc).
|
||||
Node baseNode(OutArcIt) const { return INVALID; }
|
||||
|
||||
/// \brief The running node of the iterator.
|
||||
///
|
||||
/// Returns the running node of the given outgoing arc iterator
|
||||
/// (i.e. the target node of the corresponding arc).
|
||||
Node runningNode(OutArcIt) const { return INVALID; }
|
||||
|
||||
/// \brief The base node of the iterator.
|
||||
///
|
||||
/// Returns the base node of the given incoming arc iterator
|
||||
/// (i.e. the target node of the corresponding arc).
|
||||
Node baseNode(InArcIt) const { return INVALID; }
|
||||
|
||||
/// \brief The running node of the iterator.
|
||||
///
|
||||
/// Returns the running node of the given incoming arc iterator
|
||||
/// (i.e. the source node of the corresponding arc).
|
||||
Node runningNode(InArcIt) const { return INVALID; }
|
||||
|
||||
/// \brief Standard graph map type for the nodes.
|
||||
///
|
||||
/// Standard graph map type for the nodes.
|
||||
/// It conforms to the ReferenceMap concept.
|
||||
template<class T>
|
||||
class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
explicit NodeMap(const Digraph&) { }
|
||||
/// Constructor with given initial value
|
||||
NodeMap(const Digraph&, T) { }
|
||||
|
||||
private:
|
||||
///Copy constructor
|
||||
NodeMap(const NodeMap& nm) :
|
||||
ReferenceMap<Node, T, T&, const T&>(nm) { }
|
||||
///Assignment operator
|
||||
template <typename CMap>
|
||||
NodeMap& operator=(const CMap&) {
|
||||
checkConcept<ReadMap<Node, T>, CMap>();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Standard graph map type for the arcs.
|
||||
///
|
||||
/// Standard graph map type for the arcs.
|
||||
/// It conforms to the ReferenceMap concept.
|
||||
template<class T>
|
||||
class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
explicit ArcMap(const Digraph&) { }
|
||||
/// Constructor with given initial value
|
||||
ArcMap(const Digraph&, T) { }
|
||||
|
||||
private:
|
||||
///Copy constructor
|
||||
ArcMap(const ArcMap& em) :
|
||||
ReferenceMap<Arc, T, T&, const T&>(em) { }
|
||||
///Assignment operator
|
||||
template <typename CMap>
|
||||
ArcMap& operator=(const CMap&) {
|
||||
checkConcept<ReadMap<Arc, T>, CMap>();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename _Digraph>
|
||||
struct Constraints {
|
||||
void constraints() {
|
||||
checkConcept<BaseDigraphComponent, _Digraph>();
|
||||
checkConcept<IterableDigraphComponent<>, _Digraph>();
|
||||
checkConcept<IDableDigraphComponent<>, _Digraph>();
|
||||
checkConcept<MappableDigraphComponent<>, _Digraph>();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
} //namespace concepts
|
||||
} //namespace lemon
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
788
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/graph.h
vendored
Normal file
788
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/graph.h
vendored
Normal file
@@ -0,0 +1,788 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
///\ingroup graph_concepts
|
||||
///\file
|
||||
///\brief The concept of undirected graphs.
|
||||
|
||||
#ifndef LEMON_CONCEPTS_GRAPH_H
|
||||
#define LEMON_CONCEPTS_GRAPH_H
|
||||
|
||||
#include <lemon/concepts/graph_components.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
#include <lemon/concept_check.h>
|
||||
#include <lemon/core.h>
|
||||
|
||||
namespace lemon {
|
||||
namespace concepts {
|
||||
|
||||
/// \ingroup graph_concepts
|
||||
///
|
||||
/// \brief Class describing the concept of undirected graphs.
|
||||
///
|
||||
/// This class describes the common interface of all undirected
|
||||
/// graphs.
|
||||
///
|
||||
/// Like all concept classes, it only provides an interface
|
||||
/// without any sensible implementation. So any general algorithm for
|
||||
/// undirected graphs should compile with this class, but it will not
|
||||
/// run properly, of course.
|
||||
/// An actual graph implementation like \ref ListGraph or
|
||||
/// \ref SmartGraph may have additional functionality.
|
||||
///
|
||||
/// The undirected graphs also fulfill the concept of \ref Digraph
|
||||
/// "directed graphs", since each edge can also be regarded as two
|
||||
/// oppositely directed arcs.
|
||||
/// Undirected graphs provide an Edge type for the undirected edges and
|
||||
/// an Arc type for the directed arcs. The Arc type is convertible to
|
||||
/// Edge or inherited from it, i.e. the corresponding edge can be
|
||||
/// obtained from an arc.
|
||||
/// EdgeIt and EdgeMap classes can be used for the edges, while ArcIt
|
||||
/// and ArcMap classes can be used for the arcs (just like in digraphs).
|
||||
/// Both InArcIt and OutArcIt iterates on the same edges but with
|
||||
/// opposite direction. IncEdgeIt also iterates on the same edges
|
||||
/// as OutArcIt and InArcIt, but it is not convertible to Arc,
|
||||
/// only to Edge.
|
||||
///
|
||||
/// In LEMON, each undirected edge has an inherent orientation.
|
||||
/// Thus it can defined if an arc is forward or backward oriented in
|
||||
/// an undirected graph with respect to this default oriantation of
|
||||
/// the represented edge.
|
||||
/// With the direction() and direct() functions the direction
|
||||
/// of an arc can be obtained and set, respectively.
|
||||
///
|
||||
/// Only nodes and edges can be added to or removed from an undirected
|
||||
/// graph and the corresponding arcs are added or removed automatically.
|
||||
///
|
||||
/// \sa Digraph
|
||||
class Graph {
|
||||
private:
|
||||
/// Graphs are \e not copy constructible. Use GraphCopy instead.
|
||||
Graph(const Graph&) {}
|
||||
/// \brief Assignment of a graph to another one is \e not allowed.
|
||||
/// Use GraphCopy instead.
|
||||
void operator=(const Graph&) {}
|
||||
|
||||
public:
|
||||
/// Default constructor.
|
||||
Graph() {}
|
||||
|
||||
/// \brief Undirected graphs should be tagged with \c UndirectedTag.
|
||||
///
|
||||
/// Undirected graphs should be tagged with \c UndirectedTag.
|
||||
///
|
||||
/// This tag helps the \c enable_if technics to make compile time
|
||||
/// specializations for undirected graphs.
|
||||
typedef True UndirectedTag;
|
||||
|
||||
/// The node type of the graph
|
||||
|
||||
/// This class identifies a node of the graph. It also serves
|
||||
/// as a base class of the node iterators,
|
||||
/// thus they convert to this type.
|
||||
class Node {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the object to an undefined value.
|
||||
Node() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
Node(const Node&) { }
|
||||
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the object to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
Node(Invalid) { }
|
||||
/// Equality operator
|
||||
|
||||
/// Equality operator.
|
||||
///
|
||||
/// Two iterators are equal if and only if they point to the
|
||||
/// same object or both are \c INVALID.
|
||||
bool operator==(Node) const { return true; }
|
||||
|
||||
/// Inequality operator
|
||||
|
||||
/// Inequality operator.
|
||||
bool operator!=(Node) const { return true; }
|
||||
|
||||
/// Artificial ordering operator.
|
||||
|
||||
/// Artificial ordering operator.
|
||||
///
|
||||
/// \note This operator only has to define some strict ordering of
|
||||
/// the items; this order has nothing to do with the iteration
|
||||
/// ordering of the items.
|
||||
bool operator<(Node) const { return false; }
|
||||
|
||||
};
|
||||
|
||||
/// Iterator class for the nodes.
|
||||
|
||||
/// This iterator goes through each node of the graph.
|
||||
/// Its usage is quite simple, for example, you can count the number
|
||||
/// of nodes in a graph \c g of type \c %Graph like this:
|
||||
///\code
|
||||
/// int count=0;
|
||||
/// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
|
||||
///\endcode
|
||||
class NodeIt : public Node {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the iterator to an undefined value.
|
||||
NodeIt() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
NodeIt(const NodeIt& n) : Node(n) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the iterator to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
NodeIt(Invalid) { }
|
||||
/// Sets the iterator to the first node.
|
||||
|
||||
/// Sets the iterator to the first node of the given digraph.
|
||||
///
|
||||
explicit NodeIt(const Graph&) { }
|
||||
/// Sets the iterator to the given node.
|
||||
|
||||
/// Sets the iterator to the given node of the given digraph.
|
||||
///
|
||||
NodeIt(const Graph&, const Node&) { }
|
||||
/// Next node.
|
||||
|
||||
/// Assign the iterator to the next node.
|
||||
///
|
||||
NodeIt& operator++() { return *this; }
|
||||
};
|
||||
|
||||
|
||||
/// The edge type of the graph
|
||||
|
||||
/// This class identifies an edge of the graph. It also serves
|
||||
/// as a base class of the edge iterators,
|
||||
/// thus they will convert to this type.
|
||||
class Edge {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the object to an undefined value.
|
||||
Edge() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
Edge(const Edge&) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the object to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
Edge(Invalid) { }
|
||||
/// Equality operator
|
||||
|
||||
/// Equality operator.
|
||||
///
|
||||
/// Two iterators are equal if and only if they point to the
|
||||
/// same object or both are \c INVALID.
|
||||
bool operator==(Edge) const { return true; }
|
||||
/// Inequality operator
|
||||
|
||||
/// Inequality operator.
|
||||
bool operator!=(Edge) const { return true; }
|
||||
|
||||
/// Artificial ordering operator.
|
||||
|
||||
/// Artificial ordering operator.
|
||||
///
|
||||
/// \note This operator only has to define some strict ordering of
|
||||
/// the edges; this order has nothing to do with the iteration
|
||||
/// ordering of the edges.
|
||||
bool operator<(Edge) const { return false; }
|
||||
};
|
||||
|
||||
/// Iterator class for the edges.
|
||||
|
||||
/// This iterator goes through each edge of the graph.
|
||||
/// Its usage is quite simple, for example, you can count the number
|
||||
/// of edges in a graph \c g of type \c %Graph as follows:
|
||||
///\code
|
||||
/// int count=0;
|
||||
/// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
|
||||
///\endcode
|
||||
class EdgeIt : public Edge {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the iterator to an undefined value.
|
||||
EdgeIt() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
EdgeIt(const EdgeIt& e) : Edge(e) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the iterator to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
EdgeIt(Invalid) { }
|
||||
/// Sets the iterator to the first edge.
|
||||
|
||||
/// Sets the iterator to the first edge of the given graph.
|
||||
///
|
||||
explicit EdgeIt(const Graph&) { }
|
||||
/// Sets the iterator to the given edge.
|
||||
|
||||
/// Sets the iterator to the given edge of the given graph.
|
||||
///
|
||||
EdgeIt(const Graph&, const Edge&) { }
|
||||
/// Next edge
|
||||
|
||||
/// Assign the iterator to the next edge.
|
||||
///
|
||||
EdgeIt& operator++() { return *this; }
|
||||
};
|
||||
|
||||
/// Iterator class for the incident edges of a node.
|
||||
|
||||
/// This iterator goes trough the incident undirected edges
|
||||
/// of a certain node of a graph.
|
||||
/// Its usage is quite simple, for example, you can compute the
|
||||
/// degree (i.e. the number of incident edges) of a node \c n
|
||||
/// in a graph \c g of type \c %Graph as follows.
|
||||
///
|
||||
///\code
|
||||
/// int count=0;
|
||||
/// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
|
||||
///\endcode
|
||||
///
|
||||
/// \warning Loop edges will be iterated twice.
|
||||
class IncEdgeIt : public Edge {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the iterator to an undefined value.
|
||||
IncEdgeIt() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the iterator to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
IncEdgeIt(Invalid) { }
|
||||
/// Sets the iterator to the first incident edge.
|
||||
|
||||
/// Sets the iterator to the first incident edge of the given node.
|
||||
///
|
||||
IncEdgeIt(const Graph&, const Node&) { }
|
||||
/// Sets the iterator to the given edge.
|
||||
|
||||
/// Sets the iterator to the given edge of the given graph.
|
||||
///
|
||||
IncEdgeIt(const Graph&, const Edge&) { }
|
||||
/// Next incident edge
|
||||
|
||||
/// Assign the iterator to the next incident edge
|
||||
/// of the corresponding node.
|
||||
IncEdgeIt& operator++() { return *this; }
|
||||
};
|
||||
|
||||
/// The arc type of the graph
|
||||
|
||||
/// This class identifies a directed arc of the graph. It also serves
|
||||
/// as a base class of the arc iterators,
|
||||
/// thus they will convert to this type.
|
||||
class Arc {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the object to an undefined value.
|
||||
Arc() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
Arc(const Arc&) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the object to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
Arc(Invalid) { }
|
||||
/// Equality operator
|
||||
|
||||
/// Equality operator.
|
||||
///
|
||||
/// Two iterators are equal if and only if they point to the
|
||||
/// same object or both are \c INVALID.
|
||||
bool operator==(Arc) const { return true; }
|
||||
/// Inequality operator
|
||||
|
||||
/// Inequality operator.
|
||||
bool operator!=(Arc) const { return true; }
|
||||
|
||||
/// Artificial ordering operator.
|
||||
|
||||
/// Artificial ordering operator.
|
||||
///
|
||||
/// \note This operator only has to define some strict ordering of
|
||||
/// the arcs; this order has nothing to do with the iteration
|
||||
/// ordering of the arcs.
|
||||
bool operator<(Arc) const { return false; }
|
||||
|
||||
/// Converison to \c Edge
|
||||
|
||||
/// Converison to \c Edge.
|
||||
///
|
||||
operator Edge() const { return Edge(); }
|
||||
};
|
||||
|
||||
/// Iterator class for the arcs.
|
||||
|
||||
/// This iterator goes through each directed arc of the graph.
|
||||
/// Its usage is quite simple, for example, you can count the number
|
||||
/// of arcs in a graph \c g of type \c %Graph as follows:
|
||||
///\code
|
||||
/// int count=0;
|
||||
/// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
|
||||
///\endcode
|
||||
class ArcIt : public Arc {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the iterator to an undefined value.
|
||||
ArcIt() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
ArcIt(const ArcIt& e) : Arc(e) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the iterator to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
ArcIt(Invalid) { }
|
||||
/// Sets the iterator to the first arc.
|
||||
|
||||
/// Sets the iterator to the first arc of the given graph.
|
||||
///
|
||||
explicit ArcIt(const Graph &g) {
|
||||
::lemon::ignore_unused_variable_warning(g);
|
||||
}
|
||||
/// Sets the iterator to the given arc.
|
||||
|
||||
/// Sets the iterator to the given arc of the given graph.
|
||||
///
|
||||
ArcIt(const Graph&, const Arc&) { }
|
||||
/// Next arc
|
||||
|
||||
/// Assign the iterator to the next arc.
|
||||
///
|
||||
ArcIt& operator++() { return *this; }
|
||||
};
|
||||
|
||||
/// Iterator class for the outgoing arcs of a node.
|
||||
|
||||
/// This iterator goes trough the \e outgoing directed arcs of a
|
||||
/// certain node of a graph.
|
||||
/// Its usage is quite simple, for example, you can count the number
|
||||
/// of outgoing arcs of a node \c n
|
||||
/// in a graph \c g of type \c %Graph as follows.
|
||||
///\code
|
||||
/// int count=0;
|
||||
/// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
|
||||
///\endcode
|
||||
class OutArcIt : public Arc {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the iterator to an undefined value.
|
||||
OutArcIt() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
OutArcIt(const OutArcIt& e) : Arc(e) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the iterator to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
OutArcIt(Invalid) { }
|
||||
/// Sets the iterator to the first outgoing arc.
|
||||
|
||||
/// Sets the iterator to the first outgoing arc of the given node.
|
||||
///
|
||||
OutArcIt(const Graph& n, const Node& g) {
|
||||
::lemon::ignore_unused_variable_warning(n);
|
||||
::lemon::ignore_unused_variable_warning(g);
|
||||
}
|
||||
/// Sets the iterator to the given arc.
|
||||
|
||||
/// Sets the iterator to the given arc of the given graph.
|
||||
///
|
||||
OutArcIt(const Graph&, const Arc&) { }
|
||||
/// Next outgoing arc
|
||||
|
||||
/// Assign the iterator to the next
|
||||
/// outgoing arc of the corresponding node.
|
||||
OutArcIt& operator++() { return *this; }
|
||||
};
|
||||
|
||||
/// Iterator class for the incoming arcs of a node.
|
||||
|
||||
/// This iterator goes trough the \e incoming directed arcs of a
|
||||
/// certain node of a graph.
|
||||
/// Its usage is quite simple, for example, you can count the number
|
||||
/// of incoming arcs of a node \c n
|
||||
/// in a graph \c g of type \c %Graph as follows.
|
||||
///\code
|
||||
/// int count=0;
|
||||
/// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
|
||||
///\endcode
|
||||
class InArcIt : public Arc {
|
||||
public:
|
||||
/// Default constructor
|
||||
|
||||
/// Default constructor.
|
||||
/// \warning It sets the iterator to an undefined value.
|
||||
InArcIt() { }
|
||||
/// Copy constructor.
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
InArcIt(const InArcIt& e) : Arc(e) { }
|
||||
/// %Invalid constructor \& conversion.
|
||||
|
||||
/// Initializes the iterator to be invalid.
|
||||
/// \sa Invalid for more details.
|
||||
InArcIt(Invalid) { }
|
||||
/// Sets the iterator to the first incoming arc.
|
||||
|
||||
/// Sets the iterator to the first incoming arc of the given node.
|
||||
///
|
||||
InArcIt(const Graph& g, const Node& n) {
|
||||
::lemon::ignore_unused_variable_warning(n);
|
||||
::lemon::ignore_unused_variable_warning(g);
|
||||
}
|
||||
/// Sets the iterator to the given arc.
|
||||
|
||||
/// Sets the iterator to the given arc of the given graph.
|
||||
///
|
||||
InArcIt(const Graph&, const Arc&) { }
|
||||
/// Next incoming arc
|
||||
|
||||
/// Assign the iterator to the next
|
||||
/// incoming arc of the corresponding node.
|
||||
InArcIt& operator++() { return *this; }
|
||||
};
|
||||
|
||||
/// \brief Standard graph map type for the nodes.
|
||||
///
|
||||
/// Standard graph map type for the nodes.
|
||||
/// It conforms to the ReferenceMap concept.
|
||||
template<class T>
|
||||
class NodeMap : public ReferenceMap<Node, T, T&, const T&>
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
explicit NodeMap(const Graph&) { }
|
||||
/// Constructor with given initial value
|
||||
NodeMap(const Graph&, T) { }
|
||||
|
||||
private:
|
||||
///Copy constructor
|
||||
NodeMap(const NodeMap& nm) :
|
||||
ReferenceMap<Node, T, T&, const T&>(nm) { }
|
||||
///Assignment operator
|
||||
template <typename CMap>
|
||||
NodeMap& operator=(const CMap&) {
|
||||
checkConcept<ReadMap<Node, T>, CMap>();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Standard graph map type for the arcs.
|
||||
///
|
||||
/// Standard graph map type for the arcs.
|
||||
/// It conforms to the ReferenceMap concept.
|
||||
template<class T>
|
||||
class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
explicit ArcMap(const Graph&) { }
|
||||
/// Constructor with given initial value
|
||||
ArcMap(const Graph&, T) { }
|
||||
|
||||
private:
|
||||
///Copy constructor
|
||||
ArcMap(const ArcMap& em) :
|
||||
ReferenceMap<Arc, T, T&, const T&>(em) { }
|
||||
///Assignment operator
|
||||
template <typename CMap>
|
||||
ArcMap& operator=(const CMap&) {
|
||||
checkConcept<ReadMap<Arc, T>, CMap>();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Standard graph map type for the edges.
|
||||
///
|
||||
/// Standard graph map type for the edges.
|
||||
/// It conforms to the ReferenceMap concept.
|
||||
template<class T>
|
||||
class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
explicit EdgeMap(const Graph&) { }
|
||||
/// Constructor with given initial value
|
||||
EdgeMap(const Graph&, T) { }
|
||||
|
||||
private:
|
||||
///Copy constructor
|
||||
EdgeMap(const EdgeMap& em) :
|
||||
ReferenceMap<Edge, T, T&, const T&>(em) {}
|
||||
///Assignment operator
|
||||
template <typename CMap>
|
||||
EdgeMap& operator=(const CMap&) {
|
||||
checkConcept<ReadMap<Edge, T>, CMap>();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief The first node of the edge.
|
||||
///
|
||||
/// Returns the first node of the given edge.
|
||||
///
|
||||
/// Edges don't have source and target nodes, however, methods
|
||||
/// u() and v() are used to query the two end-nodes of an edge.
|
||||
/// The orientation of an edge that arises this way is called
|
||||
/// the inherent direction, it is used to define the default
|
||||
/// direction for the corresponding arcs.
|
||||
/// \sa v()
|
||||
/// \sa direction()
|
||||
Node u(Edge) const { return INVALID; }
|
||||
|
||||
/// \brief The second node of the edge.
|
||||
///
|
||||
/// Returns the second node of the given edge.
|
||||
///
|
||||
/// Edges don't have source and target nodes, however, methods
|
||||
/// u() and v() are used to query the two end-nodes of an edge.
|
||||
/// The orientation of an edge that arises this way is called
|
||||
/// the inherent direction, it is used to define the default
|
||||
/// direction for the corresponding arcs.
|
||||
/// \sa u()
|
||||
/// \sa direction()
|
||||
Node v(Edge) const { return INVALID; }
|
||||
|
||||
/// \brief The source node of the arc.
|
||||
///
|
||||
/// Returns the source node of the given arc.
|
||||
Node source(Arc) const { return INVALID; }
|
||||
|
||||
/// \brief The target node of the arc.
|
||||
///
|
||||
/// Returns the target node of the given arc.
|
||||
Node target(Arc) const { return INVALID; }
|
||||
|
||||
/// \brief The ID of the node.
|
||||
///
|
||||
/// Returns the ID of the given node.
|
||||
int id(Node) const { return -1; }
|
||||
|
||||
/// \brief The ID of the edge.
|
||||
///
|
||||
/// Returns the ID of the given edge.
|
||||
int id(Edge) const { return -1; }
|
||||
|
||||
/// \brief The ID of the arc.
|
||||
///
|
||||
/// Returns the ID of the given arc.
|
||||
int id(Arc) const { return -1; }
|
||||
|
||||
/// \brief The node with the given ID.
|
||||
///
|
||||
/// Returns the node with the given ID.
|
||||
/// \pre The argument should be a valid node ID in the graph.
|
||||
Node nodeFromId(int) const { return INVALID; }
|
||||
|
||||
/// \brief The edge with the given ID.
|
||||
///
|
||||
/// Returns the edge with the given ID.
|
||||
/// \pre The argument should be a valid edge ID in the graph.
|
||||
Edge edgeFromId(int) const { return INVALID; }
|
||||
|
||||
/// \brief The arc with the given ID.
|
||||
///
|
||||
/// Returns the arc with the given ID.
|
||||
/// \pre The argument should be a valid arc ID in the graph.
|
||||
Arc arcFromId(int) const { return INVALID; }
|
||||
|
||||
/// \brief An upper bound on the node IDs.
|
||||
///
|
||||
/// Returns an upper bound on the node IDs.
|
||||
int maxNodeId() const { return -1; }
|
||||
|
||||
/// \brief An upper bound on the edge IDs.
|
||||
///
|
||||
/// Returns an upper bound on the edge IDs.
|
||||
int maxEdgeId() const { return -1; }
|
||||
|
||||
/// \brief An upper bound on the arc IDs.
|
||||
///
|
||||
/// Returns an upper bound on the arc IDs.
|
||||
int maxArcId() const { return -1; }
|
||||
|
||||
/// \brief The direction of the arc.
|
||||
///
|
||||
/// Returns \c true if the direction of the given arc is the same as
|
||||
/// the inherent orientation of the represented edge.
|
||||
bool direction(Arc) const { return true; }
|
||||
|
||||
/// \brief Direct the edge.
|
||||
///
|
||||
/// Direct the given edge. The returned arc
|
||||
/// represents the given edge and its direction comes
|
||||
/// from the bool parameter. If it is \c true, then the direction
|
||||
/// of the arc is the same as the inherent orientation of the edge.
|
||||
Arc direct(Edge, bool) const {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
/// \brief Direct the edge.
|
||||
///
|
||||
/// Direct the given edge. The returned arc represents the given
|
||||
/// edge and its source node is the given node.
|
||||
Arc direct(Edge, Node) const {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
/// \brief The oppositely directed arc.
|
||||
///
|
||||
/// Returns the oppositely directed arc representing the same edge.
|
||||
Arc oppositeArc(Arc) const { return INVALID; }
|
||||
|
||||
/// \brief The opposite node on the edge.
|
||||
///
|
||||
/// Returns the opposite node on the given edge.
|
||||
Node oppositeNode(Node, Edge) const { return INVALID; }
|
||||
|
||||
void first(Node&) const {}
|
||||
void next(Node&) const {}
|
||||
|
||||
void first(Edge&) const {}
|
||||
void next(Edge&) const {}
|
||||
|
||||
void first(Arc&) const {}
|
||||
void next(Arc&) const {}
|
||||
|
||||
void firstOut(Arc&, Node) const {}
|
||||
void nextOut(Arc&) const {}
|
||||
|
||||
void firstIn(Arc&, Node) const {}
|
||||
void nextIn(Arc&) const {}
|
||||
|
||||
void firstInc(Edge &, bool &, const Node &) const {}
|
||||
void nextInc(Edge &, bool &) const {}
|
||||
|
||||
// The second parameter is dummy.
|
||||
Node fromId(int, Node) const { return INVALID; }
|
||||
// The second parameter is dummy.
|
||||
Edge fromId(int, Edge) const { return INVALID; }
|
||||
// The second parameter is dummy.
|
||||
Arc fromId(int, Arc) const { return INVALID; }
|
||||
|
||||
// Dummy parameter.
|
||||
int maxId(Node) const { return -1; }
|
||||
// Dummy parameter.
|
||||
int maxId(Edge) const { return -1; }
|
||||
// Dummy parameter.
|
||||
int maxId(Arc) const { return -1; }
|
||||
|
||||
/// \brief The base node of the iterator.
|
||||
///
|
||||
/// Returns the base node of the given incident edge iterator.
|
||||
Node baseNode(IncEdgeIt) const { return INVALID; }
|
||||
|
||||
/// \brief The running node of the iterator.
|
||||
///
|
||||
/// Returns the running node of the given incident edge iterator.
|
||||
Node runningNode(IncEdgeIt) const { return INVALID; }
|
||||
|
||||
/// \brief The base node of the iterator.
|
||||
///
|
||||
/// Returns the base node of the given outgoing arc iterator
|
||||
/// (i.e. the source node of the corresponding arc).
|
||||
Node baseNode(OutArcIt) const { return INVALID; }
|
||||
|
||||
/// \brief The running node of the iterator.
|
||||
///
|
||||
/// Returns the running node of the given outgoing arc iterator
|
||||
/// (i.e. the target node of the corresponding arc).
|
||||
Node runningNode(OutArcIt) const { return INVALID; }
|
||||
|
||||
/// \brief The base node of the iterator.
|
||||
///
|
||||
/// Returns the base node of the given incoming arc iterator
|
||||
/// (i.e. the target node of the corresponding arc).
|
||||
Node baseNode(InArcIt) const { return INVALID; }
|
||||
|
||||
/// \brief The running node of the iterator.
|
||||
///
|
||||
/// Returns the running node of the given incoming arc iterator
|
||||
/// (i.e. the source node of the corresponding arc).
|
||||
Node runningNode(InArcIt) const { return INVALID; }
|
||||
|
||||
template <typename _Graph>
|
||||
struct Constraints {
|
||||
void constraints() {
|
||||
checkConcept<BaseGraphComponent, _Graph>();
|
||||
checkConcept<IterableGraphComponent<>, _Graph>();
|
||||
checkConcept<IDableGraphComponent<>, _Graph>();
|
||||
checkConcept<MappableGraphComponent<>, _Graph>();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
2134
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/graph_components.h
vendored
Normal file
2134
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/graph_components.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
324
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/heap.h
vendored
Normal file
324
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/heap.h
vendored
Normal file
@@ -0,0 +1,324 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_CONCEPTS_HEAP_H
|
||||
#define LEMON_CONCEPTS_HEAP_H
|
||||
|
||||
///\ingroup concept
|
||||
///\file
|
||||
///\brief The concept of heaps.
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/concept_check.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
namespace concepts {
|
||||
|
||||
/// \addtogroup concept
|
||||
/// @{
|
||||
|
||||
/// \brief The heap concept.
|
||||
///
|
||||
/// This concept class describes the main interface of heaps.
|
||||
/// The various \ref heaps "heap structures" are efficient
|
||||
/// implementations of the abstract data type \e priority \e queue.
|
||||
/// They store items with specified values called \e priorities
|
||||
/// in such a way that finding and removing the item with minimum
|
||||
/// priority are efficient. The basic operations are adding and
|
||||
/// erasing items, changing the priority of an item, etc.
|
||||
///
|
||||
/// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
|
||||
/// Any class that conforms to this concept can be used easily in such
|
||||
/// algorithms.
|
||||
///
|
||||
/// \tparam PR Type of the priorities of the items.
|
||||
/// \tparam IM A read-writable item map with \c int values, used
|
||||
/// internally to handle the cross references.
|
||||
/// \tparam CMP A functor class for comparing the priorities.
|
||||
/// The default is \c std::less<PR>.
|
||||
#ifdef DOXYGEN
|
||||
template <typename PR, typename IM, typename CMP>
|
||||
#else
|
||||
template <typename PR, typename IM, typename CMP = std::less<PR> >
|
||||
#endif
|
||||
class Heap {
|
||||
public:
|
||||
|
||||
/// Type of the item-int map.
|
||||
typedef IM ItemIntMap;
|
||||
/// Type of the priorities.
|
||||
typedef PR Prio;
|
||||
/// Type of the items stored in the heap.
|
||||
typedef typename ItemIntMap::Key Item;
|
||||
|
||||
/// \brief Type to represent the states of the items.
|
||||
///
|
||||
/// Each item has a state associated to it. It can be "in heap",
|
||||
/// "pre-heap" or "post-heap". The latter two are indifferent from the
|
||||
/// heap's point of view, but may be useful to the user.
|
||||
///
|
||||
/// The item-int map must be initialized in such way that it assigns
|
||||
/// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
|
||||
enum State {
|
||||
IN_HEAP = 0, ///< = 0. The "in heap" state constant.
|
||||
PRE_HEAP = -1, ///< = -1. The "pre-heap" state constant.
|
||||
POST_HEAP = -2 ///< = -2. The "post-heap" state constant.
|
||||
};
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to keys of type
|
||||
/// \c Item. It is used internally by the heap implementations to
|
||||
/// handle the cross references. The assigned value must be
|
||||
/// \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
#ifdef DOXYGEN
|
||||
explicit Heap(ItemIntMap &map) {}
|
||||
#else
|
||||
explicit Heap(ItemIntMap&) {}
|
||||
#endif
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to keys of type
|
||||
/// \c Item. It is used internally by the heap implementations to
|
||||
/// handle the cross references. The assigned value must be
|
||||
/// \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
/// \param comp The function object used for comparing the priorities.
|
||||
#ifdef DOXYGEN
|
||||
explicit Heap(ItemIntMap &map, const CMP &comp) {}
|
||||
#else
|
||||
explicit Heap(ItemIntMap&, const CMP&) {}
|
||||
#endif
|
||||
|
||||
/// \brief The number of items stored in the heap.
|
||||
///
|
||||
/// This function returns the number of items stored in the heap.
|
||||
int size() const { return 0; }
|
||||
|
||||
/// \brief Check if the heap is empty.
|
||||
///
|
||||
/// This function returns \c true if the heap is empty.
|
||||
bool empty() const { return false; }
|
||||
|
||||
/// \brief Make the heap empty.
|
||||
///
|
||||
/// This functon makes the heap empty.
|
||||
/// It does not change the cross reference map. If you want to reuse
|
||||
/// a heap that is not surely empty, you should first clear it and
|
||||
/// then you should set the cross reference map to \c PRE_HEAP
|
||||
/// for each item.
|
||||
void clear() {}
|
||||
|
||||
/// \brief Insert an item into the heap with the given priority.
|
||||
///
|
||||
/// This function inserts the given item into the heap with the
|
||||
/// given priority.
|
||||
/// \param i The item to insert.
|
||||
/// \param p The priority of the item.
|
||||
/// \pre \e i must not be stored in the heap.
|
||||
#ifdef DOXYGEN
|
||||
void push(const Item &i, const Prio &p) {}
|
||||
#else
|
||||
void push(const Item&, const Prio&) {}
|
||||
#endif
|
||||
|
||||
/// \brief Return the item having minimum priority.
|
||||
///
|
||||
/// This function returns the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Item top() const { return Item(); }
|
||||
|
||||
/// \brief The minimum priority.
|
||||
///
|
||||
/// This function returns the minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Prio prio() const { return Prio(); }
|
||||
|
||||
/// \brief Remove the item having minimum priority.
|
||||
///
|
||||
/// This function removes the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
void pop() {}
|
||||
|
||||
/// \brief Remove the given item from the heap.
|
||||
///
|
||||
/// This function removes the given item from the heap if it is
|
||||
/// already stored.
|
||||
/// \param i The item to delete.
|
||||
/// \pre \e i must be in the heap.
|
||||
#ifdef DOXYGEN
|
||||
void erase(const Item &i) {}
|
||||
#else
|
||||
void erase(const Item&) {}
|
||||
#endif
|
||||
|
||||
/// \brief The priority of the given item.
|
||||
///
|
||||
/// This function returns the priority of the given item.
|
||||
/// \param i The item.
|
||||
/// \pre \e i must be in the heap.
|
||||
#ifdef DOXYGEN
|
||||
Prio operator[](const Item &i) const {}
|
||||
#else
|
||||
Prio operator[](const Item&) const { return Prio(); }
|
||||
#endif
|
||||
|
||||
/// \brief Set the priority of an item or insert it, if it is
|
||||
/// not stored in the heap.
|
||||
///
|
||||
/// This method sets the priority of the given item if it is
|
||||
/// already stored in the heap. Otherwise it inserts the given
|
||||
/// item into the heap with the given priority.
|
||||
///
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
#ifdef DOXYGEN
|
||||
void set(const Item &i, const Prio &p) {}
|
||||
#else
|
||||
void set(const Item&, const Prio&) {}
|
||||
#endif
|
||||
|
||||
/// \brief Decrease the priority of an item to the given value.
|
||||
///
|
||||
/// This function decreases the priority of an item to the given value.
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
/// \pre \e i must be stored in the heap with priority at least \e p.
|
||||
#ifdef DOXYGEN
|
||||
void decrease(const Item &i, const Prio &p) {}
|
||||
#else
|
||||
void decrease(const Item&, const Prio&) {}
|
||||
#endif
|
||||
|
||||
/// \brief Increase the priority of an item to the given value.
|
||||
///
|
||||
/// This function increases the priority of an item to the given value.
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
/// \pre \e i must be stored in the heap with priority at most \e p.
|
||||
#ifdef DOXYGEN
|
||||
void increase(const Item &i, const Prio &p) {}
|
||||
#else
|
||||
void increase(const Item&, const Prio&) {}
|
||||
#endif
|
||||
|
||||
/// \brief Return the state of an item.
|
||||
///
|
||||
/// This method returns \c PRE_HEAP if the given item has never
|
||||
/// been in the heap, \c IN_HEAP if it is in the heap at the moment,
|
||||
/// and \c POST_HEAP otherwise.
|
||||
/// In the latter case it is possible that the item will get back
|
||||
/// to the heap again.
|
||||
/// \param i The item.
|
||||
#ifdef DOXYGEN
|
||||
State state(const Item &i) const {}
|
||||
#else
|
||||
State state(const Item&) const { return PRE_HEAP; }
|
||||
#endif
|
||||
|
||||
/// \brief Set the state of an item in the heap.
|
||||
///
|
||||
/// This function sets the state of the given item in the heap.
|
||||
/// It can be used to manually clear the heap when it is important
|
||||
/// to achive better time complexity.
|
||||
/// \param i The item.
|
||||
/// \param st The state. It should not be \c IN_HEAP.
|
||||
#ifdef DOXYGEN
|
||||
void state(const Item& i, State st) {}
|
||||
#else
|
||||
void state(const Item&, State) {}
|
||||
#endif
|
||||
|
||||
|
||||
template <typename _Heap>
|
||||
struct Constraints {
|
||||
public:
|
||||
void constraints() {
|
||||
typedef typename _Heap::Item OwnItem;
|
||||
typedef typename _Heap::Prio OwnPrio;
|
||||
typedef typename _Heap::State OwnState;
|
||||
|
||||
Item item;
|
||||
Prio prio;
|
||||
item=Item();
|
||||
prio=Prio();
|
||||
::lemon::ignore_unused_variable_warning(item);
|
||||
::lemon::ignore_unused_variable_warning(prio);
|
||||
|
||||
OwnItem own_item;
|
||||
OwnPrio own_prio;
|
||||
OwnState own_state;
|
||||
own_item=Item();
|
||||
own_prio=Prio();
|
||||
::lemon::ignore_unused_variable_warning(own_item);
|
||||
::lemon::ignore_unused_variable_warning(own_prio);
|
||||
::lemon::ignore_unused_variable_warning(own_state);
|
||||
|
||||
_Heap heap1(map);
|
||||
_Heap heap2 = heap1;
|
||||
::lemon::ignore_unused_variable_warning(heap1);
|
||||
::lemon::ignore_unused_variable_warning(heap2);
|
||||
|
||||
int s = heap.size();
|
||||
::lemon::ignore_unused_variable_warning(s);
|
||||
bool e = heap.empty();
|
||||
::lemon::ignore_unused_variable_warning(e);
|
||||
|
||||
prio = heap.prio();
|
||||
item = heap.top();
|
||||
prio = heap[item];
|
||||
own_prio = heap.prio();
|
||||
own_item = heap.top();
|
||||
own_prio = heap[own_item];
|
||||
|
||||
heap.push(item, prio);
|
||||
heap.push(own_item, own_prio);
|
||||
heap.pop();
|
||||
|
||||
heap.set(item, prio);
|
||||
heap.decrease(item, prio);
|
||||
heap.increase(item, prio);
|
||||
heap.set(own_item, own_prio);
|
||||
heap.decrease(own_item, own_prio);
|
||||
heap.increase(own_item, own_prio);
|
||||
|
||||
heap.erase(item);
|
||||
heap.erase(own_item);
|
||||
heap.clear();
|
||||
|
||||
own_state = heap.state(own_item);
|
||||
heap.state(own_item, own_state);
|
||||
|
||||
own_state = _Heap::PRE_HEAP;
|
||||
own_state = _Heap::IN_HEAP;
|
||||
own_state = _Heap::POST_HEAP;
|
||||
}
|
||||
|
||||
_Heap& heap;
|
||||
ItemIntMap& map;
|
||||
Constraints() {}
|
||||
};
|
||||
};
|
||||
|
||||
/// @}
|
||||
} // namespace lemon
|
||||
}
|
||||
#endif
|
||||
223
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/maps.h
vendored
Normal file
223
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/maps.h
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_CONCEPTS_MAPS_H
|
||||
#define LEMON_CONCEPTS_MAPS_H
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/concept_check.h>
|
||||
|
||||
///\ingroup map_concepts
|
||||
///\file
|
||||
///\brief The concept of maps.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
namespace concepts {
|
||||
|
||||
/// \addtogroup map_concepts
|
||||
/// @{
|
||||
|
||||
/// Readable map concept
|
||||
|
||||
/// Readable map concept.
|
||||
///
|
||||
template<typename K, typename T>
|
||||
class ReadMap
|
||||
{
|
||||
public:
|
||||
/// The key type of the map.
|
||||
typedef K Key;
|
||||
/// \brief The value type of the map.
|
||||
/// (The type of objects associated with the keys).
|
||||
typedef T Value;
|
||||
|
||||
/// Returns the value associated with the given key.
|
||||
Value operator[](const Key &) const {
|
||||
return *(static_cast<Value *>(0)+1);
|
||||
}
|
||||
|
||||
template<typename _ReadMap>
|
||||
struct Constraints {
|
||||
void constraints() {
|
||||
Value val = m[key];
|
||||
val = m[key];
|
||||
typename _ReadMap::Value own_val = m[own_key];
|
||||
own_val = m[own_key];
|
||||
|
||||
::lemon::ignore_unused_variable_warning(key);
|
||||
::lemon::ignore_unused_variable_warning(val);
|
||||
::lemon::ignore_unused_variable_warning(own_key);
|
||||
::lemon::ignore_unused_variable_warning(own_val);
|
||||
}
|
||||
const Key& key;
|
||||
const typename _ReadMap::Key& own_key;
|
||||
const _ReadMap& m;
|
||||
Constraints() {}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Writable map concept
|
||||
|
||||
/// Writable map concept.
|
||||
///
|
||||
template<typename K, typename T>
|
||||
class WriteMap
|
||||
{
|
||||
public:
|
||||
/// The key type of the map.
|
||||
typedef K Key;
|
||||
/// \brief The value type of the map.
|
||||
/// (The type of objects associated with the keys).
|
||||
typedef T Value;
|
||||
|
||||
/// Sets the value associated with the given key.
|
||||
void set(const Key &, const Value &) {}
|
||||
|
||||
/// Default constructor.
|
||||
WriteMap() {}
|
||||
|
||||
template <typename _WriteMap>
|
||||
struct Constraints {
|
||||
void constraints() {
|
||||
m.set(key, val);
|
||||
m.set(own_key, own_val);
|
||||
|
||||
::lemon::ignore_unused_variable_warning(key);
|
||||
::lemon::ignore_unused_variable_warning(val);
|
||||
::lemon::ignore_unused_variable_warning(own_key);
|
||||
::lemon::ignore_unused_variable_warning(own_val);
|
||||
}
|
||||
const Key& key;
|
||||
const Value& val;
|
||||
const typename _WriteMap::Key& own_key;
|
||||
const typename _WriteMap::Value& own_val;
|
||||
_WriteMap& m;
|
||||
Constraints() {}
|
||||
};
|
||||
};
|
||||
|
||||
/// Read/writable map concept
|
||||
|
||||
/// Read/writable map concept.
|
||||
///
|
||||
template<typename K, typename T>
|
||||
class ReadWriteMap : public ReadMap<K,T>,
|
||||
public WriteMap<K,T>
|
||||
{
|
||||
public:
|
||||
/// The key type of the map.
|
||||
typedef K Key;
|
||||
/// \brief The value type of the map.
|
||||
/// (The type of objects associated with the keys).
|
||||
typedef T Value;
|
||||
|
||||
/// Returns the value associated with the given key.
|
||||
Value operator[](const Key &) const {
|
||||
Value *r = 0;
|
||||
return *r;
|
||||
}
|
||||
|
||||
/// Sets the value associated with the given key.
|
||||
void set(const Key &, const Value &) {}
|
||||
|
||||
template<typename _ReadWriteMap>
|
||||
struct Constraints {
|
||||
void constraints() {
|
||||
checkConcept<ReadMap<K, T>, _ReadWriteMap >();
|
||||
checkConcept<WriteMap<K, T>, _ReadWriteMap >();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/// Dereferable map concept
|
||||
|
||||
/// Dereferable map concept.
|
||||
///
|
||||
template<typename K, typename T, typename R, typename CR>
|
||||
class ReferenceMap : public ReadWriteMap<K,T>
|
||||
{
|
||||
public:
|
||||
/// Tag for reference maps.
|
||||
typedef True ReferenceMapTag;
|
||||
/// The key type of the map.
|
||||
typedef K Key;
|
||||
/// \brief The value type of the map.
|
||||
/// (The type of objects associated with the keys).
|
||||
typedef T Value;
|
||||
/// The reference type of the map.
|
||||
typedef R Reference;
|
||||
/// The const reference type of the map.
|
||||
typedef CR ConstReference;
|
||||
|
||||
public:
|
||||
|
||||
/// Returns a reference to the value associated with the given key.
|
||||
Reference operator[](const Key &) {
|
||||
Value *r = 0;
|
||||
return *r;
|
||||
}
|
||||
|
||||
/// Returns a const reference to the value associated with the given key.
|
||||
ConstReference operator[](const Key &) const {
|
||||
Value *r = 0;
|
||||
return *r;
|
||||
}
|
||||
|
||||
/// Sets the value associated with the given key.
|
||||
void set(const Key &k,const Value &t) { operator[](k)=t; }
|
||||
|
||||
template<typename _ReferenceMap>
|
||||
struct Constraints {
|
||||
typename enable_if<typename _ReferenceMap::ReferenceMapTag, void>::type
|
||||
constraints() {
|
||||
checkConcept<ReadWriteMap<K, T>, _ReferenceMap >();
|
||||
ref = m[key];
|
||||
m[key] = val;
|
||||
m[key] = ref;
|
||||
m[key] = cref;
|
||||
own_ref = m[own_key];
|
||||
m[own_key] = own_val;
|
||||
m[own_key] = own_ref;
|
||||
m[own_key] = own_cref;
|
||||
m[key] = m[own_key];
|
||||
m[own_key] = m[key];
|
||||
}
|
||||
const Key& key;
|
||||
Value& val;
|
||||
Reference ref;
|
||||
ConstReference cref;
|
||||
const typename _ReferenceMap::Key& own_key;
|
||||
typename _ReferenceMap::Value& own_val;
|
||||
typename _ReferenceMap::Reference own_ref;
|
||||
typename _ReferenceMap::ConstReference own_cref;
|
||||
_ReferenceMap& m;
|
||||
Constraints() {}
|
||||
};
|
||||
};
|
||||
|
||||
// @}
|
||||
|
||||
} //namespace concepts
|
||||
|
||||
} //namespace lemon
|
||||
|
||||
#endif
|
||||
312
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/path.h
vendored
Normal file
312
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/concepts/path.h
vendored
Normal file
@@ -0,0 +1,312 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
///\ingroup concept
|
||||
///\file
|
||||
///\brief The concept of paths
|
||||
///
|
||||
|
||||
#ifndef LEMON_CONCEPTS_PATH_H
|
||||
#define LEMON_CONCEPTS_PATH_H
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/concept_check.h>
|
||||
|
||||
namespace lemon {
|
||||
namespace concepts {
|
||||
|
||||
/// \addtogroup concept
|
||||
/// @{
|
||||
|
||||
/// \brief A skeleton structure for representing directed paths in
|
||||
/// a digraph.
|
||||
///
|
||||
/// A skeleton structure for representing directed paths in a
|
||||
/// digraph.
|
||||
/// In a sense, a path can be treated as a list of arcs.
|
||||
/// LEMON path types just store this list. As a consequence, they cannot
|
||||
/// enumerate the nodes on the path directly and a zero length path
|
||||
/// cannot store its source node.
|
||||
///
|
||||
/// The arcs of a path should be stored in the order of their directions,
|
||||
/// i.e. the target node of each arc should be the same as the source
|
||||
/// node of the next arc. This consistency could be checked using
|
||||
/// \ref checkPath().
|
||||
/// The source and target nodes of a (consistent) path can be obtained
|
||||
/// using \ref pathSource() and \ref pathTarget().
|
||||
///
|
||||
/// A path can be constructed from another path of any type using the
|
||||
/// copy constructor or the assignment operator.
|
||||
///
|
||||
/// \tparam GR The digraph type in which the path is.
|
||||
template <typename GR>
|
||||
class Path {
|
||||
public:
|
||||
|
||||
/// Type of the underlying digraph.
|
||||
typedef GR Digraph;
|
||||
/// Arc type of the underlying digraph.
|
||||
typedef typename Digraph::Arc Arc;
|
||||
|
||||
class ArcIt;
|
||||
|
||||
/// \brief Default constructor
|
||||
Path() {}
|
||||
|
||||
/// \brief Template copy constructor
|
||||
template <typename CPath>
|
||||
Path(const CPath& cpath) {}
|
||||
|
||||
/// \brief Template assigment operator
|
||||
template <typename CPath>
|
||||
Path& operator=(const CPath& cpath) {
|
||||
::lemon::ignore_unused_variable_warning(cpath);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Length of the path, i.e. the number of arcs on the path.
|
||||
int length() const { return 0;}
|
||||
|
||||
/// Returns whether the path is empty.
|
||||
bool empty() const { return true;}
|
||||
|
||||
/// Resets the path to an empty path.
|
||||
void clear() {}
|
||||
|
||||
/// \brief LEMON style iterator for enumerating the arcs of a path.
|
||||
///
|
||||
/// LEMON style iterator class for enumerating the arcs of a path.
|
||||
class ArcIt {
|
||||
public:
|
||||
/// Default constructor
|
||||
ArcIt() {}
|
||||
/// Invalid constructor
|
||||
ArcIt(Invalid) {}
|
||||
/// Sets the iterator to the first arc of the given path
|
||||
ArcIt(const Path &) {}
|
||||
|
||||
/// Conversion to \c Arc
|
||||
operator Arc() const { return INVALID; }
|
||||
|
||||
/// Next arc
|
||||
ArcIt& operator++() {return *this;}
|
||||
|
||||
/// Comparison operator
|
||||
bool operator==(const ArcIt&) const {return true;}
|
||||
/// Comparison operator
|
||||
bool operator!=(const ArcIt&) const {return true;}
|
||||
/// Comparison operator
|
||||
bool operator<(const ArcIt&) const {return false;}
|
||||
|
||||
};
|
||||
|
||||
template <typename _Path>
|
||||
struct Constraints {
|
||||
void constraints() {
|
||||
Path<Digraph> pc;
|
||||
_Path p, pp(pc);
|
||||
int l = p.length();
|
||||
int e = p.empty();
|
||||
p.clear();
|
||||
|
||||
p = pc;
|
||||
|
||||
typename _Path::ArcIt id, ii(INVALID), i(p);
|
||||
|
||||
++i;
|
||||
typename Digraph::Arc ed = i;
|
||||
|
||||
e = (i == ii);
|
||||
e = (i != ii);
|
||||
e = (i < ii);
|
||||
|
||||
::lemon::ignore_unused_variable_warning(l);
|
||||
::lemon::ignore_unused_variable_warning(pp);
|
||||
::lemon::ignore_unused_variable_warning(e);
|
||||
::lemon::ignore_unused_variable_warning(id);
|
||||
::lemon::ignore_unused_variable_warning(ii);
|
||||
::lemon::ignore_unused_variable_warning(ed);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
namespace _path_bits {
|
||||
|
||||
template <typename _Digraph, typename _Path, typename RevPathTag = void>
|
||||
struct PathDumperConstraints {
|
||||
void constraints() {
|
||||
int l = p.length();
|
||||
int e = p.empty();
|
||||
|
||||
typename _Path::ArcIt id, i(p);
|
||||
|
||||
++i;
|
||||
typename _Digraph::Arc ed = i;
|
||||
|
||||
e = (i == INVALID);
|
||||
e = (i != INVALID);
|
||||
|
||||
::lemon::ignore_unused_variable_warning(l);
|
||||
::lemon::ignore_unused_variable_warning(e);
|
||||
::lemon::ignore_unused_variable_warning(id);
|
||||
::lemon::ignore_unused_variable_warning(ed);
|
||||
}
|
||||
_Path& p;
|
||||
PathDumperConstraints() {}
|
||||
};
|
||||
|
||||
template <typename _Digraph, typename _Path>
|
||||
struct PathDumperConstraints<
|
||||
_Digraph, _Path,
|
||||
typename enable_if<typename _Path::RevPathTag, void>::type
|
||||
> {
|
||||
void constraints() {
|
||||
int l = p.length();
|
||||
int e = p.empty();
|
||||
|
||||
typename _Path::RevArcIt id, i(p);
|
||||
|
||||
++i;
|
||||
typename _Digraph::Arc ed = i;
|
||||
|
||||
e = (i == INVALID);
|
||||
e = (i != INVALID);
|
||||
|
||||
::lemon::ignore_unused_variable_warning(l);
|
||||
::lemon::ignore_unused_variable_warning(e);
|
||||
::lemon::ignore_unused_variable_warning(id);
|
||||
::lemon::ignore_unused_variable_warning(ed);
|
||||
}
|
||||
_Path& p;
|
||||
PathDumperConstraints() {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// \brief A skeleton structure for path dumpers.
|
||||
///
|
||||
/// A skeleton structure for path dumpers. The path dumpers are
|
||||
/// the generalization of the paths, they can enumerate the arcs
|
||||
/// of the path either in forward or in backward order.
|
||||
/// These classes are typically not used directly, they are rather
|
||||
/// used to be assigned to a real path type.
|
||||
///
|
||||
/// The main purpose of this concept is that the shortest path
|
||||
/// algorithms can enumerate the arcs easily in reverse order.
|
||||
/// In LEMON, such algorithms give back a (reverse) path dumper that
|
||||
/// can be assigned to a real path. The dumpers can be implemented as
|
||||
/// an adaptor class to the predecessor map.
|
||||
///
|
||||
/// \tparam GR The digraph type in which the path is.
|
||||
template <typename GR>
|
||||
class PathDumper {
|
||||
public:
|
||||
|
||||
/// Type of the underlying digraph.
|
||||
typedef GR Digraph;
|
||||
/// Arc type of the underlying digraph.
|
||||
typedef typename Digraph::Arc Arc;
|
||||
|
||||
/// Length of the path, i.e. the number of arcs on the path.
|
||||
int length() const { return 0;}
|
||||
|
||||
/// Returns whether the path is empty.
|
||||
bool empty() const { return true;}
|
||||
|
||||
/// \brief Forward or reverse dumping
|
||||
///
|
||||
/// If this tag is defined to be \c True, then reverse dumping
|
||||
/// is provided in the path dumper. In this case, \c RevArcIt
|
||||
/// iterator should be implemented instead of \c ArcIt iterator.
|
||||
typedef False RevPathTag;
|
||||
|
||||
/// \brief LEMON style iterator for enumerating the arcs of a path.
|
||||
///
|
||||
/// LEMON style iterator class for enumerating the arcs of a path.
|
||||
class ArcIt {
|
||||
public:
|
||||
/// Default constructor
|
||||
ArcIt() {}
|
||||
/// Invalid constructor
|
||||
ArcIt(Invalid) {}
|
||||
/// Sets the iterator to the first arc of the given path
|
||||
ArcIt(const PathDumper&) {}
|
||||
|
||||
/// Conversion to \c Arc
|
||||
operator Arc() const { return INVALID; }
|
||||
|
||||
/// Next arc
|
||||
ArcIt& operator++() {return *this;}
|
||||
|
||||
/// Comparison operator
|
||||
bool operator==(const ArcIt&) const {return true;}
|
||||
/// Comparison operator
|
||||
bool operator!=(const ArcIt&) const {return true;}
|
||||
/// Comparison operator
|
||||
bool operator<(const ArcIt&) const {return false;}
|
||||
|
||||
};
|
||||
|
||||
/// \brief LEMON style iterator for enumerating the arcs of a path
|
||||
/// in reverse direction.
|
||||
///
|
||||
/// LEMON style iterator class for enumerating the arcs of a path
|
||||
/// in reverse direction.
|
||||
class RevArcIt {
|
||||
public:
|
||||
/// Default constructor
|
||||
RevArcIt() {}
|
||||
/// Invalid constructor
|
||||
RevArcIt(Invalid) {}
|
||||
/// Sets the iterator to the last arc of the given path
|
||||
RevArcIt(const PathDumper &) {}
|
||||
|
||||
/// Conversion to \c Arc
|
||||
operator Arc() const { return INVALID; }
|
||||
|
||||
/// Next arc
|
||||
RevArcIt& operator++() {return *this;}
|
||||
|
||||
/// Comparison operator
|
||||
bool operator==(const RevArcIt&) const {return true;}
|
||||
/// Comparison operator
|
||||
bool operator!=(const RevArcIt&) const {return true;}
|
||||
/// Comparison operator
|
||||
bool operator<(const RevArcIt&) const {return false;}
|
||||
|
||||
};
|
||||
|
||||
template <typename _Path>
|
||||
struct Constraints {
|
||||
void constraints() {
|
||||
function_requires<_path_bits::
|
||||
PathDumperConstraints<Digraph, _Path> >();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
///@}
|
||||
}
|
||||
|
||||
} // namespace lemon
|
||||
|
||||
#endif
|
||||
22
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/config.h.in
vendored
Normal file
22
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/config.h.in
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
#define LEMON_VERSION "@PROJECT_VERSION@"
|
||||
#cmakedefine LEMON_HAVE_LONG_LONG 1
|
||||
|
||||
#cmakedefine LEMON_HAVE_LP 1
|
||||
#cmakedefine LEMON_HAVE_MIP 1
|
||||
#cmakedefine LEMON_HAVE_GLPK 1
|
||||
#cmakedefine LEMON_HAVE_CPLEX 1
|
||||
#cmakedefine LEMON_HAVE_SOPLEX 1
|
||||
#cmakedefine LEMON_HAVE_CLP 1
|
||||
#cmakedefine LEMON_HAVE_CBC 1
|
||||
|
||||
#define _LEMON_CPLEX 1
|
||||
#define _LEMON_CLP 2
|
||||
#define _LEMON_GLPK 3
|
||||
#define _LEMON_SOPLEX 4
|
||||
#define _LEMON_CBC 5
|
||||
|
||||
#cmakedefine LEMON_DEFAULT_LP _LEMON_@LEMON_DEFAULT_LP@
|
||||
#cmakedefine LEMON_DEFAULT_MIP _LEMON_@LEMON_DEFAULT_MIP@
|
||||
|
||||
#cmakedefine LEMON_USE_PTHREAD 1
|
||||
#cmakedefine LEMON_USE_WIN32_THREADS 1
|
||||
1688
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/connectivity.h
vendored
Normal file
1688
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/connectivity.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2506
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/core.h
vendored
Normal file
2506
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/core.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1607
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cost_scaling.h
vendored
Normal file
1607
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cost_scaling.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
249
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/counter.h
vendored
Normal file
249
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/counter.h
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_COUNTER_H
|
||||
#define LEMON_COUNTER_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
///\ingroup timecount
|
||||
///\file
|
||||
///\brief Tools for counting steps and events
|
||||
|
||||
namespace lemon
|
||||
{
|
||||
|
||||
template<class P> class _NoSubCounter;
|
||||
|
||||
template<class P>
|
||||
class _SubCounter
|
||||
{
|
||||
P &_parent;
|
||||
std::string _title;
|
||||
std::ostream &_os;
|
||||
int count;
|
||||
public:
|
||||
|
||||
typedef _SubCounter<_SubCounter<P> > SubCounter;
|
||||
typedef _NoSubCounter<_SubCounter<P> > NoSubCounter;
|
||||
|
||||
_SubCounter(P &parent)
|
||||
: _parent(parent), _title(), _os(std::cerr), count(0) {}
|
||||
_SubCounter(P &parent,std::string title,std::ostream &os=std::cerr)
|
||||
: _parent(parent), _title(title), _os(os), count(0) {}
|
||||
_SubCounter(P &parent,const char *title,std::ostream &os=std::cerr)
|
||||
: _parent(parent), _title(title), _os(os), count(0) {}
|
||||
~_SubCounter() {
|
||||
_os << _title << count <<std::endl;
|
||||
_parent+=count;
|
||||
}
|
||||
_SubCounter &operator++() { count++; return *this;}
|
||||
int operator++(int) { return count++; }
|
||||
_SubCounter &operator--() { count--; return *this;}
|
||||
int operator--(int) { return count--; }
|
||||
_SubCounter &operator+=(int c) { count+=c; return *this;}
|
||||
_SubCounter &operator-=(int c) { count-=c; return *this;}
|
||||
operator int() {return count;}
|
||||
};
|
||||
|
||||
template<class P>
|
||||
class _NoSubCounter
|
||||
{
|
||||
P &_parent;
|
||||
public:
|
||||
typedef _NoSubCounter<_NoSubCounter<P> > SubCounter;
|
||||
typedef _NoSubCounter<_NoSubCounter<P> > NoSubCounter;
|
||||
|
||||
_NoSubCounter(P &parent) :_parent(parent) {}
|
||||
_NoSubCounter(P &parent,std::string,std::ostream &)
|
||||
:_parent(parent) {}
|
||||
_NoSubCounter(P &parent,std::string)
|
||||
:_parent(parent) {}
|
||||
_NoSubCounter(P &parent,const char *,std::ostream &)
|
||||
:_parent(parent) {}
|
||||
_NoSubCounter(P &parent,const char *)
|
||||
:_parent(parent) {}
|
||||
~_NoSubCounter() {}
|
||||
_NoSubCounter &operator++() { ++_parent; return *this;}
|
||||
int operator++(int) { _parent++; return 0;}
|
||||
_NoSubCounter &operator--() { --_parent; return *this;}
|
||||
int operator--(int) { _parent--; return 0;}
|
||||
_NoSubCounter &operator+=(int c) { _parent+=c; return *this;}
|
||||
_NoSubCounter &operator-=(int c) { _parent-=c; return *this;}
|
||||
operator int() {return 0;}
|
||||
};
|
||||
|
||||
|
||||
/// \addtogroup timecount
|
||||
/// @{
|
||||
|
||||
/// A counter class
|
||||
|
||||
/// This class makes it easier to count certain events (e.g. for debug
|
||||
/// reasons).
|
||||
/// You can increment or decrement the counter using \c operator++,
|
||||
/// \c operator--, \c operator+= and \c operator-=. You can also
|
||||
/// define subcounters for the different phases of the algorithm or
|
||||
/// for different types of operations.
|
||||
/// A report containing the given title and the value of the counter
|
||||
/// is automatically printed on destruction.
|
||||
///
|
||||
/// The following example shows the usage of counters and subcounters.
|
||||
/// \code
|
||||
/// // Bubble sort
|
||||
/// std::vector<T> v;
|
||||
/// ...
|
||||
/// Counter op("Operations: ");
|
||||
/// Counter::SubCounter as(op, "Assignments: ");
|
||||
/// Counter::SubCounter co(op, "Comparisons: ");
|
||||
/// for (int i = v.size()-1; i > 0; --i) {
|
||||
/// for (int j = 0; j < i; ++j) {
|
||||
/// if (v[j] > v[j+1]) {
|
||||
/// T tmp = v[j];
|
||||
/// v[j] = v[j+1];
|
||||
/// v[j+1] = tmp;
|
||||
/// as += 3; // three assignments
|
||||
/// }
|
||||
/// ++co; // one comparison
|
||||
/// }
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// This code prints out something like that:
|
||||
/// \code
|
||||
/// Comparisons: 45
|
||||
/// Assignments: 57
|
||||
/// Operations: 102
|
||||
/// \endcode
|
||||
///
|
||||
/// \sa NoCounter
|
||||
class Counter
|
||||
{
|
||||
std::string _title;
|
||||
std::ostream &_os;
|
||||
int count;
|
||||
public:
|
||||
|
||||
/// SubCounter class
|
||||
|
||||
/// This class can be used to setup subcounters for a \ref Counter
|
||||
/// to have finer reports. A subcounter provides exactly the same
|
||||
/// operations as the main \ref Counter, but it also increments and
|
||||
/// decrements the value of its parent.
|
||||
/// Subcounters can also have subcounters.
|
||||
///
|
||||
/// The parent counter must be given as the first parameter of the
|
||||
/// constructor. Apart from that a title and an \c ostream object
|
||||
/// can also be given just like for the main \ref Counter.
|
||||
///
|
||||
/// A report containing the given title and the value of the
|
||||
/// subcounter is automatically printed on destruction. If you
|
||||
/// would like to turn off this report, use \ref NoSubCounter
|
||||
/// instead.
|
||||
///
|
||||
/// \sa NoSubCounter
|
||||
typedef _SubCounter<Counter> SubCounter;
|
||||
|
||||
/// SubCounter class without printing report on destruction
|
||||
|
||||
/// This class can be used to setup subcounters for a \ref Counter.
|
||||
/// It is the same as \ref SubCounter but it does not print report
|
||||
/// on destruction. (It modifies the value of its parent, so 'No'
|
||||
/// only means 'do not print'.)
|
||||
///
|
||||
/// Replacing \ref SubCounter "SubCounter"s with \ref NoSubCounter
|
||||
/// "NoSubCounter"s makes it possible to turn off reporting
|
||||
/// subcounter values without actually removing the definitions
|
||||
/// and the increment or decrement operators.
|
||||
///
|
||||
/// \sa SubCounter
|
||||
typedef _NoSubCounter<Counter> NoSubCounter;
|
||||
|
||||
/// Constructor.
|
||||
Counter() : _title(), _os(std::cerr), count(0) {}
|
||||
/// Constructor.
|
||||
Counter(std::string title,std::ostream &os=std::cerr)
|
||||
: _title(title), _os(os), count(0) {}
|
||||
/// Constructor.
|
||||
Counter(const char *title,std::ostream &os=std::cerr)
|
||||
: _title(title), _os(os), count(0) {}
|
||||
/// Destructor. Prints the given title and the value of the counter.
|
||||
~Counter() {
|
||||
_os << _title << count <<std::endl;
|
||||
}
|
||||
///\e
|
||||
Counter &operator++() { count++; return *this;}
|
||||
///\e
|
||||
int operator++(int) { return count++;}
|
||||
///\e
|
||||
Counter &operator--() { count--; return *this;}
|
||||
///\e
|
||||
int operator--(int) { return count--;}
|
||||
///\e
|
||||
Counter &operator+=(int c) { count+=c; return *this;}
|
||||
///\e
|
||||
Counter &operator-=(int c) { count-=c; return *this;}
|
||||
/// Resets the counter to the given value.
|
||||
|
||||
/// Resets the counter to the given value.
|
||||
/// \note This function does not reset the values of
|
||||
/// \ref SubCounter "SubCounter"s but it resets \ref NoSubCounter
|
||||
/// "NoSubCounter"s along with the main counter.
|
||||
void reset(int c=0) {count=c;}
|
||||
/// Returns the value of the counter.
|
||||
operator int() {return count;}
|
||||
};
|
||||
|
||||
/// 'Do nothing' version of Counter.
|
||||
|
||||
/// This class can be used in the same way as \ref Counter, but it
|
||||
/// does not count at all and does not print report on destruction.
|
||||
///
|
||||
/// Replacing a \ref Counter with a \ref NoCounter makes it possible
|
||||
/// to turn off all counting and reporting (SubCounters should also
|
||||
/// be replaced with NoSubCounters), so it does not affect the
|
||||
/// efficiency of the program at all.
|
||||
///
|
||||
/// \sa Counter
|
||||
class NoCounter
|
||||
{
|
||||
public:
|
||||
typedef _NoSubCounter<NoCounter> SubCounter;
|
||||
typedef _NoSubCounter<NoCounter> NoSubCounter;
|
||||
|
||||
NoCounter() {}
|
||||
NoCounter(std::string,std::ostream &) {}
|
||||
NoCounter(const char *,std::ostream &) {}
|
||||
NoCounter(std::string) {}
|
||||
NoCounter(const char *) {}
|
||||
NoCounter &operator++() { return *this; }
|
||||
int operator++(int) { return 0; }
|
||||
NoCounter &operator--() { return *this; }
|
||||
int operator--(int) { return 0; }
|
||||
NoCounter &operator+=(int) { return *this;}
|
||||
NoCounter &operator-=(int) { return *this;}
|
||||
void reset(int) {}
|
||||
void reset() {}
|
||||
operator int() {return 0;}
|
||||
};
|
||||
|
||||
///@}
|
||||
}
|
||||
|
||||
#endif
|
||||
994
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cplex.cc
vendored
Normal file
994
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cplex.cc
vendored
Normal file
@@ -0,0 +1,994 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
#include <lemon/cplex.h>
|
||||
|
||||
extern "C" {
|
||||
#include <ilcplex/cplex.h>
|
||||
}
|
||||
|
||||
|
||||
///\file
|
||||
///\brief Implementation of the LEMON-CPLEX lp solver interface.
|
||||
namespace lemon {
|
||||
|
||||
CplexEnv::LicenseError::LicenseError(int status) {
|
||||
if (!CPXgeterrorstring(0, status, _message)) {
|
||||
std::strcpy(_message, "Cplex unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
CplexEnv::CplexEnv() {
|
||||
int status;
|
||||
_cnt = new int;
|
||||
(*_cnt) = 1;
|
||||
_env = CPXopenCPLEX(&status);
|
||||
if (_env == 0) {
|
||||
delete _cnt;
|
||||
_cnt = 0;
|
||||
throw LicenseError(status);
|
||||
}
|
||||
}
|
||||
|
||||
CplexEnv::CplexEnv(const CplexEnv& other) {
|
||||
_env = other._env;
|
||||
_cnt = other._cnt;
|
||||
++(*_cnt);
|
||||
}
|
||||
|
||||
CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
|
||||
_env = other._env;
|
||||
_cnt = other._cnt;
|
||||
++(*_cnt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CplexEnv::~CplexEnv() {
|
||||
--(*_cnt);
|
||||
if (*_cnt == 0) {
|
||||
delete _cnt;
|
||||
CPXcloseCPLEX(&_env);
|
||||
}
|
||||
}
|
||||
|
||||
CplexBase::CplexBase() : LpBase() {
|
||||
int status;
|
||||
_prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
|
||||
messageLevel(MESSAGE_NOTHING);
|
||||
}
|
||||
|
||||
CplexBase::CplexBase(const CplexEnv& env)
|
||||
: LpBase(), _env(env) {
|
||||
int status;
|
||||
_prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
|
||||
messageLevel(MESSAGE_NOTHING);
|
||||
}
|
||||
|
||||
CplexBase::CplexBase(const CplexBase& cplex)
|
||||
: LpBase() {
|
||||
int status;
|
||||
_prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
|
||||
rows = cplex.rows;
|
||||
cols = cplex.cols;
|
||||
messageLevel(MESSAGE_NOTHING);
|
||||
}
|
||||
|
||||
CplexBase::~CplexBase() {
|
||||
CPXfreeprob(cplexEnv(),&_prob);
|
||||
}
|
||||
|
||||
int CplexBase::_addCol() {
|
||||
int i = CPXgetnumcols(cplexEnv(), _prob);
|
||||
double lb = -INF, ub = INF;
|
||||
CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
int CplexBase::_addRow() {
|
||||
int i = CPXgetnumrows(cplexEnv(), _prob);
|
||||
const double ub = INF;
|
||||
const char s = 'L';
|
||||
CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
|
||||
return i;
|
||||
}
|
||||
|
||||
int CplexBase::_addRow(Value lb, ExprIterator b,
|
||||
ExprIterator e, Value ub) {
|
||||
int i = CPXgetnumrows(cplexEnv(), _prob);
|
||||
if (lb == -INF) {
|
||||
const char s = 'L';
|
||||
CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
|
||||
} else if (ub == INF) {
|
||||
const char s = 'G';
|
||||
CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
|
||||
} else if (lb == ub){
|
||||
const char s = 'E';
|
||||
CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
|
||||
} else {
|
||||
const char s = 'R';
|
||||
double len = ub - lb;
|
||||
CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
|
||||
}
|
||||
|
||||
std::vector<int> indices;
|
||||
std::vector<int> rowlist;
|
||||
std::vector<Value> values;
|
||||
|
||||
for(ExprIterator it=b; it!=e; ++it) {
|
||||
indices.push_back(it->first);
|
||||
values.push_back(it->second);
|
||||
rowlist.push_back(i);
|
||||
}
|
||||
|
||||
CPXchgcoeflist(cplexEnv(), _prob, values.size(),
|
||||
&rowlist.front(), &indices.front(), &values.front());
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void CplexBase::_eraseCol(int i) {
|
||||
CPXdelcols(cplexEnv(), _prob, i, i);
|
||||
}
|
||||
|
||||
void CplexBase::_eraseRow(int i) {
|
||||
CPXdelrows(cplexEnv(), _prob, i, i);
|
||||
}
|
||||
|
||||
void CplexBase::_eraseColId(int i) {
|
||||
cols.eraseIndex(i);
|
||||
cols.shiftIndices(i);
|
||||
}
|
||||
void CplexBase::_eraseRowId(int i) {
|
||||
rows.eraseIndex(i);
|
||||
rows.shiftIndices(i);
|
||||
}
|
||||
|
||||
void CplexBase::_getColName(int col, std::string &name) const {
|
||||
int size;
|
||||
CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col);
|
||||
if (size == 0) {
|
||||
name.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
size *= -1;
|
||||
std::vector<char> buf(size);
|
||||
char *cname;
|
||||
int tmp;
|
||||
CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size,
|
||||
&tmp, col, col);
|
||||
name = cname;
|
||||
}
|
||||
|
||||
void CplexBase::_setColName(int col, const std::string &name) {
|
||||
char *cname;
|
||||
cname = const_cast<char*>(name.c_str());
|
||||
CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname);
|
||||
}
|
||||
|
||||
int CplexBase::_colByName(const std::string& name) const {
|
||||
int index;
|
||||
if (CPXgetcolindex(cplexEnv(), _prob,
|
||||
const_cast<char*>(name.c_str()), &index) == 0) {
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CplexBase::_getRowName(int row, std::string &name) const {
|
||||
int size;
|
||||
CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row);
|
||||
if (size == 0) {
|
||||
name.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
size *= -1;
|
||||
std::vector<char> buf(size);
|
||||
char *cname;
|
||||
int tmp;
|
||||
CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size,
|
||||
&tmp, row, row);
|
||||
name = cname;
|
||||
}
|
||||
|
||||
void CplexBase::_setRowName(int row, const std::string &name) {
|
||||
char *cname;
|
||||
cname = const_cast<char*>(name.c_str());
|
||||
CPXchgrowname(cplexEnv(), _prob, 1, &row, &cname);
|
||||
}
|
||||
|
||||
int CplexBase::_rowByName(const std::string& name) const {
|
||||
int index;
|
||||
if (CPXgetrowindex(cplexEnv(), _prob,
|
||||
const_cast<char*>(name.c_str()), &index) == 0) {
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CplexBase::_setRowCoeffs(int i, ExprIterator b,
|
||||
ExprIterator e)
|
||||
{
|
||||
std::vector<int> indices;
|
||||
std::vector<int> rowlist;
|
||||
std::vector<Value> values;
|
||||
|
||||
for(ExprIterator it=b; it!=e; ++it) {
|
||||
indices.push_back(it->first);
|
||||
values.push_back(it->second);
|
||||
rowlist.push_back(i);
|
||||
}
|
||||
|
||||
CPXchgcoeflist(cplexEnv(), _prob, values.size(),
|
||||
&rowlist.front(), &indices.front(), &values.front());
|
||||
}
|
||||
|
||||
void CplexBase::_getRowCoeffs(int i, InsertIterator b) const {
|
||||
int tmp1, tmp2, tmp3, length;
|
||||
CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
|
||||
|
||||
length = -length;
|
||||
std::vector<int> indices(length);
|
||||
std::vector<double> values(length);
|
||||
|
||||
CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2,
|
||||
&indices.front(), &values.front(),
|
||||
length, &tmp3, i, i);
|
||||
|
||||
for (int i = 0; i < length; ++i) {
|
||||
*b = std::make_pair(indices[i], values[i]);
|
||||
++b;
|
||||
}
|
||||
}
|
||||
|
||||
void CplexBase::_setColCoeffs(int i, ExprIterator b, ExprIterator e) {
|
||||
std::vector<int> indices;
|
||||
std::vector<int> collist;
|
||||
std::vector<Value> values;
|
||||
|
||||
for(ExprIterator it=b; it!=e; ++it) {
|
||||
indices.push_back(it->first);
|
||||
values.push_back(it->second);
|
||||
collist.push_back(i);
|
||||
}
|
||||
|
||||
CPXchgcoeflist(cplexEnv(), _prob, values.size(),
|
||||
&indices.front(), &collist.front(), &values.front());
|
||||
}
|
||||
|
||||
void CplexBase::_getColCoeffs(int i, InsertIterator b) const {
|
||||
|
||||
int tmp1, tmp2, tmp3, length;
|
||||
CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
|
||||
|
||||
length = -length;
|
||||
std::vector<int> indices(length);
|
||||
std::vector<double> values(length);
|
||||
|
||||
CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2,
|
||||
&indices.front(), &values.front(),
|
||||
length, &tmp3, i, i);
|
||||
|
||||
for (int i = 0; i < length; ++i) {
|
||||
*b = std::make_pair(indices[i], values[i]);
|
||||
++b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CplexBase::_setCoeff(int row, int col, Value value) {
|
||||
CPXchgcoef(cplexEnv(), _prob, row, col, value);
|
||||
}
|
||||
|
||||
CplexBase::Value CplexBase::_getCoeff(int row, int col) const {
|
||||
CplexBase::Value value;
|
||||
CPXgetcoef(cplexEnv(), _prob, row, col, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void CplexBase::_setColLowerBound(int i, Value value) {
|
||||
const char s = 'L';
|
||||
CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
|
||||
}
|
||||
|
||||
CplexBase::Value CplexBase::_getColLowerBound(int i) const {
|
||||
CplexBase::Value res;
|
||||
CPXgetlb(cplexEnv(), _prob, &res, i, i);
|
||||
return res <= -CPX_INFBOUND ? -INF : res;
|
||||
}
|
||||
|
||||
void CplexBase::_setColUpperBound(int i, Value value)
|
||||
{
|
||||
const char s = 'U';
|
||||
CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
|
||||
}
|
||||
|
||||
CplexBase::Value CplexBase::_getColUpperBound(int i) const {
|
||||
CplexBase::Value res;
|
||||
CPXgetub(cplexEnv(), _prob, &res, i, i);
|
||||
return res >= CPX_INFBOUND ? INF : res;
|
||||
}
|
||||
|
||||
CplexBase::Value CplexBase::_getRowLowerBound(int i) const {
|
||||
char s;
|
||||
CPXgetsense(cplexEnv(), _prob, &s, i, i);
|
||||
CplexBase::Value res;
|
||||
|
||||
switch (s) {
|
||||
case 'G':
|
||||
case 'R':
|
||||
case 'E':
|
||||
CPXgetrhs(cplexEnv(), _prob, &res, i, i);
|
||||
return res <= -CPX_INFBOUND ? -INF : res;
|
||||
default:
|
||||
return -INF;
|
||||
}
|
||||
}
|
||||
|
||||
CplexBase::Value CplexBase::_getRowUpperBound(int i) const {
|
||||
char s;
|
||||
CPXgetsense(cplexEnv(), _prob, &s, i, i);
|
||||
CplexBase::Value res;
|
||||
|
||||
switch (s) {
|
||||
case 'L':
|
||||
case 'E':
|
||||
CPXgetrhs(cplexEnv(), _prob, &res, i, i);
|
||||
return res >= CPX_INFBOUND ? INF : res;
|
||||
case 'R':
|
||||
CPXgetrhs(cplexEnv(), _prob, &res, i, i);
|
||||
{
|
||||
double rng;
|
||||
CPXgetrngval(cplexEnv(), _prob, &rng, i, i);
|
||||
res += rng;
|
||||
}
|
||||
return res >= CPX_INFBOUND ? INF : res;
|
||||
default:
|
||||
return INF;
|
||||
}
|
||||
}
|
||||
|
||||
//This is easier to implement
|
||||
void CplexBase::_set_row_bounds(int i, Value lb, Value ub) {
|
||||
if (lb == -INF) {
|
||||
const char s = 'L';
|
||||
CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
|
||||
CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub);
|
||||
} else if (ub == INF) {
|
||||
const char s = 'G';
|
||||
CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
|
||||
CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
|
||||
} else if (lb == ub){
|
||||
const char s = 'E';
|
||||
CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
|
||||
CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
|
||||
} else {
|
||||
const char s = 'R';
|
||||
CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
|
||||
CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
|
||||
double len = ub - lb;
|
||||
CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
|
||||
}
|
||||
}
|
||||
|
||||
void CplexBase::_setRowLowerBound(int i, Value lb)
|
||||
{
|
||||
LEMON_ASSERT(lb != INF, "Invalid bound");
|
||||
_set_row_bounds(i, lb, CplexBase::_getRowUpperBound(i));
|
||||
}
|
||||
|
||||
void CplexBase::_setRowUpperBound(int i, Value ub)
|
||||
{
|
||||
|
||||
LEMON_ASSERT(ub != -INF, "Invalid bound");
|
||||
_set_row_bounds(i, CplexBase::_getRowLowerBound(i), ub);
|
||||
}
|
||||
|
||||
void CplexBase::_setObjCoeffs(ExprIterator b, ExprIterator e)
|
||||
{
|
||||
std::vector<int> indices;
|
||||
std::vector<Value> values;
|
||||
for(ExprIterator it=b; it!=e; ++it) {
|
||||
indices.push_back(it->first);
|
||||
values.push_back(it->second);
|
||||
}
|
||||
CPXchgobj(cplexEnv(), _prob, values.size(),
|
||||
&indices.front(), &values.front());
|
||||
|
||||
}
|
||||
|
||||
void CplexBase::_getObjCoeffs(InsertIterator b) const
|
||||
{
|
||||
int num = CPXgetnumcols(cplexEnv(), _prob);
|
||||
std::vector<Value> x(num);
|
||||
|
||||
CPXgetobj(cplexEnv(), _prob, &x.front(), 0, num - 1);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
if (x[i] != 0.0) {
|
||||
*b = std::make_pair(i, x[i]);
|
||||
++b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CplexBase::_setObjCoeff(int i, Value obj_coef)
|
||||
{
|
||||
CPXchgobj(cplexEnv(), _prob, 1, &i, &obj_coef);
|
||||
}
|
||||
|
||||
CplexBase::Value CplexBase::_getObjCoeff(int i) const
|
||||
{
|
||||
Value x;
|
||||
CPXgetobj(cplexEnv(), _prob, &x, i, i);
|
||||
return x;
|
||||
}
|
||||
|
||||
void CplexBase::_setSense(CplexBase::Sense sense) {
|
||||
switch (sense) {
|
||||
case MIN:
|
||||
CPXchgobjsen(cplexEnv(), _prob, CPX_MIN);
|
||||
break;
|
||||
case MAX:
|
||||
CPXchgobjsen(cplexEnv(), _prob, CPX_MAX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CplexBase::Sense CplexBase::_getSense() const {
|
||||
switch (CPXgetobjsen(cplexEnv(), _prob)) {
|
||||
case CPX_MIN:
|
||||
return MIN;
|
||||
case CPX_MAX:
|
||||
return MAX;
|
||||
default:
|
||||
LEMON_ASSERT(false, "Invalid sense");
|
||||
return CplexBase::Sense();
|
||||
}
|
||||
}
|
||||
|
||||
void CplexBase::_clear() {
|
||||
CPXfreeprob(cplexEnv(),&_prob);
|
||||
int status;
|
||||
_prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
|
||||
}
|
||||
|
||||
void CplexBase::_messageLevel(MessageLevel level) {
|
||||
switch (level) {
|
||||
case MESSAGE_NOTHING:
|
||||
_message_enabled = false;
|
||||
break;
|
||||
case MESSAGE_ERROR:
|
||||
case MESSAGE_WARNING:
|
||||
case MESSAGE_NORMAL:
|
||||
case MESSAGE_VERBOSE:
|
||||
_message_enabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CplexBase::_applyMessageLevel() {
|
||||
CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND,
|
||||
_message_enabled ? CPX_ON : CPX_OFF);
|
||||
}
|
||||
|
||||
void CplexBase::_write(std::string file, std::string format) const
|
||||
{
|
||||
if(format == "MPS" || format == "LP")
|
||||
CPXwriteprob(cplexEnv(), cplexLp(), file.c_str(), format.c_str());
|
||||
else if(format == "SOL")
|
||||
CPXsolwrite(cplexEnv(), cplexLp(), file.c_str());
|
||||
else throw UnsupportedFormatError(format);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// CplexLp members
|
||||
|
||||
CplexLp::CplexLp()
|
||||
: LpBase(), LpSolver(), CplexBase() {}
|
||||
|
||||
CplexLp::CplexLp(const CplexEnv& env)
|
||||
: LpBase(), LpSolver(), CplexBase(env) {}
|
||||
|
||||
CplexLp::CplexLp(const CplexLp& other)
|
||||
: LpBase(), LpSolver(), CplexBase(other) {}
|
||||
|
||||
CplexLp::~CplexLp() {}
|
||||
|
||||
CplexLp* CplexLp::newSolver() const { return new CplexLp; }
|
||||
CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); }
|
||||
|
||||
const char* CplexLp::_solverName() const { return "CplexLp"; }
|
||||
|
||||
void CplexLp::_clear_temporals() {
|
||||
_col_status.clear();
|
||||
_row_status.clear();
|
||||
_primal_ray.clear();
|
||||
_dual_ray.clear();
|
||||
}
|
||||
|
||||
// The routine returns zero unless an error occurred during the
|
||||
// optimization. Examples of errors include exhausting available
|
||||
// memory (CPXERR_NO_MEMORY) or encountering invalid data in the
|
||||
// CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
|
||||
// user-specified CPLEX limit, or proving the model infeasible or
|
||||
// unbounded, are not considered errors. Note that a zero return
|
||||
// value does not necessarily mean that a solution exists. Use query
|
||||
// routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
|
||||
// further information about the status of the optimization.
|
||||
CplexLp::SolveExitStatus CplexLp::convertStatus(int status) {
|
||||
#if CPX_VERSION >= 800
|
||||
if (status == 0) {
|
||||
switch (CPXgetstat(cplexEnv(), _prob)) {
|
||||
case CPX_STAT_OPTIMAL:
|
||||
case CPX_STAT_INFEASIBLE:
|
||||
case CPX_STAT_UNBOUNDED:
|
||||
return SOLVED;
|
||||
default:
|
||||
return UNSOLVED;
|
||||
}
|
||||
} else {
|
||||
return UNSOLVED;
|
||||
}
|
||||
#else
|
||||
if (status == 0) {
|
||||
//We want to exclude some cases
|
||||
switch (CPXgetstat(cplexEnv(), _prob)) {
|
||||
case CPX_OBJ_LIM:
|
||||
case CPX_IT_LIM_FEAS:
|
||||
case CPX_IT_LIM_INFEAS:
|
||||
case CPX_TIME_LIM_FEAS:
|
||||
case CPX_TIME_LIM_INFEAS:
|
||||
return UNSOLVED;
|
||||
default:
|
||||
return SOLVED;
|
||||
}
|
||||
} else {
|
||||
return UNSOLVED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CplexLp::SolveExitStatus CplexLp::_solve() {
|
||||
_clear_temporals();
|
||||
_applyMessageLevel();
|
||||
return convertStatus(CPXlpopt(cplexEnv(), _prob));
|
||||
}
|
||||
|
||||
CplexLp::SolveExitStatus CplexLp::solvePrimal() {
|
||||
_clear_temporals();
|
||||
_applyMessageLevel();
|
||||
return convertStatus(CPXprimopt(cplexEnv(), _prob));
|
||||
}
|
||||
|
||||
CplexLp::SolveExitStatus CplexLp::solveDual() {
|
||||
_clear_temporals();
|
||||
_applyMessageLevel();
|
||||
return convertStatus(CPXdualopt(cplexEnv(), _prob));
|
||||
}
|
||||
|
||||
CplexLp::SolveExitStatus CplexLp::solveBarrier() {
|
||||
_clear_temporals();
|
||||
_applyMessageLevel();
|
||||
return convertStatus(CPXbaropt(cplexEnv(), _prob));
|
||||
}
|
||||
|
||||
CplexLp::Value CplexLp::_getPrimal(int i) const {
|
||||
Value x;
|
||||
CPXgetx(cplexEnv(), _prob, &x, i, i);
|
||||
return x;
|
||||
}
|
||||
|
||||
CplexLp::Value CplexLp::_getDual(int i) const {
|
||||
Value y;
|
||||
CPXgetpi(cplexEnv(), _prob, &y, i, i);
|
||||
return y;
|
||||
}
|
||||
|
||||
CplexLp::Value CplexLp::_getPrimalValue() const {
|
||||
Value objval;
|
||||
CPXgetobjval(cplexEnv(), _prob, &objval);
|
||||
return objval;
|
||||
}
|
||||
|
||||
CplexLp::VarStatus CplexLp::_getColStatus(int i) const {
|
||||
if (_col_status.empty()) {
|
||||
_col_status.resize(CPXgetnumcols(cplexEnv(), _prob));
|
||||
CPXgetbase(cplexEnv(), _prob, &_col_status.front(), 0);
|
||||
}
|
||||
switch (_col_status[i]) {
|
||||
case CPX_BASIC:
|
||||
return BASIC;
|
||||
case CPX_FREE_SUPER:
|
||||
return FREE;
|
||||
case CPX_AT_LOWER:
|
||||
return LOWER;
|
||||
case CPX_AT_UPPER:
|
||||
return UPPER;
|
||||
default:
|
||||
LEMON_ASSERT(false, "Wrong column status");
|
||||
return CplexLp::VarStatus();
|
||||
}
|
||||
}
|
||||
|
||||
CplexLp::VarStatus CplexLp::_getRowStatus(int i) const {
|
||||
if (_row_status.empty()) {
|
||||
_row_status.resize(CPXgetnumrows(cplexEnv(), _prob));
|
||||
CPXgetbase(cplexEnv(), _prob, 0, &_row_status.front());
|
||||
}
|
||||
switch (_row_status[i]) {
|
||||
case CPX_BASIC:
|
||||
return BASIC;
|
||||
case CPX_AT_LOWER:
|
||||
{
|
||||
char s;
|
||||
CPXgetsense(cplexEnv(), _prob, &s, i, i);
|
||||
return s != 'L' ? LOWER : UPPER;
|
||||
}
|
||||
case CPX_AT_UPPER:
|
||||
return UPPER;
|
||||
default:
|
||||
LEMON_ASSERT(false, "Wrong row status");
|
||||
return CplexLp::VarStatus();
|
||||
}
|
||||
}
|
||||
|
||||
CplexLp::Value CplexLp::_getPrimalRay(int i) const {
|
||||
if (_primal_ray.empty()) {
|
||||
_primal_ray.resize(CPXgetnumcols(cplexEnv(), _prob));
|
||||
CPXgetray(cplexEnv(), _prob, &_primal_ray.front());
|
||||
}
|
||||
return _primal_ray[i];
|
||||
}
|
||||
|
||||
CplexLp::Value CplexLp::_getDualRay(int i) const {
|
||||
if (_dual_ray.empty()) {
|
||||
|
||||
}
|
||||
return _dual_ray[i];
|
||||
}
|
||||
|
||||
// Cplex 7.0 status values
|
||||
// This table lists the statuses, returned by the CPXgetstat()
|
||||
// routine, for solutions to LP problems or mixed integer problems. If
|
||||
// no solution exists, the return value is zero.
|
||||
|
||||
// For Simplex, Barrier
|
||||
// 1 CPX_OPTIMAL
|
||||
// Optimal solution found
|
||||
// 2 CPX_INFEASIBLE
|
||||
// Problem infeasible
|
||||
// 3 CPX_UNBOUNDED
|
||||
// Problem unbounded
|
||||
// 4 CPX_OBJ_LIM
|
||||
// Objective limit exceeded in Phase II
|
||||
// 5 CPX_IT_LIM_FEAS
|
||||
// Iteration limit exceeded in Phase II
|
||||
// 6 CPX_IT_LIM_INFEAS
|
||||
// Iteration limit exceeded in Phase I
|
||||
// 7 CPX_TIME_LIM_FEAS
|
||||
// Time limit exceeded in Phase II
|
||||
// 8 CPX_TIME_LIM_INFEAS
|
||||
// Time limit exceeded in Phase I
|
||||
// 9 CPX_NUM_BEST_FEAS
|
||||
// Problem non-optimal, singularities in Phase II
|
||||
// 10 CPX_NUM_BEST_INFEAS
|
||||
// Problem non-optimal, singularities in Phase I
|
||||
// 11 CPX_OPTIMAL_INFEAS
|
||||
// Optimal solution found, unscaled infeasibilities
|
||||
// 12 CPX_ABORT_FEAS
|
||||
// Aborted in Phase II
|
||||
// 13 CPX_ABORT_INFEAS
|
||||
// Aborted in Phase I
|
||||
// 14 CPX_ABORT_DUAL_INFEAS
|
||||
// Aborted in barrier, dual infeasible
|
||||
// 15 CPX_ABORT_PRIM_INFEAS
|
||||
// Aborted in barrier, primal infeasible
|
||||
// 16 CPX_ABORT_PRIM_DUAL_INFEAS
|
||||
// Aborted in barrier, primal and dual infeasible
|
||||
// 17 CPX_ABORT_PRIM_DUAL_FEAS
|
||||
// Aborted in barrier, primal and dual feasible
|
||||
// 18 CPX_ABORT_CROSSOVER
|
||||
// Aborted in crossover
|
||||
// 19 CPX_INForUNBD
|
||||
// Infeasible or unbounded
|
||||
// 20 CPX_PIVOT
|
||||
// User pivot used
|
||||
//
|
||||
// Pending return values
|
||||
// ??case CPX_ABORT_DUAL_INFEAS
|
||||
// ??case CPX_ABORT_CROSSOVER
|
||||
// ??case CPX_INForUNBD
|
||||
// ??case CPX_PIVOT
|
||||
|
||||
//Some more interesting stuff:
|
||||
|
||||
// CPX_PARAM_PROBMETHOD 1062 int LPMETHOD
|
||||
// 0 Automatic
|
||||
// 1 Primal Simplex
|
||||
// 2 Dual Simplex
|
||||
// 3 Network Simplex
|
||||
// 4 Standard Barrier
|
||||
// Default: 0
|
||||
// Description: Method for linear optimization.
|
||||
// Determines which algorithm is used when CPXlpopt() (or "optimize"
|
||||
// in the Interactive Optimizer) is called. Currently the behavior of
|
||||
// the "Automatic" setting is that CPLEX simply invokes the dual
|
||||
// simplex method, but this capability may be expanded in the future
|
||||
// so that CPLEX chooses the method based on problem characteristics
|
||||
#if CPX_VERSION < 900
|
||||
void statusSwitch(CPXENVptr cplexEnv(),int& stat){
|
||||
int lpmethod;
|
||||
CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod);
|
||||
if (lpmethod==2){
|
||||
if (stat==CPX_UNBOUNDED){
|
||||
stat=CPX_INFEASIBLE;
|
||||
}
|
||||
else{
|
||||
if (stat==CPX_INFEASIBLE)
|
||||
stat=CPX_UNBOUNDED;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void statusSwitch(CPXENVptr,int&){}
|
||||
#endif
|
||||
|
||||
CplexLp::ProblemType CplexLp::_getPrimalType() const {
|
||||
// Unboundedness not treated well: the following is from cplex 9.0 doc
|
||||
// About Unboundedness
|
||||
|
||||
// The treatment of models that are unbounded involves a few
|
||||
// subtleties. Specifically, a declaration of unboundedness means that
|
||||
// ILOG CPLEX has determined that the model has an unbounded
|
||||
// ray. Given any feasible solution x with objective z, a multiple of
|
||||
// the unbounded ray can be added to x to give a feasible solution
|
||||
// with objective z-1 (or z+1 for maximization models). Thus, if a
|
||||
// feasible solution exists, then the optimal objective is
|
||||
// unbounded. Note that ILOG CPLEX has not necessarily concluded that
|
||||
// a feasible solution exists. Users can call the routine CPXsolninfo
|
||||
// to determine whether ILOG CPLEX has also concluded that the model
|
||||
// has a feasible solution.
|
||||
|
||||
int stat = CPXgetstat(cplexEnv(), _prob);
|
||||
#if CPX_VERSION >= 800
|
||||
switch (stat)
|
||||
{
|
||||
case CPX_STAT_OPTIMAL:
|
||||
return OPTIMAL;
|
||||
case CPX_STAT_UNBOUNDED:
|
||||
return UNBOUNDED;
|
||||
case CPX_STAT_INFEASIBLE:
|
||||
return INFEASIBLE;
|
||||
default:
|
||||
return UNDEFINED;
|
||||
}
|
||||
#else
|
||||
statusSwitch(cplexEnv(),stat);
|
||||
//CPXgetstat(cplexEnv(), _prob);
|
||||
switch (stat) {
|
||||
case 0:
|
||||
return UNDEFINED; //Undefined
|
||||
case CPX_OPTIMAL://Optimal
|
||||
return OPTIMAL;
|
||||
case CPX_UNBOUNDED://Unbounded
|
||||
return INFEASIBLE;//In case of dual simplex
|
||||
//return UNBOUNDED;
|
||||
case CPX_INFEASIBLE://Infeasible
|
||||
// case CPX_IT_LIM_INFEAS:
|
||||
// case CPX_TIME_LIM_INFEAS:
|
||||
// case CPX_NUM_BEST_INFEAS:
|
||||
// case CPX_OPTIMAL_INFEAS:
|
||||
// case CPX_ABORT_INFEAS:
|
||||
// case CPX_ABORT_PRIM_INFEAS:
|
||||
// case CPX_ABORT_PRIM_DUAL_INFEAS:
|
||||
return UNBOUNDED;//In case of dual simplex
|
||||
//return INFEASIBLE;
|
||||
// case CPX_OBJ_LIM:
|
||||
// case CPX_IT_LIM_FEAS:
|
||||
// case CPX_TIME_LIM_FEAS:
|
||||
// case CPX_NUM_BEST_FEAS:
|
||||
// case CPX_ABORT_FEAS:
|
||||
// case CPX_ABORT_PRIM_DUAL_FEAS:
|
||||
// return FEASIBLE;
|
||||
default:
|
||||
return UNDEFINED; //Everything else comes here
|
||||
//FIXME error
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Cplex 9.0 status values
|
||||
// CPX_STAT_ABORT_DUAL_OBJ_LIM
|
||||
// CPX_STAT_ABORT_IT_LIM
|
||||
// CPX_STAT_ABORT_OBJ_LIM
|
||||
// CPX_STAT_ABORT_PRIM_OBJ_LIM
|
||||
// CPX_STAT_ABORT_TIME_LIM
|
||||
// CPX_STAT_ABORT_USER
|
||||
// CPX_STAT_FEASIBLE_RELAXED
|
||||
// CPX_STAT_INFEASIBLE
|
||||
// CPX_STAT_INForUNBD
|
||||
// CPX_STAT_NUM_BEST
|
||||
// CPX_STAT_OPTIMAL
|
||||
// CPX_STAT_OPTIMAL_FACE_UNBOUNDED
|
||||
// CPX_STAT_OPTIMAL_INFEAS
|
||||
// CPX_STAT_OPTIMAL_RELAXED
|
||||
// CPX_STAT_UNBOUNDED
|
||||
|
||||
CplexLp::ProblemType CplexLp::_getDualType() const {
|
||||
int stat = CPXgetstat(cplexEnv(), _prob);
|
||||
#if CPX_VERSION >= 800
|
||||
switch (stat) {
|
||||
case CPX_STAT_OPTIMAL:
|
||||
return OPTIMAL;
|
||||
case CPX_STAT_UNBOUNDED:
|
||||
return INFEASIBLE;
|
||||
default:
|
||||
return UNDEFINED;
|
||||
}
|
||||
#else
|
||||
statusSwitch(cplexEnv(),stat);
|
||||
switch (stat) {
|
||||
case 0:
|
||||
return UNDEFINED; //Undefined
|
||||
case CPX_OPTIMAL://Optimal
|
||||
return OPTIMAL;
|
||||
case CPX_UNBOUNDED:
|
||||
return INFEASIBLE;
|
||||
default:
|
||||
return UNDEFINED; //Everything else comes here
|
||||
//FIXME error
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// CplexMip members
|
||||
|
||||
CplexMip::CplexMip()
|
||||
: LpBase(), MipSolver(), CplexBase() {
|
||||
|
||||
#if CPX_VERSION < 800
|
||||
CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MIP);
|
||||
#else
|
||||
CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MILP);
|
||||
#endif
|
||||
}
|
||||
|
||||
CplexMip::CplexMip(const CplexEnv& env)
|
||||
: LpBase(), MipSolver(), CplexBase(env) {
|
||||
|
||||
#if CPX_VERSION < 800
|
||||
CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MIP);
|
||||
#else
|
||||
CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MILP);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
CplexMip::CplexMip(const CplexMip& other)
|
||||
: LpBase(), MipSolver(), CplexBase(other) {}
|
||||
|
||||
CplexMip::~CplexMip() {}
|
||||
|
||||
CplexMip* CplexMip::newSolver() const { return new CplexMip; }
|
||||
CplexMip* CplexMip::cloneSolver() const {return new CplexMip(*this); }
|
||||
|
||||
const char* CplexMip::_solverName() const { return "CplexMip"; }
|
||||
|
||||
void CplexMip::_setColType(int i, CplexMip::ColTypes col_type) {
|
||||
|
||||
// Note If a variable is to be changed to binary, a call to CPXchgbds
|
||||
// should also be made to change the bounds to 0 and 1.
|
||||
|
||||
switch (col_type){
|
||||
case INTEGER: {
|
||||
const char t = 'I';
|
||||
CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
|
||||
} break;
|
||||
case REAL: {
|
||||
const char t = 'C';
|
||||
CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CplexMip::ColTypes CplexMip::_getColType(int i) const {
|
||||
char t;
|
||||
CPXgetctype (cplexEnv(), _prob, &t, i, i);
|
||||
switch (t) {
|
||||
case 'I':
|
||||
return INTEGER;
|
||||
case 'C':
|
||||
return REAL;
|
||||
default:
|
||||
LEMON_ASSERT(false, "Invalid column type");
|
||||
return ColTypes();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CplexMip::SolveExitStatus CplexMip::_solve() {
|
||||
int status;
|
||||
_applyMessageLevel();
|
||||
status = CPXmipopt (cplexEnv(), _prob);
|
||||
if (status==0)
|
||||
return SOLVED;
|
||||
else
|
||||
return UNSOLVED;
|
||||
|
||||
}
|
||||
|
||||
|
||||
CplexMip::ProblemType CplexMip::_getType() const {
|
||||
|
||||
int stat = CPXgetstat(cplexEnv(), _prob);
|
||||
|
||||
//Fortunately, MIP statuses did not change for cplex 8.0
|
||||
switch (stat) {
|
||||
case CPXMIP_OPTIMAL:
|
||||
// Optimal integer solution has been found.
|
||||
case CPXMIP_OPTIMAL_TOL:
|
||||
// Optimal soluton with the tolerance defined by epgap or epagap has
|
||||
// been found.
|
||||
return OPTIMAL;
|
||||
//This also exists in later issues
|
||||
// case CPXMIP_UNBOUNDED:
|
||||
//return UNBOUNDED;
|
||||
case CPXMIP_INFEASIBLE:
|
||||
return INFEASIBLE;
|
||||
default:
|
||||
return UNDEFINED;
|
||||
}
|
||||
//Unboundedness not treated well: the following is from cplex 9.0 doc
|
||||
// About Unboundedness
|
||||
|
||||
// The treatment of models that are unbounded involves a few
|
||||
// subtleties. Specifically, a declaration of unboundedness means that
|
||||
// ILOG CPLEX has determined that the model has an unbounded
|
||||
// ray. Given any feasible solution x with objective z, a multiple of
|
||||
// the unbounded ray can be added to x to give a feasible solution
|
||||
// with objective z-1 (or z+1 for maximization models). Thus, if a
|
||||
// feasible solution exists, then the optimal objective is
|
||||
// unbounded. Note that ILOG CPLEX has not necessarily concluded that
|
||||
// a feasible solution exists. Users can call the routine CPXsolninfo
|
||||
// to determine whether ILOG CPLEX has also concluded that the model
|
||||
// has a feasible solution.
|
||||
}
|
||||
|
||||
CplexMip::Value CplexMip::_getSol(int i) const {
|
||||
Value x;
|
||||
CPXgetmipx(cplexEnv(), _prob, &x, i, i);
|
||||
return x;
|
||||
}
|
||||
|
||||
CplexMip::Value CplexMip::_getSolValue() const {
|
||||
Value objval;
|
||||
CPXgetmipobjval(cplexEnv(), _prob, &objval);
|
||||
return objval;
|
||||
}
|
||||
|
||||
} //namespace lemon
|
||||
|
||||
292
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cplex.h
vendored
Normal file
292
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cplex.h
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_CPLEX_H
|
||||
#define LEMON_CPLEX_H
|
||||
|
||||
///\file
|
||||
///\brief Header of the LEMON-CPLEX lp solver interface.
|
||||
|
||||
#include <lemon/lp_base.h>
|
||||
|
||||
struct cpxenv;
|
||||
struct cpxlp;
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \brief Reference counted wrapper around cpxenv pointer
|
||||
///
|
||||
/// The cplex uses environment object which is responsible for
|
||||
/// checking the proper license usage. This class provides a simple
|
||||
/// interface for share the environment object between different
|
||||
/// problems.
|
||||
class CplexEnv {
|
||||
friend class CplexBase;
|
||||
private:
|
||||
cpxenv* _env;
|
||||
mutable int* _cnt;
|
||||
|
||||
public:
|
||||
|
||||
/// \brief This exception is thrown when the license check is not
|
||||
/// sufficient
|
||||
class LicenseError : public Exception {
|
||||
friend class CplexEnv;
|
||||
private:
|
||||
|
||||
LicenseError(int status);
|
||||
char _message[510];
|
||||
|
||||
public:
|
||||
|
||||
/// The short error message
|
||||
virtual const char* what() const throw() {
|
||||
return _message;
|
||||
}
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
CplexEnv();
|
||||
/// Shallow copy constructor
|
||||
CplexEnv(const CplexEnv&);
|
||||
/// Shallow assignement
|
||||
CplexEnv& operator=(const CplexEnv&);
|
||||
/// Destructor
|
||||
virtual ~CplexEnv();
|
||||
|
||||
protected:
|
||||
|
||||
cpxenv* cplexEnv() { return _env; }
|
||||
const cpxenv* cplexEnv() const { return _env; }
|
||||
};
|
||||
|
||||
/// \brief Base interface for the CPLEX LP and MIP solver
|
||||
///
|
||||
/// This class implements the common interface of the CPLEX LP and
|
||||
/// MIP solvers.
|
||||
/// \ingroup lp_group
|
||||
class CplexBase : virtual public LpBase {
|
||||
protected:
|
||||
|
||||
CplexEnv _env;
|
||||
cpxlp* _prob;
|
||||
|
||||
CplexBase();
|
||||
CplexBase(const CplexEnv&);
|
||||
CplexBase(const CplexBase &);
|
||||
virtual ~CplexBase();
|
||||
|
||||
virtual int _addCol();
|
||||
virtual int _addRow();
|
||||
virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
|
||||
|
||||
virtual void _eraseCol(int i);
|
||||
virtual void _eraseRow(int i);
|
||||
|
||||
virtual void _eraseColId(int i);
|
||||
virtual void _eraseRowId(int i);
|
||||
|
||||
virtual void _getColName(int col, std::string& name) const;
|
||||
virtual void _setColName(int col, const std::string& name);
|
||||
virtual int _colByName(const std::string& name) const;
|
||||
|
||||
virtual void _getRowName(int row, std::string& name) const;
|
||||
virtual void _setRowName(int row, const std::string& name);
|
||||
virtual int _rowByName(const std::string& name) const;
|
||||
|
||||
virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
|
||||
virtual void _getRowCoeffs(int i, InsertIterator b) const;
|
||||
|
||||
virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
|
||||
virtual void _getColCoeffs(int i, InsertIterator b) const;
|
||||
|
||||
virtual void _setCoeff(int row, int col, Value value);
|
||||
virtual Value _getCoeff(int row, int col) const;
|
||||
|
||||
virtual void _setColLowerBound(int i, Value value);
|
||||
virtual Value _getColLowerBound(int i) const;
|
||||
|
||||
virtual void _setColUpperBound(int i, Value value);
|
||||
virtual Value _getColUpperBound(int i) const;
|
||||
|
||||
private:
|
||||
void _set_row_bounds(int i, Value lb, Value ub);
|
||||
protected:
|
||||
|
||||
virtual void _setRowLowerBound(int i, Value value);
|
||||
virtual Value _getRowLowerBound(int i) const;
|
||||
|
||||
virtual void _setRowUpperBound(int i, Value value);
|
||||
virtual Value _getRowUpperBound(int i) const;
|
||||
|
||||
virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
|
||||
virtual void _getObjCoeffs(InsertIterator b) const;
|
||||
|
||||
virtual void _setObjCoeff(int i, Value obj_coef);
|
||||
virtual Value _getObjCoeff(int i) const;
|
||||
|
||||
virtual void _setSense(Sense sense);
|
||||
virtual Sense _getSense() const;
|
||||
|
||||
virtual void _clear();
|
||||
|
||||
virtual void _messageLevel(MessageLevel level);
|
||||
void _applyMessageLevel();
|
||||
|
||||
bool _message_enabled;
|
||||
|
||||
void _write(std::string file, std::string format) const;
|
||||
|
||||
public:
|
||||
|
||||
/// Returns the used \c CplexEnv instance
|
||||
const CplexEnv& env() const { return _env; }
|
||||
|
||||
/// \brief Returns the const cpxenv pointer
|
||||
///
|
||||
/// \note The cpxenv might be destructed with the solver.
|
||||
const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
|
||||
|
||||
/// \brief Returns the const cpxenv pointer
|
||||
///
|
||||
/// \note The cpxenv might be destructed with the solver.
|
||||
cpxenv* cplexEnv() { return _env.cplexEnv(); }
|
||||
|
||||
/// Returns the cplex problem object
|
||||
cpxlp* cplexLp() { return _prob; }
|
||||
/// Returns the cplex problem object
|
||||
const cpxlp* cplexLp() const { return _prob; }
|
||||
|
||||
#ifdef DOXYGEN
|
||||
/// Write the problem or the solution to a file in the given format
|
||||
|
||||
/// This function writes the problem or the solution
|
||||
/// to a file in the given format.
|
||||
/// Trying to write in an unsupported format will trigger
|
||||
/// \ref lemon::LpBase::UnsupportedFormatError "UnsupportedFormatError".
|
||||
/// \param file The file path
|
||||
/// \param format The output file format.
|
||||
/// Supportted formats are "MPS", "LP" and "SOL".
|
||||
void write(std::string file, std::string format = "MPS") const {}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/// \brief Interface for the CPLEX LP solver
|
||||
///
|
||||
/// This class implements an interface for the CPLEX LP solver.
|
||||
///\ingroup lp_group
|
||||
class CplexLp : public LpSolver, public CplexBase {
|
||||
public:
|
||||
/// \e
|
||||
CplexLp();
|
||||
/// \e
|
||||
CplexLp(const CplexEnv&);
|
||||
/// \e
|
||||
CplexLp(const CplexLp&);
|
||||
/// \e
|
||||
virtual ~CplexLp();
|
||||
|
||||
/// \e
|
||||
virtual CplexLp* cloneSolver() const;
|
||||
/// \e
|
||||
virtual CplexLp* newSolver() const;
|
||||
|
||||
private:
|
||||
|
||||
// these values cannot retrieved element by element
|
||||
mutable std::vector<int> _col_status;
|
||||
mutable std::vector<int> _row_status;
|
||||
|
||||
mutable std::vector<Value> _primal_ray;
|
||||
mutable std::vector<Value> _dual_ray;
|
||||
|
||||
void _clear_temporals();
|
||||
|
||||
SolveExitStatus convertStatus(int status);
|
||||
|
||||
protected:
|
||||
|
||||
virtual const char* _solverName() const;
|
||||
|
||||
virtual SolveExitStatus _solve();
|
||||
virtual Value _getPrimal(int i) const;
|
||||
virtual Value _getDual(int i) const;
|
||||
virtual Value _getPrimalValue() const;
|
||||
|
||||
virtual VarStatus _getColStatus(int i) const;
|
||||
virtual VarStatus _getRowStatus(int i) const;
|
||||
|
||||
virtual Value _getPrimalRay(int i) const;
|
||||
virtual Value _getDualRay(int i) const;
|
||||
|
||||
virtual ProblemType _getPrimalType() const;
|
||||
virtual ProblemType _getDualType() const;
|
||||
|
||||
public:
|
||||
|
||||
/// Solve with primal simplex method
|
||||
SolveExitStatus solvePrimal();
|
||||
|
||||
/// Solve with dual simplex method
|
||||
SolveExitStatus solveDual();
|
||||
|
||||
/// Solve with barrier method
|
||||
SolveExitStatus solveBarrier();
|
||||
|
||||
};
|
||||
|
||||
/// \brief Interface for the CPLEX MIP solver
|
||||
///
|
||||
/// This class implements an interface for the CPLEX MIP solver.
|
||||
///\ingroup lp_group
|
||||
class CplexMip : public MipSolver, public CplexBase {
|
||||
public:
|
||||
/// \e
|
||||
CplexMip();
|
||||
/// \e
|
||||
CplexMip(const CplexEnv&);
|
||||
/// \e
|
||||
CplexMip(const CplexMip&);
|
||||
/// \e
|
||||
virtual ~CplexMip();
|
||||
|
||||
/// \e
|
||||
virtual CplexMip* cloneSolver() const;
|
||||
/// \e
|
||||
virtual CplexMip* newSolver() const;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
virtual const char* _solverName() const;
|
||||
|
||||
virtual ColTypes _getColType(int col) const;
|
||||
virtual void _setColType(int col, ColTypes col_type);
|
||||
|
||||
virtual SolveExitStatus _solve();
|
||||
virtual ProblemType _getType() const;
|
||||
virtual Value _getSol(int i) const;
|
||||
virtual Value _getSolValue() const;
|
||||
|
||||
};
|
||||
|
||||
} //END OF NAMESPACE LEMON
|
||||
|
||||
#endif //LEMON_CPLEX_H
|
||||
|
||||
1230
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cycle_canceling.h
vendored
Normal file
1230
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/cycle_canceling.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1637
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/dfs.h
vendored
Normal file
1637
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/dfs.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
352
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/dheap.h
vendored
Normal file
352
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/dheap.h
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_DHEAP_H
|
||||
#define LEMON_DHEAP_H
|
||||
|
||||
///\ingroup heaps
|
||||
///\file
|
||||
///\brief D-ary heap implementation.
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \ingroup heaps
|
||||
///
|
||||
///\brief D-ary heap data structure.
|
||||
///
|
||||
/// This class implements the \e D-ary \e heap data structure.
|
||||
/// It fully conforms to the \ref concepts::Heap "heap concept".
|
||||
///
|
||||
/// The \ref DHeap "D-ary heap" is a generalization of the
|
||||
/// \ref BinHeap "binary heap" structure, its nodes have at most
|
||||
/// \c D children, instead of two.
|
||||
/// \ref BinHeap and \ref QuadHeap are specialized implementations
|
||||
/// of this structure for <tt>D=2</tt> and <tt>D=4</tt>, respectively.
|
||||
///
|
||||
/// \tparam PR Type of the priorities of the items.
|
||||
/// \tparam IM A read-writable item map with \c int values, used
|
||||
/// internally to handle the cross references.
|
||||
/// \tparam D The degree of the heap, each node have at most \e D
|
||||
/// children. The default is 16. Powers of two are suggested to use
|
||||
/// so that the multiplications and divisions needed to traverse the
|
||||
/// nodes of the heap could be performed faster.
|
||||
/// \tparam CMP A functor class for comparing the priorities.
|
||||
/// The default is \c std::less<PR>.
|
||||
///
|
||||
///\sa BinHeap
|
||||
///\sa FouraryHeap
|
||||
#ifdef DOXYGEN
|
||||
template <typename PR, typename IM, int D, typename CMP>
|
||||
#else
|
||||
template <typename PR, typename IM, int D = 16,
|
||||
typename CMP = std::less<PR> >
|
||||
#endif
|
||||
class DHeap {
|
||||
public:
|
||||
/// Type of the item-int map.
|
||||
typedef IM ItemIntMap;
|
||||
/// Type of the priorities.
|
||||
typedef PR Prio;
|
||||
/// Type of the items stored in the heap.
|
||||
typedef typename ItemIntMap::Key Item;
|
||||
/// Type of the item-priority pairs.
|
||||
typedef std::pair<Item,Prio> Pair;
|
||||
/// Functor type for comparing the priorities.
|
||||
typedef CMP Compare;
|
||||
|
||||
/// \brief Type to represent the states of the items.
|
||||
///
|
||||
/// Each item has a state associated to it. It can be "in heap",
|
||||
/// "pre-heap" or "post-heap". The latter two are indifferent from the
|
||||
/// heap's point of view, but may be useful to the user.
|
||||
///
|
||||
/// The item-int map must be initialized in such way that it assigns
|
||||
/// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
|
||||
enum State {
|
||||
IN_HEAP = 0, ///< = 0.
|
||||
PRE_HEAP = -1, ///< = -1.
|
||||
POST_HEAP = -2 ///< = -2.
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<Pair> _data;
|
||||
Compare _comp;
|
||||
ItemIntMap &_iim;
|
||||
|
||||
public:
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to the items.
|
||||
/// It is used internally to handle the cross references.
|
||||
/// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
explicit DHeap(ItemIntMap &map) : _iim(map) {}
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to the items.
|
||||
/// It is used internally to handle the cross references.
|
||||
/// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
/// \param comp The function object used for comparing the priorities.
|
||||
DHeap(ItemIntMap &map, const Compare &comp)
|
||||
: _iim(map), _comp(comp) {}
|
||||
|
||||
/// \brief The number of items stored in the heap.
|
||||
///
|
||||
/// This function returns the number of items stored in the heap.
|
||||
int size() const { return _data.size(); }
|
||||
|
||||
/// \brief Check if the heap is empty.
|
||||
///
|
||||
/// This function returns \c true if the heap is empty.
|
||||
bool empty() const { return _data.empty(); }
|
||||
|
||||
/// \brief Make the heap empty.
|
||||
///
|
||||
/// This functon makes the heap empty.
|
||||
/// It does not change the cross reference map. If you want to reuse
|
||||
/// a heap that is not surely empty, you should first clear it and
|
||||
/// then you should set the cross reference map to \c PRE_HEAP
|
||||
/// for each item.
|
||||
void clear() { _data.clear(); }
|
||||
|
||||
private:
|
||||
int parent(int i) { return (i-1)/D; }
|
||||
int firstChild(int i) { return D*i+1; }
|
||||
|
||||
bool less(const Pair &p1, const Pair &p2) const {
|
||||
return _comp(p1.second, p2.second);
|
||||
}
|
||||
|
||||
void bubbleUp(int hole, Pair p) {
|
||||
int par = parent(hole);
|
||||
while( hole>0 && less(p,_data[par]) ) {
|
||||
move(_data[par],hole);
|
||||
hole = par;
|
||||
par = parent(hole);
|
||||
}
|
||||
move(p, hole);
|
||||
}
|
||||
|
||||
void bubbleDown(int hole, Pair p, int length) {
|
||||
if( length>1 ) {
|
||||
int child = firstChild(hole);
|
||||
while( child+D<=length ) {
|
||||
int min=child;
|
||||
for (int i=1; i<D; ++i) {
|
||||
if( less(_data[child+i], _data[min]) )
|
||||
min=child+i;
|
||||
}
|
||||
if( !less(_data[min], p) )
|
||||
goto ok;
|
||||
move(_data[min], hole);
|
||||
hole = min;
|
||||
child = firstChild(hole);
|
||||
}
|
||||
if ( child<length ) {
|
||||
int min = child;
|
||||
while (++child < length) {
|
||||
if( less(_data[child], _data[min]) )
|
||||
min=child;
|
||||
}
|
||||
if( less(_data[min], p) ) {
|
||||
move(_data[min], hole);
|
||||
hole = min;
|
||||
}
|
||||
}
|
||||
}
|
||||
ok:
|
||||
move(p, hole);
|
||||
}
|
||||
|
||||
void move(const Pair &p, int i) {
|
||||
_data[i] = p;
|
||||
_iim.set(p.first, i);
|
||||
}
|
||||
|
||||
public:
|
||||
/// \brief Insert a pair of item and priority into the heap.
|
||||
///
|
||||
/// This function inserts \c p.first to the heap with priority
|
||||
/// \c p.second.
|
||||
/// \param p The pair to insert.
|
||||
/// \pre \c p.first must not be stored in the heap.
|
||||
void push(const Pair &p) {
|
||||
int n = _data.size();
|
||||
_data.resize(n+1);
|
||||
bubbleUp(n, p);
|
||||
}
|
||||
|
||||
/// \brief Insert an item into the heap with the given priority.
|
||||
///
|
||||
/// This function inserts the given item into the heap with the
|
||||
/// given priority.
|
||||
/// \param i The item to insert.
|
||||
/// \param p The priority of the item.
|
||||
/// \pre \e i must not be stored in the heap.
|
||||
void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
|
||||
|
||||
/// \brief Return the item having minimum priority.
|
||||
///
|
||||
/// This function returns the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Item top() const { return _data[0].first; }
|
||||
|
||||
/// \brief The minimum priority.
|
||||
///
|
||||
/// This function returns the minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Prio prio() const { return _data[0].second; }
|
||||
|
||||
/// \brief Remove the item having minimum priority.
|
||||
///
|
||||
/// This function removes the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
void pop() {
|
||||
int n = _data.size()-1;
|
||||
_iim.set(_data[0].first, POST_HEAP);
|
||||
if (n>0) bubbleDown(0, _data[n], n);
|
||||
_data.pop_back();
|
||||
}
|
||||
|
||||
/// \brief Remove the given item from the heap.
|
||||
///
|
||||
/// This function removes the given item from the heap if it is
|
||||
/// already stored.
|
||||
/// \param i The item to delete.
|
||||
/// \pre \e i must be in the heap.
|
||||
void erase(const Item &i) {
|
||||
int h = _iim[i];
|
||||
int n = _data.size()-1;
|
||||
_iim.set(_data[h].first, POST_HEAP);
|
||||
if( h<n ) {
|
||||
if( less(_data[parent(h)], _data[n]) )
|
||||
bubbleDown(h, _data[n], n);
|
||||
else
|
||||
bubbleUp(h, _data[n]);
|
||||
}
|
||||
_data.pop_back();
|
||||
}
|
||||
|
||||
/// \brief The priority of the given item.
|
||||
///
|
||||
/// This function returns the priority of the given item.
|
||||
/// \param i The item.
|
||||
/// \pre \e i must be in the heap.
|
||||
Prio operator[](const Item &i) const {
|
||||
int idx = _iim[i];
|
||||
return _data[idx].second;
|
||||
}
|
||||
|
||||
/// \brief Set the priority of an item or insert it, if it is
|
||||
/// not stored in the heap.
|
||||
///
|
||||
/// This method sets the priority of the given item if it is
|
||||
/// already stored in the heap. Otherwise it inserts the given
|
||||
/// item into the heap with the given priority.
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
void set(const Item &i, const Prio &p) {
|
||||
int idx = _iim[i];
|
||||
if( idx<0 )
|
||||
push(i,p);
|
||||
else if( _comp(p, _data[idx].second) )
|
||||
bubbleUp(idx, Pair(i,p));
|
||||
else
|
||||
bubbleDown(idx, Pair(i,p), _data.size());
|
||||
}
|
||||
|
||||
/// \brief Decrease the priority of an item to the given value.
|
||||
///
|
||||
/// This function decreases the priority of an item to the given value.
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
/// \pre \e i must be stored in the heap with priority at least \e p.
|
||||
void decrease(const Item &i, const Prio &p) {
|
||||
int idx = _iim[i];
|
||||
bubbleUp(idx, Pair(i,p));
|
||||
}
|
||||
|
||||
/// \brief Increase the priority of an item to the given value.
|
||||
///
|
||||
/// This function increases the priority of an item to the given value.
|
||||
/// \param i The item.
|
||||
/// \param p The priority.
|
||||
/// \pre \e i must be stored in the heap with priority at most \e p.
|
||||
void increase(const Item &i, const Prio &p) {
|
||||
int idx = _iim[i];
|
||||
bubbleDown(idx, Pair(i,p), _data.size());
|
||||
}
|
||||
|
||||
/// \brief Return the state of an item.
|
||||
///
|
||||
/// This method returns \c PRE_HEAP if the given item has never
|
||||
/// been in the heap, \c IN_HEAP if it is in the heap at the moment,
|
||||
/// and \c POST_HEAP otherwise.
|
||||
/// In the latter case it is possible that the item will get back
|
||||
/// to the heap again.
|
||||
/// \param i The item.
|
||||
State state(const Item &i) const {
|
||||
int s = _iim[i];
|
||||
if (s>=0) s=0;
|
||||
return State(s);
|
||||
}
|
||||
|
||||
/// \brief Set the state of an item in the heap.
|
||||
///
|
||||
/// This function sets the state of the given item in the heap.
|
||||
/// It can be used to manually clear the heap when it is important
|
||||
/// to achive better time complexity.
|
||||
/// \param i The item.
|
||||
/// \param st The state. It should not be \c IN_HEAP.
|
||||
void state(const Item& i, State st) {
|
||||
switch (st) {
|
||||
case POST_HEAP:
|
||||
case PRE_HEAP:
|
||||
if (state(i) == IN_HEAP) erase(i);
|
||||
_iim[i] = st;
|
||||
break;
|
||||
case IN_HEAP:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Replace an item in the heap.
|
||||
///
|
||||
/// This function replaces item \c i with item \c j.
|
||||
/// Item \c i must be in the heap, while \c j must be out of the heap.
|
||||
/// After calling this method, item \c i will be out of the
|
||||
/// heap and \c j will be in the heap with the same prioriority
|
||||
/// as item \c i had before.
|
||||
void replace(const Item& i, const Item& j) {
|
||||
int idx=_iim[i];
|
||||
_iim.set(i, _iim[j]);
|
||||
_iim.set(j, idx);
|
||||
_data[idx].first=j;
|
||||
}
|
||||
|
||||
}; // class DHeap
|
||||
|
||||
} // namespace lemon
|
||||
|
||||
#endif // LEMON_DHEAP_H
|
||||
1303
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/dijkstra.h
vendored
Normal file
1303
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/dijkstra.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
726
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/dim2.h
vendored
Normal file
726
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/dim2.h
vendored
Normal file
@@ -0,0 +1,726 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_DIM2_H
|
||||
#define LEMON_DIM2_H
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
///\ingroup geomdat
|
||||
///\file
|
||||
///\brief A simple two dimensional vector and a bounding box implementation
|
||||
|
||||
namespace lemon {
|
||||
|
||||
///Tools for handling two dimensional coordinates
|
||||
|
||||
///This namespace is a storage of several
|
||||
///tools for handling two dimensional coordinates
|
||||
namespace dim2 {
|
||||
|
||||
/// \addtogroup geomdat
|
||||
/// @{
|
||||
|
||||
/// Two dimensional vector (plain vector)
|
||||
|
||||
/// A simple two dimensional vector (plain vector) implementation
|
||||
/// with the usual vector operations.
|
||||
template<typename T>
|
||||
class Point {
|
||||
|
||||
public:
|
||||
|
||||
typedef T Value;
|
||||
|
||||
///First coordinate
|
||||
T x;
|
||||
///Second coordinate
|
||||
T y;
|
||||
|
||||
///Default constructor
|
||||
Point() {}
|
||||
|
||||
///Construct an instance from coordinates
|
||||
Point(T a, T b) : x(a), y(b) { }
|
||||
|
||||
///Returns the dimension of the vector (i.e. returns 2).
|
||||
|
||||
///The dimension of the vector.
|
||||
///This function always returns 2.
|
||||
int size() const { return 2; }
|
||||
|
||||
///Subscripting operator
|
||||
|
||||
///\c p[0] is \c p.x and \c p[1] is \c p.y
|
||||
///
|
||||
T& operator[](int idx) { return idx == 0 ? x : y; }
|
||||
|
||||
///Const subscripting operator
|
||||
|
||||
///\c p[0] is \c p.x and \c p[1] is \c p.y
|
||||
///
|
||||
const T& operator[](int idx) const { return idx == 0 ? x : y; }
|
||||
|
||||
///Conversion constructor
|
||||
template<class TT> Point(const Point<TT> &p) : x(p.x), y(p.y) {}
|
||||
|
||||
///Give back the square of the norm of the vector
|
||||
T normSquare() const {
|
||||
return x*x+y*y;
|
||||
}
|
||||
|
||||
///Increment the left hand side by \c u
|
||||
Point<T>& operator +=(const Point<T>& u) {
|
||||
x += u.x;
|
||||
y += u.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///Decrement the left hand side by \c u
|
||||
Point<T>& operator -=(const Point<T>& u) {
|
||||
x -= u.x;
|
||||
y -= u.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///Multiply the left hand side with a scalar
|
||||
Point<T>& operator *=(const T &u) {
|
||||
x *= u;
|
||||
y *= u;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///Divide the left hand side by a scalar
|
||||
Point<T>& operator /=(const T &u) {
|
||||
x /= u;
|
||||
y /= u;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///Return the scalar product of two vectors
|
||||
T operator *(const Point<T>& u) const {
|
||||
return x*u.x+y*u.y;
|
||||
}
|
||||
|
||||
///Return the sum of two vectors
|
||||
Point<T> operator+(const Point<T> &u) const {
|
||||
Point<T> b=*this;
|
||||
return b+=u;
|
||||
}
|
||||
|
||||
///Return the negative of the vector
|
||||
Point<T> operator-() const {
|
||||
Point<T> b=*this;
|
||||
b.x=-b.x; b.y=-b.y;
|
||||
return b;
|
||||
}
|
||||
|
||||
///Return the difference of two vectors
|
||||
Point<T> operator-(const Point<T> &u) const {
|
||||
Point<T> b=*this;
|
||||
return b-=u;
|
||||
}
|
||||
|
||||
///Return a vector multiplied by a scalar
|
||||
Point<T> operator*(const T &u) const {
|
||||
Point<T> b=*this;
|
||||
return b*=u;
|
||||
}
|
||||
|
||||
///Return a vector divided by a scalar
|
||||
Point<T> operator/(const T &u) const {
|
||||
Point<T> b=*this;
|
||||
return b/=u;
|
||||
}
|
||||
|
||||
///Test equality
|
||||
bool operator==(const Point<T> &u) const {
|
||||
return (x==u.x) && (y==u.y);
|
||||
}
|
||||
|
||||
///Test inequality
|
||||
bool operator!=(Point u) const {
|
||||
return (x!=u.x) || (y!=u.y);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
///Return a Point
|
||||
|
||||
///Return a Point.
|
||||
///\relates Point
|
||||
template <typename T>
|
||||
inline Point<T> makePoint(const T& x, const T& y) {
|
||||
return Point<T>(x, y);
|
||||
}
|
||||
|
||||
///Return a vector multiplied by a scalar
|
||||
|
||||
///Return a vector multiplied by a scalar.
|
||||
///\relates Point
|
||||
template<typename T> Point<T> operator*(const T &u,const Point<T> &x) {
|
||||
return x*u;
|
||||
}
|
||||
|
||||
///Read a plain vector from a stream
|
||||
|
||||
///Read a plain vector from a stream.
|
||||
///\relates Point
|
||||
///
|
||||
template<typename T>
|
||||
inline std::istream& operator>>(std::istream &is, Point<T> &z) {
|
||||
char c;
|
||||
if (is >> c) {
|
||||
if (c != '(') is.putback(c);
|
||||
} else {
|
||||
is.clear();
|
||||
}
|
||||
if (!(is >> z.x)) return is;
|
||||
if (is >> c) {
|
||||
if (c != ',') is.putback(c);
|
||||
} else {
|
||||
is.clear();
|
||||
}
|
||||
if (!(is >> z.y)) return is;
|
||||
if (is >> c) {
|
||||
if (c != ')') is.putback(c);
|
||||
} else {
|
||||
is.clear();
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
///Write a plain vector to a stream
|
||||
|
||||
///Write a plain vector to a stream.
|
||||
///\relates Point
|
||||
///
|
||||
template<typename T>
|
||||
inline std::ostream& operator<<(std::ostream &os, const Point<T>& z)
|
||||
{
|
||||
os << "(" << z.x << "," << z.y << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
///Rotate by 90 degrees
|
||||
|
||||
///Returns the parameter rotated by 90 degrees in positive direction.
|
||||
///\relates Point
|
||||
///
|
||||
template<typename T>
|
||||
inline Point<T> rot90(const Point<T> &z)
|
||||
{
|
||||
return Point<T>(-z.y,z.x);
|
||||
}
|
||||
|
||||
///Rotate by 180 degrees
|
||||
|
||||
///Returns the parameter rotated by 180 degrees.
|
||||
///\relates Point
|
||||
///
|
||||
template<typename T>
|
||||
inline Point<T> rot180(const Point<T> &z)
|
||||
{
|
||||
return Point<T>(-z.x,-z.y);
|
||||
}
|
||||
|
||||
///Rotate by 270 degrees
|
||||
|
||||
///Returns the parameter rotated by 90 degrees in negative direction.
|
||||
///\relates Point
|
||||
///
|
||||
template<typename T>
|
||||
inline Point<T> rot270(const Point<T> &z)
|
||||
{
|
||||
return Point<T>(z.y,-z.x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Bounding box of plain vectors (points).
|
||||
|
||||
/// A class to calculate or store the bounding box of plain vectors
|
||||
/// (\ref Point "points").
|
||||
template<typename T>
|
||||
class Box {
|
||||
Point<T> _bottom_left, _top_right;
|
||||
bool _empty;
|
||||
public:
|
||||
|
||||
///Default constructor: creates an empty box
|
||||
Box() { _empty = true; }
|
||||
|
||||
///Construct a box from one point
|
||||
Box(Point<T> a) {
|
||||
_bottom_left = _top_right = a;
|
||||
_empty = false;
|
||||
}
|
||||
|
||||
///Construct a box from two points
|
||||
|
||||
///Construct a box from two points.
|
||||
///\param a The bottom left corner.
|
||||
///\param b The top right corner.
|
||||
///\warning The coordinates of the bottom left corner must be no more
|
||||
///than those of the top right one.
|
||||
Box(Point<T> a,Point<T> b)
|
||||
{
|
||||
_bottom_left = a;
|
||||
_top_right = b;
|
||||
_empty = false;
|
||||
}
|
||||
|
||||
///Construct a box from four numbers
|
||||
|
||||
///Construct a box from four numbers.
|
||||
///\param l The left side of the box.
|
||||
///\param b The bottom of the box.
|
||||
///\param r The right side of the box.
|
||||
///\param t The top of the box.
|
||||
///\warning The left side must be no more than the right side and
|
||||
///bottom must be no more than the top.
|
||||
Box(T l,T b,T r,T t)
|
||||
{
|
||||
_bottom_left=Point<T>(l,b);
|
||||
_top_right=Point<T>(r,t);
|
||||
_empty = false;
|
||||
}
|
||||
|
||||
///Return \c true if the box is empty.
|
||||
|
||||
///Return \c true if the box is empty (i.e. return \c false
|
||||
///if at least one point was added to the box or the coordinates of
|
||||
///the box were set).
|
||||
///
|
||||
///The coordinates of an empty box are not defined.
|
||||
bool empty() const {
|
||||
return _empty;
|
||||
}
|
||||
|
||||
///Make the box empty
|
||||
void clear() {
|
||||
_empty = true;
|
||||
}
|
||||
|
||||
///Give back the bottom left corner of the box
|
||||
|
||||
///Give back the bottom left corner of the box.
|
||||
///If the box is empty, then the return value is not defined.
|
||||
Point<T> bottomLeft() const {
|
||||
return _bottom_left;
|
||||
}
|
||||
|
||||
///Set the bottom left corner of the box
|
||||
|
||||
///Set the bottom left corner of the box.
|
||||
///\pre The box must not be empty.
|
||||
void bottomLeft(Point<T> p) {
|
||||
_bottom_left = p;
|
||||
}
|
||||
|
||||
///Give back the top right corner of the box
|
||||
|
||||
///Give back the top right corner of the box.
|
||||
///If the box is empty, then the return value is not defined.
|
||||
Point<T> topRight() const {
|
||||
return _top_right;
|
||||
}
|
||||
|
||||
///Set the top right corner of the box
|
||||
|
||||
///Set the top right corner of the box.
|
||||
///\pre The box must not be empty.
|
||||
void topRight(Point<T> p) {
|
||||
_top_right = p;
|
||||
}
|
||||
|
||||
///Give back the bottom right corner of the box
|
||||
|
||||
///Give back the bottom right corner of the box.
|
||||
///If the box is empty, then the return value is not defined.
|
||||
Point<T> bottomRight() const {
|
||||
return Point<T>(_top_right.x,_bottom_left.y);
|
||||
}
|
||||
|
||||
///Set the bottom right corner of the box
|
||||
|
||||
///Set the bottom right corner of the box.
|
||||
///\pre The box must not be empty.
|
||||
void bottomRight(Point<T> p) {
|
||||
_top_right.x = p.x;
|
||||
_bottom_left.y = p.y;
|
||||
}
|
||||
|
||||
///Give back the top left corner of the box
|
||||
|
||||
///Give back the top left corner of the box.
|
||||
///If the box is empty, then the return value is not defined.
|
||||
Point<T> topLeft() const {
|
||||
return Point<T>(_bottom_left.x,_top_right.y);
|
||||
}
|
||||
|
||||
///Set the top left corner of the box
|
||||
|
||||
///Set the top left corner of the box.
|
||||
///\pre The box must not be empty.
|
||||
void topLeft(Point<T> p) {
|
||||
_top_right.y = p.y;
|
||||
_bottom_left.x = p.x;
|
||||
}
|
||||
|
||||
///Give back the bottom of the box
|
||||
|
||||
///Give back the bottom of the box.
|
||||
///If the box is empty, then the return value is not defined.
|
||||
T bottom() const {
|
||||
return _bottom_left.y;
|
||||
}
|
||||
|
||||
///Set the bottom of the box
|
||||
|
||||
///Set the bottom of the box.
|
||||
///\pre The box must not be empty.
|
||||
void bottom(T t) {
|
||||
_bottom_left.y = t;
|
||||
}
|
||||
|
||||
///Give back the top of the box
|
||||
|
||||
///Give back the top of the box.
|
||||
///If the box is empty, then the return value is not defined.
|
||||
T top() const {
|
||||
return _top_right.y;
|
||||
}
|
||||
|
||||
///Set the top of the box
|
||||
|
||||
///Set the top of the box.
|
||||
///\pre The box must not be empty.
|
||||
void top(T t) {
|
||||
_top_right.y = t;
|
||||
}
|
||||
|
||||
///Give back the left side of the box
|
||||
|
||||
///Give back the left side of the box.
|
||||
///If the box is empty, then the return value is not defined.
|
||||
T left() const {
|
||||
return _bottom_left.x;
|
||||
}
|
||||
|
||||
///Set the left side of the box
|
||||
|
||||
///Set the left side of the box.
|
||||
///\pre The box must not be empty.
|
||||
void left(T t) {
|
||||
_bottom_left.x = t;
|
||||
}
|
||||
|
||||
/// Give back the right side of the box
|
||||
|
||||
/// Give back the right side of the box.
|
||||
///If the box is empty, then the return value is not defined.
|
||||
T right() const {
|
||||
return _top_right.x;
|
||||
}
|
||||
|
||||
///Set the right side of the box
|
||||
|
||||
///Set the right side of the box.
|
||||
///\pre The box must not be empty.
|
||||
void right(T t) {
|
||||
_top_right.x = t;
|
||||
}
|
||||
|
||||
///Give back the height of the box
|
||||
|
||||
///Give back the height of the box.
|
||||
///If the box is empty, then the return value is not defined.
|
||||
T height() const {
|
||||
return _top_right.y-_bottom_left.y;
|
||||
}
|
||||
|
||||
///Give back the width of the box
|
||||
|
||||
///Give back the width of the box.
|
||||
///If the box is empty, then the return value is not defined.
|
||||
T width() const {
|
||||
return _top_right.x-_bottom_left.x;
|
||||
}
|
||||
|
||||
///Checks whether a point is inside the box
|
||||
bool inside(const Point<T>& u) const {
|
||||
if (_empty)
|
||||
return false;
|
||||
else {
|
||||
return ( (u.x-_bottom_left.x)*(_top_right.x-u.x) >= 0 &&
|
||||
(u.y-_bottom_left.y)*(_top_right.y-u.y) >= 0 );
|
||||
}
|
||||
}
|
||||
|
||||
///Increments the box with a point
|
||||
|
||||
///Increments the box with a point.
|
||||
///
|
||||
Box& add(const Point<T>& u){
|
||||
if (_empty) {
|
||||
_bottom_left = _top_right = u;
|
||||
_empty = false;
|
||||
}
|
||||
else {
|
||||
if (_bottom_left.x > u.x) _bottom_left.x = u.x;
|
||||
if (_bottom_left.y > u.y) _bottom_left.y = u.y;
|
||||
if (_top_right.x < u.x) _top_right.x = u.x;
|
||||
if (_top_right.y < u.y) _top_right.y = u.y;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///Increments the box to contain another box
|
||||
|
||||
///Increments the box to contain another box.
|
||||
///
|
||||
Box& add(const Box &u){
|
||||
if ( !u.empty() ){
|
||||
add(u._bottom_left);
|
||||
add(u._top_right);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///Intersection of two boxes
|
||||
|
||||
///Intersection of two boxes.
|
||||
///
|
||||
Box operator&(const Box& u) const {
|
||||
Box b;
|
||||
if (_empty || u._empty) {
|
||||
b._empty = true;
|
||||
} else {
|
||||
b._bottom_left.x = std::max(_bottom_left.x, u._bottom_left.x);
|
||||
b._bottom_left.y = std::max(_bottom_left.y, u._bottom_left.y);
|
||||
b._top_right.x = std::min(_top_right.x, u._top_right.x);
|
||||
b._top_right.y = std::min(_top_right.y, u._top_right.y);
|
||||
b._empty = b._bottom_left.x > b._top_right.x ||
|
||||
b._bottom_left.y > b._top_right.y;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
};//class Box
|
||||
|
||||
|
||||
///Read a box from a stream
|
||||
|
||||
///Read a box from a stream.
|
||||
///\relates Box
|
||||
template<typename T>
|
||||
inline std::istream& operator>>(std::istream &is, Box<T>& b) {
|
||||
char c;
|
||||
Point<T> p;
|
||||
if (is >> c) {
|
||||
if (c != '(') is.putback(c);
|
||||
} else {
|
||||
is.clear();
|
||||
}
|
||||
if (!(is >> p)) return is;
|
||||
b.bottomLeft(p);
|
||||
if (is >> c) {
|
||||
if (c != ',') is.putback(c);
|
||||
} else {
|
||||
is.clear();
|
||||
}
|
||||
if (!(is >> p)) return is;
|
||||
b.topRight(p);
|
||||
if (is >> c) {
|
||||
if (c != ')') is.putback(c);
|
||||
} else {
|
||||
is.clear();
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
///Write a box to a stream
|
||||
|
||||
///Write a box to a stream.
|
||||
///\relates Box
|
||||
template<typename T>
|
||||
inline std::ostream& operator<<(std::ostream &os, const Box<T>& b)
|
||||
{
|
||||
os << "(" << b.bottomLeft() << "," << b.topRight() << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
///Map of x-coordinates of a <tt>Point</tt>-map
|
||||
|
||||
///Map of x-coordinates of a \ref Point "Point"-map.
|
||||
///
|
||||
template<class M>
|
||||
class XMap
|
||||
{
|
||||
M& _map;
|
||||
public:
|
||||
|
||||
typedef typename M::Value::Value Value;
|
||||
typedef typename M::Key Key;
|
||||
///\e
|
||||
XMap(M& map) : _map(map) {}
|
||||
Value operator[](Key k) const {return _map[k].x;}
|
||||
void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
|
||||
};
|
||||
|
||||
///Returns an XMap class
|
||||
|
||||
///This function just returns an XMap class.
|
||||
///\relates XMap
|
||||
template<class M>
|
||||
inline XMap<M> xMap(M &m)
|
||||
{
|
||||
return XMap<M>(m);
|
||||
}
|
||||
|
||||
template<class M>
|
||||
inline XMap<M> xMap(const M &m)
|
||||
{
|
||||
return XMap<M>(m);
|
||||
}
|
||||
|
||||
///Constant (read only) version of XMap
|
||||
|
||||
///Constant (read only) version of XMap.
|
||||
///
|
||||
template<class M>
|
||||
class ConstXMap
|
||||
{
|
||||
const M& _map;
|
||||
public:
|
||||
|
||||
typedef typename M::Value::Value Value;
|
||||
typedef typename M::Key Key;
|
||||
///\e
|
||||
ConstXMap(const M &map) : _map(map) {}
|
||||
Value operator[](Key k) const {return _map[k].x;}
|
||||
};
|
||||
|
||||
///Returns a ConstXMap class
|
||||
|
||||
///This function just returns a ConstXMap class.
|
||||
///\relates ConstXMap
|
||||
template<class M>
|
||||
inline ConstXMap<M> xMap(const M &m)
|
||||
{
|
||||
return ConstXMap<M>(m);
|
||||
}
|
||||
|
||||
///Map of y-coordinates of a <tt>Point</tt>-map
|
||||
|
||||
///Map of y-coordinates of a \ref Point "Point"-map.
|
||||
///
|
||||
template<class M>
|
||||
class YMap
|
||||
{
|
||||
M& _map;
|
||||
public:
|
||||
|
||||
typedef typename M::Value::Value Value;
|
||||
typedef typename M::Key Key;
|
||||
///\e
|
||||
YMap(M& map) : _map(map) {}
|
||||
Value operator[](Key k) const {return _map[k].y;}
|
||||
void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
|
||||
};
|
||||
|
||||
///Returns a YMap class
|
||||
|
||||
///This function just returns a YMap class.
|
||||
///\relates YMap
|
||||
template<class M>
|
||||
inline YMap<M> yMap(M &m)
|
||||
{
|
||||
return YMap<M>(m);
|
||||
}
|
||||
|
||||
template<class M>
|
||||
inline YMap<M> yMap(const M &m)
|
||||
{
|
||||
return YMap<M>(m);
|
||||
}
|
||||
|
||||
///Constant (read only) version of YMap
|
||||
|
||||
///Constant (read only) version of YMap.
|
||||
///
|
||||
template<class M>
|
||||
class ConstYMap
|
||||
{
|
||||
const M& _map;
|
||||
public:
|
||||
|
||||
typedef typename M::Value::Value Value;
|
||||
typedef typename M::Key Key;
|
||||
///\e
|
||||
ConstYMap(const M &map) : _map(map) {}
|
||||
Value operator[](Key k) const {return _map[k].y;}
|
||||
};
|
||||
|
||||
///Returns a ConstYMap class
|
||||
|
||||
///This function just returns a ConstYMap class.
|
||||
///\relates ConstYMap
|
||||
template<class M>
|
||||
inline ConstYMap<M> yMap(const M &m)
|
||||
{
|
||||
return ConstYMap<M>(m);
|
||||
}
|
||||
|
||||
|
||||
///\brief Map of the normSquare() of a <tt>Point</tt>-map
|
||||
///
|
||||
///Map of the \ref Point::normSquare() "normSquare()"
|
||||
///of a \ref Point "Point"-map.
|
||||
template<class M>
|
||||
class NormSquareMap
|
||||
{
|
||||
const M& _map;
|
||||
public:
|
||||
|
||||
typedef typename M::Value::Value Value;
|
||||
typedef typename M::Key Key;
|
||||
///\e
|
||||
NormSquareMap(const M &map) : _map(map) {}
|
||||
Value operator[](Key k) const {return _map[k].normSquare();}
|
||||
};
|
||||
|
||||
///Returns a NormSquareMap class
|
||||
|
||||
///This function just returns a NormSquareMap class.
|
||||
///\relates NormSquareMap
|
||||
template<class M>
|
||||
inline NormSquareMap<M> normSquareMap(const M &m)
|
||||
{
|
||||
return NormSquareMap<M>(m);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
} //namespce dim2
|
||||
|
||||
} //namespace lemon
|
||||
|
||||
#endif //LEMON_DIM2_H
|
||||
448
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/dimacs.h
vendored
Normal file
448
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/dimacs.h
vendored
Normal file
@@ -0,0 +1,448 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_DIMACS_H
|
||||
#define LEMON_DIMACS_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <lemon/maps.h>
|
||||
#include <lemon/error.h>
|
||||
/// \ingroup dimacs_group
|
||||
/// \file
|
||||
/// \brief DIMACS file format reader.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \addtogroup dimacs_group
|
||||
/// @{
|
||||
|
||||
/// DIMACS file type descriptor.
|
||||
struct DimacsDescriptor
|
||||
{
|
||||
///\brief DIMACS file type enum
|
||||
///
|
||||
///DIMACS file type enum.
|
||||
enum Type {
|
||||
NONE, ///< Undefined type.
|
||||
MIN, ///< DIMACS file type for minimum cost flow problems.
|
||||
MAX, ///< DIMACS file type for maximum flow problems.
|
||||
SP, ///< DIMACS file type for shostest path problems.
|
||||
MAT ///< DIMACS file type for plain graphs and matching problems.
|
||||
};
|
||||
///The file type
|
||||
Type type;
|
||||
///The number of nodes in the graph
|
||||
int nodeNum;
|
||||
///The number of edges in the graph
|
||||
int edgeNum;
|
||||
int lineShift;
|
||||
///Constructor. It sets the type to \c NONE.
|
||||
DimacsDescriptor() : type(NONE) {}
|
||||
};
|
||||
|
||||
///Discover the type of a DIMACS file
|
||||
|
||||
///This function starts seeking the beginning of the given file for the
|
||||
///problem type and size info.
|
||||
///The found data is returned in a special struct that can be evaluated
|
||||
///and passed to the appropriate reader function.
|
||||
DimacsDescriptor dimacsType(std::istream& is)
|
||||
{
|
||||
DimacsDescriptor r;
|
||||
std::string problem,str;
|
||||
char c;
|
||||
r.lineShift=0;
|
||||
while (is >> c)
|
||||
switch(c)
|
||||
{
|
||||
case 'p':
|
||||
if(is >> problem >> r.nodeNum >> r.edgeNum)
|
||||
{
|
||||
getline(is, str);
|
||||
r.lineShift++;
|
||||
if(problem=="min") r.type=DimacsDescriptor::MIN;
|
||||
else if(problem=="max") r.type=DimacsDescriptor::MAX;
|
||||
else if(problem=="sp") r.type=DimacsDescriptor::SP;
|
||||
else if(problem=="mat") r.type=DimacsDescriptor::MAT;
|
||||
else throw FormatError("Unknown problem type");
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw FormatError("Missing or wrong problem type declaration.");
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
getline(is, str);
|
||||
r.lineShift++;
|
||||
break;
|
||||
default:
|
||||
throw FormatError("Unknown DIMACS declaration.");
|
||||
}
|
||||
throw FormatError("Missing problem type declaration.");
|
||||
}
|
||||
|
||||
|
||||
/// \brief DIMACS minimum cost flow reader function.
|
||||
///
|
||||
/// This function reads a minimum cost flow instance from DIMACS format,
|
||||
/// i.e. from a DIMACS file having a line starting with
|
||||
/// \code
|
||||
/// p min
|
||||
/// \endcode
|
||||
/// At the beginning, \c g is cleared by \c g.clear(). The supply
|
||||
/// amount of the nodes are written to the \c supply node map
|
||||
/// (they are signed values). The lower bounds, capacities and costs
|
||||
/// of the arcs are written to the \c lower, \c capacity and \c cost
|
||||
/// arc maps.
|
||||
///
|
||||
/// If the capacity of an arc is less than the lower bound, it will
|
||||
/// be set to "infinite" instead. The actual value of "infinite" is
|
||||
/// contolled by the \c infty parameter. If it is 0 (the default value),
|
||||
/// \c std::numeric_limits<Capacity>::infinity() will be used if available,
|
||||
/// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
|
||||
/// a non-zero value, that value will be used as "infinite".
|
||||
///
|
||||
/// If the file type was previously evaluated by dimacsType(), then
|
||||
/// the descriptor struct should be given by the \c dest parameter.
|
||||
template <typename Digraph, typename LowerMap,
|
||||
typename CapacityMap, typename CostMap,
|
||||
typename SupplyMap>
|
||||
void readDimacsMin(std::istream& is,
|
||||
Digraph &g,
|
||||
LowerMap& lower,
|
||||
CapacityMap& capacity,
|
||||
CostMap& cost,
|
||||
SupplyMap& supply,
|
||||
typename CapacityMap::Value infty = 0,
|
||||
DimacsDescriptor desc=DimacsDescriptor())
|
||||
{
|
||||
g.clear();
|
||||
std::vector<typename Digraph::Node> nodes;
|
||||
typename Digraph::Arc e;
|
||||
std::string problem, str;
|
||||
char c;
|
||||
int i, j;
|
||||
if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
|
||||
if(desc.type!=DimacsDescriptor::MIN)
|
||||
throw FormatError("Problem type mismatch");
|
||||
|
||||
nodes.resize(desc.nodeNum + 1);
|
||||
for (int k = 1; k <= desc.nodeNum; ++k) {
|
||||
nodes[k] = g.addNode();
|
||||
supply.set(nodes[k], 0);
|
||||
}
|
||||
|
||||
typename SupplyMap::Value sup;
|
||||
typename CapacityMap::Value low;
|
||||
typename CapacityMap::Value cap;
|
||||
typename CostMap::Value co;
|
||||
typedef typename CapacityMap::Value Capacity;
|
||||
if(infty==0)
|
||||
infty = std::numeric_limits<Capacity>::has_infinity ?
|
||||
std::numeric_limits<Capacity>::infinity() :
|
||||
std::numeric_limits<Capacity>::max();
|
||||
|
||||
while (is >> c) {
|
||||
switch (c) {
|
||||
case 'c': // comment line
|
||||
getline(is, str);
|
||||
break;
|
||||
case 'n': // node definition line
|
||||
is >> i >> sup;
|
||||
getline(is, str);
|
||||
supply.set(nodes[i], sup);
|
||||
break;
|
||||
case 'a': // arc definition line
|
||||
is >> i >> j >> low >> cap >> co;
|
||||
getline(is, str);
|
||||
e = g.addArc(nodes[i], nodes[j]);
|
||||
lower.set(e, low);
|
||||
if (cap >= low)
|
||||
capacity.set(e, cap);
|
||||
else
|
||||
capacity.set(e, infty);
|
||||
cost.set(e, co);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Digraph, typename CapacityMap>
|
||||
void _readDimacs(std::istream& is,
|
||||
Digraph &g,
|
||||
CapacityMap& capacity,
|
||||
typename Digraph::Node &s,
|
||||
typename Digraph::Node &t,
|
||||
typename CapacityMap::Value infty = 0,
|
||||
DimacsDescriptor desc=DimacsDescriptor()) {
|
||||
g.clear();
|
||||
s=t=INVALID;
|
||||
std::vector<typename Digraph::Node> nodes;
|
||||
typename Digraph::Arc e;
|
||||
char c, d;
|
||||
int i, j;
|
||||
typename CapacityMap::Value _cap;
|
||||
std::string str;
|
||||
nodes.resize(desc.nodeNum + 1);
|
||||
for (int k = 1; k <= desc.nodeNum; ++k) {
|
||||
nodes[k] = g.addNode();
|
||||
}
|
||||
typedef typename CapacityMap::Value Capacity;
|
||||
|
||||
if(infty==0)
|
||||
infty = std::numeric_limits<Capacity>::has_infinity ?
|
||||
std::numeric_limits<Capacity>::infinity() :
|
||||
std::numeric_limits<Capacity>::max();
|
||||
|
||||
while (is >> c) {
|
||||
switch (c) {
|
||||
case 'c': // comment line
|
||||
getline(is, str);
|
||||
break;
|
||||
case 'n': // node definition line
|
||||
if (desc.type==DimacsDescriptor::SP) { // shortest path problem
|
||||
is >> i;
|
||||
getline(is, str);
|
||||
s = nodes[i];
|
||||
}
|
||||
if (desc.type==DimacsDescriptor::MAX) { // max flow problem
|
||||
is >> i >> d;
|
||||
getline(is, str);
|
||||
if (d == 's') s = nodes[i];
|
||||
if (d == 't') t = nodes[i];
|
||||
}
|
||||
break;
|
||||
case 'a': // arc definition line
|
||||
if (desc.type==DimacsDescriptor::SP) {
|
||||
is >> i >> j >> _cap;
|
||||
getline(is, str);
|
||||
e = g.addArc(nodes[i], nodes[j]);
|
||||
capacity.set(e, _cap);
|
||||
}
|
||||
else if (desc.type==DimacsDescriptor::MAX) {
|
||||
is >> i >> j >> _cap;
|
||||
getline(is, str);
|
||||
e = g.addArc(nodes[i], nodes[j]);
|
||||
if (_cap >= 0)
|
||||
capacity.set(e, _cap);
|
||||
else
|
||||
capacity.set(e, infty);
|
||||
}
|
||||
else {
|
||||
is >> i >> j;
|
||||
getline(is, str);
|
||||
g.addArc(nodes[i], nodes[j]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief DIMACS maximum flow reader function.
|
||||
///
|
||||
/// This function reads a maximum flow instance from DIMACS format,
|
||||
/// i.e. from a DIMACS file having a line starting with
|
||||
/// \code
|
||||
/// p max
|
||||
/// \endcode
|
||||
/// At the beginning, \c g is cleared by \c g.clear(). The arc
|
||||
/// capacities are written to the \c capacity arc map and \c s and
|
||||
/// \c t are set to the source and the target nodes.
|
||||
///
|
||||
/// If the capacity of an arc is negative, it will
|
||||
/// be set to "infinite" instead. The actual value of "infinite" is
|
||||
/// contolled by the \c infty parameter. If it is 0 (the default value),
|
||||
/// \c std::numeric_limits<Capacity>::infinity() will be used if available,
|
||||
/// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
|
||||
/// a non-zero value, that value will be used as "infinite".
|
||||
///
|
||||
/// If the file type was previously evaluated by dimacsType(), then
|
||||
/// the descriptor struct should be given by the \c dest parameter.
|
||||
template<typename Digraph, typename CapacityMap>
|
||||
void readDimacsMax(std::istream& is,
|
||||
Digraph &g,
|
||||
CapacityMap& capacity,
|
||||
typename Digraph::Node &s,
|
||||
typename Digraph::Node &t,
|
||||
typename CapacityMap::Value infty = 0,
|
||||
DimacsDescriptor desc=DimacsDescriptor()) {
|
||||
if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
|
||||
if(desc.type!=DimacsDescriptor::MAX)
|
||||
throw FormatError("Problem type mismatch");
|
||||
_readDimacs(is,g,capacity,s,t,infty,desc);
|
||||
}
|
||||
|
||||
/// \brief DIMACS shortest path reader function.
|
||||
///
|
||||
/// This function reads a shortest path instance from DIMACS format,
|
||||
/// i.e. from a DIMACS file having a line starting with
|
||||
/// \code
|
||||
/// p sp
|
||||
/// \endcode
|
||||
/// At the beginning, \c g is cleared by \c g.clear(). The arc
|
||||
/// lengths are written to the \c length arc map and \c s is set to the
|
||||
/// source node.
|
||||
///
|
||||
/// If the file type was previously evaluated by dimacsType(), then
|
||||
/// the descriptor struct should be given by the \c dest parameter.
|
||||
template<typename Digraph, typename LengthMap>
|
||||
void readDimacsSp(std::istream& is,
|
||||
Digraph &g,
|
||||
LengthMap& length,
|
||||
typename Digraph::Node &s,
|
||||
DimacsDescriptor desc=DimacsDescriptor()) {
|
||||
typename Digraph::Node t;
|
||||
if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
|
||||
if(desc.type!=DimacsDescriptor::SP)
|
||||
throw FormatError("Problem type mismatch");
|
||||
_readDimacs(is, g, length, s, t, 0, desc);
|
||||
}
|
||||
|
||||
/// \brief DIMACS capacitated digraph reader function.
|
||||
///
|
||||
/// This function reads an arc capacitated digraph instance from
|
||||
/// DIMACS 'max' or 'sp' format.
|
||||
/// At the beginning, \c g is cleared by \c g.clear()
|
||||
/// and the arc capacities/lengths are written to the \c capacity
|
||||
/// arc map.
|
||||
///
|
||||
/// In case of the 'max' format, if the capacity of an arc is negative,
|
||||
/// it will
|
||||
/// be set to "infinite" instead. The actual value of "infinite" is
|
||||
/// contolled by the \c infty parameter. If it is 0 (the default value),
|
||||
/// \c std::numeric_limits<Capacity>::infinity() will be used if available,
|
||||
/// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
|
||||
/// a non-zero value, that value will be used as "infinite".
|
||||
///
|
||||
/// If the file type was previously evaluated by dimacsType(), then
|
||||
/// the descriptor struct should be given by the \c dest parameter.
|
||||
template<typename Digraph, typename CapacityMap>
|
||||
void readDimacsCap(std::istream& is,
|
||||
Digraph &g,
|
||||
CapacityMap& capacity,
|
||||
typename CapacityMap::Value infty = 0,
|
||||
DimacsDescriptor desc=DimacsDescriptor()) {
|
||||
typename Digraph::Node u,v;
|
||||
if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
|
||||
if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
|
||||
throw FormatError("Problem type mismatch");
|
||||
_readDimacs(is, g, capacity, u, v, infty, desc);
|
||||
}
|
||||
|
||||
template<typename Graph>
|
||||
typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
|
||||
_addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
|
||||
dummy<0> = 0)
|
||||
{
|
||||
g.addEdge(s,t);
|
||||
}
|
||||
template<typename Graph>
|
||||
typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
|
||||
_addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
|
||||
dummy<1> = 1)
|
||||
{
|
||||
g.addArc(s,t);
|
||||
}
|
||||
|
||||
/// \brief DIMACS plain (di)graph reader function.
|
||||
///
|
||||
/// This function reads a plain (di)graph without any designated nodes
|
||||
/// and maps (e.g. a matching instance) from DIMACS format, i.e. from
|
||||
/// DIMACS files having a line starting with
|
||||
/// \code
|
||||
/// p mat
|
||||
/// \endcode
|
||||
/// At the beginning, \c g is cleared by \c g.clear().
|
||||
///
|
||||
/// If the file type was previously evaluated by dimacsType(), then
|
||||
/// the descriptor struct should be given by the \c dest parameter.
|
||||
template<typename Graph>
|
||||
void readDimacsMat(std::istream& is, Graph &g,
|
||||
DimacsDescriptor desc=DimacsDescriptor())
|
||||
{
|
||||
if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
|
||||
if(desc.type!=DimacsDescriptor::MAT)
|
||||
throw FormatError("Problem type mismatch");
|
||||
|
||||
g.clear();
|
||||
std::vector<typename Graph::Node> nodes;
|
||||
char c;
|
||||
int i, j;
|
||||
std::string str;
|
||||
nodes.resize(desc.nodeNum + 1);
|
||||
for (int k = 1; k <= desc.nodeNum; ++k) {
|
||||
nodes[k] = g.addNode();
|
||||
}
|
||||
|
||||
while (is >> c) {
|
||||
switch (c) {
|
||||
case 'c': // comment line
|
||||
getline(is, str);
|
||||
break;
|
||||
case 'n': // node definition line
|
||||
break;
|
||||
case 'a': // arc definition line
|
||||
is >> i >> j;
|
||||
getline(is, str);
|
||||
_addArcEdge(g,nodes[i], nodes[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// DIMACS plain digraph writer function.
|
||||
///
|
||||
/// This function writes a digraph without any designated nodes and
|
||||
/// maps into DIMACS format, i.e. into DIMACS file having a line
|
||||
/// starting with
|
||||
/// \code
|
||||
/// p mat
|
||||
/// \endcode
|
||||
/// If \c comment is not empty, then it will be printed in the first line
|
||||
/// prefixed by 'c'.
|
||||
template<typename Digraph>
|
||||
void writeDimacsMat(std::ostream& os, const Digraph &g,
|
||||
std::string comment="") {
|
||||
typedef typename Digraph::NodeIt NodeIt;
|
||||
typedef typename Digraph::ArcIt ArcIt;
|
||||
|
||||
if(!comment.empty())
|
||||
os << "c " << comment << std::endl;
|
||||
os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
|
||||
|
||||
typename Digraph::template NodeMap<int> nodes(g);
|
||||
int i = 1;
|
||||
for(NodeIt v(g); v != INVALID; ++v) {
|
||||
nodes.set(v, i);
|
||||
++i;
|
||||
}
|
||||
for(ArcIt e(g); e != INVALID; ++e) {
|
||||
os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
} //namespace lemon
|
||||
|
||||
#endif //LEMON_DIMACS_H
|
||||
1420
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/edge_set.h
vendored
Normal file
1420
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/edge_set.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
556
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/edmonds_karp.h
vendored
Normal file
556
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/edmonds_karp.h
vendored
Normal file
@@ -0,0 +1,556 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_EDMONDS_KARP_H
|
||||
#define LEMON_EDMONDS_KARP_H
|
||||
|
||||
/// \file
|
||||
/// \ingroup max_flow
|
||||
/// \brief Implementation of the Edmonds-Karp algorithm.
|
||||
|
||||
#include <lemon/tolerance.h>
|
||||
#include <vector>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \brief Default traits class of EdmondsKarp class.
|
||||
///
|
||||
/// Default traits class of EdmondsKarp class.
|
||||
/// \param GR Digraph type.
|
||||
/// \param CAP Type of capacity map.
|
||||
template <typename GR, typename CAP>
|
||||
struct EdmondsKarpDefaultTraits {
|
||||
|
||||
/// \brief The digraph type the algorithm runs on.
|
||||
typedef GR Digraph;
|
||||
|
||||
/// \brief The type of the map that stores the arc capacities.
|
||||
///
|
||||
/// The type of the map that stores the arc capacities.
|
||||
/// It must meet the \ref concepts::ReadMap "ReadMap" concept.
|
||||
typedef CAP CapacityMap;
|
||||
|
||||
/// \brief The type of the flow values.
|
||||
typedef typename CapacityMap::Value Value;
|
||||
|
||||
/// \brief The type of the map that stores the flow values.
|
||||
///
|
||||
/// The type of the map that stores the flow values.
|
||||
/// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
|
||||
#ifdef DOXYGEN
|
||||
typedef GR::ArcMap<Value> FlowMap;
|
||||
#else
|
||||
typedef typename Digraph::template ArcMap<Value> FlowMap;
|
||||
#endif
|
||||
|
||||
/// \brief Instantiates a FlowMap.
|
||||
///
|
||||
/// This function instantiates a \ref FlowMap.
|
||||
/// \param digraph The digraph for which we would like to define
|
||||
/// the flow map.
|
||||
static FlowMap* createFlowMap(const Digraph& digraph) {
|
||||
return new FlowMap(digraph);
|
||||
}
|
||||
|
||||
/// \brief The tolerance used by the algorithm
|
||||
///
|
||||
/// The tolerance used by the algorithm to handle inexact computation.
|
||||
typedef lemon::Tolerance<Value> Tolerance;
|
||||
|
||||
};
|
||||
|
||||
/// \ingroup max_flow
|
||||
///
|
||||
/// \brief Edmonds-Karp algorithms class.
|
||||
///
|
||||
/// This class provides an implementation of the \e Edmonds-Karp \e
|
||||
/// algorithm producing a \ref max_flow "flow of maximum value" in a
|
||||
/// digraph \cite clrs01algorithms, \cite amo93networkflows,
|
||||
/// \cite edmondskarp72theoretical.
|
||||
/// The Edmonds-Karp algorithm is slower than the Preflow
|
||||
/// algorithm, but it has an advantage of the step-by-step execution
|
||||
/// control with feasible flow solutions. The \e source node, the \e
|
||||
/// target node, the \e capacity of the arcs and the \e starting \e
|
||||
/// flow value of the arcs should be passed to the algorithm
|
||||
/// through the constructor.
|
||||
///
|
||||
/// The time complexity of the algorithm is \f$ O(nm^2) \f$ in
|
||||
/// worst case. Always try the Preflow algorithm instead of this if
|
||||
/// you just want to compute the optimal flow.
|
||||
///
|
||||
/// \tparam GR The type of the digraph the algorithm runs on.
|
||||
/// \tparam CAP The type of the capacity map. The default map
|
||||
/// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
|
||||
/// \tparam TR The traits class that defines various types used by the
|
||||
/// algorithm. By default, it is \ref EdmondsKarpDefaultTraits
|
||||
/// "EdmondsKarpDefaultTraits<GR, CAP>".
|
||||
/// In most cases, this parameter should not be set directly,
|
||||
/// consider to use the named template parameters instead.
|
||||
|
||||
#ifdef DOXYGEN
|
||||
template <typename GR, typename CAP, typename TR>
|
||||
#else
|
||||
template <typename GR,
|
||||
typename CAP = typename GR::template ArcMap<int>,
|
||||
typename TR = EdmondsKarpDefaultTraits<GR, CAP> >
|
||||
#endif
|
||||
class EdmondsKarp {
|
||||
public:
|
||||
|
||||
/// \brief The \ref lemon::EdmondsKarpDefaultTraits "traits class"
|
||||
/// of the algorithm.
|
||||
typedef TR Traits;
|
||||
/// The type of the digraph the algorithm runs on.
|
||||
typedef typename Traits::Digraph Digraph;
|
||||
/// The type of the capacity map.
|
||||
typedef typename Traits::CapacityMap CapacityMap;
|
||||
/// The type of the flow values.
|
||||
typedef typename Traits::Value Value;
|
||||
|
||||
/// The type of the flow map.
|
||||
typedef typename Traits::FlowMap FlowMap;
|
||||
/// The type of the tolerance.
|
||||
typedef typename Traits::Tolerance Tolerance;
|
||||
|
||||
private:
|
||||
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
typedef typename Digraph::template NodeMap<Arc> PredMap;
|
||||
|
||||
const Digraph& _graph;
|
||||
const CapacityMap* _capacity;
|
||||
|
||||
Node _source, _target;
|
||||
|
||||
FlowMap* _flow;
|
||||
bool _local_flow;
|
||||
|
||||
PredMap* _pred;
|
||||
std::vector<Node> _queue;
|
||||
|
||||
Tolerance _tolerance;
|
||||
Value _flow_value;
|
||||
|
||||
void createStructures() {
|
||||
if (!_flow) {
|
||||
_flow = Traits::createFlowMap(_graph);
|
||||
_local_flow = true;
|
||||
}
|
||||
if (!_pred) {
|
||||
_pred = new PredMap(_graph);
|
||||
}
|
||||
_queue.resize(countNodes(_graph));
|
||||
}
|
||||
|
||||
void destroyStructures() {
|
||||
if (_local_flow) {
|
||||
delete _flow;
|
||||
}
|
||||
if (_pred) {
|
||||
delete _pred;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
typedef EdmondsKarp Create;
|
||||
|
||||
///\name Named template parameters
|
||||
|
||||
///@{
|
||||
|
||||
template <typename T>
|
||||
struct SetFlowMapTraits : public Traits {
|
||||
typedef T FlowMap;
|
||||
static FlowMap *createFlowMap(const Digraph&) {
|
||||
LEMON_ASSERT(false, "FlowMap is not initialized");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief \ref named-templ-param "Named parameter" for setting
|
||||
/// FlowMap type
|
||||
///
|
||||
/// \ref named-templ-param "Named parameter" for setting FlowMap
|
||||
/// type
|
||||
template <typename T>
|
||||
struct SetFlowMap
|
||||
: public EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > {
|
||||
typedef EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > Create;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
protected:
|
||||
|
||||
EdmondsKarp() {}
|
||||
|
||||
public:
|
||||
|
||||
/// \brief The constructor of the class.
|
||||
///
|
||||
/// The constructor of the class.
|
||||
/// \param digraph The digraph the algorithm runs on.
|
||||
/// \param capacity The capacity of the arcs.
|
||||
/// \param source The source node.
|
||||
/// \param target The target node.
|
||||
EdmondsKarp(const Digraph& digraph, const CapacityMap& capacity,
|
||||
Node source, Node target)
|
||||
: _graph(digraph), _capacity(&capacity), _source(source), _target(target),
|
||||
_flow(0), _local_flow(false), _pred(0), _tolerance(), _flow_value()
|
||||
{
|
||||
LEMON_ASSERT(_source != _target,
|
||||
"Flow source and target are the same nodes.");
|
||||
}
|
||||
|
||||
/// \brief Destructor.
|
||||
///
|
||||
/// Destructor.
|
||||
~EdmondsKarp() {
|
||||
destroyStructures();
|
||||
}
|
||||
|
||||
/// \brief Sets the capacity map.
|
||||
///
|
||||
/// Sets the capacity map.
|
||||
/// \return <tt>(*this)</tt>
|
||||
EdmondsKarp& capacityMap(const CapacityMap& map) {
|
||||
_capacity = ↦
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Sets the flow map.
|
||||
///
|
||||
/// Sets the flow map.
|
||||
/// If you don't use this function before calling \ref run() or
|
||||
/// \ref init(), an instance will be allocated automatically.
|
||||
/// The destructor deallocates this automatically allocated map,
|
||||
/// of course.
|
||||
/// \return <tt>(*this)</tt>
|
||||
EdmondsKarp& flowMap(FlowMap& map) {
|
||||
if (_local_flow) {
|
||||
delete _flow;
|
||||
_local_flow = false;
|
||||
}
|
||||
_flow = ↦
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Sets the source node.
|
||||
///
|
||||
/// Sets the source node.
|
||||
/// \return <tt>(*this)</tt>
|
||||
EdmondsKarp& source(const Node& node) {
|
||||
_source = node;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Sets the target node.
|
||||
///
|
||||
/// Sets the target node.
|
||||
/// \return <tt>(*this)</tt>
|
||||
EdmondsKarp& target(const Node& node) {
|
||||
_target = node;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Sets the tolerance used by algorithm.
|
||||
///
|
||||
/// Sets the tolerance used by algorithm.
|
||||
/// \return <tt>(*this)</tt>
|
||||
EdmondsKarp& tolerance(const Tolerance& tolerance) {
|
||||
_tolerance = tolerance;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Returns a const reference to the tolerance.
|
||||
///
|
||||
/// Returns a const reference to the tolerance object used by
|
||||
/// the algorithm.
|
||||
const Tolerance& tolerance() const {
|
||||
return _tolerance;
|
||||
}
|
||||
|
||||
/// \name Execution control
|
||||
/// The simplest way to execute the algorithm is to use \ref run().\n
|
||||
/// If you need better control on the initial solution or the execution,
|
||||
/// you have to call one of the \ref init() functions first, then
|
||||
/// \ref start() or multiple times the \ref augment() function.
|
||||
|
||||
///@{
|
||||
|
||||
/// \brief Initializes the algorithm.
|
||||
///
|
||||
/// Initializes the internal data structures and sets the initial
|
||||
/// flow to zero on each arc.
|
||||
void init() {
|
||||
createStructures();
|
||||
for (ArcIt it(_graph); it != INVALID; ++it) {
|
||||
_flow->set(it, 0);
|
||||
}
|
||||
_flow_value = 0;
|
||||
}
|
||||
|
||||
/// \brief Initializes the algorithm using the given flow map.
|
||||
///
|
||||
/// Initializes the internal data structures and sets the initial
|
||||
/// flow to the given \c flowMap. The \c flowMap should
|
||||
/// contain a feasible flow, i.e. at each node excluding the source
|
||||
/// and the target, the incoming flow should be equal to the
|
||||
/// outgoing flow.
|
||||
template <typename FlowMap>
|
||||
void init(const FlowMap& flowMap) {
|
||||
createStructures();
|
||||
for (ArcIt e(_graph); e != INVALID; ++e) {
|
||||
_flow->set(e, flowMap[e]);
|
||||
}
|
||||
_flow_value = 0;
|
||||
for (OutArcIt jt(_graph, _source); jt != INVALID; ++jt) {
|
||||
_flow_value += (*_flow)[jt];
|
||||
}
|
||||
for (InArcIt jt(_graph, _source); jt != INVALID; ++jt) {
|
||||
_flow_value -= (*_flow)[jt];
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Initializes the algorithm using the given flow map.
|
||||
///
|
||||
/// Initializes the internal data structures and sets the initial
|
||||
/// flow to the given \c flowMap. The \c flowMap should
|
||||
/// contain a feasible flow, i.e. at each node excluding the source
|
||||
/// and the target, the incoming flow should be equal to the
|
||||
/// outgoing flow.
|
||||
/// \return \c false when the given \c flowMap does not contain a
|
||||
/// feasible flow.
|
||||
template <typename FlowMap>
|
||||
bool checkedInit(const FlowMap& flowMap) {
|
||||
createStructures();
|
||||
for (ArcIt e(_graph); e != INVALID; ++e) {
|
||||
_flow->set(e, flowMap[e]);
|
||||
}
|
||||
for (NodeIt it(_graph); it != INVALID; ++it) {
|
||||
if (it == _source || it == _target) continue;
|
||||
Value outFlow = 0;
|
||||
for (OutArcIt jt(_graph, it); jt != INVALID; ++jt) {
|
||||
outFlow += (*_flow)[jt];
|
||||
}
|
||||
Value inFlow = 0;
|
||||
for (InArcIt jt(_graph, it); jt != INVALID; ++jt) {
|
||||
inFlow += (*_flow)[jt];
|
||||
}
|
||||
if (_tolerance.different(outFlow, inFlow)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (ArcIt it(_graph); it != INVALID; ++it) {
|
||||
if (_tolerance.less((*_flow)[it], 0)) return false;
|
||||
if (_tolerance.less((*_capacity)[it], (*_flow)[it])) return false;
|
||||
}
|
||||
_flow_value = 0;
|
||||
for (OutArcIt jt(_graph, _source); jt != INVALID; ++jt) {
|
||||
_flow_value += (*_flow)[jt];
|
||||
}
|
||||
for (InArcIt jt(_graph, _source); jt != INVALID; ++jt) {
|
||||
_flow_value -= (*_flow)[jt];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \brief Augments the solution along a shortest path.
|
||||
///
|
||||
/// Augments the solution along a shortest path. This function searches a
|
||||
/// shortest path between the source and the target
|
||||
/// in the residual digraph by the Bfs algoritm.
|
||||
/// Then it increases the flow on this path with the minimal residual
|
||||
/// capacity on the path. If there is no such path, it gives back
|
||||
/// false.
|
||||
/// \return \c false when the augmenting did not success, i.e. the
|
||||
/// current flow is a feasible and optimal solution.
|
||||
bool augment() {
|
||||
for (NodeIt n(_graph); n != INVALID; ++n) {
|
||||
_pred->set(n, INVALID);
|
||||
}
|
||||
|
||||
int first = 0, last = 1;
|
||||
|
||||
_queue[0] = _source;
|
||||
_pred->set(_source, OutArcIt(_graph, _source));
|
||||
|
||||
while (first != last && (*_pred)[_target] == INVALID) {
|
||||
Node n = _queue[first++];
|
||||
|
||||
for (OutArcIt e(_graph, n); e != INVALID; ++e) {
|
||||
Value rem = (*_capacity)[e] - (*_flow)[e];
|
||||
Node t = _graph.target(e);
|
||||
if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
|
||||
_pred->set(t, e);
|
||||
_queue[last++] = t;
|
||||
}
|
||||
}
|
||||
for (InArcIt e(_graph, n); e != INVALID; ++e) {
|
||||
Value rem = (*_flow)[e];
|
||||
Node t = _graph.source(e);
|
||||
if (_tolerance.positive(rem) && (*_pred)[t] == INVALID) {
|
||||
_pred->set(t, e);
|
||||
_queue[last++] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((*_pred)[_target] != INVALID) {
|
||||
Node n = _target;
|
||||
Arc e = (*_pred)[n];
|
||||
|
||||
Value prem = (*_capacity)[e] - (*_flow)[e];
|
||||
n = _graph.source(e);
|
||||
while (n != _source) {
|
||||
e = (*_pred)[n];
|
||||
if (_graph.target(e) == n) {
|
||||
Value rem = (*_capacity)[e] - (*_flow)[e];
|
||||
if (rem < prem) prem = rem;
|
||||
n = _graph.source(e);
|
||||
} else {
|
||||
Value rem = (*_flow)[e];
|
||||
if (rem < prem) prem = rem;
|
||||
n = _graph.target(e);
|
||||
}
|
||||
}
|
||||
|
||||
n = _target;
|
||||
e = (*_pred)[n];
|
||||
|
||||
_flow->set(e, (*_flow)[e] + prem);
|
||||
n = _graph.source(e);
|
||||
while (n != _source) {
|
||||
e = (*_pred)[n];
|
||||
if (_graph.target(e) == n) {
|
||||
_flow->set(e, (*_flow)[e] + prem);
|
||||
n = _graph.source(e);
|
||||
} else {
|
||||
_flow->set(e, (*_flow)[e] - prem);
|
||||
n = _graph.target(e);
|
||||
}
|
||||
}
|
||||
|
||||
_flow_value += prem;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Executes the algorithm
|
||||
///
|
||||
/// Executes the algorithm by performing augmenting phases until the
|
||||
/// optimal solution is reached.
|
||||
/// \pre One of the \ref init() functions must be called before
|
||||
/// using this function.
|
||||
void start() {
|
||||
while (augment()) {}
|
||||
}
|
||||
|
||||
/// \brief Runs the algorithm.
|
||||
///
|
||||
/// Runs the Edmonds-Karp algorithm.
|
||||
/// \note ek.run() is just a shortcut of the following code.
|
||||
///\code
|
||||
/// ek.init();
|
||||
/// ek.start();
|
||||
///\endcode
|
||||
void run() {
|
||||
init();
|
||||
start();
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Query Functions
|
||||
/// The result of the Edmonds-Karp algorithm can be obtained using these
|
||||
/// functions.\n
|
||||
/// Either \ref run() or \ref start() should be called before using them.
|
||||
|
||||
///@{
|
||||
|
||||
/// \brief Returns the value of the maximum flow.
|
||||
///
|
||||
/// Returns the value of the maximum flow found by the algorithm.
|
||||
///
|
||||
/// \pre Either \ref run() or \ref init() must be called before
|
||||
/// using this function.
|
||||
Value flowValue() const {
|
||||
return _flow_value;
|
||||
}
|
||||
|
||||
/// \brief Returns the flow value on the given arc.
|
||||
///
|
||||
/// Returns the flow value on the given arc.
|
||||
///
|
||||
/// \pre Either \ref run() or \ref init() must be called before
|
||||
/// using this function.
|
||||
Value flow(const Arc& arc) const {
|
||||
return (*_flow)[arc];
|
||||
}
|
||||
|
||||
/// \brief Returns a const reference to the flow map.
|
||||
///
|
||||
/// Returns a const reference to the arc map storing the found flow.
|
||||
///
|
||||
/// \pre Either \ref run() or \ref init() must be called before
|
||||
/// using this function.
|
||||
const FlowMap& flowMap() const {
|
||||
return *_flow;
|
||||
}
|
||||
|
||||
/// \brief Returns \c true when the node is on the source side of the
|
||||
/// minimum cut.
|
||||
///
|
||||
/// Returns true when the node is on the source side of the found
|
||||
/// minimum cut.
|
||||
///
|
||||
/// \pre Either \ref run() or \ref init() must be called before
|
||||
/// using this function.
|
||||
bool minCut(const Node& node) const {
|
||||
return ((*_pred)[node] != INVALID) || node == _source;
|
||||
}
|
||||
|
||||
/// \brief Gives back a minimum value cut.
|
||||
///
|
||||
/// Sets \c cutMap to the characteristic vector of a minimum value
|
||||
/// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
|
||||
/// node map with \c bool (or convertible) value type.
|
||||
///
|
||||
/// \note This function calls \ref minCut() for each node, so it runs in
|
||||
/// O(n) time.
|
||||
///
|
||||
/// \pre Either \ref run() or \ref init() must be called before
|
||||
/// using this function.
|
||||
template <typename CutMap>
|
||||
void minCutMap(CutMap& cutMap) const {
|
||||
for (NodeIt n(_graph); n != INVALID; ++n) {
|
||||
cutMap.set(n, (*_pred)[n] != INVALID);
|
||||
}
|
||||
cutMap.set(_source, true);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
982
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/elevator.h
vendored
Normal file
982
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/elevator.h
vendored
Normal file
@@ -0,0 +1,982 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_ELEVATOR_H
|
||||
#define LEMON_ELEVATOR_H
|
||||
|
||||
///\ingroup auxdat
|
||||
///\file
|
||||
///\brief Elevator class
|
||||
///
|
||||
///Elevator class implements an efficient data structure
|
||||
///for labeling items in push-relabel type algorithms.
|
||||
///
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/bits/traits.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
///Class for handling "labels" in push-relabel type algorithms.
|
||||
|
||||
///A class for handling "labels" in push-relabel type algorithms.
|
||||
///
|
||||
///\ingroup auxdat
|
||||
///Using this class you can assign "labels" (nonnegative integer numbers)
|
||||
///to the edges or nodes of a graph, manipulate and query them through
|
||||
///operations typically arising in "push-relabel" type algorithms.
|
||||
///
|
||||
///Each item is either \em active or not, and you can also choose a
|
||||
///highest level active item.
|
||||
///
|
||||
///\sa LinkedElevator
|
||||
///
|
||||
///\param GR Type of the underlying graph.
|
||||
///\param Item Type of the items the data is assigned to (\c GR::Node,
|
||||
///\c GR::Arc or \c GR::Edge).
|
||||
template<class GR, class Item>
|
||||
class Elevator
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Item Key;
|
||||
typedef int Value;
|
||||
|
||||
private:
|
||||
|
||||
typedef Item *Vit;
|
||||
typedef typename ItemSetTraits<GR,Item>::template Map<Vit>::Type VitMap;
|
||||
typedef typename ItemSetTraits<GR,Item>::template Map<int>::Type IntMap;
|
||||
|
||||
const GR &_g;
|
||||
int _max_level;
|
||||
int _item_num;
|
||||
VitMap _where;
|
||||
IntMap _level;
|
||||
std::vector<Item> _items;
|
||||
std::vector<Vit> _first;
|
||||
std::vector<Vit> _last_active;
|
||||
|
||||
int _highest_active;
|
||||
|
||||
void copy(Item i, Vit p)
|
||||
{
|
||||
_where[*p=i] = p;
|
||||
}
|
||||
void copy(Vit s, Vit p)
|
||||
{
|
||||
if(s!=p)
|
||||
{
|
||||
Item i=*s;
|
||||
*p=i;
|
||||
_where[i] = p;
|
||||
}
|
||||
}
|
||||
void swap(Vit i, Vit j)
|
||||
{
|
||||
Item ti=*i;
|
||||
Vit ct = _where[ti];
|
||||
_where[ti] = _where[*i=*j];
|
||||
_where[*j] = ct;
|
||||
*j=ti;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
///Constructor with given maximum level.
|
||||
|
||||
///Constructor with given maximum level.
|
||||
///
|
||||
///\param graph The underlying graph.
|
||||
///\param max_level The maximum allowed level.
|
||||
///Set the range of the possible labels to <tt>[0..max_level]</tt>.
|
||||
Elevator(const GR &graph,int max_level) :
|
||||
_g(graph),
|
||||
_max_level(max_level),
|
||||
_item_num(_max_level),
|
||||
_where(graph),
|
||||
_level(graph,0),
|
||||
_items(_max_level),
|
||||
_first(_max_level+2),
|
||||
_last_active(_max_level+2),
|
||||
_highest_active(-1) {}
|
||||
///Constructor.
|
||||
|
||||
///Constructor.
|
||||
///
|
||||
///\param graph The underlying graph.
|
||||
///Set the range of the possible labels to <tt>[0..max_level]</tt>,
|
||||
///where \c max_level is equal to the number of labeled items in the graph.
|
||||
Elevator(const GR &graph) :
|
||||
_g(graph),
|
||||
_max_level(countItems<GR, Item>(graph)),
|
||||
_item_num(_max_level),
|
||||
_where(graph),
|
||||
_level(graph,0),
|
||||
_items(_max_level),
|
||||
_first(_max_level+2),
|
||||
_last_active(_max_level+2),
|
||||
_highest_active(-1)
|
||||
{
|
||||
}
|
||||
|
||||
///Activate item \c i.
|
||||
|
||||
///Activate item \c i.
|
||||
///\pre Item \c i shouldn't be active before.
|
||||
void activate(Item i)
|
||||
{
|
||||
const int l=_level[i];
|
||||
swap(_where[i],++_last_active[l]);
|
||||
if(l>_highest_active) _highest_active=l;
|
||||
}
|
||||
|
||||
///Deactivate item \c i.
|
||||
|
||||
///Deactivate item \c i.
|
||||
///\pre Item \c i must be active before.
|
||||
void deactivate(Item i)
|
||||
{
|
||||
swap(_where[i],_last_active[_level[i]]--);
|
||||
while(_highest_active>=0 &&
|
||||
_last_active[_highest_active]<_first[_highest_active])
|
||||
_highest_active--;
|
||||
}
|
||||
|
||||
///Query whether item \c i is active
|
||||
bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
|
||||
|
||||
///Return the level of item \c i.
|
||||
int operator[](Item i) const { return _level[i]; }
|
||||
|
||||
///Return the number of items on level \c l.
|
||||
int onLevel(int l) const
|
||||
{
|
||||
return _first[l+1]-_first[l];
|
||||
}
|
||||
///Return true if level \c l is empty.
|
||||
bool emptyLevel(int l) const
|
||||
{
|
||||
return _first[l+1]-_first[l]==0;
|
||||
}
|
||||
///Return the number of items above level \c l.
|
||||
int aboveLevel(int l) const
|
||||
{
|
||||
return _first[_max_level+1]-_first[l+1];
|
||||
}
|
||||
///Return the number of active items on level \c l.
|
||||
int activesOnLevel(int l) const
|
||||
{
|
||||
return _last_active[l]-_first[l]+1;
|
||||
}
|
||||
///Return true if there is no active item on level \c l.
|
||||
bool activeFree(int l) const
|
||||
{
|
||||
return _last_active[l]<_first[l];
|
||||
}
|
||||
///Return the maximum allowed level.
|
||||
int maxLevel() const
|
||||
{
|
||||
return _max_level;
|
||||
}
|
||||
|
||||
///\name Highest Active Item
|
||||
///Functions for working with the highest level
|
||||
///active item.
|
||||
|
||||
///@{
|
||||
|
||||
///Return a highest level active item.
|
||||
|
||||
///Return a highest level active item or INVALID if there is no active
|
||||
///item.
|
||||
Item highestActive() const
|
||||
{
|
||||
return _highest_active>=0?*_last_active[_highest_active]:INVALID;
|
||||
}
|
||||
|
||||
///Return the highest active level.
|
||||
|
||||
///Return the level of the highest active item or -1 if there is no active
|
||||
///item.
|
||||
int highestActiveLevel() const
|
||||
{
|
||||
return _highest_active;
|
||||
}
|
||||
|
||||
///Lift the highest active item by one.
|
||||
|
||||
///Lift the item returned by highestActive() by one.
|
||||
///
|
||||
void liftHighestActive()
|
||||
{
|
||||
Item it = *_last_active[_highest_active];
|
||||
++_level[it];
|
||||
swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
|
||||
--_first[++_highest_active];
|
||||
}
|
||||
|
||||
///Lift the highest active item to the given level.
|
||||
|
||||
///Lift the item returned by highestActive() to level \c new_level.
|
||||
///
|
||||
///\warning \c new_level must be strictly higher
|
||||
///than the current level.
|
||||
///
|
||||
void liftHighestActive(int new_level)
|
||||
{
|
||||
const Item li = *_last_active[_highest_active];
|
||||
|
||||
copy(--_first[_highest_active+1],_last_active[_highest_active]--);
|
||||
for(int l=_highest_active+1;l<new_level;l++)
|
||||
{
|
||||
copy(--_first[l+1],_first[l]);
|
||||
--_last_active[l];
|
||||
}
|
||||
copy(li,_first[new_level]);
|
||||
_level[li] = new_level;
|
||||
_highest_active=new_level;
|
||||
}
|
||||
|
||||
///Lift the highest active item to the top level.
|
||||
|
||||
///Lift the item returned by highestActive() to the top level and
|
||||
///deactivate it.
|
||||
void liftHighestActiveToTop()
|
||||
{
|
||||
const Item li = *_last_active[_highest_active];
|
||||
|
||||
copy(--_first[_highest_active+1],_last_active[_highest_active]--);
|
||||
for(int l=_highest_active+1;l<_max_level;l++)
|
||||
{
|
||||
copy(--_first[l+1],_first[l]);
|
||||
--_last_active[l];
|
||||
}
|
||||
copy(li,_first[_max_level]);
|
||||
--_last_active[_max_level];
|
||||
_level[li] = _max_level;
|
||||
|
||||
while(_highest_active>=0 &&
|
||||
_last_active[_highest_active]<_first[_highest_active])
|
||||
_highest_active--;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
///\name Active Item on Certain Level
|
||||
///Functions for working with the active items.
|
||||
|
||||
///@{
|
||||
|
||||
///Return an active item on level \c l.
|
||||
|
||||
///Return an active item on level \c l or \ref INVALID if there is no such
|
||||
///an item. (\c l must be from the range [0...\c max_level].
|
||||
Item activeOn(int l) const
|
||||
{
|
||||
return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
|
||||
}
|
||||
|
||||
///Lift the active item returned by \c activeOn(level) by one.
|
||||
|
||||
///Lift the active item returned by \ref activeOn() "activeOn(level)"
|
||||
///by one.
|
||||
Item liftActiveOn(int level)
|
||||
{
|
||||
Item it =*_last_active[level];
|
||||
++_level[it];
|
||||
swap(_last_active[level]--, --_first[level+1]);
|
||||
if (level+1>_highest_active) ++_highest_active;
|
||||
}
|
||||
|
||||
///Lift the active item returned by \c activeOn(level) to the given level.
|
||||
|
||||
///Lift the active item returned by \ref activeOn() "activeOn(level)"
|
||||
///to the given level.
|
||||
void liftActiveOn(int level, int new_level)
|
||||
{
|
||||
const Item ai = *_last_active[level];
|
||||
|
||||
copy(--_first[level+1], _last_active[level]--);
|
||||
for(int l=level+1;l<new_level;l++)
|
||||
{
|
||||
copy(_last_active[l],_first[l]);
|
||||
copy(--_first[l+1], _last_active[l]--);
|
||||
}
|
||||
copy(ai,_first[new_level]);
|
||||
_level[ai] = new_level;
|
||||
if (new_level>_highest_active) _highest_active=new_level;
|
||||
}
|
||||
|
||||
///Lift the active item returned by \c activeOn(level) to the top level.
|
||||
|
||||
///Lift the active item returned by \ref activeOn() "activeOn(level)"
|
||||
///to the top level and deactivate it.
|
||||
void liftActiveToTop(int level)
|
||||
{
|
||||
const Item ai = *_last_active[level];
|
||||
|
||||
copy(--_first[level+1],_last_active[level]--);
|
||||
for(int l=level+1;l<_max_level;l++)
|
||||
{
|
||||
copy(_last_active[l],_first[l]);
|
||||
copy(--_first[l+1], _last_active[l]--);
|
||||
}
|
||||
copy(ai,_first[_max_level]);
|
||||
--_last_active[_max_level];
|
||||
_level[ai] = _max_level;
|
||||
|
||||
if (_highest_active==level) {
|
||||
while(_highest_active>=0 &&
|
||||
_last_active[_highest_active]<_first[_highest_active])
|
||||
_highest_active--;
|
||||
}
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
///Lift an active item to a higher level.
|
||||
|
||||
///Lift an active item to a higher level.
|
||||
///\param i The item to be lifted. It must be active.
|
||||
///\param new_level The new level of \c i. It must be strictly higher
|
||||
///than the current level.
|
||||
///
|
||||
void lift(Item i, int new_level)
|
||||
{
|
||||
const int lo = _level[i];
|
||||
const Vit w = _where[i];
|
||||
|
||||
copy(_last_active[lo],w);
|
||||
copy(--_first[lo+1],_last_active[lo]--);
|
||||
for(int l=lo+1;l<new_level;l++)
|
||||
{
|
||||
copy(_last_active[l],_first[l]);
|
||||
copy(--_first[l+1],_last_active[l]--);
|
||||
}
|
||||
copy(i,_first[new_level]);
|
||||
_level[i] = new_level;
|
||||
if(new_level>_highest_active) _highest_active=new_level;
|
||||
}
|
||||
|
||||
///Move an inactive item to the top but one level (in a dirty way).
|
||||
|
||||
///This function moves an inactive item from the top level to the top
|
||||
///but one level (in a dirty way).
|
||||
///\warning It makes the underlying datastructure corrupt, so use it
|
||||
///only if you really know what it is for.
|
||||
///\pre The item is on the top level.
|
||||
void dirtyTopButOne(Item i) {
|
||||
_level[i] = _max_level - 1;
|
||||
}
|
||||
|
||||
///Lift all items on and above the given level to the top level.
|
||||
|
||||
///This function lifts all items on and above level \c l to the top
|
||||
///level and deactivates them.
|
||||
void liftToTop(int l)
|
||||
{
|
||||
const Vit f=_first[l];
|
||||
const Vit tl=_first[_max_level];
|
||||
for(Vit i=f;i!=tl;++i)
|
||||
_level[*i] = _max_level;
|
||||
for(int i=l;i<=_max_level;i++)
|
||||
{
|
||||
_first[i]=f;
|
||||
_last_active[i]=f-1;
|
||||
}
|
||||
for(_highest_active=l-1;
|
||||
_highest_active>=0 &&
|
||||
_last_active[_highest_active]<_first[_highest_active];
|
||||
_highest_active--) ;
|
||||
}
|
||||
|
||||
private:
|
||||
int _init_lev;
|
||||
Vit _init_num;
|
||||
|
||||
public:
|
||||
|
||||
///\name Initialization
|
||||
///Using these functions you can initialize the levels of the items.
|
||||
///\n
|
||||
///The initialization must be started with calling \c initStart().
|
||||
///Then the items should be listed level by level starting with the
|
||||
///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
|
||||
///Finally \c initFinish() must be called.
|
||||
///The items not listed are put on the highest level.
|
||||
///@{
|
||||
|
||||
///Start the initialization process.
|
||||
void initStart()
|
||||
{
|
||||
_init_lev=0;
|
||||
_init_num=&_items[0];
|
||||
_first[0]=&_items[0];
|
||||
_last_active[0]=&_items[0]-1;
|
||||
Vit n=&_items[0];
|
||||
for(typename ItemSetTraits<GR,Item>::ItemIt i(_g);i!=INVALID;++i)
|
||||
{
|
||||
*n=i;
|
||||
_where[i] = n;
|
||||
_level[i] = _max_level;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
///Add an item to the current level.
|
||||
void initAddItem(Item i)
|
||||
{
|
||||
swap(_where[i],_init_num);
|
||||
_level[i] = _init_lev;
|
||||
++_init_num;
|
||||
}
|
||||
|
||||
///Start a new level.
|
||||
|
||||
///Start a new level.
|
||||
///It shouldn't be used before the items on level 0 are listed.
|
||||
void initNewLevel()
|
||||
{
|
||||
_init_lev++;
|
||||
_first[_init_lev]=_init_num;
|
||||
_last_active[_init_lev]=_init_num-1;
|
||||
}
|
||||
|
||||
///Finalize the initialization process.
|
||||
void initFinish()
|
||||
{
|
||||
for(_init_lev++;_init_lev<=_max_level;_init_lev++)
|
||||
{
|
||||
_first[_init_lev]=_init_num;
|
||||
_last_active[_init_lev]=_init_num-1;
|
||||
}
|
||||
_first[_max_level+1]=&_items[0]+_item_num;
|
||||
_last_active[_max_level+1]=&_items[0]+_item_num-1;
|
||||
_highest_active = -1;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
};
|
||||
|
||||
///Class for handling "labels" in push-relabel type algorithms.
|
||||
|
||||
///A class for handling "labels" in push-relabel type algorithms.
|
||||
///
|
||||
///\ingroup auxdat
|
||||
///Using this class you can assign "labels" (nonnegative integer numbers)
|
||||
///to the edges or nodes of a graph, manipulate and query them through
|
||||
///operations typically arising in "push-relabel" type algorithms.
|
||||
///
|
||||
///Each item is either \em active or not, and you can also choose a
|
||||
///highest level active item.
|
||||
///
|
||||
///\sa Elevator
|
||||
///
|
||||
///\param GR Type of the underlying graph.
|
||||
///\param Item Type of the items the data is assigned to (\c GR::Node,
|
||||
///\c GR::Arc or \c GR::Edge).
|
||||
template <class GR, class Item>
|
||||
class LinkedElevator {
|
||||
public:
|
||||
|
||||
typedef Item Key;
|
||||
typedef int Value;
|
||||
|
||||
private:
|
||||
|
||||
typedef typename ItemSetTraits<GR,Item>::
|
||||
template Map<Item>::Type ItemMap;
|
||||
typedef typename ItemSetTraits<GR,Item>::
|
||||
template Map<int>::Type IntMap;
|
||||
typedef typename ItemSetTraits<GR,Item>::
|
||||
template Map<bool>::Type BoolMap;
|
||||
|
||||
const GR &_graph;
|
||||
int _max_level;
|
||||
int _item_num;
|
||||
std::vector<Item> _first, _last;
|
||||
ItemMap _prev, _next;
|
||||
int _highest_active;
|
||||
IntMap _level;
|
||||
BoolMap _active;
|
||||
|
||||
public:
|
||||
///Constructor with given maximum level.
|
||||
|
||||
///Constructor with given maximum level.
|
||||
///
|
||||
///\param graph The underlying graph.
|
||||
///\param max_level The maximum allowed level.
|
||||
///Set the range of the possible labels to <tt>[0..max_level]</tt>.
|
||||
LinkedElevator(const GR& graph, int max_level)
|
||||
: _graph(graph), _max_level(max_level), _item_num(_max_level),
|
||||
_first(_max_level + 1), _last(_max_level + 1),
|
||||
_prev(graph), _next(graph),
|
||||
_highest_active(-1), _level(graph), _active(graph) {}
|
||||
|
||||
///Constructor.
|
||||
|
||||
///Constructor.
|
||||
///
|
||||
///\param graph The underlying graph.
|
||||
///Set the range of the possible labels to <tt>[0..max_level]</tt>,
|
||||
///where \c max_level is equal to the number of labeled items in the graph.
|
||||
LinkedElevator(const GR& graph)
|
||||
: _graph(graph), _max_level(countItems<GR, Item>(graph)),
|
||||
_item_num(_max_level),
|
||||
_first(_max_level + 1), _last(_max_level + 1),
|
||||
_prev(graph, INVALID), _next(graph, INVALID),
|
||||
_highest_active(-1), _level(graph), _active(graph) {}
|
||||
|
||||
|
||||
///Activate item \c i.
|
||||
|
||||
///Activate item \c i.
|
||||
///\pre Item \c i shouldn't be active before.
|
||||
void activate(Item i) {
|
||||
_active[i] = true;
|
||||
|
||||
int level = _level[i];
|
||||
if (level > _highest_active) {
|
||||
_highest_active = level;
|
||||
}
|
||||
|
||||
if (_prev[i] == INVALID || _active[_prev[i]]) return;
|
||||
//unlace
|
||||
_next[_prev[i]] = _next[i];
|
||||
if (_next[i] != INVALID) {
|
||||
_prev[_next[i]] = _prev[i];
|
||||
} else {
|
||||
_last[level] = _prev[i];
|
||||
}
|
||||
//lace
|
||||
_next[i] = _first[level];
|
||||
_prev[_first[level]] = i;
|
||||
_prev[i] = INVALID;
|
||||
_first[level] = i;
|
||||
|
||||
}
|
||||
|
||||
///Deactivate item \c i.
|
||||
|
||||
///Deactivate item \c i.
|
||||
///\pre Item \c i must be active before.
|
||||
void deactivate(Item i) {
|
||||
_active[i] = false;
|
||||
int level = _level[i];
|
||||
|
||||
if (_next[i] == INVALID || !_active[_next[i]])
|
||||
goto find_highest_level;
|
||||
|
||||
//unlace
|
||||
_prev[_next[i]] = _prev[i];
|
||||
if (_prev[i] != INVALID) {
|
||||
_next[_prev[i]] = _next[i];
|
||||
} else {
|
||||
_first[_level[i]] = _next[i];
|
||||
}
|
||||
//lace
|
||||
_prev[i] = _last[level];
|
||||
_next[_last[level]] = i;
|
||||
_next[i] = INVALID;
|
||||
_last[level] = i;
|
||||
|
||||
find_highest_level:
|
||||
if (level == _highest_active) {
|
||||
while (_highest_active >= 0 && activeFree(_highest_active))
|
||||
--_highest_active;
|
||||
}
|
||||
}
|
||||
|
||||
///Query whether item \c i is active
|
||||
bool active(Item i) const { return _active[i]; }
|
||||
|
||||
///Return the level of item \c i.
|
||||
int operator[](Item i) const { return _level[i]; }
|
||||
|
||||
///Return the number of items on level \c l.
|
||||
int onLevel(int l) const {
|
||||
int num = 0;
|
||||
Item n = _first[l];
|
||||
while (n != INVALID) {
|
||||
++num;
|
||||
n = _next[n];
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
///Return true if the level is empty.
|
||||
bool emptyLevel(int l) const {
|
||||
return _first[l] == INVALID;
|
||||
}
|
||||
|
||||
///Return the number of items above level \c l.
|
||||
int aboveLevel(int l) const {
|
||||
int num = 0;
|
||||
for (int level = l + 1; level < _max_level; ++level)
|
||||
num += onLevel(level);
|
||||
return num;
|
||||
}
|
||||
|
||||
///Return the number of active items on level \c l.
|
||||
int activesOnLevel(int l) const {
|
||||
int num = 0;
|
||||
Item n = _first[l];
|
||||
while (n != INVALID && _active[n]) {
|
||||
++num;
|
||||
n = _next[n];
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
///Return true if there is no active item on level \c l.
|
||||
bool activeFree(int l) const {
|
||||
return _first[l] == INVALID || !_active[_first[l]];
|
||||
}
|
||||
|
||||
///Return the maximum allowed level.
|
||||
int maxLevel() const {
|
||||
return _max_level;
|
||||
}
|
||||
|
||||
///\name Highest Active Item
|
||||
///Functions for working with the highest level
|
||||
///active item.
|
||||
|
||||
///@{
|
||||
|
||||
///Return a highest level active item.
|
||||
|
||||
///Return a highest level active item or INVALID if there is no active
|
||||
///item.
|
||||
Item highestActive() const {
|
||||
return _highest_active >= 0 ? _first[_highest_active] : INVALID;
|
||||
}
|
||||
|
||||
///Return the highest active level.
|
||||
|
||||
///Return the level of the highest active item or -1 if there is no active
|
||||
///item.
|
||||
int highestActiveLevel() const {
|
||||
return _highest_active;
|
||||
}
|
||||
|
||||
///Lift the highest active item by one.
|
||||
|
||||
///Lift the item returned by highestActive() by one.
|
||||
///
|
||||
void liftHighestActive() {
|
||||
Item i = _first[_highest_active];
|
||||
if (_next[i] != INVALID) {
|
||||
_prev[_next[i]] = INVALID;
|
||||
_first[_highest_active] = _next[i];
|
||||
} else {
|
||||
_first[_highest_active] = INVALID;
|
||||
_last[_highest_active] = INVALID;
|
||||
}
|
||||
_level[i] = ++_highest_active;
|
||||
if (_first[_highest_active] == INVALID) {
|
||||
_first[_highest_active] = i;
|
||||
_last[_highest_active] = i;
|
||||
_prev[i] = INVALID;
|
||||
_next[i] = INVALID;
|
||||
} else {
|
||||
_prev[_first[_highest_active]] = i;
|
||||
_next[i] = _first[_highest_active];
|
||||
_first[_highest_active] = i;
|
||||
}
|
||||
}
|
||||
|
||||
///Lift the highest active item to the given level.
|
||||
|
||||
///Lift the item returned by highestActive() to level \c new_level.
|
||||
///
|
||||
///\warning \c new_level must be strictly higher
|
||||
///than the current level.
|
||||
///
|
||||
void liftHighestActive(int new_level) {
|
||||
Item i = _first[_highest_active];
|
||||
if (_next[i] != INVALID) {
|
||||
_prev[_next[i]] = INVALID;
|
||||
_first[_highest_active] = _next[i];
|
||||
} else {
|
||||
_first[_highest_active] = INVALID;
|
||||
_last[_highest_active] = INVALID;
|
||||
}
|
||||
_level[i] = _highest_active = new_level;
|
||||
if (_first[_highest_active] == INVALID) {
|
||||
_first[_highest_active] = _last[_highest_active] = i;
|
||||
_prev[i] = INVALID;
|
||||
_next[i] = INVALID;
|
||||
} else {
|
||||
_prev[_first[_highest_active]] = i;
|
||||
_next[i] = _first[_highest_active];
|
||||
_first[_highest_active] = i;
|
||||
}
|
||||
}
|
||||
|
||||
///Lift the highest active item to the top level.
|
||||
|
||||
///Lift the item returned by highestActive() to the top level and
|
||||
///deactivate it.
|
||||
void liftHighestActiveToTop() {
|
||||
Item i = _first[_highest_active];
|
||||
_level[i] = _max_level;
|
||||
if (_next[i] != INVALID) {
|
||||
_prev[_next[i]] = INVALID;
|
||||
_first[_highest_active] = _next[i];
|
||||
} else {
|
||||
_first[_highest_active] = INVALID;
|
||||
_last[_highest_active] = INVALID;
|
||||
}
|
||||
while (_highest_active >= 0 && activeFree(_highest_active))
|
||||
--_highest_active;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
///\name Active Item on Certain Level
|
||||
///Functions for working with the active items.
|
||||
|
||||
///@{
|
||||
|
||||
///Return an active item on level \c l.
|
||||
|
||||
///Return an active item on level \c l or \ref INVALID if there is no such
|
||||
///an item. (\c l must be from the range [0...\c max_level].
|
||||
Item activeOn(int l) const
|
||||
{
|
||||
return _active[_first[l]] ? _first[l] : INVALID;
|
||||
}
|
||||
|
||||
///Lift the active item returned by \c activeOn(l) by one.
|
||||
|
||||
///Lift the active item returned by \ref activeOn() "activeOn(l)"
|
||||
///by one.
|
||||
Item liftActiveOn(int l)
|
||||
{
|
||||
Item i = _first[l];
|
||||
if (_next[i] != INVALID) {
|
||||
_prev[_next[i]] = INVALID;
|
||||
_first[l] = _next[i];
|
||||
} else {
|
||||
_first[l] = INVALID;
|
||||
_last[l] = INVALID;
|
||||
}
|
||||
_level[i] = ++l;
|
||||
if (_first[l] == INVALID) {
|
||||
_first[l] = _last[l] = i;
|
||||
_prev[i] = INVALID;
|
||||
_next[i] = INVALID;
|
||||
} else {
|
||||
_prev[_first[l]] = i;
|
||||
_next[i] = _first[l];
|
||||
_first[l] = i;
|
||||
}
|
||||
if (_highest_active < l) {
|
||||
_highest_active = l;
|
||||
}
|
||||
}
|
||||
|
||||
///Lift the active item returned by \c activeOn(l) to the given level.
|
||||
|
||||
///Lift the active item returned by \ref activeOn() "activeOn(l)"
|
||||
///to the given level.
|
||||
void liftActiveOn(int l, int new_level)
|
||||
{
|
||||
Item i = _first[l];
|
||||
if (_next[i] != INVALID) {
|
||||
_prev[_next[i]] = INVALID;
|
||||
_first[l] = _next[i];
|
||||
} else {
|
||||
_first[l] = INVALID;
|
||||
_last[l] = INVALID;
|
||||
}
|
||||
_level[i] = l = new_level;
|
||||
if (_first[l] == INVALID) {
|
||||
_first[l] = _last[l] = i;
|
||||
_prev[i] = INVALID;
|
||||
_next[i] = INVALID;
|
||||
} else {
|
||||
_prev[_first[l]] = i;
|
||||
_next[i] = _first[l];
|
||||
_first[l] = i;
|
||||
}
|
||||
if (_highest_active < l) {
|
||||
_highest_active = l;
|
||||
}
|
||||
}
|
||||
|
||||
///Lift the active item returned by \c activeOn(l) to the top level.
|
||||
|
||||
///Lift the active item returned by \ref activeOn() "activeOn(l)"
|
||||
///to the top level and deactivate it.
|
||||
void liftActiveToTop(int l)
|
||||
{
|
||||
Item i = _first[l];
|
||||
if (_next[i] != INVALID) {
|
||||
_prev[_next[i]] = INVALID;
|
||||
_first[l] = _next[i];
|
||||
} else {
|
||||
_first[l] = INVALID;
|
||||
_last[l] = INVALID;
|
||||
}
|
||||
_level[i] = _max_level;
|
||||
if (l == _highest_active) {
|
||||
while (_highest_active >= 0 && activeFree(_highest_active))
|
||||
--_highest_active;
|
||||
}
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
/// \brief Lift an active item to a higher level.
|
||||
///
|
||||
/// Lift an active item to a higher level.
|
||||
/// \param i The item to be lifted. It must be active.
|
||||
/// \param new_level The new level of \c i. It must be strictly higher
|
||||
/// than the current level.
|
||||
///
|
||||
void lift(Item i, int new_level) {
|
||||
if (_next[i] != INVALID) {
|
||||
_prev[_next[i]] = _prev[i];
|
||||
} else {
|
||||
_last[new_level] = _prev[i];
|
||||
}
|
||||
if (_prev[i] != INVALID) {
|
||||
_next[_prev[i]] = _next[i];
|
||||
} else {
|
||||
_first[new_level] = _next[i];
|
||||
}
|
||||
_level[i] = new_level;
|
||||
if (_first[new_level] == INVALID) {
|
||||
_first[new_level] = _last[new_level] = i;
|
||||
_prev[i] = INVALID;
|
||||
_next[i] = INVALID;
|
||||
} else {
|
||||
_prev[_first[new_level]] = i;
|
||||
_next[i] = _first[new_level];
|
||||
_first[new_level] = i;
|
||||
}
|
||||
if (_highest_active < new_level) {
|
||||
_highest_active = new_level;
|
||||
}
|
||||
}
|
||||
|
||||
///Move an inactive item to the top but one level (in a dirty way).
|
||||
|
||||
///This function moves an inactive item from the top level to the top
|
||||
///but one level (in a dirty way).
|
||||
///\warning It makes the underlying datastructure corrupt, so use it
|
||||
///only if you really know what it is for.
|
||||
///\pre The item is on the top level.
|
||||
void dirtyTopButOne(Item i) {
|
||||
_level[i] = _max_level - 1;
|
||||
}
|
||||
|
||||
///Lift all items on and above the given level to the top level.
|
||||
|
||||
///This function lifts all items on and above level \c l to the top
|
||||
///level and deactivates them.
|
||||
void liftToTop(int l) {
|
||||
for (int i = l + 1; _first[i] != INVALID; ++i) {
|
||||
Item n = _first[i];
|
||||
while (n != INVALID) {
|
||||
_level[n] = _max_level;
|
||||
n = _next[n];
|
||||
}
|
||||
_first[i] = INVALID;
|
||||
_last[i] = INVALID;
|
||||
}
|
||||
if (_highest_active > l - 1) {
|
||||
_highest_active = l - 1;
|
||||
while (_highest_active >= 0 && activeFree(_highest_active))
|
||||
--_highest_active;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int _init_level;
|
||||
|
||||
public:
|
||||
|
||||
///\name Initialization
|
||||
///Using these functions you can initialize the levels of the items.
|
||||
///\n
|
||||
///The initialization must be started with calling \c initStart().
|
||||
///Then the items should be listed level by level starting with the
|
||||
///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
|
||||
///Finally \c initFinish() must be called.
|
||||
///The items not listed are put on the highest level.
|
||||
///@{
|
||||
|
||||
///Start the initialization process.
|
||||
void initStart() {
|
||||
|
||||
for (int i = 0; i <= _max_level; ++i) {
|
||||
_first[i] = _last[i] = INVALID;
|
||||
}
|
||||
_init_level = 0;
|
||||
for(typename ItemSetTraits<GR,Item>::ItemIt i(_graph);
|
||||
i != INVALID; ++i) {
|
||||
_level[i] = _max_level;
|
||||
_active[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
///Add an item to the current level.
|
||||
void initAddItem(Item i) {
|
||||
_level[i] = _init_level;
|
||||
if (_last[_init_level] == INVALID) {
|
||||
_first[_init_level] = i;
|
||||
_last[_init_level] = i;
|
||||
_prev[i] = INVALID;
|
||||
_next[i] = INVALID;
|
||||
} else {
|
||||
_prev[i] = _last[_init_level];
|
||||
_next[i] = INVALID;
|
||||
_next[_last[_init_level]] = i;
|
||||
_last[_init_level] = i;
|
||||
}
|
||||
}
|
||||
|
||||
///Start a new level.
|
||||
|
||||
///Start a new level.
|
||||
///It shouldn't be used before the items on level 0 are listed.
|
||||
void initNewLevel() {
|
||||
++_init_level;
|
||||
}
|
||||
|
||||
///Finalize the initialization process.
|
||||
void initFinish() {
|
||||
_highest_active = -1;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
};
|
||||
|
||||
|
||||
} //END OF NAMESPACE LEMON
|
||||
|
||||
#endif
|
||||
|
||||
276
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/error.h
vendored
Normal file
276
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/error.h
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_ERROR_H
|
||||
#define LEMON_ERROR_H
|
||||
|
||||
/// \ingroup exceptions
|
||||
/// \file
|
||||
/// \brief Basic exception classes and error handling.
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \addtogroup exceptions
|
||||
/// @{
|
||||
|
||||
/// \brief Generic exception class.
|
||||
///
|
||||
/// Base class for exceptions used in LEMON.
|
||||
///
|
||||
class Exception : public std::exception {
|
||||
public:
|
||||
///Constructor
|
||||
Exception() throw() {}
|
||||
///Virtual destructor
|
||||
virtual ~Exception() throw() {}
|
||||
///A short description of the exception
|
||||
virtual const char* what() const throw() {
|
||||
return "lemon::Exception";
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Input-Output error
|
||||
///
|
||||
/// This exception is thrown when a file operation cannot be
|
||||
/// succeeded.
|
||||
class IoError : public Exception {
|
||||
protected:
|
||||
std::string _message;
|
||||
std::string _file;
|
||||
|
||||
mutable std::string _what;
|
||||
public:
|
||||
|
||||
/// Copy constructor
|
||||
IoError(const IoError &error) throw() : Exception() {
|
||||
message(error._message);
|
||||
file(error._file);
|
||||
}
|
||||
|
||||
/// Constructor
|
||||
explicit IoError(const char *message) throw() {
|
||||
IoError::message(message);
|
||||
}
|
||||
|
||||
/// Constructor
|
||||
explicit IoError(const std::string &message) throw() {
|
||||
IoError::message(message);
|
||||
}
|
||||
|
||||
/// Constructor
|
||||
explicit IoError(const char *message,
|
||||
const std::string &file) throw() {
|
||||
IoError::message(message);
|
||||
IoError::file(file);
|
||||
}
|
||||
|
||||
/// Constructor
|
||||
explicit IoError(const std::string &message,
|
||||
const std::string &file) throw() {
|
||||
IoError::message(message);
|
||||
IoError::file(file);
|
||||
}
|
||||
|
||||
/// Virtual destructor
|
||||
virtual ~IoError() throw() {}
|
||||
|
||||
/// Set the error message
|
||||
void message(const char *message) throw() {
|
||||
try {
|
||||
_message = message;
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
/// Set the error message
|
||||
void message(const std::string& message) throw() {
|
||||
try {
|
||||
_message = message;
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
/// Set the file name
|
||||
void file(const std::string &file) throw() {
|
||||
try {
|
||||
_file = file;
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
/// Returns the error message
|
||||
const std::string& message() const throw() {
|
||||
return _message;
|
||||
}
|
||||
|
||||
/// \brief Returns the filename
|
||||
///
|
||||
/// Returns the filename or an empty string if it was not specified.
|
||||
const std::string& file() const throw() {
|
||||
return _file;
|
||||
}
|
||||
|
||||
/// \brief Returns a short error message
|
||||
///
|
||||
/// Returns a short error message which contains the message and the
|
||||
/// file name.
|
||||
virtual const char* what() const throw() {
|
||||
try {
|
||||
_what.clear();
|
||||
std::ostringstream oss;
|
||||
oss << "lemon:IoError" << ": ";
|
||||
oss << _message;
|
||||
if (!_file.empty()) {
|
||||
oss << " ('" << _file << "')";
|
||||
}
|
||||
_what = oss.str();
|
||||
}
|
||||
catch (...) {}
|
||||
if (!_what.empty()) return _what.c_str();
|
||||
else return "lemon:IoError";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// \brief Format error
|
||||
///
|
||||
/// This exception is thrown when an input file has wrong
|
||||
/// format or a data representation is not legal.
|
||||
class FormatError : public Exception {
|
||||
protected:
|
||||
std::string _message;
|
||||
std::string _file;
|
||||
int _line;
|
||||
|
||||
mutable std::string _what;
|
||||
public:
|
||||
|
||||
/// Copy constructor
|
||||
FormatError(const FormatError &error) throw() : Exception() {
|
||||
message(error._message);
|
||||
file(error._file);
|
||||
line(error._line);
|
||||
}
|
||||
|
||||
/// Constructor
|
||||
explicit FormatError(const char *message) throw() {
|
||||
FormatError::message(message);
|
||||
_line = 0;
|
||||
}
|
||||
|
||||
/// Constructor
|
||||
explicit FormatError(const std::string &message) throw() {
|
||||
FormatError::message(message);
|
||||
_line = 0;
|
||||
}
|
||||
|
||||
/// Constructor
|
||||
explicit FormatError(const char *message,
|
||||
const std::string &file, int line = 0) throw() {
|
||||
FormatError::message(message);
|
||||
FormatError::file(file);
|
||||
FormatError::line(line);
|
||||
}
|
||||
|
||||
/// Constructor
|
||||
explicit FormatError(const std::string &message,
|
||||
const std::string &file, int line = 0) throw() {
|
||||
FormatError::message(message);
|
||||
FormatError::file(file);
|
||||
FormatError::line(line);
|
||||
}
|
||||
|
||||
/// Virtual destructor
|
||||
virtual ~FormatError() throw() {}
|
||||
|
||||
/// Set the line number
|
||||
void line(int line) throw() { _line = line; }
|
||||
|
||||
/// Set the error message
|
||||
void message(const char *message) throw() {
|
||||
try {
|
||||
_message = message;
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
/// Set the error message
|
||||
void message(const std::string& message) throw() {
|
||||
try {
|
||||
_message = message;
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
/// Set the file name
|
||||
void file(const std::string &file) throw() {
|
||||
try {
|
||||
_file = file;
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
/// \brief Returns the line number
|
||||
///
|
||||
/// Returns the line number or zero if it was not specified.
|
||||
int line() const throw() { return _line; }
|
||||
|
||||
/// Returns the error message
|
||||
const std::string& message() const throw() {
|
||||
return _message;
|
||||
}
|
||||
|
||||
/// \brief Returns the filename
|
||||
///
|
||||
/// Returns the filename or an empty string if it was not specified.
|
||||
const std::string& file() const throw() {
|
||||
return _file;
|
||||
}
|
||||
|
||||
/// \brief Returns a short error message
|
||||
///
|
||||
/// Returns a short error message which contains the message, the
|
||||
/// file name and the line number.
|
||||
virtual const char* what() const throw() {
|
||||
try {
|
||||
_what.clear();
|
||||
std::ostringstream oss;
|
||||
oss << "lemon:FormatError" << ": ";
|
||||
oss << _message;
|
||||
if (!_file.empty() || _line != 0) {
|
||||
oss << " (";
|
||||
if (!_file.empty()) oss << "in file '" << _file << "'";
|
||||
if (!_file.empty() && _line != 0) oss << " ";
|
||||
if (_line != 0) oss << "at line " << _line;
|
||||
oss << ")";
|
||||
}
|
||||
_what = oss.str();
|
||||
}
|
||||
catch (...) {}
|
||||
if (!_what.empty()) return _what.c_str();
|
||||
else return "lemon:FormatError";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
}
|
||||
|
||||
#endif // LEMON_ERROR_H
|
||||
287
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/euler.h
vendored
Normal file
287
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/euler.h
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_EULER_H
|
||||
#define LEMON_EULER_H
|
||||
|
||||
#include<lemon/core.h>
|
||||
#include<lemon/adaptors.h>
|
||||
#include<lemon/connectivity.h>
|
||||
#include <list>
|
||||
|
||||
/// \ingroup graph_properties
|
||||
/// \file
|
||||
/// \brief Euler tour iterators and a function for checking the \e Eulerian
|
||||
/// property.
|
||||
///
|
||||
///This file provides Euler tour iterators and a function to check
|
||||
///if a (di)graph is \e Eulerian.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
///Euler tour iterator for digraphs.
|
||||
|
||||
/// \ingroup graph_properties
|
||||
///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
|
||||
///graph (if there exists) and it converts to the \c Arc type of the digraph.
|
||||
///
|
||||
///For example, if the given digraph has an Euler tour (i.e it has only one
|
||||
///non-trivial component and the in-degree is equal to the out-degree
|
||||
///for all nodes), then the following code will put the arcs of \c g
|
||||
///to the vector \c et according to an Euler tour of \c g.
|
||||
///\code
|
||||
/// std::vector<ListDigraph::Arc> et;
|
||||
/// for(DiEulerIt<ListDigraph> e(g); e!=INVALID; ++e)
|
||||
/// et.push_back(e);
|
||||
///\endcode
|
||||
///If \c g has no Euler tour, then the resulted walk will not be closed
|
||||
///or not contain all arcs.
|
||||
///\sa EulerIt
|
||||
template<typename GR>
|
||||
class DiEulerIt
|
||||
{
|
||||
typedef typename GR::Node Node;
|
||||
typedef typename GR::NodeIt NodeIt;
|
||||
typedef typename GR::Arc Arc;
|
||||
typedef typename GR::ArcIt ArcIt;
|
||||
typedef typename GR::OutArcIt OutArcIt;
|
||||
typedef typename GR::InArcIt InArcIt;
|
||||
|
||||
const GR &g;
|
||||
typename GR::template NodeMap<OutArcIt> narc;
|
||||
std::list<Arc> euler;
|
||||
|
||||
public:
|
||||
|
||||
///Constructor
|
||||
|
||||
///Constructor.
|
||||
///\param gr A digraph.
|
||||
///\param start The starting point of the tour. If it is not given,
|
||||
///the tour will start from the first node that has an outgoing arc.
|
||||
DiEulerIt(const GR &gr, typename GR::Node start = INVALID)
|
||||
: g(gr), narc(g)
|
||||
{
|
||||
if (start==INVALID) {
|
||||
NodeIt n(g);
|
||||
while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
|
||||
start=n;
|
||||
}
|
||||
if (start!=INVALID) {
|
||||
for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
|
||||
while (narc[start]!=INVALID) {
|
||||
euler.push_back(narc[start]);
|
||||
Node next=g.target(narc[start]);
|
||||
++narc[start];
|
||||
start=next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///Arc conversion
|
||||
operator Arc() { return euler.empty()?INVALID:euler.front(); }
|
||||
///Compare with \c INVALID
|
||||
bool operator==(Invalid) { return euler.empty(); }
|
||||
///Compare with \c INVALID
|
||||
bool operator!=(Invalid) { return !euler.empty(); }
|
||||
|
||||
///Next arc of the tour
|
||||
|
||||
///Next arc of the tour
|
||||
///
|
||||
DiEulerIt &operator++() {
|
||||
Node s=g.target(euler.front());
|
||||
euler.pop_front();
|
||||
typename std::list<Arc>::iterator next=euler.begin();
|
||||
while(narc[s]!=INVALID) {
|
||||
euler.insert(next,narc[s]);
|
||||
Node n=g.target(narc[s]);
|
||||
++narc[s];
|
||||
s=n;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
///Postfix incrementation
|
||||
|
||||
/// Postfix incrementation.
|
||||
///
|
||||
///\warning This incrementation
|
||||
///returns an \c Arc, not a \ref DiEulerIt, as one may
|
||||
///expect.
|
||||
Arc operator++(int)
|
||||
{
|
||||
Arc e=*this;
|
||||
++(*this);
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
///Euler tour iterator for graphs.
|
||||
|
||||
/// \ingroup graph_properties
|
||||
///This iterator provides an Euler tour (Eulerian circuit) of an
|
||||
///\e undirected graph (if there exists) and it converts to the \c Arc
|
||||
///and \c Edge types of the graph.
|
||||
///
|
||||
///For example, if the given graph has an Euler tour (i.e it has only one
|
||||
///non-trivial component and the degree of each node is even),
|
||||
///the following code will print the arc IDs according to an
|
||||
///Euler tour of \c g.
|
||||
///\code
|
||||
/// for(EulerIt<ListGraph> e(g); e!=INVALID; ++e) {
|
||||
/// std::cout << g.id(Edge(e)) << std::eol;
|
||||
/// }
|
||||
///\endcode
|
||||
///Although this iterator is for undirected graphs, it still returns
|
||||
///arcs in order to indicate the direction of the tour.
|
||||
///(But arcs convert to edges, of course.)
|
||||
///
|
||||
///If \c g has no Euler tour, then the resulted walk will not be closed
|
||||
///or not contain all edges.
|
||||
template<typename GR>
|
||||
class EulerIt
|
||||
{
|
||||
typedef typename GR::Node Node;
|
||||
typedef typename GR::NodeIt NodeIt;
|
||||
typedef typename GR::Arc Arc;
|
||||
typedef typename GR::Edge Edge;
|
||||
typedef typename GR::ArcIt ArcIt;
|
||||
typedef typename GR::OutArcIt OutArcIt;
|
||||
typedef typename GR::InArcIt InArcIt;
|
||||
|
||||
const GR &g;
|
||||
typename GR::template NodeMap<OutArcIt> narc;
|
||||
typename GR::template EdgeMap<bool> visited;
|
||||
std::list<Arc> euler;
|
||||
|
||||
public:
|
||||
|
||||
///Constructor
|
||||
|
||||
///Constructor.
|
||||
///\param gr A graph.
|
||||
///\param start The starting point of the tour. If it is not given,
|
||||
///the tour will start from the first node that has an incident edge.
|
||||
EulerIt(const GR &gr, typename GR::Node start = INVALID)
|
||||
: g(gr), narc(g), visited(g, false)
|
||||
{
|
||||
if (start==INVALID) {
|
||||
NodeIt n(g);
|
||||
while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
|
||||
start=n;
|
||||
}
|
||||
if (start!=INVALID) {
|
||||
for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
|
||||
while(narc[start]!=INVALID) {
|
||||
euler.push_back(narc[start]);
|
||||
visited[narc[start]]=true;
|
||||
Node next=g.target(narc[start]);
|
||||
++narc[start];
|
||||
start=next;
|
||||
while(narc[start]!=INVALID && visited[narc[start]]) ++narc[start];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///Arc conversion
|
||||
operator Arc() const { return euler.empty()?INVALID:euler.front(); }
|
||||
///Edge conversion
|
||||
operator Edge() const { return euler.empty()?INVALID:euler.front(); }
|
||||
///Compare with \c INVALID
|
||||
bool operator==(Invalid) const { return euler.empty(); }
|
||||
///Compare with \c INVALID
|
||||
bool operator!=(Invalid) const { return !euler.empty(); }
|
||||
|
||||
///Next arc of the tour
|
||||
|
||||
///Next arc of the tour
|
||||
///
|
||||
EulerIt &operator++() {
|
||||
Node s=g.target(euler.front());
|
||||
euler.pop_front();
|
||||
typename std::list<Arc>::iterator next=euler.begin();
|
||||
while(narc[s]!=INVALID) {
|
||||
while(narc[s]!=INVALID && visited[narc[s]]) ++narc[s];
|
||||
if(narc[s]==INVALID) break;
|
||||
else {
|
||||
euler.insert(next,narc[s]);
|
||||
visited[narc[s]]=true;
|
||||
Node n=g.target(narc[s]);
|
||||
++narc[s];
|
||||
s=n;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///Postfix incrementation
|
||||
|
||||
/// Postfix incrementation.
|
||||
///
|
||||
///\warning This incrementation returns an \c Arc (which converts to
|
||||
///an \c Edge), not an \ref EulerIt, as one may expect.
|
||||
Arc operator++(int)
|
||||
{
|
||||
Arc e=*this;
|
||||
++(*this);
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///Check if the given graph is Eulerian
|
||||
|
||||
/// \ingroup graph_properties
|
||||
///This function checks if the given graph is Eulerian.
|
||||
///It works for both directed and undirected graphs.
|
||||
///
|
||||
///By definition, a digraph is called \e Eulerian if
|
||||
///and only if it is connected and the number of incoming and outgoing
|
||||
///arcs are the same for each node.
|
||||
///Similarly, an undirected graph is called \e Eulerian if
|
||||
///and only if it is connected and the number of incident edges is even
|
||||
///for each node.
|
||||
///
|
||||
///\note There are (di)graphs that are not Eulerian, but still have an
|
||||
/// Euler tour, since they may contain isolated nodes.
|
||||
///
|
||||
///\sa DiEulerIt, EulerIt
|
||||
template<typename GR>
|
||||
#ifdef DOXYGEN
|
||||
bool
|
||||
#else
|
||||
typename enable_if<UndirectedTagIndicator<GR>,bool>::type
|
||||
eulerian(const GR &g)
|
||||
{
|
||||
for(typename GR::NodeIt n(g);n!=INVALID;++n)
|
||||
if(countIncEdges(g,n)%2) return false;
|
||||
return connected(g);
|
||||
}
|
||||
template<class GR>
|
||||
typename disable_if<UndirectedTagIndicator<GR>,bool>::type
|
||||
#endif
|
||||
eulerian(const GR &g)
|
||||
{
|
||||
for(typename GR::NodeIt n(g);n!=INVALID;++n)
|
||||
if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
|
||||
return connected(undirector(g));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
475
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/fib_heap.h
vendored
Normal file
475
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/fib_heap.h
vendored
Normal file
@@ -0,0 +1,475 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_FIB_HEAP_H
|
||||
#define LEMON_FIB_HEAP_H
|
||||
|
||||
///\file
|
||||
///\ingroup heaps
|
||||
///\brief Fibonacci heap implementation.
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <lemon/math.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \ingroup heaps
|
||||
///
|
||||
/// \brief Fibonacci heap data structure.
|
||||
///
|
||||
/// This class implements the \e Fibonacci \e heap data structure.
|
||||
/// It fully conforms to the \ref concepts::Heap "heap concept".
|
||||
///
|
||||
/// The methods \ref increase() and \ref erase() are not efficient in a
|
||||
/// Fibonacci heap. In case of many calls of these operations, it is
|
||||
/// better to use other heap structure, e.g. \ref BinHeap "binary heap".
|
||||
///
|
||||
/// \tparam PR Type of the priorities of the items.
|
||||
/// \tparam IM A read-writable item map with \c int values, used
|
||||
/// internally to handle the cross references.
|
||||
/// \tparam CMP A functor class for comparing the priorities.
|
||||
/// The default is \c std::less<PR>.
|
||||
#ifdef DOXYGEN
|
||||
template <typename PR, typename IM, typename CMP>
|
||||
#else
|
||||
template <typename PR, typename IM, typename CMP = std::less<PR> >
|
||||
#endif
|
||||
class FibHeap {
|
||||
public:
|
||||
|
||||
/// Type of the item-int map.
|
||||
typedef IM ItemIntMap;
|
||||
/// Type of the priorities.
|
||||
typedef PR Prio;
|
||||
/// Type of the items stored in the heap.
|
||||
typedef typename ItemIntMap::Key Item;
|
||||
/// Type of the item-priority pairs.
|
||||
typedef std::pair<Item,Prio> Pair;
|
||||
/// Functor type for comparing the priorities.
|
||||
typedef CMP Compare;
|
||||
|
||||
private:
|
||||
class Store;
|
||||
|
||||
std::vector<Store> _data;
|
||||
int _minimum;
|
||||
ItemIntMap &_iim;
|
||||
Compare _comp;
|
||||
int _num;
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Type to represent the states of the items.
|
||||
///
|
||||
/// Each item has a state associated to it. It can be "in heap",
|
||||
/// "pre-heap" or "post-heap". The latter two are indifferent from the
|
||||
/// heap's point of view, but may be useful to the user.
|
||||
///
|
||||
/// The item-int map must be initialized in such way that it assigns
|
||||
/// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
|
||||
enum State {
|
||||
IN_HEAP = 0, ///< = 0.
|
||||
PRE_HEAP = -1, ///< = -1.
|
||||
POST_HEAP = -2 ///< = -2.
|
||||
};
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to the items.
|
||||
/// It is used internally to handle the cross references.
|
||||
/// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
explicit FibHeap(ItemIntMap &map)
|
||||
: _minimum(0), _iim(map), _num() {}
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param map A map that assigns \c int values to the items.
|
||||
/// It is used internally to handle the cross references.
|
||||
/// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
|
||||
/// \param comp The function object used for comparing the priorities.
|
||||
FibHeap(ItemIntMap &map, const Compare &comp)
|
||||
: _minimum(0), _iim(map), _comp(comp), _num() {}
|
||||
|
||||
/// \brief The number of items stored in the heap.
|
||||
///
|
||||
/// This function returns the number of items stored in the heap.
|
||||
int size() const { return _num; }
|
||||
|
||||
/// \brief Check if the heap is empty.
|
||||
///
|
||||
/// This function returns \c true if the heap is empty.
|
||||
bool empty() const { return _num==0; }
|
||||
|
||||
/// \brief Make the heap empty.
|
||||
///
|
||||
/// This functon makes the heap empty.
|
||||
/// It does not change the cross reference map. If you want to reuse
|
||||
/// a heap that is not surely empty, you should first clear it and
|
||||
/// then you should set the cross reference map to \c PRE_HEAP
|
||||
/// for each item.
|
||||
void clear() {
|
||||
_data.clear(); _minimum = 0; _num = 0;
|
||||
}
|
||||
|
||||
/// \brief Insert an item into the heap with the given priority.
|
||||
///
|
||||
/// This function inserts the given item into the heap with the
|
||||
/// given priority.
|
||||
/// \param item The item to insert.
|
||||
/// \param prio The priority of the item.
|
||||
/// \pre \e item must not be stored in the heap.
|
||||
void push (const Item& item, const Prio& prio) {
|
||||
int i=_iim[item];
|
||||
if ( i < 0 ) {
|
||||
int s=_data.size();
|
||||
_iim.set( item, s );
|
||||
Store st;
|
||||
st.name=item;
|
||||
_data.push_back(st);
|
||||
i=s;
|
||||
} else {
|
||||
_data[i].parent=_data[i].child=-1;
|
||||
_data[i].degree=0;
|
||||
_data[i].in=true;
|
||||
_data[i].marked=false;
|
||||
}
|
||||
|
||||
if ( _num ) {
|
||||
_data[_data[_minimum].right_neighbor].left_neighbor=i;
|
||||
_data[i].right_neighbor=_data[_minimum].right_neighbor;
|
||||
_data[_minimum].right_neighbor=i;
|
||||
_data[i].left_neighbor=_minimum;
|
||||
if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
|
||||
} else {
|
||||
_data[i].right_neighbor=_data[i].left_neighbor=i;
|
||||
_minimum=i;
|
||||
}
|
||||
_data[i].prio=prio;
|
||||
++_num;
|
||||
}
|
||||
|
||||
/// \brief Return the item having minimum priority.
|
||||
///
|
||||
/// This function returns the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Item top() const { return _data[_minimum].name; }
|
||||
|
||||
/// \brief The minimum priority.
|
||||
///
|
||||
/// This function returns the minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
Prio prio() const { return _data[_minimum].prio; }
|
||||
|
||||
/// \brief Remove the item having minimum priority.
|
||||
///
|
||||
/// This function removes the item having minimum priority.
|
||||
/// \pre The heap must be non-empty.
|
||||
void pop() {
|
||||
/*The first case is that there are only one root.*/
|
||||
if ( _data[_minimum].left_neighbor==_minimum ) {
|
||||
_data[_minimum].in=false;
|
||||
if ( _data[_minimum].degree!=0 ) {
|
||||
makeRoot(_data[_minimum].child);
|
||||
_minimum=_data[_minimum].child;
|
||||
balance();
|
||||
}
|
||||
} else {
|
||||
int right=_data[_minimum].right_neighbor;
|
||||
unlace(_minimum);
|
||||
_data[_minimum].in=false;
|
||||
if ( _data[_minimum].degree > 0 ) {
|
||||
int left=_data[_minimum].left_neighbor;
|
||||
int child=_data[_minimum].child;
|
||||
int last_child=_data[child].left_neighbor;
|
||||
|
||||
makeRoot(child);
|
||||
|
||||
_data[left].right_neighbor=child;
|
||||
_data[child].left_neighbor=left;
|
||||
_data[right].left_neighbor=last_child;
|
||||
_data[last_child].right_neighbor=right;
|
||||
}
|
||||
_minimum=right;
|
||||
balance();
|
||||
} // the case where there are more roots
|
||||
--_num;
|
||||
}
|
||||
|
||||
/// \brief Remove the given item from the heap.
|
||||
///
|
||||
/// This function removes the given item from the heap if it is
|
||||
/// already stored.
|
||||
/// \param item The item to delete.
|
||||
/// \pre \e item must be in the heap.
|
||||
void erase (const Item& item) {
|
||||
int i=_iim[item];
|
||||
|
||||
if ( i >= 0 && _data[i].in ) {
|
||||
if ( _data[i].parent!=-1 ) {
|
||||
int p=_data[i].parent;
|
||||
cut(i,p);
|
||||
cascade(p);
|
||||
}
|
||||
_minimum=i; //As if its prio would be -infinity
|
||||
pop();
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief The priority of the given item.
|
||||
///
|
||||
/// This function returns the priority of the given item.
|
||||
/// \param item The item.
|
||||
/// \pre \e item must be in the heap.
|
||||
Prio operator[](const Item& item) const {
|
||||
return _data[_iim[item]].prio;
|
||||
}
|
||||
|
||||
/// \brief Set the priority of an item or insert it, if it is
|
||||
/// not stored in the heap.
|
||||
///
|
||||
/// This method sets the priority of the given item if it is
|
||||
/// already stored in the heap. Otherwise it inserts the given
|
||||
/// item into the heap with the given priority.
|
||||
/// \param item The item.
|
||||
/// \param prio The priority.
|
||||
void set (const Item& item, const Prio& prio) {
|
||||
int i=_iim[item];
|
||||
if ( i >= 0 && _data[i].in ) {
|
||||
if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
|
||||
if ( _comp(_data[i].prio, prio) ) increase(item, prio);
|
||||
} else push(item, prio);
|
||||
}
|
||||
|
||||
/// \brief Decrease the priority of an item to the given value.
|
||||
///
|
||||
/// This function decreases the priority of an item to the given value.
|
||||
/// \param item The item.
|
||||
/// \param prio The priority.
|
||||
/// \pre \e item must be stored in the heap with priority at least \e prio.
|
||||
void decrease (const Item& item, const Prio& prio) {
|
||||
int i=_iim[item];
|
||||
_data[i].prio=prio;
|
||||
int p=_data[i].parent;
|
||||
|
||||
if ( p!=-1 && _comp(prio, _data[p].prio) ) {
|
||||
cut(i,p);
|
||||
cascade(p);
|
||||
}
|
||||
if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
|
||||
}
|
||||
|
||||
/// \brief Increase the priority of an item to the given value.
|
||||
///
|
||||
/// This function increases the priority of an item to the given value.
|
||||
/// \param item The item.
|
||||
/// \param prio The priority.
|
||||
/// \pre \e item must be stored in the heap with priority at most \e prio.
|
||||
void increase (const Item& item, const Prio& prio) {
|
||||
erase(item);
|
||||
push(item, prio);
|
||||
}
|
||||
|
||||
/// \brief Return the state of an item.
|
||||
///
|
||||
/// This method returns \c PRE_HEAP if the given item has never
|
||||
/// been in the heap, \c IN_HEAP if it is in the heap at the moment,
|
||||
/// and \c POST_HEAP otherwise.
|
||||
/// In the latter case it is possible that the item will get back
|
||||
/// to the heap again.
|
||||
/// \param item The item.
|
||||
State state(const Item &item) const {
|
||||
int i=_iim[item];
|
||||
if( i>=0 ) {
|
||||
if ( _data[i].in ) i=0;
|
||||
else i=-2;
|
||||
}
|
||||
return State(i);
|
||||
}
|
||||
|
||||
/// \brief Set the state of an item in the heap.
|
||||
///
|
||||
/// This function sets the state of the given item in the heap.
|
||||
/// It can be used to manually clear the heap when it is important
|
||||
/// to achive better time complexity.
|
||||
/// \param i The item.
|
||||
/// \param st The state. It should not be \c IN_HEAP.
|
||||
void state(const Item& i, State st) {
|
||||
switch (st) {
|
||||
case POST_HEAP:
|
||||
case PRE_HEAP:
|
||||
if (state(i) == IN_HEAP) {
|
||||
erase(i);
|
||||
}
|
||||
_iim[i] = st;
|
||||
break;
|
||||
case IN_HEAP:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void balance() {
|
||||
|
||||
int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
|
||||
|
||||
std::vector<int> A(maxdeg,-1);
|
||||
|
||||
/*
|
||||
*Recall that now minimum does not point to the minimum prio element.
|
||||
*We set minimum to this during balance().
|
||||
*/
|
||||
int anchor=_data[_minimum].left_neighbor;
|
||||
int next=_minimum;
|
||||
bool end=false;
|
||||
|
||||
do {
|
||||
int active=next;
|
||||
if ( anchor==active ) end=true;
|
||||
int d=_data[active].degree;
|
||||
next=_data[active].right_neighbor;
|
||||
|
||||
while (A[d]!=-1) {
|
||||
if( _comp(_data[active].prio, _data[A[d]].prio) ) {
|
||||
fuse(active,A[d]);
|
||||
} else {
|
||||
fuse(A[d],active);
|
||||
active=A[d];
|
||||
}
|
||||
A[d]=-1;
|
||||
++d;
|
||||
}
|
||||
A[d]=active;
|
||||
} while ( !end );
|
||||
|
||||
|
||||
while ( _data[_minimum].parent >=0 )
|
||||
_minimum=_data[_minimum].parent;
|
||||
int s=_minimum;
|
||||
int m=_minimum;
|
||||
do {
|
||||
if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
|
||||
s=_data[s].right_neighbor;
|
||||
} while ( s != m );
|
||||
}
|
||||
|
||||
void makeRoot(int c) {
|
||||
int s=c;
|
||||
do {
|
||||
_data[s].parent=-1;
|
||||
s=_data[s].right_neighbor;
|
||||
} while ( s != c );
|
||||
}
|
||||
|
||||
void cut(int a, int b) {
|
||||
/*
|
||||
*Replacing a from the children of b.
|
||||
*/
|
||||
--_data[b].degree;
|
||||
|
||||
if ( _data[b].degree !=0 ) {
|
||||
int child=_data[b].child;
|
||||
if ( child==a )
|
||||
_data[b].child=_data[child].right_neighbor;
|
||||
unlace(a);
|
||||
}
|
||||
|
||||
|
||||
/*Lacing a to the roots.*/
|
||||
int right=_data[_minimum].right_neighbor;
|
||||
_data[_minimum].right_neighbor=a;
|
||||
_data[a].left_neighbor=_minimum;
|
||||
_data[a].right_neighbor=right;
|
||||
_data[right].left_neighbor=a;
|
||||
|
||||
_data[a].parent=-1;
|
||||
_data[a].marked=false;
|
||||
}
|
||||
|
||||
void cascade(int a) {
|
||||
if ( _data[a].parent!=-1 ) {
|
||||
int p=_data[a].parent;
|
||||
|
||||
if ( _data[a].marked==false ) _data[a].marked=true;
|
||||
else {
|
||||
cut(a,p);
|
||||
cascade(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fuse(int a, int b) {
|
||||
unlace(b);
|
||||
|
||||
/*Lacing b under a.*/
|
||||
_data[b].parent=a;
|
||||
|
||||
if (_data[a].degree==0) {
|
||||
_data[b].left_neighbor=b;
|
||||
_data[b].right_neighbor=b;
|
||||
_data[a].child=b;
|
||||
} else {
|
||||
int child=_data[a].child;
|
||||
int last_child=_data[child].left_neighbor;
|
||||
_data[child].left_neighbor=b;
|
||||
_data[b].right_neighbor=child;
|
||||
_data[last_child].right_neighbor=b;
|
||||
_data[b].left_neighbor=last_child;
|
||||
}
|
||||
|
||||
++_data[a].degree;
|
||||
|
||||
_data[b].marked=false;
|
||||
}
|
||||
|
||||
/*
|
||||
*It is invoked only if a has siblings.
|
||||
*/
|
||||
void unlace(int a) {
|
||||
int leftn=_data[a].left_neighbor;
|
||||
int rightn=_data[a].right_neighbor;
|
||||
_data[leftn].right_neighbor=rightn;
|
||||
_data[rightn].left_neighbor=leftn;
|
||||
}
|
||||
|
||||
|
||||
class Store {
|
||||
friend class FibHeap;
|
||||
|
||||
Item name;
|
||||
int parent;
|
||||
int left_neighbor;
|
||||
int right_neighbor;
|
||||
int child;
|
||||
int degree;
|
||||
bool marked;
|
||||
bool in;
|
||||
Prio prio;
|
||||
|
||||
Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
|
||||
};
|
||||
};
|
||||
|
||||
} //namespace lemon
|
||||
|
||||
#endif //LEMON_FIB_HEAP_H
|
||||
|
||||
2139
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/fractional_matching.h
vendored
Normal file
2139
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/fractional_matching.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1082
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/full_graph.h
vendored
Normal file
1082
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/full_graph.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1012
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/glpk.cc
vendored
Normal file
1012
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/glpk.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
263
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/glpk.h
vendored
Normal file
263
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/glpk.h
vendored
Normal file
@@ -0,0 +1,263 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_GLPK_H
|
||||
#define LEMON_GLPK_H
|
||||
|
||||
///\file
|
||||
///\brief Header of the LEMON-GLPK lp solver interface.
|
||||
///\ingroup lp_group
|
||||
|
||||
#include <lemon/lp_base.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
namespace _solver_bits {
|
||||
class VoidPtr {
|
||||
private:
|
||||
void *_ptr;
|
||||
public:
|
||||
VoidPtr() : _ptr(0) {}
|
||||
|
||||
template <typename T>
|
||||
VoidPtr(T* ptr) : _ptr(reinterpret_cast<void*>(ptr)) {}
|
||||
|
||||
template <typename T>
|
||||
VoidPtr& operator=(T* ptr) {
|
||||
_ptr = reinterpret_cast<void*>(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
operator T*() const { return reinterpret_cast<T*>(_ptr); }
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief Base interface for the GLPK LP and MIP solver
|
||||
///
|
||||
/// This class implements the common interface of the GLPK LP and MIP solver.
|
||||
/// \ingroup lp_group
|
||||
class GlpkBase : virtual public LpBase {
|
||||
protected:
|
||||
|
||||
_solver_bits::VoidPtr lp;
|
||||
|
||||
GlpkBase();
|
||||
GlpkBase(const GlpkBase&);
|
||||
virtual ~GlpkBase();
|
||||
|
||||
protected:
|
||||
|
||||
virtual int _addCol();
|
||||
virtual int _addRow();
|
||||
virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
|
||||
|
||||
virtual void _eraseCol(int i);
|
||||
virtual void _eraseRow(int i);
|
||||
|
||||
virtual void _eraseColId(int i);
|
||||
virtual void _eraseRowId(int i);
|
||||
|
||||
virtual void _getColName(int col, std::string& name) const;
|
||||
virtual void _setColName(int col, const std::string& name);
|
||||
virtual int _colByName(const std::string& name) const;
|
||||
|
||||
virtual void _getRowName(int row, std::string& name) const;
|
||||
virtual void _setRowName(int row, const std::string& name);
|
||||
virtual int _rowByName(const std::string& name) const;
|
||||
|
||||
virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
|
||||
virtual void _getRowCoeffs(int i, InsertIterator b) const;
|
||||
|
||||
virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
|
||||
virtual void _getColCoeffs(int i, InsertIterator b) const;
|
||||
|
||||
virtual void _setCoeff(int row, int col, Value value);
|
||||
virtual Value _getCoeff(int row, int col) const;
|
||||
|
||||
virtual void _setColLowerBound(int i, Value value);
|
||||
virtual Value _getColLowerBound(int i) const;
|
||||
|
||||
virtual void _setColUpperBound(int i, Value value);
|
||||
virtual Value _getColUpperBound(int i) const;
|
||||
|
||||
virtual void _setRowLowerBound(int i, Value value);
|
||||
virtual Value _getRowLowerBound(int i) const;
|
||||
|
||||
virtual void _setRowUpperBound(int i, Value value);
|
||||
virtual Value _getRowUpperBound(int i) const;
|
||||
|
||||
virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
|
||||
virtual void _getObjCoeffs(InsertIterator b) const;
|
||||
|
||||
virtual void _setObjCoeff(int i, Value obj_coef);
|
||||
virtual Value _getObjCoeff(int i) const;
|
||||
|
||||
virtual void _setSense(Sense);
|
||||
virtual Sense _getSense() const;
|
||||
|
||||
virtual void _clear();
|
||||
|
||||
virtual void _messageLevel(MessageLevel level);
|
||||
|
||||
virtual void _write(std::string file, std::string format) const;
|
||||
|
||||
private:
|
||||
|
||||
static void freeEnv();
|
||||
|
||||
struct FreeEnvHelper {
|
||||
~FreeEnvHelper() {
|
||||
freeEnv();
|
||||
}
|
||||
};
|
||||
|
||||
static FreeEnvHelper freeEnvHelper;
|
||||
|
||||
protected:
|
||||
|
||||
int _message_level;
|
||||
|
||||
public:
|
||||
|
||||
///Pointer to the underlying GLPK data structure.
|
||||
_solver_bits::VoidPtr lpx() {return lp;}
|
||||
///Const pointer to the underlying GLPK data structure.
|
||||
_solver_bits::VoidPtr lpx() const {return lp;}
|
||||
|
||||
///Returns the constraint identifier understood by GLPK.
|
||||
int lpxRow(Row r) const { return rows(id(r)); }
|
||||
|
||||
///Returns the variable identifier understood by GLPK.
|
||||
int lpxCol(Col c) const { return cols(id(c)); }
|
||||
|
||||
#ifdef DOXYGEN
|
||||
/// Write the problem or the solution to a file in the given format
|
||||
|
||||
/// This function writes the problem or the solution
|
||||
/// to a file in the given format.
|
||||
/// Trying to write in an unsupported format will trigger
|
||||
/// \ref LpBase::UnsupportedFormatError.
|
||||
/// \param file The file path
|
||||
/// \param format The output file format.
|
||||
/// Supportted formats are "MPS" and "LP".
|
||||
void write(std::string file, std::string format = "MPS") const {}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/// \brief Interface for the GLPK LP solver
|
||||
///
|
||||
/// This class implements an interface for the GLPK LP solver.
|
||||
///\ingroup lp_group
|
||||
class GlpkLp : public LpSolver, public GlpkBase {
|
||||
public:
|
||||
|
||||
///\e
|
||||
GlpkLp();
|
||||
///\e
|
||||
GlpkLp(const GlpkLp&);
|
||||
|
||||
///\e
|
||||
virtual GlpkLp* cloneSolver() const;
|
||||
///\e
|
||||
virtual GlpkLp* newSolver() const;
|
||||
|
||||
private:
|
||||
|
||||
mutable std::vector<double> _primal_ray;
|
||||
mutable std::vector<double> _dual_ray;
|
||||
|
||||
void _clear_temporals();
|
||||
|
||||
protected:
|
||||
|
||||
virtual const char* _solverName() const;
|
||||
|
||||
virtual SolveExitStatus _solve();
|
||||
virtual Value _getPrimal(int i) const;
|
||||
virtual Value _getDual(int i) const;
|
||||
|
||||
virtual Value _getPrimalValue() const;
|
||||
|
||||
virtual VarStatus _getColStatus(int i) const;
|
||||
virtual VarStatus _getRowStatus(int i) const;
|
||||
|
||||
virtual Value _getPrimalRay(int i) const;
|
||||
virtual Value _getDualRay(int i) const;
|
||||
|
||||
virtual ProblemType _getPrimalType() const;
|
||||
virtual ProblemType _getDualType() const;
|
||||
|
||||
public:
|
||||
|
||||
///Solve with primal simplex
|
||||
SolveExitStatus solvePrimal();
|
||||
|
||||
///Solve with dual simplex
|
||||
SolveExitStatus solveDual();
|
||||
|
||||
private:
|
||||
|
||||
bool _presolve;
|
||||
|
||||
public:
|
||||
|
||||
///Turns on or off the presolver
|
||||
|
||||
///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
|
||||
///
|
||||
///The presolver is off by default.
|
||||
void presolver(bool presolve);
|
||||
|
||||
};
|
||||
|
||||
/// \brief Interface for the GLPK MIP solver
|
||||
///
|
||||
/// This class implements an interface for the GLPK MIP solver.
|
||||
///\ingroup lp_group
|
||||
class GlpkMip : public MipSolver, public GlpkBase {
|
||||
public:
|
||||
|
||||
///\e
|
||||
GlpkMip();
|
||||
///\e
|
||||
GlpkMip(const GlpkMip&);
|
||||
|
||||
virtual GlpkMip* cloneSolver() const;
|
||||
virtual GlpkMip* newSolver() const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual const char* _solverName() const;
|
||||
|
||||
virtual ColTypes _getColType(int col) const;
|
||||
virtual void _setColType(int col, ColTypes col_type);
|
||||
|
||||
virtual SolveExitStatus _solve();
|
||||
virtual ProblemType _getType() const;
|
||||
virtual Value _getSol(int i) const;
|
||||
virtual Value _getSolValue() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} //END OF NAMESPACE LEMON
|
||||
|
||||
#endif //LEMON_GLPK_H
|
||||
|
||||
568
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/gomory_hu.h
vendored
Normal file
568
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/gomory_hu.h
vendored
Normal file
@@ -0,0 +1,568 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_GOMORY_HU_TREE_H
|
||||
#define LEMON_GOMORY_HU_TREE_H
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/preflow.h>
|
||||
#include <lemon/concept_check.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
|
||||
/// \ingroup min_cut
|
||||
/// \file
|
||||
/// \brief Gomory-Hu cut tree in graphs.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \ingroup min_cut
|
||||
///
|
||||
/// \brief Gomory-Hu cut tree algorithm
|
||||
///
|
||||
/// The Gomory-Hu tree is a tree on the node set of a given graph, but it
|
||||
/// may contain edges which are not in the original graph. It has the
|
||||
/// property that the minimum capacity edge of the path between two nodes
|
||||
/// in this tree has the same weight as the minimum cut in the graph
|
||||
/// between these nodes. Moreover the components obtained by removing
|
||||
/// this edge from the tree determine the corresponding minimum cut.
|
||||
/// Therefore once this tree is computed, the minimum cut between any pair
|
||||
/// of nodes can easily be obtained.
|
||||
///
|
||||
/// The algorithm calculates \e n-1 distinct minimum cuts (currently with
|
||||
/// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{m})\f$ overall
|
||||
/// time complexity. It calculates a rooted Gomory-Hu tree.
|
||||
/// The structure of the tree and the edge weights can be
|
||||
/// obtained using \c predNode(), \c predValue() and \c rootDist().
|
||||
/// The functions \c minCutMap() and \c minCutValue() calculate
|
||||
/// the minimum cut and the minimum cut value between any two nodes
|
||||
/// in the graph. You can also list (iterate on) the nodes and the
|
||||
/// edges of the cuts using \c MinCutNodeIt and \c MinCutEdgeIt.
|
||||
///
|
||||
/// \tparam GR The type of the undirected graph the algorithm runs on.
|
||||
/// \tparam CAP The type of the edge map containing the capacities.
|
||||
/// The default map type is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
|
||||
#ifdef DOXYGEN
|
||||
template <typename GR,
|
||||
typename CAP>
|
||||
#else
|
||||
template <typename GR,
|
||||
typename CAP = typename GR::template EdgeMap<int> >
|
||||
#endif
|
||||
class GomoryHu {
|
||||
public:
|
||||
|
||||
/// The graph type of the algorithm
|
||||
typedef GR Graph;
|
||||
/// The capacity map type of the algorithm
|
||||
typedef CAP Capacity;
|
||||
/// The value type of capacities
|
||||
typedef typename Capacity::Value Value;
|
||||
|
||||
private:
|
||||
|
||||
TEMPLATE_GRAPH_TYPEDEFS(Graph);
|
||||
|
||||
const Graph& _graph;
|
||||
const Capacity& _capacity;
|
||||
|
||||
Node _root;
|
||||
typename Graph::template NodeMap<Node>* _pred;
|
||||
typename Graph::template NodeMap<Value>* _weight;
|
||||
typename Graph::template NodeMap<int>* _order;
|
||||
|
||||
void createStructures() {
|
||||
if (!_pred) {
|
||||
_pred = new typename Graph::template NodeMap<Node>(_graph);
|
||||
}
|
||||
if (!_weight) {
|
||||
_weight = new typename Graph::template NodeMap<Value>(_graph);
|
||||
}
|
||||
if (!_order) {
|
||||
_order = new typename Graph::template NodeMap<int>(_graph);
|
||||
}
|
||||
}
|
||||
|
||||
void destroyStructures() {
|
||||
if (_pred) {
|
||||
delete _pred;
|
||||
}
|
||||
if (_weight) {
|
||||
delete _weight;
|
||||
}
|
||||
if (_order) {
|
||||
delete _order;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constructor
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param graph The undirected graph the algorithm runs on.
|
||||
/// \param capacity The edge capacity map.
|
||||
GomoryHu(const Graph& graph, const Capacity& capacity)
|
||||
: _graph(graph), _capacity(capacity),
|
||||
_pred(0), _weight(0), _order(0)
|
||||
{
|
||||
checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
|
||||
}
|
||||
|
||||
|
||||
/// \brief Destructor
|
||||
///
|
||||
/// Destructor.
|
||||
~GomoryHu() {
|
||||
destroyStructures();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Initialize the internal data structures
|
||||
void init() {
|
||||
createStructures();
|
||||
|
||||
_root = NodeIt(_graph);
|
||||
for (NodeIt n(_graph); n != INVALID; ++n) {
|
||||
(*_pred)[n] = _root;
|
||||
(*_order)[n] = -1;
|
||||
}
|
||||
(*_pred)[_root] = INVALID;
|
||||
(*_weight)[_root] = std::numeric_limits<Value>::max();
|
||||
}
|
||||
|
||||
|
||||
// Start the algorithm
|
||||
void start() {
|
||||
Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
|
||||
|
||||
for (NodeIt n(_graph); n != INVALID; ++n) {
|
||||
if (n == _root) continue;
|
||||
|
||||
Node pn = (*_pred)[n];
|
||||
fa.source(n);
|
||||
fa.target(pn);
|
||||
|
||||
fa.runMinCut();
|
||||
|
||||
(*_weight)[n] = fa.flowValue();
|
||||
|
||||
for (NodeIt nn(_graph); nn != INVALID; ++nn) {
|
||||
if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
|
||||
(*_pred)[nn] = n;
|
||||
}
|
||||
}
|
||||
if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
|
||||
(*_pred)[n] = (*_pred)[pn];
|
||||
(*_pred)[pn] = n;
|
||||
(*_weight)[n] = (*_weight)[pn];
|
||||
(*_weight)[pn] = fa.flowValue();
|
||||
}
|
||||
}
|
||||
|
||||
(*_order)[_root] = 0;
|
||||
int index = 1;
|
||||
|
||||
for (NodeIt n(_graph); n != INVALID; ++n) {
|
||||
std::vector<Node> st;
|
||||
Node nn = n;
|
||||
while ((*_order)[nn] == -1) {
|
||||
st.push_back(nn);
|
||||
nn = (*_pred)[nn];
|
||||
}
|
||||
while (!st.empty()) {
|
||||
(*_order)[st.back()] = index++;
|
||||
st.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
///\name Execution Control
|
||||
|
||||
///@{
|
||||
|
||||
/// \brief Run the Gomory-Hu algorithm.
|
||||
///
|
||||
/// This function runs the Gomory-Hu algorithm.
|
||||
void run() {
|
||||
init();
|
||||
start();
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
///\name Query Functions
|
||||
///The results of the algorithm can be obtained using these
|
||||
///functions.\n
|
||||
///\ref run() should be called before using them.\n
|
||||
///See also \ref MinCutNodeIt and \ref MinCutEdgeIt.
|
||||
|
||||
///@{
|
||||
|
||||
/// \brief Return the predecessor node in the Gomory-Hu tree.
|
||||
///
|
||||
/// This function returns the predecessor node of the given node
|
||||
/// in the Gomory-Hu tree.
|
||||
/// If \c node is the root of the tree, then it returns \c INVALID.
|
||||
///
|
||||
/// \pre \ref run() must be called before using this function.
|
||||
Node predNode(const Node& node) const {
|
||||
return (*_pred)[node];
|
||||
}
|
||||
|
||||
/// \brief Return the weight of the predecessor edge in the
|
||||
/// Gomory-Hu tree.
|
||||
///
|
||||
/// This function returns the weight of the predecessor edge of the
|
||||
/// given node in the Gomory-Hu tree.
|
||||
/// If \c node is the root of the tree, the result is undefined.
|
||||
///
|
||||
/// \pre \ref run() must be called before using this function.
|
||||
Value predValue(const Node& node) const {
|
||||
return (*_weight)[node];
|
||||
}
|
||||
|
||||
/// \brief Return the distance from the root node in the Gomory-Hu tree.
|
||||
///
|
||||
/// This function returns the distance of the given node from the root
|
||||
/// node in the Gomory-Hu tree.
|
||||
///
|
||||
/// \pre \ref run() must be called before using this function.
|
||||
int rootDist(const Node& node) const {
|
||||
return (*_order)[node];
|
||||
}
|
||||
|
||||
/// \brief Return the minimum cut value between two nodes
|
||||
///
|
||||
/// This function returns the minimum cut value between the nodes
|
||||
/// \c s and \c t.
|
||||
/// It finds the nearest common ancestor of the given nodes in the
|
||||
/// Gomory-Hu tree and calculates the minimum weight edge on the
|
||||
/// paths to the ancestor.
|
||||
///
|
||||
/// \pre \ref run() must be called before using this function.
|
||||
Value minCutValue(const Node& s, const Node& t) const {
|
||||
Node sn = s, tn = t;
|
||||
Value value = std::numeric_limits<Value>::max();
|
||||
|
||||
while (sn != tn) {
|
||||
if ((*_order)[sn] < (*_order)[tn]) {
|
||||
if ((*_weight)[tn] <= value) value = (*_weight)[tn];
|
||||
tn = (*_pred)[tn];
|
||||
} else {
|
||||
if ((*_weight)[sn] <= value) value = (*_weight)[sn];
|
||||
sn = (*_pred)[sn];
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/// \brief Return the minimum cut between two nodes
|
||||
///
|
||||
/// This function returns the minimum cut between the nodes \c s and \c t
|
||||
/// in the \c cutMap parameter by setting the nodes in the component of
|
||||
/// \c s to \c true and the other nodes to \c false.
|
||||
///
|
||||
/// For higher level interfaces see MinCutNodeIt and MinCutEdgeIt.
|
||||
///
|
||||
/// \param s The base node.
|
||||
/// \param t The node you want to separate from node \c s.
|
||||
/// \param cutMap The cut will be returned in this map.
|
||||
/// It must be a \c bool (or convertible) \ref concepts::ReadWriteMap
|
||||
/// "ReadWriteMap" on the graph nodes.
|
||||
///
|
||||
/// \return The value of the minimum cut between \c s and \c t.
|
||||
///
|
||||
/// \pre \ref run() must be called before using this function.
|
||||
template <typename CutMap>
|
||||
Value minCutMap(const Node& s,
|
||||
const Node& t,
|
||||
CutMap& cutMap
|
||||
) const {
|
||||
Node sn = s, tn = t;
|
||||
bool s_root=false;
|
||||
Node rn = INVALID;
|
||||
Value value = std::numeric_limits<Value>::max();
|
||||
|
||||
while (sn != tn) {
|
||||
if ((*_order)[sn] < (*_order)[tn]) {
|
||||
if ((*_weight)[tn] <= value) {
|
||||
rn = tn;
|
||||
s_root = false;
|
||||
value = (*_weight)[tn];
|
||||
}
|
||||
tn = (*_pred)[tn];
|
||||
} else {
|
||||
if ((*_weight)[sn] <= value) {
|
||||
rn = sn;
|
||||
s_root = true;
|
||||
value = (*_weight)[sn];
|
||||
}
|
||||
sn = (*_pred)[sn];
|
||||
}
|
||||
}
|
||||
|
||||
typename Graph::template NodeMap<bool> reached(_graph, false);
|
||||
reached[_root] = true;
|
||||
cutMap.set(_root, !s_root);
|
||||
reached[rn] = true;
|
||||
cutMap.set(rn, s_root);
|
||||
|
||||
std::vector<Node> st;
|
||||
for (NodeIt n(_graph); n != INVALID; ++n) {
|
||||
st.clear();
|
||||
Node nn = n;
|
||||
while (!reached[nn]) {
|
||||
st.push_back(nn);
|
||||
nn = (*_pred)[nn];
|
||||
}
|
||||
while (!st.empty()) {
|
||||
cutMap.set(st.back(), cutMap[nn]);
|
||||
st.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
friend class MinCutNodeIt;
|
||||
|
||||
/// Iterate on the nodes of a minimum cut
|
||||
|
||||
/// This iterator class lists the nodes of a minimum cut found by
|
||||
/// GomoryHu. Before using it, you must allocate a GomoryHu class
|
||||
/// and call its \ref GomoryHu::run() "run()" method.
|
||||
///
|
||||
/// This example counts the nodes in the minimum cut separating \c s from
|
||||
/// \c t.
|
||||
/// \code
|
||||
/// GomoryHu<Graph> gom(g, capacities);
|
||||
/// gom.run();
|
||||
/// int cnt=0;
|
||||
/// for(GomoryHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
|
||||
/// \endcode
|
||||
class MinCutNodeIt
|
||||
{
|
||||
bool _side;
|
||||
typename Graph::NodeIt _node_it;
|
||||
typename Graph::template NodeMap<bool> _cut;
|
||||
public:
|
||||
/// Constructor
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
MinCutNodeIt(GomoryHu const &gomory,
|
||||
///< The GomoryHu class. You must call its
|
||||
/// run() method
|
||||
/// before initializing this iterator.
|
||||
const Node& s, ///< The base node.
|
||||
const Node& t,
|
||||
///< The node you want to separate from node \c s.
|
||||
bool side=true
|
||||
///< If it is \c true (default) then the iterator lists
|
||||
/// the nodes of the component containing \c s,
|
||||
/// otherwise it lists the other component.
|
||||
/// \note As the minimum cut is not always unique,
|
||||
/// \code
|
||||
/// MinCutNodeIt(gomory, s, t, true);
|
||||
/// \endcode
|
||||
/// and
|
||||
/// \code
|
||||
/// MinCutNodeIt(gomory, t, s, false);
|
||||
/// \endcode
|
||||
/// does not necessarily give the same set of nodes.
|
||||
/// However, it is ensured that
|
||||
/// \code
|
||||
/// MinCutNodeIt(gomory, s, t, true);
|
||||
/// \endcode
|
||||
/// and
|
||||
/// \code
|
||||
/// MinCutNodeIt(gomory, s, t, false);
|
||||
/// \endcode
|
||||
/// together list each node exactly once.
|
||||
)
|
||||
: _side(side), _cut(gomory._graph)
|
||||
{
|
||||
gomory.minCutMap(s,t,_cut);
|
||||
for(_node_it=typename Graph::NodeIt(gomory._graph);
|
||||
_node_it!=INVALID && _cut[_node_it]!=_side;
|
||||
++_node_it) {}
|
||||
}
|
||||
/// Conversion to \c Node
|
||||
|
||||
/// Conversion to \c Node.
|
||||
///
|
||||
operator typename Graph::Node() const
|
||||
{
|
||||
return _node_it;
|
||||
}
|
||||
bool operator==(Invalid) { return _node_it==INVALID; }
|
||||
bool operator!=(Invalid) { return _node_it!=INVALID; }
|
||||
/// Next node
|
||||
|
||||
/// Next node.
|
||||
///
|
||||
MinCutNodeIt &operator++()
|
||||
{
|
||||
for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {}
|
||||
return *this;
|
||||
}
|
||||
/// Postfix incrementation
|
||||
|
||||
/// Postfix incrementation.
|
||||
///
|
||||
/// \warning This incrementation
|
||||
/// returns a \c Node, not a \c MinCutNodeIt, as one may
|
||||
/// expect.
|
||||
typename Graph::Node operator++(int)
|
||||
{
|
||||
typename Graph::Node n=*this;
|
||||
++(*this);
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
friend class MinCutEdgeIt;
|
||||
|
||||
/// Iterate on the edges of a minimum cut
|
||||
|
||||
/// This iterator class lists the edges of a minimum cut found by
|
||||
/// GomoryHu. Before using it, you must allocate a GomoryHu class
|
||||
/// and call its \ref GomoryHu::run() "run()" method.
|
||||
///
|
||||
/// This example computes the value of the minimum cut separating \c s from
|
||||
/// \c t.
|
||||
/// \code
|
||||
/// GomoryHu<Graph> gom(g, capacities);
|
||||
/// gom.run();
|
||||
/// int value=0;
|
||||
/// for(GomoryHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
|
||||
/// value+=capacities[e];
|
||||
/// \endcode
|
||||
/// The result will be the same as the value returned by
|
||||
/// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)".
|
||||
class MinCutEdgeIt
|
||||
{
|
||||
bool _side;
|
||||
const Graph &_graph;
|
||||
typename Graph::NodeIt _node_it;
|
||||
typename Graph::OutArcIt _arc_it;
|
||||
typename Graph::template NodeMap<bool> _cut;
|
||||
void step()
|
||||
{
|
||||
++_arc_it;
|
||||
while(_node_it!=INVALID && _arc_it==INVALID)
|
||||
{
|
||||
for(++_node_it;_node_it!=INVALID&&!_cut[_node_it];++_node_it) {}
|
||||
if(_node_it!=INVALID)
|
||||
_arc_it=typename Graph::OutArcIt(_graph,_node_it);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
MinCutEdgeIt(GomoryHu const &gomory,
|
||||
///< The GomoryHu class. You must call its
|
||||
/// run() method
|
||||
/// before initializing this iterator.
|
||||
const Node& s, ///< The base node.
|
||||
const Node& t,
|
||||
///< The node you want to separate from node \c s.
|
||||
bool side=true
|
||||
///< If it is \c true (default) then the listed arcs
|
||||
/// will be oriented from the
|
||||
/// nodes of the component containing \c s,
|
||||
/// otherwise they will be oriented in the opposite
|
||||
/// direction.
|
||||
)
|
||||
: _graph(gomory._graph), _cut(_graph)
|
||||
{
|
||||
gomory.minCutMap(s,t,_cut);
|
||||
if(!side)
|
||||
for(typename Graph::NodeIt n(_graph);n!=INVALID;++n)
|
||||
_cut[n]=!_cut[n];
|
||||
|
||||
for(_node_it=typename Graph::NodeIt(_graph);
|
||||
_node_it!=INVALID && !_cut[_node_it];
|
||||
++_node_it) {}
|
||||
_arc_it = _node_it!=INVALID ?
|
||||
typename Graph::OutArcIt(_graph,_node_it) : INVALID;
|
||||
while(_node_it!=INVALID && _arc_it == INVALID)
|
||||
{
|
||||
for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {}
|
||||
if(_node_it!=INVALID)
|
||||
_arc_it= typename Graph::OutArcIt(_graph,_node_it);
|
||||
}
|
||||
while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
|
||||
}
|
||||
/// Conversion to \c Arc
|
||||
|
||||
/// Conversion to \c Arc.
|
||||
///
|
||||
operator typename Graph::Arc() const
|
||||
{
|
||||
return _arc_it;
|
||||
}
|
||||
/// Conversion to \c Edge
|
||||
|
||||
/// Conversion to \c Edge.
|
||||
///
|
||||
operator typename Graph::Edge() const
|
||||
{
|
||||
return _arc_it;
|
||||
}
|
||||
bool operator==(Invalid) { return _node_it==INVALID; }
|
||||
bool operator!=(Invalid) { return _node_it!=INVALID; }
|
||||
/// Next edge
|
||||
|
||||
/// Next edge.
|
||||
///
|
||||
MinCutEdgeIt &operator++()
|
||||
{
|
||||
step();
|
||||
while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
|
||||
return *this;
|
||||
}
|
||||
/// Postfix incrementation
|
||||
|
||||
/// Postfix incrementation.
|
||||
///
|
||||
/// \warning This incrementation
|
||||
/// returns an \c Arc, not a \c MinCutEdgeIt, as one may expect.
|
||||
typename Graph::Arc operator++(int)
|
||||
{
|
||||
typename Graph::Arc e=*this;
|
||||
++(*this);
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
1186
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/graph_to_eps.h
vendored
Normal file
1186
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/graph_to_eps.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
251
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/greedy_tsp.h
vendored
Normal file
251
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/greedy_tsp.h
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_GREEDY_TSP_H
|
||||
#define LEMON_GREEDY_TSP_H
|
||||
|
||||
/// \ingroup tsp
|
||||
/// \file
|
||||
/// \brief Greedy algorithm for symmetric TSP
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <lemon/full_graph.h>
|
||||
#include <lemon/unionfind.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \ingroup tsp
|
||||
///
|
||||
/// \brief Greedy algorithm for symmetric TSP.
|
||||
///
|
||||
/// GreedyTsp implements the greedy heuristic for solving
|
||||
/// symmetric \ref tsp "TSP".
|
||||
///
|
||||
/// This algorithm is quite similar to the \ref NearestNeighborTsp
|
||||
/// "nearest neighbor" heuristic, but it maintains a set of disjoint paths.
|
||||
/// At each step, the shortest possible edge is added to these paths
|
||||
/// as long as it does not create a cycle of less than n edges and it does
|
||||
/// not increase the degree of any node above two.
|
||||
///
|
||||
/// This method runs in O(n<sup>2</sup>) time.
|
||||
/// It quickly finds a relatively short tour for most TSP instances,
|
||||
/// but it could also yield a really bad (or even the worst) solution
|
||||
/// in special cases.
|
||||
///
|
||||
/// \tparam CM Type of the cost map.
|
||||
template <typename CM>
|
||||
class GreedyTsp
|
||||
{
|
||||
public:
|
||||
|
||||
/// Type of the cost map
|
||||
typedef CM CostMap;
|
||||
/// Type of the edge costs
|
||||
typedef typename CM::Value Cost;
|
||||
|
||||
private:
|
||||
|
||||
GRAPH_TYPEDEFS(FullGraph);
|
||||
|
||||
const FullGraph &_gr;
|
||||
const CostMap &_cost;
|
||||
Cost _sum;
|
||||
std::vector<Node> _path;
|
||||
|
||||
private:
|
||||
|
||||
// Functor class to compare edges by their costs
|
||||
class EdgeComp {
|
||||
private:
|
||||
const CostMap &_cost;
|
||||
|
||||
public:
|
||||
EdgeComp(const CostMap &cost) : _cost(cost) {}
|
||||
|
||||
bool operator()(const Edge &a, const Edge &b) const {
|
||||
return _cost[a] < _cost[b];
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constructor
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param gr The \ref FullGraph "full graph" the algorithm runs on.
|
||||
/// \param cost The cost map.
|
||||
GreedyTsp(const FullGraph &gr, const CostMap &cost)
|
||||
: _gr(gr), _cost(cost) {}
|
||||
|
||||
/// \name Execution Control
|
||||
/// @{
|
||||
|
||||
/// \brief Runs the algorithm.
|
||||
///
|
||||
/// This function runs the algorithm.
|
||||
///
|
||||
/// \return The total cost of the found tour.
|
||||
Cost run() {
|
||||
_path.clear();
|
||||
|
||||
if (_gr.nodeNum() == 0) return _sum = 0;
|
||||
else if (_gr.nodeNum() == 1) {
|
||||
_path.push_back(_gr(0));
|
||||
return _sum = 0;
|
||||
}
|
||||
|
||||
std::vector<int> plist;
|
||||
plist.resize(_gr.nodeNum()*2, -1);
|
||||
|
||||
std::vector<Edge> sorted_edges;
|
||||
sorted_edges.reserve(_gr.edgeNum());
|
||||
for (EdgeIt e(_gr); e != INVALID; ++e)
|
||||
sorted_edges.push_back(e);
|
||||
std::sort(sorted_edges.begin(), sorted_edges.end(), EdgeComp(_cost));
|
||||
|
||||
FullGraph::NodeMap<int> item_int_map(_gr);
|
||||
UnionFind<FullGraph::NodeMap<int> > union_find(item_int_map);
|
||||
for (NodeIt n(_gr); n != INVALID; ++n)
|
||||
union_find.insert(n);
|
||||
|
||||
FullGraph::NodeMap<int> degree(_gr, 0);
|
||||
|
||||
int nodesNum = 0, i = 0;
|
||||
while (nodesNum != _gr.nodeNum()-1) {
|
||||
Edge e = sorted_edges[i++];
|
||||
Node u = _gr.u(e),
|
||||
v = _gr.v(e);
|
||||
|
||||
if (degree[u] <= 1 && degree[v] <= 1) {
|
||||
if (union_find.join(u, v)) {
|
||||
const int uid = _gr.id(u),
|
||||
vid = _gr.id(v);
|
||||
|
||||
plist[uid*2 + degree[u]] = vid;
|
||||
plist[vid*2 + degree[v]] = uid;
|
||||
|
||||
++degree[u];
|
||||
++degree[v];
|
||||
++nodesNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0, n=-1; i<_gr.nodeNum()*2; ++i) {
|
||||
if (plist[i] == -1) {
|
||||
if (n==-1) {
|
||||
n = i;
|
||||
} else {
|
||||
plist[n] = i/2;
|
||||
plist[i] = n/2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0, next=0, last=-1; i!=_gr.nodeNum(); ++i) {
|
||||
_path.push_back(_gr.nodeFromId(next));
|
||||
if (plist[2*next] != last) {
|
||||
last = next;
|
||||
next = plist[2*next];
|
||||
} else {
|
||||
last = next;
|
||||
next = plist[2*next+1];
|
||||
}
|
||||
}
|
||||
|
||||
_sum = _cost[_gr.edge(_path.back(), _path.front())];
|
||||
for (int i = 0; i < int(_path.size())-1; ++i) {
|
||||
_sum += _cost[_gr.edge(_path[i], _path[i+1])];
|
||||
}
|
||||
|
||||
return _sum;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Query Functions
|
||||
/// @{
|
||||
|
||||
/// \brief The total cost of the found tour.
|
||||
///
|
||||
/// This function returns the total cost of the found tour.
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
Cost tourCost() const {
|
||||
return _sum;
|
||||
}
|
||||
|
||||
/// \brief Returns a const reference to the node sequence of the
|
||||
/// found tour.
|
||||
///
|
||||
/// This function returns a const reference to a vector
|
||||
/// that stores the node sequence of the found tour.
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
const std::vector<Node>& tourNodes() const {
|
||||
return _path;
|
||||
}
|
||||
|
||||
/// \brief Gives back the node sequence of the found tour.
|
||||
///
|
||||
/// This function copies the node sequence of the found tour into
|
||||
/// an STL container through the given output iterator. The
|
||||
/// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
|
||||
/// For example,
|
||||
/// \code
|
||||
/// std::vector<FullGraph::Node> nodes(countNodes(graph));
|
||||
/// tsp.tourNodes(nodes.begin());
|
||||
/// \endcode
|
||||
/// or
|
||||
/// \code
|
||||
/// std::list<FullGraph::Node> nodes;
|
||||
/// tsp.tourNodes(std::back_inserter(nodes));
|
||||
/// \endcode
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
template <typename Iterator>
|
||||
void tourNodes(Iterator out) const {
|
||||
std::copy(_path.begin(), _path.end(), out);
|
||||
}
|
||||
|
||||
/// \brief Gives back the found tour as a path.
|
||||
///
|
||||
/// This function copies the found tour as a list of arcs/edges into
|
||||
/// the given \ref lemon::concepts::Path "path structure".
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
template <typename Path>
|
||||
void tour(Path &path) const {
|
||||
path.clear();
|
||||
for (int i = 0; i < int(_path.size()) - 1; ++i) {
|
||||
path.addBack(_gr.arc(_path[i], _path[i+1]));
|
||||
}
|
||||
if (int(_path.size()) >= 2) {
|
||||
path.addBack(_gr.arc(_path.back(), _path.front()));
|
||||
}
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
}; // namespace lemon
|
||||
|
||||
#endif
|
||||
699
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/grid_graph.h
vendored
Normal file
699
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/grid_graph.h
vendored
Normal file
@@ -0,0 +1,699 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRID_GRAPH_H
|
||||
#define GRID_GRAPH_H
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/bits/graph_extender.h>
|
||||
#include <lemon/dim2.h>
|
||||
#include <lemon/assert.h>
|
||||
|
||||
///\ingroup graphs
|
||||
///\file
|
||||
///\brief GridGraph class.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
class GridGraphBase {
|
||||
|
||||
public:
|
||||
|
||||
typedef GridGraphBase Graph;
|
||||
|
||||
class Node;
|
||||
class Edge;
|
||||
class Arc;
|
||||
|
||||
public:
|
||||
|
||||
GridGraphBase() {}
|
||||
|
||||
protected:
|
||||
|
||||
void construct(int width, int height) {
|
||||
_width = width; _height = height;
|
||||
_node_num = width * height;
|
||||
_edge_num = 2 * _node_num - width - height;
|
||||
_edge_limit = _node_num - _width;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Node operator()(int i, int j) const {
|
||||
LEMON_DEBUG(0 <= i && i < _width &&
|
||||
0 <= j && j < _height, "Index out of range");
|
||||
return Node(i + j * _width);
|
||||
}
|
||||
|
||||
int col(Node n) const {
|
||||
return n._id % _width;
|
||||
}
|
||||
|
||||
int row(Node n) const {
|
||||
return n._id / _width;
|
||||
}
|
||||
|
||||
dim2::Point<int> pos(Node n) const {
|
||||
return dim2::Point<int>(col(n), row(n));
|
||||
}
|
||||
|
||||
int width() const {
|
||||
return _width;
|
||||
}
|
||||
|
||||
int height() const {
|
||||
return _height;
|
||||
}
|
||||
|
||||
typedef True NodeNumTag;
|
||||
typedef True EdgeNumTag;
|
||||
typedef True ArcNumTag;
|
||||
|
||||
int nodeNum() const { return _node_num; }
|
||||
int edgeNum() const { return _edge_num; }
|
||||
int arcNum() const { return 2 * _edge_num; }
|
||||
|
||||
Node u(Edge edge) const {
|
||||
if (edge._id < _edge_limit) {
|
||||
return edge._id;
|
||||
} else {
|
||||
return (edge._id - _edge_limit) % (_width - 1) +
|
||||
(edge._id - _edge_limit) / (_width - 1) * _width;
|
||||
}
|
||||
}
|
||||
|
||||
Node v(Edge edge) const {
|
||||
if (edge._id < _edge_limit) {
|
||||
return edge._id + _width;
|
||||
} else {
|
||||
return (edge._id - _edge_limit) % (_width - 1) +
|
||||
(edge._id - _edge_limit) / (_width - 1) * _width + 1;
|
||||
}
|
||||
}
|
||||
|
||||
Node source(Arc arc) const {
|
||||
return (arc._id & 1) == 1 ? u(arc) : v(arc);
|
||||
}
|
||||
|
||||
Node target(Arc arc) const {
|
||||
return (arc._id & 1) == 1 ? v(arc) : u(arc);
|
||||
}
|
||||
|
||||
static int id(Node node) { return node._id; }
|
||||
static int id(Edge edge) { return edge._id; }
|
||||
static int id(Arc arc) { return arc._id; }
|
||||
|
||||
int maxNodeId() const { return _node_num - 1; }
|
||||
int maxEdgeId() const { return _edge_num - 1; }
|
||||
int maxArcId() const { return 2 * _edge_num - 1; }
|
||||
|
||||
static Node nodeFromId(int id) { return Node(id);}
|
||||
static Edge edgeFromId(int id) { return Edge(id);}
|
||||
static Arc arcFromId(int id) { return Arc(id);}
|
||||
|
||||
typedef True FindEdgeTag;
|
||||
typedef True FindArcTag;
|
||||
|
||||
Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
|
||||
if (prev != INVALID) return INVALID;
|
||||
if (v._id > u._id) {
|
||||
if (v._id - u._id == _width)
|
||||
return Edge(u._id);
|
||||
if (v._id - u._id == 1 && u._id % _width < _width - 1) {
|
||||
return Edge(u._id / _width * (_width - 1) +
|
||||
u._id % _width + _edge_limit);
|
||||
}
|
||||
} else {
|
||||
if (u._id - v._id == _width)
|
||||
return Edge(v._id);
|
||||
if (u._id - v._id == 1 && v._id % _width < _width - 1) {
|
||||
return Edge(v._id / _width * (_width - 1) +
|
||||
v._id % _width + _edge_limit);
|
||||
}
|
||||
}
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
Arc findArc(Node u, Node v, Arc prev = INVALID) const {
|
||||
if (prev != INVALID) return INVALID;
|
||||
if (v._id > u._id) {
|
||||
if (v._id - u._id == _width)
|
||||
return Arc((u._id << 1) | 1);
|
||||
if (v._id - u._id == 1 && u._id % _width < _width - 1) {
|
||||
return Arc(((u._id / _width * (_width - 1) +
|
||||
u._id % _width + _edge_limit) << 1) | 1);
|
||||
}
|
||||
} else {
|
||||
if (u._id - v._id == _width)
|
||||
return Arc(v._id << 1);
|
||||
if (u._id - v._id == 1 && v._id % _width < _width - 1) {
|
||||
return Arc((v._id / _width * (_width - 1) +
|
||||
v._id % _width + _edge_limit) << 1);
|
||||
}
|
||||
}
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
class Node {
|
||||
friend class GridGraphBase;
|
||||
|
||||
protected:
|
||||
int _id;
|
||||
Node(int id) : _id(id) {}
|
||||
public:
|
||||
Node() {}
|
||||
Node (Invalid) : _id(-1) {}
|
||||
bool operator==(const Node node) const {return _id == node._id;}
|
||||
bool operator!=(const Node node) const {return _id != node._id;}
|
||||
bool operator<(const Node node) const {return _id < node._id;}
|
||||
};
|
||||
|
||||
class Edge {
|
||||
friend class GridGraphBase;
|
||||
friend class Arc;
|
||||
|
||||
protected:
|
||||
int _id;
|
||||
|
||||
Edge(int id) : _id(id) {}
|
||||
|
||||
public:
|
||||
Edge() {}
|
||||
Edge (Invalid) : _id(-1) {}
|
||||
bool operator==(const Edge edge) const {return _id == edge._id;}
|
||||
bool operator!=(const Edge edge) const {return _id != edge._id;}
|
||||
bool operator<(const Edge edge) const {return _id < edge._id;}
|
||||
};
|
||||
|
||||
class Arc {
|
||||
friend class GridGraphBase;
|
||||
|
||||
protected:
|
||||
int _id;
|
||||
|
||||
Arc(int id) : _id(id) {}
|
||||
|
||||
public:
|
||||
Arc() {}
|
||||
Arc (Invalid) : _id(-1) {}
|
||||
operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
|
||||
bool operator==(const Arc arc) const {return _id == arc._id;}
|
||||
bool operator!=(const Arc arc) const {return _id != arc._id;}
|
||||
bool operator<(const Arc arc) const {return _id < arc._id;}
|
||||
};
|
||||
|
||||
static bool direction(Arc arc) {
|
||||
return (arc._id & 1) == 1;
|
||||
}
|
||||
|
||||
static Arc direct(Edge edge, bool dir) {
|
||||
return Arc((edge._id << 1) | (dir ? 1 : 0));
|
||||
}
|
||||
|
||||
void first(Node& node) const {
|
||||
node._id = _node_num - 1;
|
||||
}
|
||||
|
||||
static void next(Node& node) {
|
||||
--node._id;
|
||||
}
|
||||
|
||||
void first(Edge& edge) const {
|
||||
edge._id = _edge_num - 1;
|
||||
}
|
||||
|
||||
static void next(Edge& edge) {
|
||||
--edge._id;
|
||||
}
|
||||
|
||||
void first(Arc& arc) const {
|
||||
arc._id = 2 * _edge_num - 1;
|
||||
}
|
||||
|
||||
static void next(Arc& arc) {
|
||||
--arc._id;
|
||||
}
|
||||
|
||||
void firstOut(Arc& arc, const Node& node) const {
|
||||
if (node._id % _width < _width - 1) {
|
||||
arc._id = (_edge_limit + node._id % _width +
|
||||
(node._id / _width) * (_width - 1)) << 1 | 1;
|
||||
return;
|
||||
}
|
||||
if (node._id < _node_num - _width) {
|
||||
arc._id = node._id << 1 | 1;
|
||||
return;
|
||||
}
|
||||
if (node._id % _width > 0) {
|
||||
arc._id = (_edge_limit + node._id % _width +
|
||||
(node._id / _width) * (_width - 1) - 1) << 1;
|
||||
return;
|
||||
}
|
||||
if (node._id >= _width) {
|
||||
arc._id = (node._id - _width) << 1;
|
||||
return;
|
||||
}
|
||||
arc._id = -1;
|
||||
}
|
||||
|
||||
void nextOut(Arc& arc) const {
|
||||
int nid = arc._id >> 1;
|
||||
if ((arc._id & 1) == 1) {
|
||||
if (nid >= _edge_limit) {
|
||||
nid = (nid - _edge_limit) % (_width - 1) +
|
||||
(nid - _edge_limit) / (_width - 1) * _width;
|
||||
if (nid < _node_num - _width) {
|
||||
arc._id = nid << 1 | 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (nid % _width > 0) {
|
||||
arc._id = (_edge_limit + nid % _width +
|
||||
(nid / _width) * (_width - 1) - 1) << 1;
|
||||
return;
|
||||
}
|
||||
if (nid >= _width) {
|
||||
arc._id = (nid - _width) << 1;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (nid >= _edge_limit) {
|
||||
nid = (nid - _edge_limit) % (_width - 1) +
|
||||
(nid - _edge_limit) / (_width - 1) * _width + 1;
|
||||
if (nid >= _width) {
|
||||
arc._id = (nid - _width) << 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
arc._id = -1;
|
||||
}
|
||||
|
||||
void firstIn(Arc& arc, const Node& node) const {
|
||||
if (node._id % _width < _width - 1) {
|
||||
arc._id = (_edge_limit + node._id % _width +
|
||||
(node._id / _width) * (_width - 1)) << 1;
|
||||
return;
|
||||
}
|
||||
if (node._id < _node_num - _width) {
|
||||
arc._id = node._id << 1;
|
||||
return;
|
||||
}
|
||||
if (node._id % _width > 0) {
|
||||
arc._id = (_edge_limit + node._id % _width +
|
||||
(node._id / _width) * (_width - 1) - 1) << 1 | 1;
|
||||
return;
|
||||
}
|
||||
if (node._id >= _width) {
|
||||
arc._id = (node._id - _width) << 1 | 1;
|
||||
return;
|
||||
}
|
||||
arc._id = -1;
|
||||
}
|
||||
|
||||
void nextIn(Arc& arc) const {
|
||||
int nid = arc._id >> 1;
|
||||
if ((arc._id & 1) == 0) {
|
||||
if (nid >= _edge_limit) {
|
||||
nid = (nid - _edge_limit) % (_width - 1) +
|
||||
(nid - _edge_limit) / (_width - 1) * _width;
|
||||
if (nid < _node_num - _width) {
|
||||
arc._id = nid << 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (nid % _width > 0) {
|
||||
arc._id = (_edge_limit + nid % _width +
|
||||
(nid / _width) * (_width - 1) - 1) << 1 | 1;
|
||||
return;
|
||||
}
|
||||
if (nid >= _width) {
|
||||
arc._id = (nid - _width) << 1 | 1;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (nid >= _edge_limit) {
|
||||
nid = (nid - _edge_limit) % (_width - 1) +
|
||||
(nid - _edge_limit) / (_width - 1) * _width + 1;
|
||||
if (nid >= _width) {
|
||||
arc._id = (nid - _width) << 1 | 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
arc._id = -1;
|
||||
}
|
||||
|
||||
void firstInc(Edge& edge, bool& dir, const Node& node) const {
|
||||
if (node._id % _width < _width - 1) {
|
||||
edge._id = _edge_limit + node._id % _width +
|
||||
(node._id / _width) * (_width - 1);
|
||||
dir = true;
|
||||
return;
|
||||
}
|
||||
if (node._id < _node_num - _width) {
|
||||
edge._id = node._id;
|
||||
dir = true;
|
||||
return;
|
||||
}
|
||||
if (node._id % _width > 0) {
|
||||
edge._id = _edge_limit + node._id % _width +
|
||||
(node._id / _width) * (_width - 1) - 1;
|
||||
dir = false;
|
||||
return;
|
||||
}
|
||||
if (node._id >= _width) {
|
||||
edge._id = node._id - _width;
|
||||
dir = false;
|
||||
return;
|
||||
}
|
||||
edge._id = -1;
|
||||
dir = true;
|
||||
}
|
||||
|
||||
void nextInc(Edge& edge, bool& dir) const {
|
||||
int nid = edge._id;
|
||||
if (dir) {
|
||||
if (nid >= _edge_limit) {
|
||||
nid = (nid - _edge_limit) % (_width - 1) +
|
||||
(nid - _edge_limit) / (_width - 1) * _width;
|
||||
if (nid < _node_num - _width) {
|
||||
edge._id = nid;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (nid % _width > 0) {
|
||||
edge._id = _edge_limit + nid % _width +
|
||||
(nid / _width) * (_width - 1) - 1;
|
||||
dir = false;
|
||||
return;
|
||||
}
|
||||
if (nid >= _width) {
|
||||
edge._id = nid - _width;
|
||||
dir = false;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (nid >= _edge_limit) {
|
||||
nid = (nid - _edge_limit) % (_width - 1) +
|
||||
(nid - _edge_limit) / (_width - 1) * _width + 1;
|
||||
if (nid >= _width) {
|
||||
edge._id = nid - _width;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
edge._id = -1;
|
||||
dir = true;
|
||||
}
|
||||
|
||||
Arc right(Node n) const {
|
||||
if (n._id % _width < _width - 1) {
|
||||
return Arc(((_edge_limit + n._id % _width +
|
||||
(n._id / _width) * (_width - 1)) << 1) | 1);
|
||||
} else {
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
Arc left(Node n) const {
|
||||
if (n._id % _width > 0) {
|
||||
return Arc((_edge_limit + n._id % _width +
|
||||
(n._id / _width) * (_width - 1) - 1) << 1);
|
||||
} else {
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
Arc up(Node n) const {
|
||||
if (n._id < _edge_limit) {
|
||||
return Arc((n._id << 1) | 1);
|
||||
} else {
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
Arc down(Node n) const {
|
||||
if (n._id >= _width) {
|
||||
return Arc((n._id - _width) << 1);
|
||||
} else {
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int _width, _height;
|
||||
int _node_num, _edge_num;
|
||||
int _edge_limit;
|
||||
};
|
||||
|
||||
|
||||
typedef GraphExtender<GridGraphBase> ExtendedGridGraphBase;
|
||||
|
||||
/// \ingroup graphs
|
||||
///
|
||||
/// \brief Grid graph class
|
||||
///
|
||||
/// GridGraph implements a special graph type. The nodes of the
|
||||
/// graph can be indexed by two integer values \c (i,j) where \c i is
|
||||
/// in the range <tt>[0..width()-1]</tt> and j is in the range
|
||||
/// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
|
||||
/// the indices differ exactly on one position and the difference is
|
||||
/// also exactly one. The nodes of the graph can be obtained by position
|
||||
/// using the \c operator()() function and the indices of the nodes can
|
||||
/// be obtained using \c pos(), \c col() and \c row() members. The outgoing
|
||||
/// arcs can be retrieved with the \c right(), \c up(), \c left()
|
||||
/// and \c down() functions, where the bottom-left corner is the
|
||||
/// origin.
|
||||
///
|
||||
/// This class is completely static and it needs constant memory space.
|
||||
/// Thus you can neither add nor delete nodes or edges, however
|
||||
/// the structure can be resized using resize().
|
||||
///
|
||||
/// \image html grid_graph.png
|
||||
/// \image latex grid_graph.eps "Grid graph" width=\textwidth
|
||||
///
|
||||
/// A short example about the basic usage:
|
||||
///\code
|
||||
/// GridGraph graph(rows, cols);
|
||||
/// GridGraph::NodeMap<int> val(graph);
|
||||
/// for (int i = 0; i < graph.width(); ++i) {
|
||||
/// for (int j = 0; j < graph.height(); ++j) {
|
||||
/// val[graph(i, j)] = i + j;
|
||||
/// }
|
||||
/// }
|
||||
///\endcode
|
||||
///
|
||||
/// This type fully conforms to the \ref concepts::Graph "Graph concept".
|
||||
/// Most of its member functions and nested classes are documented
|
||||
/// only in the concept class.
|
||||
///
|
||||
/// This class provides constant time counting for nodes, edges and arcs.
|
||||
class GridGraph : public ExtendedGridGraphBase {
|
||||
typedef ExtendedGridGraphBase Parent;
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Map to get the indices of the nodes as \ref dim2::Point
|
||||
/// "dim2::Point<int>".
|
||||
///
|
||||
/// Map to get the indices of the nodes as \ref dim2::Point
|
||||
/// "dim2::Point<int>".
|
||||
class IndexMap {
|
||||
public:
|
||||
/// \brief The key type of the map
|
||||
typedef GridGraph::Node Key;
|
||||
/// \brief The value type of the map
|
||||
typedef dim2::Point<int> Value;
|
||||
|
||||
/// \brief Constructor
|
||||
IndexMap(const GridGraph& graph) : _graph(graph) {}
|
||||
|
||||
/// \brief The subscript operator
|
||||
Value operator[](Key key) const {
|
||||
return _graph.pos(key);
|
||||
}
|
||||
|
||||
private:
|
||||
const GridGraph& _graph;
|
||||
};
|
||||
|
||||
/// \brief Map to get the column of the nodes.
|
||||
///
|
||||
/// Map to get the column of the nodes.
|
||||
class ColMap {
|
||||
public:
|
||||
/// \brief The key type of the map
|
||||
typedef GridGraph::Node Key;
|
||||
/// \brief The value type of the map
|
||||
typedef int Value;
|
||||
|
||||
/// \brief Constructor
|
||||
ColMap(const GridGraph& graph) : _graph(graph) {}
|
||||
|
||||
/// \brief The subscript operator
|
||||
Value operator[](Key key) const {
|
||||
return _graph.col(key);
|
||||
}
|
||||
|
||||
private:
|
||||
const GridGraph& _graph;
|
||||
};
|
||||
|
||||
/// \brief Map to get the row of the nodes.
|
||||
///
|
||||
/// Map to get the row of the nodes.
|
||||
class RowMap {
|
||||
public:
|
||||
/// \brief The key type of the map
|
||||
typedef GridGraph::Node Key;
|
||||
/// \brief The value type of the map
|
||||
typedef int Value;
|
||||
|
||||
/// \brief Constructor
|
||||
RowMap(const GridGraph& graph) : _graph(graph) {}
|
||||
|
||||
/// \brief The subscript operator
|
||||
Value operator[](Key key) const {
|
||||
return _graph.row(key);
|
||||
}
|
||||
|
||||
private:
|
||||
const GridGraph& _graph;
|
||||
};
|
||||
|
||||
/// \brief Constructor
|
||||
///
|
||||
/// Construct a grid graph with the given size.
|
||||
GridGraph(int width, int height) { construct(width, height); }
|
||||
|
||||
/// \brief Resizes the graph
|
||||
///
|
||||
/// This function resizes the graph. It fully destroys and
|
||||
/// rebuilds the structure, therefore the maps of the graph will be
|
||||
/// reallocated automatically and the previous values will be lost.
|
||||
void resize(int width, int height) {
|
||||
Parent::notifier(Arc()).clear();
|
||||
Parent::notifier(Edge()).clear();
|
||||
Parent::notifier(Node()).clear();
|
||||
construct(width, height);
|
||||
Parent::notifier(Node()).build();
|
||||
Parent::notifier(Edge()).build();
|
||||
Parent::notifier(Arc()).build();
|
||||
}
|
||||
|
||||
/// \brief The node on the given position.
|
||||
///
|
||||
/// Gives back the node on the given position.
|
||||
Node operator()(int i, int j) const {
|
||||
return Parent::operator()(i, j);
|
||||
}
|
||||
|
||||
/// \brief The column index of the node.
|
||||
///
|
||||
/// Gives back the column index of the node.
|
||||
int col(Node n) const {
|
||||
return Parent::col(n);
|
||||
}
|
||||
|
||||
/// \brief The row index of the node.
|
||||
///
|
||||
/// Gives back the row index of the node.
|
||||
int row(Node n) const {
|
||||
return Parent::row(n);
|
||||
}
|
||||
|
||||
/// \brief The position of the node.
|
||||
///
|
||||
/// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
|
||||
dim2::Point<int> pos(Node n) const {
|
||||
return Parent::pos(n);
|
||||
}
|
||||
|
||||
/// \brief The number of the columns.
|
||||
///
|
||||
/// Gives back the number of the columns.
|
||||
int width() const {
|
||||
return Parent::width();
|
||||
}
|
||||
|
||||
/// \brief The number of the rows.
|
||||
///
|
||||
/// Gives back the number of the rows.
|
||||
int height() const {
|
||||
return Parent::height();
|
||||
}
|
||||
|
||||
/// \brief The arc goes right from the node.
|
||||
///
|
||||
/// Gives back the arc goes right from the node. If there is not
|
||||
/// outgoing arc then it gives back INVALID.
|
||||
Arc right(Node n) const {
|
||||
return Parent::right(n);
|
||||
}
|
||||
|
||||
/// \brief The arc goes left from the node.
|
||||
///
|
||||
/// Gives back the arc goes left from the node. If there is not
|
||||
/// outgoing arc then it gives back INVALID.
|
||||
Arc left(Node n) const {
|
||||
return Parent::left(n);
|
||||
}
|
||||
|
||||
/// \brief The arc goes up from the node.
|
||||
///
|
||||
/// Gives back the arc goes up from the node. If there is not
|
||||
/// outgoing arc then it gives back INVALID.
|
||||
Arc up(Node n) const {
|
||||
return Parent::up(n);
|
||||
}
|
||||
|
||||
/// \brief The arc goes down from the node.
|
||||
///
|
||||
/// Gives back the arc goes down from the node. If there is not
|
||||
/// outgoing arc then it gives back INVALID.
|
||||
Arc down(Node n) const {
|
||||
return Parent::down(n);
|
||||
}
|
||||
|
||||
/// \brief Index map of the grid graph
|
||||
///
|
||||
/// Just returns an IndexMap for the grid graph.
|
||||
IndexMap indexMap() const {
|
||||
return IndexMap(*this);
|
||||
}
|
||||
|
||||
/// \brief Row map of the grid graph
|
||||
///
|
||||
/// Just returns a RowMap for the grid graph.
|
||||
RowMap rowMap() const {
|
||||
return RowMap(*this);
|
||||
}
|
||||
|
||||
/// \brief Column map of the grid graph
|
||||
///
|
||||
/// Just returns a ColMap for the grid graph.
|
||||
ColMap colMap() const {
|
||||
return ColMap(*this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
840
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/grosso_locatelli_pullan_mc.h
vendored
Normal file
840
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/grosso_locatelli_pullan_mc.h
vendored
Normal file
@@ -0,0 +1,840 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_GROSSO_LOCATELLI_PULLAN_MC_H
|
||||
#define LEMON_GROSSO_LOCATELLI_PULLAN_MC_H
|
||||
|
||||
/// \ingroup approx_algs
|
||||
///
|
||||
/// \file
|
||||
/// \brief The iterated local search algorithm of Grosso, Locatelli, and Pullan
|
||||
/// for the maximum clique problem
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/random.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \addtogroup approx_algs
|
||||
/// @{
|
||||
|
||||
/// \brief Implementation of the iterated local search algorithm of Grosso,
|
||||
/// Locatelli, and Pullan for the maximum clique problem
|
||||
///
|
||||
/// \ref GrossoLocatelliPullanMc implements the iterated local search
|
||||
/// algorithm of Grosso, Locatelli, and Pullan for solving the \e maximum
|
||||
/// \e clique \e problem \cite grosso08maxclique.
|
||||
/// It is to find the largest complete subgraph (\e clique) in an
|
||||
/// undirected graph, i.e., the largest set of nodes where each
|
||||
/// pair of nodes is connected.
|
||||
///
|
||||
/// This class provides a simple but highly efficient and robust heuristic
|
||||
/// method that quickly finds a quite large clique, but not necessarily the
|
||||
/// largest one.
|
||||
/// The algorithm performs a certain number of iterations to find several
|
||||
/// cliques and selects the largest one among them. Various limits can be
|
||||
/// specified to control the running time and the effectiveness of the
|
||||
/// search process.
|
||||
///
|
||||
/// \tparam GR The undirected graph type the algorithm runs on.
|
||||
///
|
||||
/// \note %GrossoLocatelliPullanMc provides three different node selection
|
||||
/// rules, from which the most powerful one is used by default.
|
||||
/// For more information, see \ref SelectionRule.
|
||||
template <typename GR>
|
||||
class GrossoLocatelliPullanMc
|
||||
{
|
||||
public:
|
||||
|
||||
/// \brief Constants for specifying the node selection rule.
|
||||
///
|
||||
/// Enum type containing constants for specifying the node selection rule
|
||||
/// for the \ref run() function.
|
||||
///
|
||||
/// During the algorithm, nodes are selected for addition to the current
|
||||
/// clique according to the applied rule.
|
||||
/// In general, the PENALTY_BASED rule turned out to be the most powerful
|
||||
/// and the most robust, thus it is the default option.
|
||||
/// However, another selection rule can be specified using the \ref run()
|
||||
/// function with the proper parameter.
|
||||
enum SelectionRule {
|
||||
|
||||
/// A node is selected randomly without any evaluation at each step.
|
||||
RANDOM,
|
||||
|
||||
/// A node of maximum degree is selected randomly at each step.
|
||||
DEGREE_BASED,
|
||||
|
||||
/// A node of minimum penalty is selected randomly at each step.
|
||||
/// The node penalties are updated adaptively after each stage of the
|
||||
/// search process.
|
||||
PENALTY_BASED
|
||||
};
|
||||
|
||||
/// \brief Constants for the causes of search termination.
|
||||
///
|
||||
/// Enum type containing constants for the different causes of search
|
||||
/// termination. The \ref run() function returns one of these values.
|
||||
enum TerminationCause {
|
||||
|
||||
/// The iteration count limit is reached.
|
||||
ITERATION_LIMIT,
|
||||
|
||||
/// The step count limit is reached.
|
||||
STEP_LIMIT,
|
||||
|
||||
/// The clique size limit is reached.
|
||||
SIZE_LIMIT
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
TEMPLATE_GRAPH_TYPEDEFS(GR);
|
||||
|
||||
typedef std::vector<int> IntVector;
|
||||
typedef std::vector<char> BoolVector;
|
||||
typedef std::vector<BoolVector> BoolMatrix;
|
||||
// Note: vector<char> is used instead of vector<bool> for efficiency reasons
|
||||
|
||||
// The underlying graph
|
||||
const GR &_graph;
|
||||
IntNodeMap _id;
|
||||
|
||||
// Internal matrix representation of the graph
|
||||
BoolMatrix _gr;
|
||||
int _n;
|
||||
|
||||
// Search options
|
||||
bool _delta_based_restart;
|
||||
int _restart_delta_limit;
|
||||
|
||||
// Search limits
|
||||
int _iteration_limit;
|
||||
int _step_limit;
|
||||
int _size_limit;
|
||||
|
||||
// The current clique
|
||||
BoolVector _clique;
|
||||
int _size;
|
||||
|
||||
// The best clique found so far
|
||||
BoolVector _best_clique;
|
||||
int _best_size;
|
||||
|
||||
// The "distances" of the nodes from the current clique.
|
||||
// _delta[u] is the number of nodes in the clique that are
|
||||
// not connected with u.
|
||||
IntVector _delta;
|
||||
|
||||
// The current tabu set
|
||||
BoolVector _tabu;
|
||||
|
||||
// Random number generator
|
||||
Random _rnd;
|
||||
|
||||
private:
|
||||
|
||||
// Implementation of the RANDOM node selection rule.
|
||||
class RandomSelectionRule
|
||||
{
|
||||
private:
|
||||
|
||||
// References to the algorithm instance
|
||||
const BoolVector &_clique;
|
||||
const IntVector &_delta;
|
||||
const BoolVector &_tabu;
|
||||
Random &_rnd;
|
||||
|
||||
// Pivot rule data
|
||||
int _n;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
RandomSelectionRule(GrossoLocatelliPullanMc &mc) :
|
||||
_clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
|
||||
_rnd(mc._rnd), _n(mc._n)
|
||||
{}
|
||||
|
||||
// Return a node index for a feasible add move or -1 if no one exists
|
||||
int nextFeasibleAddNode() const {
|
||||
int start_node = _rnd[_n];
|
||||
for (int i = start_node; i != _n; i++) {
|
||||
if (_delta[i] == 0 && !_tabu[i]) return i;
|
||||
}
|
||||
for (int i = 0; i != start_node; i++) {
|
||||
if (_delta[i] == 0 && !_tabu[i]) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Return a node index for a feasible swap move or -1 if no one exists
|
||||
int nextFeasibleSwapNode() const {
|
||||
int start_node = _rnd[_n];
|
||||
for (int i = start_node; i != _n; i++) {
|
||||
if (!_clique[i] && _delta[i] == 1 && !_tabu[i]) return i;
|
||||
}
|
||||
for (int i = 0; i != start_node; i++) {
|
||||
if (!_clique[i] && _delta[i] == 1 && !_tabu[i]) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Return a node index for an add move or -1 if no one exists
|
||||
int nextAddNode() const {
|
||||
int start_node = _rnd[_n];
|
||||
for (int i = start_node; i != _n; i++) {
|
||||
if (_delta[i] == 0) return i;
|
||||
}
|
||||
for (int i = 0; i != start_node; i++) {
|
||||
if (_delta[i] == 0) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Update internal data structures between stages (if necessary)
|
||||
void update() {}
|
||||
|
||||
}; //class RandomSelectionRule
|
||||
|
||||
|
||||
// Implementation of the DEGREE_BASED node selection rule.
|
||||
class DegreeBasedSelectionRule
|
||||
{
|
||||
private:
|
||||
|
||||
// References to the algorithm instance
|
||||
const BoolVector &_clique;
|
||||
const IntVector &_delta;
|
||||
const BoolVector &_tabu;
|
||||
Random &_rnd;
|
||||
|
||||
// Pivot rule data
|
||||
int _n;
|
||||
IntVector _deg;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
DegreeBasedSelectionRule(GrossoLocatelliPullanMc &mc) :
|
||||
_clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
|
||||
_rnd(mc._rnd), _n(mc._n), _deg(_n)
|
||||
{
|
||||
for (int i = 0; i != _n; i++) {
|
||||
int d = 0;
|
||||
BoolVector &row = mc._gr[i];
|
||||
for (int j = 0; j != _n; j++) {
|
||||
if (row[j]) d++;
|
||||
}
|
||||
_deg[i] = d;
|
||||
}
|
||||
}
|
||||
|
||||
// Return a node index for a feasible add move or -1 if no one exists
|
||||
int nextFeasibleAddNode() const {
|
||||
int start_node = _rnd[_n];
|
||||
int node = -1, max_deg = -1;
|
||||
for (int i = start_node; i != _n; i++) {
|
||||
if (_delta[i] == 0 && !_tabu[i] && _deg[i] > max_deg) {
|
||||
node = i;
|
||||
max_deg = _deg[i];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i != start_node; i++) {
|
||||
if (_delta[i] == 0 && !_tabu[i] && _deg[i] > max_deg) {
|
||||
node = i;
|
||||
max_deg = _deg[i];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Return a node index for a feasible swap move or -1 if no one exists
|
||||
int nextFeasibleSwapNode() const {
|
||||
int start_node = _rnd[_n];
|
||||
int node = -1, max_deg = -1;
|
||||
for (int i = start_node; i != _n; i++) {
|
||||
if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
|
||||
_deg[i] > max_deg) {
|
||||
node = i;
|
||||
max_deg = _deg[i];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i != start_node; i++) {
|
||||
if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
|
||||
_deg[i] > max_deg) {
|
||||
node = i;
|
||||
max_deg = _deg[i];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Return a node index for an add move or -1 if no one exists
|
||||
int nextAddNode() const {
|
||||
int start_node = _rnd[_n];
|
||||
int node = -1, max_deg = -1;
|
||||
for (int i = start_node; i != _n; i++) {
|
||||
if (_delta[i] == 0 && _deg[i] > max_deg) {
|
||||
node = i;
|
||||
max_deg = _deg[i];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i != start_node; i++) {
|
||||
if (_delta[i] == 0 && _deg[i] > max_deg) {
|
||||
node = i;
|
||||
max_deg = _deg[i];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Update internal data structures between stages (if necessary)
|
||||
void update() {}
|
||||
|
||||
}; //class DegreeBasedSelectionRule
|
||||
|
||||
|
||||
// Implementation of the PENALTY_BASED node selection rule.
|
||||
class PenaltyBasedSelectionRule
|
||||
{
|
||||
private:
|
||||
|
||||
// References to the algorithm instance
|
||||
const BoolVector &_clique;
|
||||
const IntVector &_delta;
|
||||
const BoolVector &_tabu;
|
||||
Random &_rnd;
|
||||
|
||||
// Pivot rule data
|
||||
int _n;
|
||||
IntVector _penalty;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
PenaltyBasedSelectionRule(GrossoLocatelliPullanMc &mc) :
|
||||
_clique(mc._clique), _delta(mc._delta), _tabu(mc._tabu),
|
||||
_rnd(mc._rnd), _n(mc._n), _penalty(_n, 0)
|
||||
{}
|
||||
|
||||
// Return a node index for a feasible add move or -1 if no one exists
|
||||
int nextFeasibleAddNode() const {
|
||||
int start_node = _rnd[_n];
|
||||
int node = -1, min_p = std::numeric_limits<int>::max();
|
||||
for (int i = start_node; i != _n; i++) {
|
||||
if (_delta[i] == 0 && !_tabu[i] && _penalty[i] < min_p) {
|
||||
node = i;
|
||||
min_p = _penalty[i];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i != start_node; i++) {
|
||||
if (_delta[i] == 0 && !_tabu[i] && _penalty[i] < min_p) {
|
||||
node = i;
|
||||
min_p = _penalty[i];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Return a node index for a feasible swap move or -1 if no one exists
|
||||
int nextFeasibleSwapNode() const {
|
||||
int start_node = _rnd[_n];
|
||||
int node = -1, min_p = std::numeric_limits<int>::max();
|
||||
for (int i = start_node; i != _n; i++) {
|
||||
if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
|
||||
_penalty[i] < min_p) {
|
||||
node = i;
|
||||
min_p = _penalty[i];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i != start_node; i++) {
|
||||
if (!_clique[i] && _delta[i] == 1 && !_tabu[i] &&
|
||||
_penalty[i] < min_p) {
|
||||
node = i;
|
||||
min_p = _penalty[i];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Return a node index for an add move or -1 if no one exists
|
||||
int nextAddNode() const {
|
||||
int start_node = _rnd[_n];
|
||||
int node = -1, min_p = std::numeric_limits<int>::max();
|
||||
for (int i = start_node; i != _n; i++) {
|
||||
if (_delta[i] == 0 && _penalty[i] < min_p) {
|
||||
node = i;
|
||||
min_p = _penalty[i];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i != start_node; i++) {
|
||||
if (_delta[i] == 0 && _penalty[i] < min_p) {
|
||||
node = i;
|
||||
min_p = _penalty[i];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Update internal data structures between stages (if necessary)
|
||||
void update() {}
|
||||
|
||||
}; //class PenaltyBasedSelectionRule
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// Constructor.
|
||||
/// The global \ref rnd "random number generator instance" is used
|
||||
/// during the algorithm.
|
||||
///
|
||||
/// \param graph The undirected graph the algorithm runs on.
|
||||
GrossoLocatelliPullanMc(const GR& graph) :
|
||||
_graph(graph), _id(_graph), _rnd(rnd)
|
||||
{
|
||||
initOptions();
|
||||
}
|
||||
|
||||
/// \brief Constructor with random seed.
|
||||
///
|
||||
/// Constructor with random seed.
|
||||
///
|
||||
/// \param graph The undirected graph the algorithm runs on.
|
||||
/// \param seed Seed value for the internal random number generator
|
||||
/// that is used during the algorithm.
|
||||
GrossoLocatelliPullanMc(const GR& graph, int seed) :
|
||||
_graph(graph), _id(_graph), _rnd(seed)
|
||||
{
|
||||
initOptions();
|
||||
}
|
||||
|
||||
/// \brief Constructor with random number generator.
|
||||
///
|
||||
/// Constructor with random number generator.
|
||||
///
|
||||
/// \param graph The undirected graph the algorithm runs on.
|
||||
/// \param random A random number generator that is used during the
|
||||
/// algorithm.
|
||||
GrossoLocatelliPullanMc(const GR& graph, const Random& random) :
|
||||
_graph(graph), _id(_graph), _rnd(random)
|
||||
{
|
||||
initOptions();
|
||||
}
|
||||
|
||||
/// \name Execution Control
|
||||
/// The \ref run() function can be used to execute the algorithm.\n
|
||||
/// The functions \ref iterationLimit(int), \ref stepLimit(int), and
|
||||
/// \ref sizeLimit(int) can be used to specify various limits for the
|
||||
/// search process.
|
||||
|
||||
/// @{
|
||||
|
||||
/// \brief Sets the maximum number of iterations.
|
||||
///
|
||||
/// This function sets the maximum number of iterations.
|
||||
/// Each iteration of the algorithm finds a maximal clique (but not
|
||||
/// necessarily the largest one) by performing several search steps
|
||||
/// (node selections).
|
||||
///
|
||||
/// This limit controls the running time and the success of the
|
||||
/// algorithm. For larger values, the algorithm runs slower, but it more
|
||||
/// likely finds larger cliques. For smaller values, the algorithm is
|
||||
/// faster but probably gives worse results.
|
||||
///
|
||||
/// The default value is \c 1000.
|
||||
/// \c -1 means that number of iterations is not limited.
|
||||
///
|
||||
/// \warning You should specify a reasonable limit for the number of
|
||||
/// iterations and/or the number of search steps.
|
||||
///
|
||||
/// \return <tt>(*this)</tt>
|
||||
///
|
||||
/// \sa stepLimit(int)
|
||||
/// \sa sizeLimit(int)
|
||||
GrossoLocatelliPullanMc& iterationLimit(int limit) {
|
||||
_iteration_limit = limit;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Sets the maximum number of search steps.
|
||||
///
|
||||
/// This function sets the maximum number of elementary search steps.
|
||||
/// Each iteration of the algorithm finds a maximal clique (but not
|
||||
/// necessarily the largest one) by performing several search steps
|
||||
/// (node selections).
|
||||
///
|
||||
/// This limit controls the running time and the success of the
|
||||
/// algorithm. For larger values, the algorithm runs slower, but it more
|
||||
/// likely finds larger cliques. For smaller values, the algorithm is
|
||||
/// faster but probably gives worse results.
|
||||
///
|
||||
/// The default value is \c -1, which means that number of steps
|
||||
/// is not limited explicitly. However, the number of iterations is
|
||||
/// limited and each iteration performs a finite number of search steps.
|
||||
///
|
||||
/// \warning You should specify a reasonable limit for the number of
|
||||
/// iterations and/or the number of search steps.
|
||||
///
|
||||
/// \return <tt>(*this)</tt>
|
||||
///
|
||||
/// \sa iterationLimit(int)
|
||||
/// \sa sizeLimit(int)
|
||||
GrossoLocatelliPullanMc& stepLimit(int limit) {
|
||||
_step_limit = limit;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Sets the desired clique size.
|
||||
///
|
||||
/// This function sets the desired clique size that serves as a search
|
||||
/// limit. If a clique of this size (or a larger one) is found, then the
|
||||
/// algorithm terminates.
|
||||
///
|
||||
/// This function is especially useful if you know an exact upper bound
|
||||
/// for the size of the cliques in the graph or if any clique above
|
||||
/// a certain size limit is sufficient for your application.
|
||||
///
|
||||
/// The default value is \c -1, which means that the size limit is set to
|
||||
/// the number of nodes in the graph.
|
||||
///
|
||||
/// \return <tt>(*this)</tt>
|
||||
///
|
||||
/// \sa iterationLimit(int)
|
||||
/// \sa stepLimit(int)
|
||||
GrossoLocatelliPullanMc& sizeLimit(int limit) {
|
||||
_size_limit = limit;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief The maximum number of iterations.
|
||||
///
|
||||
/// This function gives back the maximum number of iterations.
|
||||
/// \c -1 means that no limit is specified.
|
||||
///
|
||||
/// \sa iterationLimit(int)
|
||||
int iterationLimit() const {
|
||||
return _iteration_limit;
|
||||
}
|
||||
|
||||
/// \brief The maximum number of search steps.
|
||||
///
|
||||
/// This function gives back the maximum number of search steps.
|
||||
/// \c -1 means that no limit is specified.
|
||||
///
|
||||
/// \sa stepLimit(int)
|
||||
int stepLimit() const {
|
||||
return _step_limit;
|
||||
}
|
||||
|
||||
/// \brief The desired clique size.
|
||||
///
|
||||
/// This function gives back the desired clique size that serves as a
|
||||
/// search limit. \c -1 means that this limit is set to the number of
|
||||
/// nodes in the graph.
|
||||
///
|
||||
/// \sa sizeLimit(int)
|
||||
int sizeLimit() const {
|
||||
return _size_limit;
|
||||
}
|
||||
|
||||
/// \brief Runs the algorithm.
|
||||
///
|
||||
/// This function runs the algorithm. If one of the specified limits
|
||||
/// is reached, the search process terminates.
|
||||
///
|
||||
/// \param rule The node selection rule. For more information, see
|
||||
/// \ref SelectionRule.
|
||||
///
|
||||
/// \return The termination cause of the search. For more information,
|
||||
/// see \ref TerminationCause.
|
||||
TerminationCause run(SelectionRule rule = PENALTY_BASED)
|
||||
{
|
||||
init();
|
||||
switch (rule) {
|
||||
case RANDOM:
|
||||
return start<RandomSelectionRule>();
|
||||
case DEGREE_BASED:
|
||||
return start<DegreeBasedSelectionRule>();
|
||||
default:
|
||||
return start<PenaltyBasedSelectionRule>();
|
||||
}
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Query Functions
|
||||
/// The results of the algorithm can be obtained using these functions.\n
|
||||
/// The run() function must be called before using them.
|
||||
|
||||
/// @{
|
||||
|
||||
/// \brief The size of the found clique
|
||||
///
|
||||
/// This function returns the size of the found clique.
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
int cliqueSize() const {
|
||||
return _best_size;
|
||||
}
|
||||
|
||||
/// \brief Gives back the found clique in a \c bool node map
|
||||
///
|
||||
/// This function gives back the characteristic vector of the found
|
||||
/// clique in the given node map.
|
||||
/// It must be a \ref concepts::WriteMap "writable" node map with
|
||||
/// \c bool (or convertible) value type.
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
template <typename CliqueMap>
|
||||
void cliqueMap(CliqueMap &map) const {
|
||||
for (NodeIt n(_graph); n != INVALID; ++n) {
|
||||
map[n] = static_cast<bool>(_best_clique[_id[n]]);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Iterator to list the nodes of the found clique
|
||||
///
|
||||
/// This iterator class lists the nodes of the found clique.
|
||||
/// Before using it, you must allocate a GrossoLocatelliPullanMc instance
|
||||
/// and call its \ref GrossoLocatelliPullanMc::run() "run()" method.
|
||||
///
|
||||
/// The following example prints out the IDs of the nodes in the found
|
||||
/// clique.
|
||||
/// \code
|
||||
/// GrossoLocatelliPullanMc<Graph> mc(g);
|
||||
/// mc.run();
|
||||
/// for (GrossoLocatelliPullanMc<Graph>::CliqueNodeIt n(mc);
|
||||
/// n != INVALID; ++n)
|
||||
/// {
|
||||
/// std::cout << g.id(n) << std::endl;
|
||||
/// }
|
||||
/// \endcode
|
||||
class CliqueNodeIt
|
||||
{
|
||||
private:
|
||||
NodeIt _it;
|
||||
BoolNodeMap _map;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
|
||||
/// Constructor.
|
||||
/// \param mc The algorithm instance.
|
||||
CliqueNodeIt(const GrossoLocatelliPullanMc &mc)
|
||||
: _map(mc._graph)
|
||||
{
|
||||
mc.cliqueMap(_map);
|
||||
for (_it = NodeIt(mc._graph); _it != INVALID && !_map[_it]; ++_it) ;
|
||||
}
|
||||
|
||||
/// Conversion to \c Node
|
||||
operator Node() const { return _it; }
|
||||
|
||||
bool operator==(Invalid) const { return _it == INVALID; }
|
||||
bool operator!=(Invalid) const { return _it != INVALID; }
|
||||
|
||||
/// Next node
|
||||
CliqueNodeIt &operator++() {
|
||||
for (++_it; _it != INVALID && !_map[_it]; ++_it) ;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Postfix incrementation
|
||||
|
||||
/// Postfix incrementation.
|
||||
///
|
||||
/// \warning This incrementation returns a \c Node, not a
|
||||
/// \c CliqueNodeIt as one may expect.
|
||||
typename GR::Node operator++(int) {
|
||||
Node n=*this;
|
||||
++(*this);
|
||||
return n;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
|
||||
// Initialize search options and limits
|
||||
void initOptions() {
|
||||
// Search options
|
||||
_delta_based_restart = true;
|
||||
_restart_delta_limit = 4;
|
||||
|
||||
// Search limits
|
||||
_iteration_limit = 1000;
|
||||
_step_limit = -1; // this is disabled by default
|
||||
_size_limit = -1; // this is disabled by default
|
||||
}
|
||||
|
||||
// Adds a node to the current clique
|
||||
void addCliqueNode(int u) {
|
||||
if (_clique[u]) return;
|
||||
_clique[u] = true;
|
||||
_size++;
|
||||
BoolVector &row = _gr[u];
|
||||
for (int i = 0; i != _n; i++) {
|
||||
if (!row[i]) _delta[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Removes a node from the current clique
|
||||
void delCliqueNode(int u) {
|
||||
if (!_clique[u]) return;
|
||||
_clique[u] = false;
|
||||
_size--;
|
||||
BoolVector &row = _gr[u];
|
||||
for (int i = 0; i != _n; i++) {
|
||||
if (!row[i]) _delta[i]--;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize data structures
|
||||
void init() {
|
||||
_n = countNodes(_graph);
|
||||
int ui = 0;
|
||||
for (NodeIt u(_graph); u != INVALID; ++u) {
|
||||
_id[u] = ui++;
|
||||
}
|
||||
_gr.clear();
|
||||
_gr.resize(_n, BoolVector(_n, false));
|
||||
ui = 0;
|
||||
for (NodeIt u(_graph); u != INVALID; ++u) {
|
||||
for (IncEdgeIt e(_graph, u); e != INVALID; ++e) {
|
||||
int vi = _id[_graph.runningNode(e)];
|
||||
_gr[ui][vi] = true;
|
||||
_gr[vi][ui] = true;
|
||||
}
|
||||
++ui;
|
||||
}
|
||||
|
||||
_clique.clear();
|
||||
_clique.resize(_n, false);
|
||||
_size = 0;
|
||||
_best_clique.clear();
|
||||
_best_clique.resize(_n, false);
|
||||
_best_size = 0;
|
||||
_delta.clear();
|
||||
_delta.resize(_n, 0);
|
||||
_tabu.clear();
|
||||
_tabu.resize(_n, false);
|
||||
}
|
||||
|
||||
// Executes the algorithm
|
||||
template <typename SelectionRuleImpl>
|
||||
TerminationCause start() {
|
||||
if (_n == 0) return SIZE_LIMIT;
|
||||
if (_n == 1) {
|
||||
_best_clique[0] = true;
|
||||
_best_size = 1;
|
||||
return SIZE_LIMIT;
|
||||
}
|
||||
|
||||
// Iterated local search algorithm
|
||||
const int max_size = _size_limit >= 0 ? _size_limit : _n;
|
||||
const int max_restart = _iteration_limit >= 0 ?
|
||||
_iteration_limit : std::numeric_limits<int>::max();
|
||||
const int max_select = _step_limit >= 0 ?
|
||||
_step_limit : std::numeric_limits<int>::max();
|
||||
|
||||
SelectionRuleImpl sel_method(*this);
|
||||
int select = 0, restart = 0;
|
||||
IntVector restart_nodes;
|
||||
while (select < max_select && restart < max_restart) {
|
||||
|
||||
// Perturbation/restart
|
||||
restart++;
|
||||
if (_delta_based_restart) {
|
||||
restart_nodes.clear();
|
||||
for (int i = 0; i != _n; i++) {
|
||||
if (_delta[i] >= _restart_delta_limit)
|
||||
restart_nodes.push_back(i);
|
||||
}
|
||||
}
|
||||
int rs_node = -1;
|
||||
if (restart_nodes.size() > 0) {
|
||||
rs_node = restart_nodes[_rnd[restart_nodes.size()]];
|
||||
} else {
|
||||
rs_node = _rnd[_n];
|
||||
}
|
||||
BoolVector &row = _gr[rs_node];
|
||||
for (int i = 0; i != _n; i++) {
|
||||
if (_clique[i] && !row[i]) delCliqueNode(i);
|
||||
}
|
||||
addCliqueNode(rs_node);
|
||||
|
||||
// Local search
|
||||
_tabu.clear();
|
||||
_tabu.resize(_n, false);
|
||||
bool tabu_empty = true;
|
||||
int max_swap = _size;
|
||||
while (select < max_select) {
|
||||
select++;
|
||||
int u;
|
||||
if ((u = sel_method.nextFeasibleAddNode()) != -1) {
|
||||
// Feasible add move
|
||||
addCliqueNode(u);
|
||||
if (tabu_empty) max_swap = _size;
|
||||
}
|
||||
else if ((u = sel_method.nextFeasibleSwapNode()) != -1) {
|
||||
// Feasible swap move
|
||||
int v = -1;
|
||||
BoolVector &row = _gr[u];
|
||||
for (int i = 0; i != _n; i++) {
|
||||
if (_clique[i] && !row[i]) {
|
||||
v = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
addCliqueNode(u);
|
||||
delCliqueNode(v);
|
||||
_tabu[v] = true;
|
||||
tabu_empty = false;
|
||||
if (--max_swap <= 0) break;
|
||||
}
|
||||
else if ((u = sel_method.nextAddNode()) != -1) {
|
||||
// Non-feasible add move
|
||||
addCliqueNode(u);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
if (_size > _best_size) {
|
||||
_best_clique = _clique;
|
||||
_best_size = _size;
|
||||
if (_best_size >= max_size) return SIZE_LIMIT;
|
||||
}
|
||||
sel_method.update();
|
||||
}
|
||||
|
||||
return (restart >= max_restart ? ITERATION_LIMIT : STEP_LIMIT);
|
||||
}
|
||||
|
||||
}; //class GrossoLocatelliPullanMc
|
||||
|
||||
///@}
|
||||
|
||||
} //namespace lemon
|
||||
|
||||
#endif //LEMON_GROSSO_LOCATELLI_PULLAN_MC_H
|
||||
1015
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/hao_orlin.h
vendored
Normal file
1015
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/hao_orlin.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
654
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/hartmann_orlin_mmc.h
vendored
Normal file
654
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/hartmann_orlin_mmc.h
vendored
Normal file
@@ -0,0 +1,654 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_HARTMANN_ORLIN_MMC_H
|
||||
#define LEMON_HARTMANN_ORLIN_MMC_H
|
||||
|
||||
/// \ingroup min_mean_cycle
|
||||
///
|
||||
/// \file
|
||||
/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/path.h>
|
||||
#include <lemon/tolerance.h>
|
||||
#include <lemon/connectivity.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \brief Default traits class of HartmannOrlinMmc class.
|
||||
///
|
||||
/// Default traits class of HartmannOrlinMmc class.
|
||||
/// \tparam GR The type of the digraph.
|
||||
/// \tparam CM The type of the cost map.
|
||||
/// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
|
||||
#ifdef DOXYGEN
|
||||
template <typename GR, typename CM>
|
||||
#else
|
||||
template <typename GR, typename CM,
|
||||
bool integer = std::numeric_limits<typename CM::Value>::is_integer>
|
||||
#endif
|
||||
struct HartmannOrlinMmcDefaultTraits
|
||||
{
|
||||
/// The type of the digraph
|
||||
typedef GR Digraph;
|
||||
/// The type of the cost map
|
||||
typedef CM CostMap;
|
||||
/// The type of the arc costs
|
||||
typedef typename CostMap::Value Cost;
|
||||
|
||||
/// \brief The large cost type used for internal computations
|
||||
///
|
||||
/// The large cost type used for internal computations.
|
||||
/// It is \c long \c long if the \c Cost type is integer,
|
||||
/// otherwise it is \c double.
|
||||
/// \c Cost must be convertible to \c LargeCost.
|
||||
typedef double LargeCost;
|
||||
|
||||
/// The tolerance type used for internal computations
|
||||
typedef lemon::Tolerance<LargeCost> Tolerance;
|
||||
|
||||
/// \brief The path type of the found cycles
|
||||
///
|
||||
/// The path type of the found cycles.
|
||||
/// It must conform to the \ref lemon::concepts::Path "Path" concept
|
||||
/// and it must have an \c addFront() function.
|
||||
typedef lemon::Path<Digraph> Path;
|
||||
};
|
||||
|
||||
// Default traits class for integer cost types
|
||||
template <typename GR, typename CM>
|
||||
struct HartmannOrlinMmcDefaultTraits<GR, CM, true>
|
||||
{
|
||||
typedef GR Digraph;
|
||||
typedef CM CostMap;
|
||||
typedef typename CostMap::Value Cost;
|
||||
#ifdef LEMON_HAVE_LONG_LONG
|
||||
typedef long long LargeCost;
|
||||
#else
|
||||
typedef long LargeCost;
|
||||
#endif
|
||||
typedef lemon::Tolerance<LargeCost> Tolerance;
|
||||
typedef lemon::Path<Digraph> Path;
|
||||
};
|
||||
|
||||
|
||||
/// \addtogroup min_mean_cycle
|
||||
/// @{
|
||||
|
||||
/// \brief Implementation of the Hartmann-Orlin algorithm for finding
|
||||
/// a minimum mean cycle.
|
||||
///
|
||||
/// This class implements the Hartmann-Orlin algorithm for finding
|
||||
/// a directed cycle of minimum mean cost in a digraph
|
||||
/// \cite hartmann93finding, \cite dasdan98minmeancycle.
|
||||
/// This method is based on \ref KarpMmc "Karp"'s original algorithm, but
|
||||
/// applies an early termination scheme. It makes the algorithm
|
||||
/// significantly faster for some problem instances, but slower for others.
|
||||
/// The algorithm runs in time O(nm) and uses space O(n<sup>2</sup>+m).
|
||||
///
|
||||
/// \tparam GR The type of the digraph the algorithm runs on.
|
||||
/// \tparam CM The type of the cost map. The default
|
||||
/// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
|
||||
/// \tparam TR The traits class that defines various types used by the
|
||||
/// algorithm. By default, it is \ref HartmannOrlinMmcDefaultTraits
|
||||
/// "HartmannOrlinMmcDefaultTraits<GR, CM>".
|
||||
/// In most cases, this parameter should not be set directly,
|
||||
/// consider to use the named template parameters instead.
|
||||
#ifdef DOXYGEN
|
||||
template <typename GR, typename CM, typename TR>
|
||||
#else
|
||||
template < typename GR,
|
||||
typename CM = typename GR::template ArcMap<int>,
|
||||
typename TR = HartmannOrlinMmcDefaultTraits<GR, CM> >
|
||||
#endif
|
||||
class HartmannOrlinMmc
|
||||
{
|
||||
public:
|
||||
|
||||
/// The type of the digraph
|
||||
typedef typename TR::Digraph Digraph;
|
||||
/// The type of the cost map
|
||||
typedef typename TR::CostMap CostMap;
|
||||
/// The type of the arc costs
|
||||
typedef typename TR::Cost Cost;
|
||||
|
||||
/// \brief The large cost type
|
||||
///
|
||||
/// The large cost type used for internal computations.
|
||||
/// By default, it is \c long \c long if the \c Cost type is integer,
|
||||
/// otherwise it is \c double.
|
||||
typedef typename TR::LargeCost LargeCost;
|
||||
|
||||
/// The tolerance type
|
||||
typedef typename TR::Tolerance Tolerance;
|
||||
|
||||
/// \brief The path type of the found cycles
|
||||
///
|
||||
/// The path type of the found cycles.
|
||||
/// Using the \ref lemon::HartmannOrlinMmcDefaultTraits
|
||||
/// "default traits class",
|
||||
/// it is \ref lemon::Path "Path<Digraph>".
|
||||
typedef typename TR::Path Path;
|
||||
|
||||
/// \brief The
|
||||
/// \ref lemon::HartmannOrlinMmcDefaultTraits "traits class"
|
||||
/// of the algorithm
|
||||
typedef TR Traits;
|
||||
|
||||
private:
|
||||
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
// Data sturcture for path data
|
||||
struct PathData
|
||||
{
|
||||
LargeCost dist;
|
||||
Arc pred;
|
||||
PathData(LargeCost d, Arc p = INVALID) :
|
||||
dist(d), pred(p) {}
|
||||
};
|
||||
|
||||
typedef typename Digraph::template NodeMap<std::vector<PathData> >
|
||||
PathDataNodeMap;
|
||||
|
||||
private:
|
||||
|
||||
// The digraph the algorithm runs on
|
||||
const Digraph &_gr;
|
||||
// The cost of the arcs
|
||||
const CostMap &_cost;
|
||||
|
||||
// Data for storing the strongly connected components
|
||||
int _comp_num;
|
||||
typename Digraph::template NodeMap<int> _comp;
|
||||
std::vector<std::vector<Node> > _comp_nodes;
|
||||
std::vector<Node>* _nodes;
|
||||
typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
|
||||
|
||||
// Data for the found cycles
|
||||
bool _curr_found, _best_found;
|
||||
LargeCost _curr_cost, _best_cost;
|
||||
int _curr_size, _best_size;
|
||||
Node _curr_node, _best_node;
|
||||
int _curr_level, _best_level;
|
||||
|
||||
Path *_cycle_path;
|
||||
bool _local_path;
|
||||
|
||||
// Node map for storing path data
|
||||
PathDataNodeMap _data;
|
||||
// The processed nodes in the last round
|
||||
std::vector<Node> _process;
|
||||
|
||||
Tolerance _tolerance;
|
||||
|
||||
// Infinite constant
|
||||
const LargeCost INF;
|
||||
|
||||
public:
|
||||
|
||||
/// \name Named Template Parameters
|
||||
/// @{
|
||||
|
||||
template <typename T>
|
||||
struct SetLargeCostTraits : public Traits {
|
||||
typedef T LargeCost;
|
||||
typedef lemon::Tolerance<T> Tolerance;
|
||||
};
|
||||
|
||||
/// \brief \ref named-templ-param "Named parameter" for setting
|
||||
/// \c LargeCost type.
|
||||
///
|
||||
/// \ref named-templ-param "Named parameter" for setting \c LargeCost
|
||||
/// type. It is used for internal computations in the algorithm.
|
||||
template <typename T>
|
||||
struct SetLargeCost
|
||||
: public HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > {
|
||||
typedef HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > Create;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct SetPathTraits : public Traits {
|
||||
typedef T Path;
|
||||
};
|
||||
|
||||
/// \brief \ref named-templ-param "Named parameter" for setting
|
||||
/// \c %Path type.
|
||||
///
|
||||
/// \ref named-templ-param "Named parameter" for setting the \c %Path
|
||||
/// type of the found cycles.
|
||||
/// It must conform to the \ref lemon::concepts::Path "Path" concept
|
||||
/// and it must have an \c addFront() function.
|
||||
template <typename T>
|
||||
struct SetPath
|
||||
: public HartmannOrlinMmc<GR, CM, SetPathTraits<T> > {
|
||||
typedef HartmannOrlinMmc<GR, CM, SetPathTraits<T> > Create;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
protected:
|
||||
|
||||
HartmannOrlinMmc() {}
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// The constructor of the class.
|
||||
///
|
||||
/// \param digraph The digraph the algorithm runs on.
|
||||
/// \param cost The costs of the arcs.
|
||||
HartmannOrlinMmc( const Digraph &digraph,
|
||||
const CostMap &cost ) :
|
||||
_gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
|
||||
_best_found(false), _best_cost(0), _best_size(1),
|
||||
_cycle_path(NULL), _local_path(false), _data(digraph),
|
||||
INF(std::numeric_limits<LargeCost>::has_infinity ?
|
||||
std::numeric_limits<LargeCost>::infinity() :
|
||||
std::numeric_limits<LargeCost>::max())
|
||||
{}
|
||||
|
||||
/// Destructor.
|
||||
~HartmannOrlinMmc() {
|
||||
if (_local_path) delete _cycle_path;
|
||||
}
|
||||
|
||||
/// \brief Set the path structure for storing the found cycle.
|
||||
///
|
||||
/// This function sets an external path structure for storing the
|
||||
/// found cycle.
|
||||
///
|
||||
/// If you don't call this function before calling \ref run() or
|
||||
/// \ref findCycleMean(), a local \ref Path "path" structure
|
||||
/// will be allocated. The destuctor deallocates this automatically
|
||||
/// allocated object, of course.
|
||||
///
|
||||
/// \note The algorithm calls only the \ref lemon::Path::addFront()
|
||||
/// "addFront()" function of the given path structure.
|
||||
///
|
||||
/// \return <tt>(*this)</tt>
|
||||
HartmannOrlinMmc& cycle(Path &path) {
|
||||
if (_local_path) {
|
||||
delete _cycle_path;
|
||||
_local_path = false;
|
||||
}
|
||||
_cycle_path = &path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Set the tolerance used by the algorithm.
|
||||
///
|
||||
/// This function sets the tolerance object used by the algorithm.
|
||||
///
|
||||
/// \return <tt>(*this)</tt>
|
||||
HartmannOrlinMmc& tolerance(const Tolerance& tolerance) {
|
||||
_tolerance = tolerance;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Return a const reference to the tolerance.
|
||||
///
|
||||
/// This function returns a const reference to the tolerance object
|
||||
/// used by the algorithm.
|
||||
const Tolerance& tolerance() const {
|
||||
return _tolerance;
|
||||
}
|
||||
|
||||
/// \name Execution control
|
||||
/// The simplest way to execute the algorithm is to call the \ref run()
|
||||
/// function.\n
|
||||
/// If you only need the minimum mean cost, you may call
|
||||
/// \ref findCycleMean().
|
||||
|
||||
/// @{
|
||||
|
||||
/// \brief Run the algorithm.
|
||||
///
|
||||
/// This function runs the algorithm.
|
||||
/// It can be called more than once (e.g. if the underlying digraph
|
||||
/// and/or the arc costs have been modified).
|
||||
///
|
||||
/// \return \c true if a directed cycle exists in the digraph.
|
||||
///
|
||||
/// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
|
||||
/// \code
|
||||
/// return mmc.findCycleMean() && mmc.findCycle();
|
||||
/// \endcode
|
||||
bool run() {
|
||||
return findCycleMean() && findCycle();
|
||||
}
|
||||
|
||||
/// \brief Find the minimum cycle mean.
|
||||
///
|
||||
/// This function finds the minimum mean cost of the directed
|
||||
/// cycles in the digraph.
|
||||
///
|
||||
/// \return \c true if a directed cycle exists in the digraph.
|
||||
bool findCycleMean() {
|
||||
// Initialization and find strongly connected components
|
||||
init();
|
||||
findComponents();
|
||||
|
||||
// Find the minimum cycle mean in the components
|
||||
for (int comp = 0; comp < _comp_num; ++comp) {
|
||||
if (!initComponent(comp)) continue;
|
||||
processRounds();
|
||||
|
||||
// Update the best cycle (global minimum mean cycle)
|
||||
if ( _curr_found && (!_best_found ||
|
||||
_curr_cost * _best_size < _best_cost * _curr_size) ) {
|
||||
_best_found = true;
|
||||
_best_cost = _curr_cost;
|
||||
_best_size = _curr_size;
|
||||
_best_node = _curr_node;
|
||||
_best_level = _curr_level;
|
||||
}
|
||||
}
|
||||
return _best_found;
|
||||
}
|
||||
|
||||
/// \brief Find a minimum mean directed cycle.
|
||||
///
|
||||
/// This function finds a directed cycle of minimum mean cost
|
||||
/// in the digraph using the data computed by findCycleMean().
|
||||
///
|
||||
/// \return \c true if a directed cycle exists in the digraph.
|
||||
///
|
||||
/// \pre \ref findCycleMean() must be called before using this function.
|
||||
bool findCycle() {
|
||||
if (!_best_found) return false;
|
||||
IntNodeMap reached(_gr, -1);
|
||||
int r = _best_level + 1;
|
||||
Node u = _best_node;
|
||||
while (reached[u] < 0) {
|
||||
reached[u] = --r;
|
||||
u = _gr.source(_data[u][r].pred);
|
||||
}
|
||||
r = reached[u];
|
||||
Arc e = _data[u][r].pred;
|
||||
_cycle_path->addFront(e);
|
||||
_best_cost = _cost[e];
|
||||
_best_size = 1;
|
||||
Node v;
|
||||
while ((v = _gr.source(e)) != u) {
|
||||
e = _data[v][--r].pred;
|
||||
_cycle_path->addFront(e);
|
||||
_best_cost += _cost[e];
|
||||
++_best_size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Query Functions
|
||||
/// The results of the algorithm can be obtained using these
|
||||
/// functions.\n
|
||||
/// The algorithm should be executed before using them.
|
||||
|
||||
/// @{
|
||||
|
||||
/// \brief Return the total cost of the found cycle.
|
||||
///
|
||||
/// This function returns the total cost of the found cycle.
|
||||
///
|
||||
/// \pre \ref run() or \ref findCycleMean() must be called before
|
||||
/// using this function.
|
||||
Cost cycleCost() const {
|
||||
return static_cast<Cost>(_best_cost);
|
||||
}
|
||||
|
||||
/// \brief Return the number of arcs on the found cycle.
|
||||
///
|
||||
/// This function returns the number of arcs on the found cycle.
|
||||
///
|
||||
/// \pre \ref run() or \ref findCycleMean() must be called before
|
||||
/// using this function.
|
||||
int cycleSize() const {
|
||||
return _best_size;
|
||||
}
|
||||
|
||||
/// \brief Return the mean cost of the found cycle.
|
||||
///
|
||||
/// This function returns the mean cost of the found cycle.
|
||||
///
|
||||
/// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
|
||||
/// following code.
|
||||
/// \code
|
||||
/// return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
|
||||
/// \endcode
|
||||
///
|
||||
/// \pre \ref run() or \ref findCycleMean() must be called before
|
||||
/// using this function.
|
||||
double cycleMean() const {
|
||||
return static_cast<double>(_best_cost) / _best_size;
|
||||
}
|
||||
|
||||
/// \brief Return the found cycle.
|
||||
///
|
||||
/// This function returns a const reference to the path structure
|
||||
/// storing the found cycle.
|
||||
///
|
||||
/// \pre \ref run() or \ref findCycle() must be called before using
|
||||
/// this function.
|
||||
const Path& cycle() const {
|
||||
return *_cycle_path;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
|
||||
// Initialization
|
||||
void init() {
|
||||
if (!_cycle_path) {
|
||||
_local_path = true;
|
||||
_cycle_path = new Path;
|
||||
}
|
||||
_cycle_path->clear();
|
||||
_best_found = false;
|
||||
_best_cost = 0;
|
||||
_best_size = 1;
|
||||
_cycle_path->clear();
|
||||
for (NodeIt u(_gr); u != INVALID; ++u)
|
||||
_data[u].clear();
|
||||
}
|
||||
|
||||
// Find strongly connected components and initialize _comp_nodes
|
||||
// and _out_arcs
|
||||
void findComponents() {
|
||||
_comp_num = stronglyConnectedComponents(_gr, _comp);
|
||||
_comp_nodes.resize(_comp_num);
|
||||
if (_comp_num == 1) {
|
||||
_comp_nodes[0].clear();
|
||||
for (NodeIt n(_gr); n != INVALID; ++n) {
|
||||
_comp_nodes[0].push_back(n);
|
||||
_out_arcs[n].clear();
|
||||
for (OutArcIt a(_gr, n); a != INVALID; ++a) {
|
||||
_out_arcs[n].push_back(a);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < _comp_num; ++i)
|
||||
_comp_nodes[i].clear();
|
||||
for (NodeIt n(_gr); n != INVALID; ++n) {
|
||||
int k = _comp[n];
|
||||
_comp_nodes[k].push_back(n);
|
||||
_out_arcs[n].clear();
|
||||
for (OutArcIt a(_gr, n); a != INVALID; ++a) {
|
||||
if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize path data for the current component
|
||||
bool initComponent(int comp) {
|
||||
_nodes = &(_comp_nodes[comp]);
|
||||
int n = _nodes->size();
|
||||
if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < n; ++i) {
|
||||
_data[(*_nodes)[i]].resize(n + 1, PathData(INF));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Process all rounds of computing path data for the current component.
|
||||
// _data[v][k] is the cost of a shortest directed walk from the root
|
||||
// node to node v containing exactly k arcs.
|
||||
void processRounds() {
|
||||
Node start = (*_nodes)[0];
|
||||
_data[start][0] = PathData(0);
|
||||
_process.clear();
|
||||
_process.push_back(start);
|
||||
|
||||
int k, n = _nodes->size();
|
||||
int next_check = 4;
|
||||
bool terminate = false;
|
||||
for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
|
||||
processNextBuildRound(k);
|
||||
if (k == next_check || k == n) {
|
||||
terminate = checkTermination(k);
|
||||
next_check = next_check * 3 / 2;
|
||||
}
|
||||
}
|
||||
for ( ; k <= n && !terminate; ++k) {
|
||||
processNextFullRound(k);
|
||||
if (k == next_check || k == n) {
|
||||
terminate = checkTermination(k);
|
||||
next_check = next_check * 3 / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process one round and rebuild _process
|
||||
void processNextBuildRound(int k) {
|
||||
std::vector<Node> next;
|
||||
Node u, v;
|
||||
Arc e;
|
||||
LargeCost d;
|
||||
for (int i = 0; i < int(_process.size()); ++i) {
|
||||
u = _process[i];
|
||||
for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
|
||||
e = _out_arcs[u][j];
|
||||
v = _gr.target(e);
|
||||
d = _data[u][k-1].dist + _cost[e];
|
||||
if (_tolerance.less(d, _data[v][k].dist)) {
|
||||
if (_data[v][k].dist == INF) next.push_back(v);
|
||||
_data[v][k] = PathData(d, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
_process.swap(next);
|
||||
}
|
||||
|
||||
// Process one round using _nodes instead of _process
|
||||
void processNextFullRound(int k) {
|
||||
Node u, v;
|
||||
Arc e;
|
||||
LargeCost d;
|
||||
for (int i = 0; i < int(_nodes->size()); ++i) {
|
||||
u = (*_nodes)[i];
|
||||
for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
|
||||
e = _out_arcs[u][j];
|
||||
v = _gr.target(e);
|
||||
d = _data[u][k-1].dist + _cost[e];
|
||||
if (_tolerance.less(d, _data[v][k].dist)) {
|
||||
_data[v][k] = PathData(d, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check early termination
|
||||
bool checkTermination(int k) {
|
||||
typedef std::pair<int, int> Pair;
|
||||
typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
|
||||
typename GR::template NodeMap<LargeCost> pi(_gr);
|
||||
int n = _nodes->size();
|
||||
LargeCost cost;
|
||||
int size;
|
||||
Node u;
|
||||
|
||||
// Search for cycles that are already found
|
||||
_curr_found = false;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
u = (*_nodes)[i];
|
||||
if (_data[u][k].dist == INF) continue;
|
||||
for (int j = k; j >= 0; --j) {
|
||||
if (level[u].first == i && level[u].second > 0) {
|
||||
// A cycle is found
|
||||
cost = _data[u][level[u].second].dist - _data[u][j].dist;
|
||||
size = level[u].second - j;
|
||||
if (!_curr_found || cost * _curr_size < _curr_cost * size) {
|
||||
_curr_cost = cost;
|
||||
_curr_size = size;
|
||||
_curr_node = u;
|
||||
_curr_level = level[u].second;
|
||||
_curr_found = true;
|
||||
}
|
||||
}
|
||||
level[u] = Pair(i, j);
|
||||
if (j != 0) {
|
||||
u = _gr.source(_data[u][j].pred);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If at least one cycle is found, check the optimality condition
|
||||
LargeCost d;
|
||||
if (_curr_found && k < n) {
|
||||
// Find node potentials
|
||||
for (int i = 0; i < n; ++i) {
|
||||
u = (*_nodes)[i];
|
||||
pi[u] = INF;
|
||||
for (int j = 0; j <= k; ++j) {
|
||||
if (_data[u][j].dist < INF) {
|
||||
d = _data[u][j].dist * _curr_size - j * _curr_cost;
|
||||
if (_tolerance.less(d, pi[u])) pi[u] = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the optimality condition for all arcs
|
||||
bool done = true;
|
||||
for (ArcIt a(_gr); a != INVALID; ++a) {
|
||||
if (_tolerance.less(_cost[a] * _curr_size - _curr_cost,
|
||||
pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
|
||||
done = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return done;
|
||||
}
|
||||
return (k == n);
|
||||
}
|
||||
|
||||
}; //class HartmannOrlinMmc
|
||||
|
||||
///@}
|
||||
|
||||
} //namespace lemon
|
||||
|
||||
#endif //LEMON_HARTMANN_ORLIN_MMC_H
|
||||
651
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/howard_mmc.h
vendored
Normal file
651
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/howard_mmc.h
vendored
Normal file
@@ -0,0 +1,651 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_HOWARD_MMC_H
|
||||
#define LEMON_HOWARD_MMC_H
|
||||
|
||||
/// \ingroup min_mean_cycle
|
||||
///
|
||||
/// \file
|
||||
/// \brief Howard's algorithm for finding a minimum mean cycle.
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/path.h>
|
||||
#include <lemon/tolerance.h>
|
||||
#include <lemon/connectivity.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \brief Default traits class of HowardMmc class.
|
||||
///
|
||||
/// Default traits class of HowardMmc class.
|
||||
/// \tparam GR The type of the digraph.
|
||||
/// \tparam CM The type of the cost map.
|
||||
/// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
|
||||
#ifdef DOXYGEN
|
||||
template <typename GR, typename CM>
|
||||
#else
|
||||
template <typename GR, typename CM,
|
||||
bool integer = std::numeric_limits<typename CM::Value>::is_integer>
|
||||
#endif
|
||||
struct HowardMmcDefaultTraits
|
||||
{
|
||||
/// The type of the digraph
|
||||
typedef GR Digraph;
|
||||
/// The type of the cost map
|
||||
typedef CM CostMap;
|
||||
/// The type of the arc costs
|
||||
typedef typename CostMap::Value Cost;
|
||||
|
||||
/// \brief The large cost type used for internal computations
|
||||
///
|
||||
/// The large cost type used for internal computations.
|
||||
/// It is \c long \c long if the \c Cost type is integer,
|
||||
/// otherwise it is \c double.
|
||||
/// \c Cost must be convertible to \c LargeCost.
|
||||
typedef double LargeCost;
|
||||
|
||||
/// The tolerance type used for internal computations
|
||||
typedef lemon::Tolerance<LargeCost> Tolerance;
|
||||
|
||||
/// \brief The path type of the found cycles
|
||||
///
|
||||
/// The path type of the found cycles.
|
||||
/// It must conform to the \ref lemon::concepts::Path "Path" concept
|
||||
/// and it must have an \c addBack() function.
|
||||
typedef lemon::Path<Digraph> Path;
|
||||
};
|
||||
|
||||
// Default traits class for integer cost types
|
||||
template <typename GR, typename CM>
|
||||
struct HowardMmcDefaultTraits<GR, CM, true>
|
||||
{
|
||||
typedef GR Digraph;
|
||||
typedef CM CostMap;
|
||||
typedef typename CostMap::Value Cost;
|
||||
#ifdef LEMON_HAVE_LONG_LONG
|
||||
typedef long long LargeCost;
|
||||
#else
|
||||
typedef long LargeCost;
|
||||
#endif
|
||||
typedef lemon::Tolerance<LargeCost> Tolerance;
|
||||
typedef lemon::Path<Digraph> Path;
|
||||
};
|
||||
|
||||
|
||||
/// \addtogroup min_mean_cycle
|
||||
/// @{
|
||||
|
||||
/// \brief Implementation of Howard's algorithm for finding a minimum
|
||||
/// mean cycle.
|
||||
///
|
||||
/// This class implements Howard's policy iteration algorithm for finding
|
||||
/// a directed cycle of minimum mean cost in a digraph
|
||||
/// \cite dasdan98minmeancycle, \cite dasdan04experimental.
|
||||
/// This class provides the most efficient algorithm for the
|
||||
/// minimum mean cycle problem, though the best known theoretical
|
||||
/// bound on its running time is exponential.
|
||||
///
|
||||
/// \tparam GR The type of the digraph the algorithm runs on.
|
||||
/// \tparam CM The type of the cost map. The default
|
||||
/// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
|
||||
/// \tparam TR The traits class that defines various types used by the
|
||||
/// algorithm. By default, it is \ref HowardMmcDefaultTraits
|
||||
/// "HowardMmcDefaultTraits<GR, CM>".
|
||||
/// In most cases, this parameter should not be set directly,
|
||||
/// consider to use the named template parameters instead.
|
||||
#ifdef DOXYGEN
|
||||
template <typename GR, typename CM, typename TR>
|
||||
#else
|
||||
template < typename GR,
|
||||
typename CM = typename GR::template ArcMap<int>,
|
||||
typename TR = HowardMmcDefaultTraits<GR, CM> >
|
||||
#endif
|
||||
class HowardMmc
|
||||
{
|
||||
public:
|
||||
|
||||
/// The type of the digraph
|
||||
typedef typename TR::Digraph Digraph;
|
||||
/// The type of the cost map
|
||||
typedef typename TR::CostMap CostMap;
|
||||
/// The type of the arc costs
|
||||
typedef typename TR::Cost Cost;
|
||||
|
||||
/// \brief The large cost type
|
||||
///
|
||||
/// The large cost type used for internal computations.
|
||||
/// By default, it is \c long \c long if the \c Cost type is integer,
|
||||
/// otherwise it is \c double.
|
||||
typedef typename TR::LargeCost LargeCost;
|
||||
|
||||
/// The tolerance type
|
||||
typedef typename TR::Tolerance Tolerance;
|
||||
|
||||
/// \brief The path type of the found cycles
|
||||
///
|
||||
/// The path type of the found cycles.
|
||||
/// Using the \ref lemon::HowardMmcDefaultTraits "default traits class",
|
||||
/// it is \ref lemon::Path "Path<Digraph>".
|
||||
typedef typename TR::Path Path;
|
||||
|
||||
/// The \ref lemon::HowardMmcDefaultTraits "traits class" of the algorithm
|
||||
typedef TR Traits;
|
||||
|
||||
/// \brief Constants for the causes of search termination.
|
||||
///
|
||||
/// Enum type containing constants for the different causes of search
|
||||
/// termination. The \ref findCycleMean() function returns one of
|
||||
/// these values.
|
||||
enum TerminationCause {
|
||||
|
||||
/// No directed cycle can be found in the digraph.
|
||||
NO_CYCLE = 0,
|
||||
|
||||
/// Optimal solution (minimum cycle mean) is found.
|
||||
OPTIMAL = 1,
|
||||
|
||||
/// The iteration count limit is reached.
|
||||
ITERATION_LIMIT
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
// The digraph the algorithm runs on
|
||||
const Digraph &_gr;
|
||||
// The cost of the arcs
|
||||
const CostMap &_cost;
|
||||
|
||||
// Data for the found cycles
|
||||
bool _curr_found, _best_found;
|
||||
LargeCost _curr_cost, _best_cost;
|
||||
int _curr_size, _best_size;
|
||||
Node _curr_node, _best_node;
|
||||
|
||||
Path *_cycle_path;
|
||||
bool _local_path;
|
||||
|
||||
// Internal data used by the algorithm
|
||||
typename Digraph::template NodeMap<Arc> _policy;
|
||||
typename Digraph::template NodeMap<bool> _reached;
|
||||
typename Digraph::template NodeMap<int> _level;
|
||||
typename Digraph::template NodeMap<LargeCost> _dist;
|
||||
|
||||
// Data for storing the strongly connected components
|
||||
int _comp_num;
|
||||
typename Digraph::template NodeMap<int> _comp;
|
||||
std::vector<std::vector<Node> > _comp_nodes;
|
||||
std::vector<Node>* _nodes;
|
||||
typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
|
||||
|
||||
// Queue used for BFS search
|
||||
std::vector<Node> _queue;
|
||||
int _qfront, _qback;
|
||||
|
||||
Tolerance _tolerance;
|
||||
|
||||
// Infinite constant
|
||||
const LargeCost INF;
|
||||
|
||||
public:
|
||||
|
||||
/// \name Named Template Parameters
|
||||
/// @{
|
||||
|
||||
template <typename T>
|
||||
struct SetLargeCostTraits : public Traits {
|
||||
typedef T LargeCost;
|
||||
typedef lemon::Tolerance<T> Tolerance;
|
||||
};
|
||||
|
||||
/// \brief \ref named-templ-param "Named parameter" for setting
|
||||
/// \c LargeCost type.
|
||||
///
|
||||
/// \ref named-templ-param "Named parameter" for setting \c LargeCost
|
||||
/// type. It is used for internal computations in the algorithm.
|
||||
template <typename T>
|
||||
struct SetLargeCost
|
||||
: public HowardMmc<GR, CM, SetLargeCostTraits<T> > {
|
||||
typedef HowardMmc<GR, CM, SetLargeCostTraits<T> > Create;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct SetPathTraits : public Traits {
|
||||
typedef T Path;
|
||||
};
|
||||
|
||||
/// \brief \ref named-templ-param "Named parameter" for setting
|
||||
/// \c %Path type.
|
||||
///
|
||||
/// \ref named-templ-param "Named parameter" for setting the \c %Path
|
||||
/// type of the found cycles.
|
||||
/// It must conform to the \ref lemon::concepts::Path "Path" concept
|
||||
/// and it must have an \c addBack() function.
|
||||
template <typename T>
|
||||
struct SetPath
|
||||
: public HowardMmc<GR, CM, SetPathTraits<T> > {
|
||||
typedef HowardMmc<GR, CM, SetPathTraits<T> > Create;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
protected:
|
||||
|
||||
HowardMmc() {}
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constructor.
|
||||
///
|
||||
/// The constructor of the class.
|
||||
///
|
||||
/// \param digraph The digraph the algorithm runs on.
|
||||
/// \param cost The costs of the arcs.
|
||||
HowardMmc( const Digraph &digraph,
|
||||
const CostMap &cost ) :
|
||||
_gr(digraph), _cost(cost), _best_found(false),
|
||||
_best_cost(0), _best_size(1), _cycle_path(NULL), _local_path(false),
|
||||
_policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
|
||||
_comp(digraph), _in_arcs(digraph),
|
||||
INF(std::numeric_limits<LargeCost>::has_infinity ?
|
||||
std::numeric_limits<LargeCost>::infinity() :
|
||||
std::numeric_limits<LargeCost>::max())
|
||||
{}
|
||||
|
||||
/// Destructor.
|
||||
~HowardMmc() {
|
||||
if (_local_path) delete _cycle_path;
|
||||
}
|
||||
|
||||
/// \brief Set the path structure for storing the found cycle.
|
||||
///
|
||||
/// This function sets an external path structure for storing the
|
||||
/// found cycle.
|
||||
///
|
||||
/// If you don't call this function before calling \ref run() or
|
||||
/// \ref findCycleMean(), a local \ref Path "path" structure
|
||||
/// will be allocated. The destuctor deallocates this automatically
|
||||
/// allocated object, of course.
|
||||
///
|
||||
/// \note The algorithm calls only the \ref lemon::Path::addBack()
|
||||
/// "addBack()" function of the given path structure.
|
||||
///
|
||||
/// \return <tt>(*this)</tt>
|
||||
HowardMmc& cycle(Path &path) {
|
||||
if (_local_path) {
|
||||
delete _cycle_path;
|
||||
_local_path = false;
|
||||
}
|
||||
_cycle_path = &path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Set the tolerance used by the algorithm.
|
||||
///
|
||||
/// This function sets the tolerance object used by the algorithm.
|
||||
///
|
||||
/// \return <tt>(*this)</tt>
|
||||
HowardMmc& tolerance(const Tolerance& tolerance) {
|
||||
_tolerance = tolerance;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Return a const reference to the tolerance.
|
||||
///
|
||||
/// This function returns a const reference to the tolerance object
|
||||
/// used by the algorithm.
|
||||
const Tolerance& tolerance() const {
|
||||
return _tolerance;
|
||||
}
|
||||
|
||||
/// \name Execution control
|
||||
/// The simplest way to execute the algorithm is to call the \ref run()
|
||||
/// function.\n
|
||||
/// If you only need the minimum mean cost, you may call
|
||||
/// \ref findCycleMean().
|
||||
|
||||
/// @{
|
||||
|
||||
/// \brief Run the algorithm.
|
||||
///
|
||||
/// This function runs the algorithm.
|
||||
/// It can be called more than once (e.g. if the underlying digraph
|
||||
/// and/or the arc costs have been modified).
|
||||
///
|
||||
/// \return \c true if a directed cycle exists in the digraph.
|
||||
///
|
||||
/// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
|
||||
/// \code
|
||||
/// return mmc.findCycleMean() && mmc.findCycle();
|
||||
/// \endcode
|
||||
bool run() {
|
||||
return findCycleMean() && findCycle();
|
||||
}
|
||||
|
||||
/// \brief Find the minimum cycle mean (or an upper bound).
|
||||
///
|
||||
/// This function finds the minimum mean cost of the directed
|
||||
/// cycles in the digraph (or an upper bound for it).
|
||||
///
|
||||
/// By default, the function finds the exact minimum cycle mean,
|
||||
/// but an optional limit can also be specified for the number of
|
||||
/// iterations performed during the search process.
|
||||
/// The return value indicates if the optimal solution is found
|
||||
/// or the iteration limit is reached. In the latter case, an
|
||||
/// approximate solution is provided, which corresponds to a directed
|
||||
/// cycle whose mean cost is relatively small, but not necessarily
|
||||
/// minimal.
|
||||
///
|
||||
/// \param limit The maximum allowed number of iterations during
|
||||
/// the search process. Its default value implies that the algorithm
|
||||
/// runs until it finds the exact optimal solution.
|
||||
///
|
||||
/// \return The termination cause of the search process.
|
||||
/// For more information, see \ref TerminationCause.
|
||||
TerminationCause findCycleMean(int limit =
|
||||
std::numeric_limits<int>::max()) {
|
||||
// Initialize and find strongly connected components
|
||||
init();
|
||||
findComponents();
|
||||
|
||||
// Find the minimum cycle mean in the components
|
||||
int iter_count = 0;
|
||||
bool iter_limit_reached = false;
|
||||
for (int comp = 0; comp < _comp_num; ++comp) {
|
||||
// Find the minimum mean cycle in the current component
|
||||
if (!buildPolicyGraph(comp)) continue;
|
||||
while (true) {
|
||||
if (++iter_count > limit) {
|
||||
iter_limit_reached = true;
|
||||
break;
|
||||
}
|
||||
findPolicyCycle();
|
||||
if (!computeNodeDistances()) break;
|
||||
}
|
||||
|
||||
// Update the best cycle (global minimum mean cycle)
|
||||
if ( _curr_found && (!_best_found ||
|
||||
_curr_cost * _best_size < _best_cost * _curr_size) ) {
|
||||
_best_found = true;
|
||||
_best_cost = _curr_cost;
|
||||
_best_size = _curr_size;
|
||||
_best_node = _curr_node;
|
||||
}
|
||||
|
||||
if (iter_limit_reached) break;
|
||||
}
|
||||
|
||||
if (iter_limit_reached) {
|
||||
return ITERATION_LIMIT;
|
||||
} else {
|
||||
return _best_found ? OPTIMAL : NO_CYCLE;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Find a minimum mean directed cycle.
|
||||
///
|
||||
/// This function finds a directed cycle of minimum mean cost
|
||||
/// in the digraph using the data computed by findCycleMean().
|
||||
///
|
||||
/// \return \c true if a directed cycle exists in the digraph.
|
||||
///
|
||||
/// \pre \ref findCycleMean() must be called before using this function.
|
||||
bool findCycle() {
|
||||
if (!_best_found) return false;
|
||||
_cycle_path->addBack(_policy[_best_node]);
|
||||
for ( Node v = _best_node;
|
||||
(v = _gr.target(_policy[v])) != _best_node; ) {
|
||||
_cycle_path->addBack(_policy[v]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Query Functions
|
||||
/// The results of the algorithm can be obtained using these
|
||||
/// functions.\n
|
||||
/// The algorithm should be executed before using them.
|
||||
|
||||
/// @{
|
||||
|
||||
/// \brief Return the total cost of the found cycle.
|
||||
///
|
||||
/// This function returns the total cost of the found cycle.
|
||||
///
|
||||
/// \pre \ref run() or \ref findCycleMean() must be called before
|
||||
/// using this function.
|
||||
Cost cycleCost() const {
|
||||
return static_cast<Cost>(_best_cost);
|
||||
}
|
||||
|
||||
/// \brief Return the number of arcs on the found cycle.
|
||||
///
|
||||
/// This function returns the number of arcs on the found cycle.
|
||||
///
|
||||
/// \pre \ref run() or \ref findCycleMean() must be called before
|
||||
/// using this function.
|
||||
int cycleSize() const {
|
||||
return _best_size;
|
||||
}
|
||||
|
||||
/// \brief Return the mean cost of the found cycle.
|
||||
///
|
||||
/// This function returns the mean cost of the found cycle.
|
||||
///
|
||||
/// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
|
||||
/// following code.
|
||||
/// \code
|
||||
/// return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
|
||||
/// \endcode
|
||||
///
|
||||
/// \pre \ref run() or \ref findCycleMean() must be called before
|
||||
/// using this function.
|
||||
double cycleMean() const {
|
||||
return static_cast<double>(_best_cost) / _best_size;
|
||||
}
|
||||
|
||||
/// \brief Return the found cycle.
|
||||
///
|
||||
/// This function returns a const reference to the path structure
|
||||
/// storing the found cycle.
|
||||
///
|
||||
/// \pre \ref run() or \ref findCycle() must be called before using
|
||||
/// this function.
|
||||
const Path& cycle() const {
|
||||
return *_cycle_path;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
|
||||
// Initialize
|
||||
void init() {
|
||||
if (!_cycle_path) {
|
||||
_local_path = true;
|
||||
_cycle_path = new Path;
|
||||
}
|
||||
_queue.resize(countNodes(_gr));
|
||||
_best_found = false;
|
||||
_best_cost = 0;
|
||||
_best_size = 1;
|
||||
_cycle_path->clear();
|
||||
}
|
||||
|
||||
// Find strongly connected components and initialize _comp_nodes
|
||||
// and _in_arcs
|
||||
void findComponents() {
|
||||
_comp_num = stronglyConnectedComponents(_gr, _comp);
|
||||
_comp_nodes.resize(_comp_num);
|
||||
if (_comp_num == 1) {
|
||||
_comp_nodes[0].clear();
|
||||
for (NodeIt n(_gr); n != INVALID; ++n) {
|
||||
_comp_nodes[0].push_back(n);
|
||||
_in_arcs[n].clear();
|
||||
for (InArcIt a(_gr, n); a != INVALID; ++a) {
|
||||
_in_arcs[n].push_back(a);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < _comp_num; ++i)
|
||||
_comp_nodes[i].clear();
|
||||
for (NodeIt n(_gr); n != INVALID; ++n) {
|
||||
int k = _comp[n];
|
||||
_comp_nodes[k].push_back(n);
|
||||
_in_arcs[n].clear();
|
||||
for (InArcIt a(_gr, n); a != INVALID; ++a) {
|
||||
if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build the policy graph in the given strongly connected component
|
||||
// (the out-degree of every node is 1)
|
||||
bool buildPolicyGraph(int comp) {
|
||||
_nodes = &(_comp_nodes[comp]);
|
||||
if (_nodes->size() < 1 ||
|
||||
(_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < int(_nodes->size()); ++i) {
|
||||
_dist[(*_nodes)[i]] = INF;
|
||||
}
|
||||
Node u, v;
|
||||
Arc e;
|
||||
for (int i = 0; i < int(_nodes->size()); ++i) {
|
||||
v = (*_nodes)[i];
|
||||
for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
|
||||
e = _in_arcs[v][j];
|
||||
u = _gr.source(e);
|
||||
if (_cost[e] < _dist[u]) {
|
||||
_dist[u] = _cost[e];
|
||||
_policy[u] = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find the minimum mean cycle in the policy graph
|
||||
void findPolicyCycle() {
|
||||
for (int i = 0; i < int(_nodes->size()); ++i) {
|
||||
_level[(*_nodes)[i]] = -1;
|
||||
}
|
||||
LargeCost ccost;
|
||||
int csize;
|
||||
Node u, v;
|
||||
_curr_found = false;
|
||||
for (int i = 0; i < int(_nodes->size()); ++i) {
|
||||
u = (*_nodes)[i];
|
||||
if (_level[u] >= 0) continue;
|
||||
for (; _level[u] < 0; u = _gr.target(_policy[u])) {
|
||||
_level[u] = i;
|
||||
}
|
||||
if (_level[u] == i) {
|
||||
// A cycle is found
|
||||
ccost = _cost[_policy[u]];
|
||||
csize = 1;
|
||||
for (v = u; (v = _gr.target(_policy[v])) != u; ) {
|
||||
ccost += _cost[_policy[v]];
|
||||
++csize;
|
||||
}
|
||||
if ( !_curr_found ||
|
||||
(ccost * _curr_size < _curr_cost * csize) ) {
|
||||
_curr_found = true;
|
||||
_curr_cost = ccost;
|
||||
_curr_size = csize;
|
||||
_curr_node = u;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Contract the policy graph and compute node distances
|
||||
bool computeNodeDistances() {
|
||||
// Find the component of the main cycle and compute node distances
|
||||
// using reverse BFS
|
||||
for (int i = 0; i < int(_nodes->size()); ++i) {
|
||||
_reached[(*_nodes)[i]] = false;
|
||||
}
|
||||
_qfront = _qback = 0;
|
||||
_queue[0] = _curr_node;
|
||||
_reached[_curr_node] = true;
|
||||
_dist[_curr_node] = 0;
|
||||
Node u, v;
|
||||
Arc e;
|
||||
while (_qfront <= _qback) {
|
||||
v = _queue[_qfront++];
|
||||
for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
|
||||
e = _in_arcs[v][j];
|
||||
u = _gr.source(e);
|
||||
if (_policy[u] == e && !_reached[u]) {
|
||||
_reached[u] = true;
|
||||
_dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
|
||||
_queue[++_qback] = u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Connect all other nodes to this component and compute node
|
||||
// distances using reverse BFS
|
||||
_qfront = 0;
|
||||
while (_qback < int(_nodes->size())-1) {
|
||||
v = _queue[_qfront++];
|
||||
for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
|
||||
e = _in_arcs[v][j];
|
||||
u = _gr.source(e);
|
||||
if (!_reached[u]) {
|
||||
_reached[u] = true;
|
||||
_policy[u] = e;
|
||||
_dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
|
||||
_queue[++_qback] = u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Improve node distances
|
||||
bool improved = false;
|
||||
for (int i = 0; i < int(_nodes->size()); ++i) {
|
||||
v = (*_nodes)[i];
|
||||
for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
|
||||
e = _in_arcs[v][j];
|
||||
u = _gr.source(e);
|
||||
LargeCost delta = _dist[v] + _cost[e] * _curr_size - _curr_cost;
|
||||
if (_tolerance.less(delta, _dist[u])) {
|
||||
_dist[u] = delta;
|
||||
_policy[u] = e;
|
||||
improved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return improved;
|
||||
}
|
||||
|
||||
}; //class HowardMmc
|
||||
|
||||
///@}
|
||||
|
||||
} //namespace lemon
|
||||
|
||||
#endif //LEMON_HOWARD_MMC_H
|
||||
459
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/hypercube_graph.h
vendored
Normal file
459
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/hypercube_graph.h
vendored
Normal file
@@ -0,0 +1,459 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HYPERCUBE_GRAPH_H
|
||||
#define HYPERCUBE_GRAPH_H
|
||||
|
||||
#include <vector>
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/assert.h>
|
||||
#include <lemon/bits/graph_extender.h>
|
||||
|
||||
///\ingroup graphs
|
||||
///\file
|
||||
///\brief HypercubeGraph class.
|
||||
|
||||
namespace lemon {
|
||||
|
||||
class HypercubeGraphBase {
|
||||
|
||||
public:
|
||||
|
||||
typedef HypercubeGraphBase Graph;
|
||||
|
||||
class Node;
|
||||
class Edge;
|
||||
class Arc;
|
||||
|
||||
public:
|
||||
|
||||
HypercubeGraphBase() {}
|
||||
|
||||
protected:
|
||||
|
||||
void construct(int dim) {
|
||||
LEMON_ASSERT(dim >= 1, "The number of dimensions must be at least 1.");
|
||||
_dim = dim;
|
||||
_node_num = 1 << dim;
|
||||
_edge_num = dim * (1 << (dim-1));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
typedef True NodeNumTag;
|
||||
typedef True EdgeNumTag;
|
||||
typedef True ArcNumTag;
|
||||
|
||||
int nodeNum() const { return _node_num; }
|
||||
int edgeNum() const { return _edge_num; }
|
||||
int arcNum() const { return 2 * _edge_num; }
|
||||
|
||||
int maxNodeId() const { return _node_num - 1; }
|
||||
int maxEdgeId() const { return _edge_num - 1; }
|
||||
int maxArcId() const { return 2 * _edge_num - 1; }
|
||||
|
||||
static Node nodeFromId(int id) { return Node(id); }
|
||||
static Edge edgeFromId(int id) { return Edge(id); }
|
||||
static Arc arcFromId(int id) { return Arc(id); }
|
||||
|
||||
static int id(Node node) { return node._id; }
|
||||
static int id(Edge edge) { return edge._id; }
|
||||
static int id(Arc arc) { return arc._id; }
|
||||
|
||||
Node u(Edge edge) const {
|
||||
int base = edge._id & ((1 << (_dim-1)) - 1);
|
||||
int k = edge._id >> (_dim-1);
|
||||
return ((base >> k) << (k+1)) | (base & ((1 << k) - 1));
|
||||
}
|
||||
|
||||
Node v(Edge edge) const {
|
||||
int base = edge._id & ((1 << (_dim-1)) - 1);
|
||||
int k = edge._id >> (_dim-1);
|
||||
return ((base >> k) << (k+1)) | (base & ((1 << k) - 1)) | (1 << k);
|
||||
}
|
||||
|
||||
Node source(Arc arc) const {
|
||||
return (arc._id & 1) == 1 ? u(arc) : v(arc);
|
||||
}
|
||||
|
||||
Node target(Arc arc) const {
|
||||
return (arc._id & 1) == 1 ? v(arc) : u(arc);
|
||||
}
|
||||
|
||||
typedef True FindEdgeTag;
|
||||
typedef True FindArcTag;
|
||||
|
||||
Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
|
||||
if (prev != INVALID) return INVALID;
|
||||
int d = u._id ^ v._id;
|
||||
int k = 0;
|
||||
if (d == 0) return INVALID;
|
||||
for ( ; (d & 1) == 0; d >>= 1) ++k;
|
||||
if (d >> 1 != 0) return INVALID;
|
||||
return (k << (_dim-1)) | ((u._id >> (k+1)) << k) |
|
||||
(u._id & ((1 << k) - 1));
|
||||
}
|
||||
|
||||
Arc findArc(Node u, Node v, Arc prev = INVALID) const {
|
||||
Edge edge = findEdge(u, v, prev);
|
||||
if (edge == INVALID) return INVALID;
|
||||
int k = edge._id >> (_dim-1);
|
||||
return ((u._id >> k) & 1) == 1 ? edge._id << 1 : (edge._id << 1) | 1;
|
||||
}
|
||||
|
||||
class Node {
|
||||
friend class HypercubeGraphBase;
|
||||
|
||||
protected:
|
||||
int _id;
|
||||
Node(int id) : _id(id) {}
|
||||
public:
|
||||
Node() {}
|
||||
Node (Invalid) : _id(-1) {}
|
||||
bool operator==(const Node node) const {return _id == node._id;}
|
||||
bool operator!=(const Node node) const {return _id != node._id;}
|
||||
bool operator<(const Node node) const {return _id < node._id;}
|
||||
};
|
||||
|
||||
class Edge {
|
||||
friend class HypercubeGraphBase;
|
||||
friend class Arc;
|
||||
|
||||
protected:
|
||||
int _id;
|
||||
|
||||
Edge(int id) : _id(id) {}
|
||||
|
||||
public:
|
||||
Edge() {}
|
||||
Edge (Invalid) : _id(-1) {}
|
||||
bool operator==(const Edge edge) const {return _id == edge._id;}
|
||||
bool operator!=(const Edge edge) const {return _id != edge._id;}
|
||||
bool operator<(const Edge edge) const {return _id < edge._id;}
|
||||
};
|
||||
|
||||
class Arc {
|
||||
friend class HypercubeGraphBase;
|
||||
|
||||
protected:
|
||||
int _id;
|
||||
|
||||
Arc(int id) : _id(id) {}
|
||||
|
||||
public:
|
||||
Arc() {}
|
||||
Arc (Invalid) : _id(-1) {}
|
||||
operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
|
||||
bool operator==(const Arc arc) const {return _id == arc._id;}
|
||||
bool operator!=(const Arc arc) const {return _id != arc._id;}
|
||||
bool operator<(const Arc arc) const {return _id < arc._id;}
|
||||
};
|
||||
|
||||
void first(Node& node) const {
|
||||
node._id = _node_num - 1;
|
||||
}
|
||||
|
||||
static void next(Node& node) {
|
||||
--node._id;
|
||||
}
|
||||
|
||||
void first(Edge& edge) const {
|
||||
edge._id = _edge_num - 1;
|
||||
}
|
||||
|
||||
static void next(Edge& edge) {
|
||||
--edge._id;
|
||||
}
|
||||
|
||||
void first(Arc& arc) const {
|
||||
arc._id = 2 * _edge_num - 1;
|
||||
}
|
||||
|
||||
static void next(Arc& arc) {
|
||||
--arc._id;
|
||||
}
|
||||
|
||||
void firstInc(Edge& edge, bool& dir, const Node& node) const {
|
||||
edge._id = node._id >> 1;
|
||||
dir = (node._id & 1) == 0;
|
||||
}
|
||||
|
||||
void nextInc(Edge& edge, bool& dir) const {
|
||||
Node n = dir ? u(edge) : v(edge);
|
||||
int k = (edge._id >> (_dim-1)) + 1;
|
||||
if (k < _dim) {
|
||||
edge._id = (k << (_dim-1)) |
|
||||
((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
|
||||
dir = ((n._id >> k) & 1) == 0;
|
||||
} else {
|
||||
edge._id = -1;
|
||||
dir = true;
|
||||
}
|
||||
}
|
||||
|
||||
void firstOut(Arc& arc, const Node& node) const {
|
||||
arc._id = ((node._id >> 1) << 1) | (~node._id & 1);
|
||||
}
|
||||
|
||||
void nextOut(Arc& arc) const {
|
||||
Node n = (arc._id & 1) == 1 ? u(arc) : v(arc);
|
||||
int k = (arc._id >> _dim) + 1;
|
||||
if (k < _dim) {
|
||||
arc._id = (k << (_dim-1)) |
|
||||
((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
|
||||
arc._id = (arc._id << 1) | (~(n._id >> k) & 1);
|
||||
} else {
|
||||
arc._id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void firstIn(Arc& arc, const Node& node) const {
|
||||
arc._id = ((node._id >> 1) << 1) | (node._id & 1);
|
||||
}
|
||||
|
||||
void nextIn(Arc& arc) const {
|
||||
Node n = (arc._id & 1) == 1 ? v(arc) : u(arc);
|
||||
int k = (arc._id >> _dim) + 1;
|
||||
if (k < _dim) {
|
||||
arc._id = (k << (_dim-1)) |
|
||||
((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
|
||||
arc._id = (arc._id << 1) | ((n._id >> k) & 1);
|
||||
} else {
|
||||
arc._id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static bool direction(Arc arc) {
|
||||
return (arc._id & 1) == 1;
|
||||
}
|
||||
|
||||
static Arc direct(Edge edge, bool dir) {
|
||||
return Arc((edge._id << 1) | (dir ? 1 : 0));
|
||||
}
|
||||
|
||||
int dimension() const {
|
||||
return _dim;
|
||||
}
|
||||
|
||||
bool projection(Node node, int n) const {
|
||||
return static_cast<bool>(node._id & (1 << n));
|
||||
}
|
||||
|
||||
int dimension(Edge edge) const {
|
||||
return edge._id >> (_dim-1);
|
||||
}
|
||||
|
||||
int dimension(Arc arc) const {
|
||||
return arc._id >> _dim;
|
||||
}
|
||||
|
||||
static int index(Node node) {
|
||||
return node._id;
|
||||
}
|
||||
|
||||
Node operator()(int ix) const {
|
||||
return Node(ix);
|
||||
}
|
||||
|
||||
private:
|
||||
int _dim;
|
||||
int _node_num, _edge_num;
|
||||
};
|
||||
|
||||
|
||||
typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase;
|
||||
|
||||
/// \ingroup graphs
|
||||
///
|
||||
/// \brief Hypercube graph class
|
||||
///
|
||||
/// HypercubeGraph implements a special graph type. The nodes of the
|
||||
/// graph are indexed with integers having at most \c dim binary digits.
|
||||
/// Two nodes are connected in the graph if and only if their indices
|
||||
/// differ only on one position in the binary form.
|
||||
/// This class is completely static and it needs constant memory space.
|
||||
/// Thus you can neither add nor delete nodes or edges, however,
|
||||
/// the structure can be resized using resize().
|
||||
///
|
||||
/// This type fully conforms to the \ref concepts::Graph "Graph concept".
|
||||
/// Most of its member functions and nested classes are documented
|
||||
/// only in the concept class.
|
||||
///
|
||||
/// This class provides constant time counting for nodes, edges and arcs.
|
||||
///
|
||||
/// \note The type of the indices is chosen to \c int for efficiency
|
||||
/// reasons. Thus the maximum dimension of this implementation is 26
|
||||
/// (assuming that the size of \c int is 32 bit).
|
||||
class HypercubeGraph : public ExtendedHypercubeGraphBase {
|
||||
typedef ExtendedHypercubeGraphBase Parent;
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constructs a hypercube graph with \c dim dimensions.
|
||||
///
|
||||
/// Constructs a hypercube graph with \c dim dimensions.
|
||||
HypercubeGraph(int dim) { construct(dim); }
|
||||
|
||||
/// \brief Resizes the graph
|
||||
///
|
||||
/// This function resizes the graph. It fully destroys and
|
||||
/// rebuilds the structure, therefore the maps of the graph will be
|
||||
/// reallocated automatically and the previous values will be lost.
|
||||
void resize(int dim) {
|
||||
Parent::notifier(Arc()).clear();
|
||||
Parent::notifier(Edge()).clear();
|
||||
Parent::notifier(Node()).clear();
|
||||
construct(dim);
|
||||
Parent::notifier(Node()).build();
|
||||
Parent::notifier(Edge()).build();
|
||||
Parent::notifier(Arc()).build();
|
||||
}
|
||||
|
||||
/// \brief The number of dimensions.
|
||||
///
|
||||
/// Gives back the number of dimensions.
|
||||
int dimension() const {
|
||||
return Parent::dimension();
|
||||
}
|
||||
|
||||
/// \brief Returns \c true if the n'th bit of the node is one.
|
||||
///
|
||||
/// Returns \c true if the n'th bit of the node is one.
|
||||
bool projection(Node node, int n) const {
|
||||
return Parent::projection(node, n);
|
||||
}
|
||||
|
||||
/// \brief The dimension id of an edge.
|
||||
///
|
||||
/// Gives back the dimension id of the given edge.
|
||||
/// It is in the range <tt>[0..dim-1]</tt>.
|
||||
int dimension(Edge edge) const {
|
||||
return Parent::dimension(edge);
|
||||
}
|
||||
|
||||
/// \brief The dimension id of an arc.
|
||||
///
|
||||
/// Gives back the dimension id of the given arc.
|
||||
/// It is in the range <tt>[0..dim-1]</tt>.
|
||||
int dimension(Arc arc) const {
|
||||
return Parent::dimension(arc);
|
||||
}
|
||||
|
||||
/// \brief The index of a node.
|
||||
///
|
||||
/// Gives back the index of the given node.
|
||||
/// The lower bits of the integer describes the node.
|
||||
static int index(Node node) {
|
||||
return Parent::index(node);
|
||||
}
|
||||
|
||||
/// \brief Gives back a node by its index.
|
||||
///
|
||||
/// Gives back a node by its index.
|
||||
Node operator()(int ix) const {
|
||||
return Parent::operator()(ix);
|
||||
}
|
||||
|
||||
/// \brief Number of nodes.
|
||||
int nodeNum() const { return Parent::nodeNum(); }
|
||||
/// \brief Number of edges.
|
||||
int edgeNum() const { return Parent::edgeNum(); }
|
||||
/// \brief Number of arcs.
|
||||
int arcNum() const { return Parent::arcNum(); }
|
||||
|
||||
/// \brief Linear combination map.
|
||||
///
|
||||
/// This map makes possible to give back a linear combination
|
||||
/// for each node. It works like the \c std::accumulate function,
|
||||
/// so it accumulates the \c bf binary function with the \c fv first
|
||||
/// value. The map accumulates only on that positions (dimensions)
|
||||
/// where the index of the node is one. The values that have to be
|
||||
/// accumulated should be given by the \c begin and \c end iterators
|
||||
/// and the length of this range should be equal to the dimension
|
||||
/// number of the graph.
|
||||
///
|
||||
///\code
|
||||
/// const int DIM = 3;
|
||||
/// HypercubeGraph graph(DIM);
|
||||
/// dim2::Point<double> base[DIM];
|
||||
/// for (int k = 0; k < DIM; ++k) {
|
||||
/// base[k].x = rnd();
|
||||
/// base[k].y = rnd();
|
||||
/// }
|
||||
/// HypercubeGraph::HyperMap<dim2::Point<double> >
|
||||
/// pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
|
||||
///\endcode
|
||||
///
|
||||
/// \see HypercubeGraph
|
||||
template <typename T, typename BF = std::plus<T> >
|
||||
class HyperMap {
|
||||
public:
|
||||
|
||||
/// \brief The key type of the map
|
||||
typedef Node Key;
|
||||
/// \brief The value type of the map
|
||||
typedef T Value;
|
||||
|
||||
/// \brief Constructor for HyperMap.
|
||||
///
|
||||
/// Construct a HyperMap for the given graph. The values that have
|
||||
/// to be accumulated should be given by the \c begin and \c end
|
||||
/// iterators and the length of this range should be equal to the
|
||||
/// dimension number of the graph.
|
||||
///
|
||||
/// This map accumulates the \c bf binary function with the \c fv
|
||||
/// first value on that positions (dimensions) where the index of
|
||||
/// the node is one.
|
||||
template <typename It>
|
||||
HyperMap(const Graph& graph, It begin, It end,
|
||||
T fv = 0, const BF& bf = BF())
|
||||
: _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf)
|
||||
{
|
||||
LEMON_ASSERT(_values.size() == graph.dimension(),
|
||||
"Wrong size of range");
|
||||
}
|
||||
|
||||
/// \brief The partial accumulated value.
|
||||
///
|
||||
/// Gives back the partial accumulated value.
|
||||
Value operator[](const Key& k) const {
|
||||
Value val = _first_value;
|
||||
int id = _graph.index(k);
|
||||
int n = 0;
|
||||
while (id != 0) {
|
||||
if (id & 1) {
|
||||
val = _bin_func(val, _values[n]);
|
||||
}
|
||||
id >>= 1;
|
||||
++n;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private:
|
||||
const Graph& _graph;
|
||||
std::vector<T> _values;
|
||||
T _first_value;
|
||||
BF _bin_func;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
533
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/insertion_tsp.h
vendored
Normal file
533
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/lemon/insertion_tsp.h
vendored
Normal file
@@ -0,0 +1,533 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_INSERTION_TSP_H
|
||||
#define LEMON_INSERTION_TSP_H
|
||||
|
||||
/// \ingroup tsp
|
||||
/// \file
|
||||
/// \brief Insertion algorithm for symmetric TSP
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <lemon/full_graph.h>
|
||||
#include <lemon/maps.h>
|
||||
#include <lemon/random.h>
|
||||
|
||||
namespace lemon {
|
||||
|
||||
/// \ingroup tsp
|
||||
///
|
||||
/// \brief Insertion algorithm for symmetric TSP.
|
||||
///
|
||||
/// InsertionTsp implements the insertion heuristic for solving
|
||||
/// symmetric \ref tsp "TSP".
|
||||
///
|
||||
/// This is a fast and effective tour construction method that has
|
||||
/// many variants.
|
||||
/// It starts with a subtour containing a few nodes of the graph and it
|
||||
/// iteratively inserts the other nodes into this subtour according to a
|
||||
/// certain node selection rule.
|
||||
///
|
||||
/// This method is among the fastest TSP algorithms, and it typically
|
||||
/// provides quite good solutions (usually much better than
|
||||
/// \ref NearestNeighborTsp and \ref GreedyTsp).
|
||||
///
|
||||
/// InsertionTsp implements four different node selection rules,
|
||||
/// from which the most effective one (\e farthest \e node \e selection)
|
||||
/// is used by default.
|
||||
/// With this choice, the algorithm runs in O(n<sup>2</sup>) time.
|
||||
/// For more information, see \ref SelectionRule.
|
||||
///
|
||||
/// \tparam CM Type of the cost map.
|
||||
template <typename CM>
|
||||
class InsertionTsp
|
||||
{
|
||||
public:
|
||||
|
||||
/// Type of the cost map
|
||||
typedef CM CostMap;
|
||||
/// Type of the edge costs
|
||||
typedef typename CM::Value Cost;
|
||||
|
||||
private:
|
||||
|
||||
GRAPH_TYPEDEFS(FullGraph);
|
||||
|
||||
const FullGraph &_gr;
|
||||
const CostMap &_cost;
|
||||
std::vector<Node> _notused;
|
||||
std::vector<Node> _tour;
|
||||
Cost _sum;
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constants for specifying the node selection rule.
|
||||
///
|
||||
/// Enum type containing constants for specifying the node selection
|
||||
/// rule for the \ref run() function.
|
||||
///
|
||||
/// During the algorithm, nodes are selected for addition to the current
|
||||
/// subtour according to the applied rule.
|
||||
/// The FARTHEST method is one of the fastest selection rules, and
|
||||
/// it is typically the most effective, thus it is the default
|
||||
/// option. The RANDOM rule usually gives slightly worse results,
|
||||
/// but it is more robust.
|
||||
///
|
||||
/// The desired selection rule can be specified as a parameter of the
|
||||
/// \ref run() function.
|
||||
enum SelectionRule {
|
||||
|
||||
/// An unvisited node having minimum distance from the current
|
||||
/// subtour is selected at each step.
|
||||
/// The algorithm runs in O(n<sup>2</sup>) time using this
|
||||
/// selection rule.
|
||||
NEAREST,
|
||||
|
||||
/// An unvisited node having maximum distance from the current
|
||||
/// subtour is selected at each step.
|
||||
/// The algorithm runs in O(n<sup>2</sup>) time using this
|
||||
/// selection rule.
|
||||
FARTHEST,
|
||||
|
||||
/// An unvisited node whose insertion results in the least
|
||||
/// increase of the subtour's total cost is selected at each step.
|
||||
/// The algorithm runs in O(n<sup>3</sup>) time using this
|
||||
/// selection rule, but in most cases, it is almost as fast as
|
||||
/// with other rules.
|
||||
CHEAPEST,
|
||||
|
||||
/// An unvisited node is selected randomly without any evaluation
|
||||
/// at each step.
|
||||
/// The global \ref rnd "random number generator instance" is used.
|
||||
/// You can seed it before executing the algorithm, if you
|
||||
/// would like to.
|
||||
/// The algorithm runs in O(n<sup>2</sup>) time using this
|
||||
/// selection rule.
|
||||
RANDOM
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Constructor
|
||||
///
|
||||
/// Constructor.
|
||||
/// \param gr The \ref FullGraph "full graph" the algorithm runs on.
|
||||
/// \param cost The cost map.
|
||||
InsertionTsp(const FullGraph &gr, const CostMap &cost)
|
||||
: _gr(gr), _cost(cost) {}
|
||||
|
||||
/// \name Execution Control
|
||||
/// @{
|
||||
|
||||
/// \brief Runs the algorithm.
|
||||
///
|
||||
/// This function runs the algorithm.
|
||||
///
|
||||
/// \param rule The node selection rule. For more information, see
|
||||
/// \ref SelectionRule.
|
||||
///
|
||||
/// \return The total cost of the found tour.
|
||||
Cost run(SelectionRule rule = FARTHEST) {
|
||||
_tour.clear();
|
||||
|
||||
if (_gr.nodeNum() == 0) return _sum = 0;
|
||||
else if (_gr.nodeNum() == 1) {
|
||||
_tour.push_back(_gr(0));
|
||||
return _sum = 0;
|
||||
}
|
||||
|
||||
switch (rule) {
|
||||
case NEAREST:
|
||||
init(true);
|
||||
start<ComparingSelection<std::less<Cost> >,
|
||||
DefaultInsertion>();
|
||||
break;
|
||||
case FARTHEST:
|
||||
init(false);
|
||||
start<ComparingSelection<std::greater<Cost> >,
|
||||
DefaultInsertion>();
|
||||
break;
|
||||
case CHEAPEST:
|
||||
init(true);
|
||||
start<CheapestSelection, CheapestInsertion>();
|
||||
break;
|
||||
case RANDOM:
|
||||
init(true);
|
||||
start<RandomSelection, DefaultInsertion>();
|
||||
break;
|
||||
}
|
||||
return _sum;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Query Functions
|
||||
/// @{
|
||||
|
||||
/// \brief The total cost of the found tour.
|
||||
///
|
||||
/// This function returns the total cost of the found tour.
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
Cost tourCost() const {
|
||||
return _sum;
|
||||
}
|
||||
|
||||
/// \brief Returns a const reference to the node sequence of the
|
||||
/// found tour.
|
||||
///
|
||||
/// This function returns a const reference to a vector
|
||||
/// that stores the node sequence of the found tour.
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
const std::vector<Node>& tourNodes() const {
|
||||
return _tour;
|
||||
}
|
||||
|
||||
/// \brief Gives back the node sequence of the found tour.
|
||||
///
|
||||
/// This function copies the node sequence of the found tour into
|
||||
/// an STL container through the given output iterator. The
|
||||
/// <tt>value_type</tt> of the container must be <tt>FullGraph::Node</tt>.
|
||||
/// For example,
|
||||
/// \code
|
||||
/// std::vector<FullGraph::Node> nodes(countNodes(graph));
|
||||
/// tsp.tourNodes(nodes.begin());
|
||||
/// \endcode
|
||||
/// or
|
||||
/// \code
|
||||
/// std::list<FullGraph::Node> nodes;
|
||||
/// tsp.tourNodes(std::back_inserter(nodes));
|
||||
/// \endcode
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
template <typename Iterator>
|
||||
void tourNodes(Iterator out) const {
|
||||
std::copy(_tour.begin(), _tour.end(), out);
|
||||
}
|
||||
|
||||
/// \brief Gives back the found tour as a path.
|
||||
///
|
||||
/// This function copies the found tour as a list of arcs/edges into
|
||||
/// the given \ref lemon::concepts::Path "path structure".
|
||||
///
|
||||
/// \pre run() must be called before using this function.
|
||||
template <typename Path>
|
||||
void tour(Path &path) const {
|
||||
path.clear();
|
||||
for (int i = 0; i < int(_tour.size()) - 1; ++i) {
|
||||
path.addBack(_gr.arc(_tour[i], _tour[i+1]));
|
||||
}
|
||||
if (int(_tour.size()) >= 2) {
|
||||
path.addBack(_gr.arc(_tour.back(), _tour.front()));
|
||||
}
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
|
||||
// Initializes the algorithm
|
||||
void init(bool min) {
|
||||
Edge min_edge = min ? mapMin(_gr, _cost) : mapMax(_gr, _cost);
|
||||
|
||||
_tour.clear();
|
||||
_tour.push_back(_gr.u(min_edge));
|
||||
_tour.push_back(_gr.v(min_edge));
|
||||
|
||||
_notused.clear();
|
||||
for (NodeIt n(_gr); n!=INVALID; ++n) {
|
||||
if (n != _gr.u(min_edge) && n != _gr.v(min_edge)) {
|
||||
_notused.push_back(n);
|
||||
}
|
||||
}
|
||||
|
||||
_sum = _cost[min_edge] * 2;
|
||||
}
|
||||
|
||||
// Executes the algorithm
|
||||
template <class SelectionFunctor, class InsertionFunctor>
|
||||
void start() {
|
||||
SelectionFunctor selectNode(_gr, _cost, _tour, _notused);
|
||||
InsertionFunctor insertNode(_gr, _cost, _tour, _sum);
|
||||
|
||||
for (int i=0; i<_gr.nodeNum()-2; ++i) {
|
||||
insertNode.insert(selectNode.select());
|
||||
}
|
||||
|
||||
_sum = _cost[_gr.edge(_tour.back(), _tour.front())];
|
||||
for (int i = 0; i < int(_tour.size())-1; ++i) {
|
||||
_sum += _cost[_gr.edge(_tour[i], _tour[i+1])];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Implementation of the nearest and farthest selection rule
|
||||
template <typename Comparator>
|
||||
class ComparingSelection {
|
||||
public:
|
||||
ComparingSelection(const FullGraph &gr, const CostMap &cost,
|
||||
std::vector<Node> &tour, std::vector<Node> ¬used)
|
||||
: _gr(gr), _cost(cost), _tour(tour), _notused(notused),
|
||||
_dist(gr, 0), _compare()
|
||||
{
|
||||
// Compute initial distances for the unused nodes
|
||||
for (unsigned int i=0; i<_notused.size(); ++i) {
|
||||
Node u = _notused[i];
|
||||
Cost min_dist = _cost[_gr.edge(u, _tour[0])];
|
||||
for (unsigned int j=1; j<_tour.size(); ++j) {
|
||||
Cost curr = _cost[_gr.edge(u, _tour[j])];
|
||||
if (curr < min_dist) {
|
||||
min_dist = curr;
|
||||
}
|
||||
}
|
||||
_dist[u] = min_dist;
|
||||
}
|
||||
}
|
||||
|
||||
Node select() {
|
||||
|
||||
// Select an used node with minimum distance
|
||||
Cost ins_dist = 0;
|
||||
int ins_node = -1;
|
||||
for (unsigned int i=0; i<_notused.size(); ++i) {
|
||||
Cost curr = _dist[_notused[i]];
|
||||
if (_compare(curr, ins_dist) || ins_node == -1) {
|
||||
ins_dist = curr;
|
||||
ins_node = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the selected node from the unused vector
|
||||
Node sn = _notused[ins_node];
|
||||
_notused[ins_node] = _notused.back();
|
||||
_notused.pop_back();
|
||||
|
||||
// Update the distances of the remaining nodes
|
||||
for (unsigned int i=0; i<_notused.size(); ++i) {
|
||||
Node u = _notused[i];
|
||||
Cost nc = _cost[_gr.edge(sn, u)];
|
||||
if (nc < _dist[u]) {
|
||||
_dist[u] = nc;
|
||||
}
|
||||
}
|
||||
|
||||
return sn;
|
||||
}
|
||||
|
||||
private:
|
||||
const FullGraph &_gr;
|
||||
const CostMap &_cost;
|
||||
std::vector<Node> &_tour;
|
||||
std::vector<Node> &_notused;
|
||||
FullGraph::NodeMap<Cost> _dist;
|
||||
Comparator _compare;
|
||||
};
|
||||
|
||||
// Implementation of the cheapest selection rule
|
||||
class CheapestSelection {
|
||||
private:
|
||||
Cost costDiff(Node u, Node v, Node w) const {
|
||||
return
|
||||
_cost[_gr.edge(u, w)] +
|
||||
_cost[_gr.edge(v, w)] -
|
||||
_cost[_gr.edge(u, v)];
|
||||
}
|
||||
|
||||
public:
|
||||
CheapestSelection(const FullGraph &gr, const CostMap &cost,
|
||||
std::vector<Node> &tour, std::vector<Node> ¬used)
|
||||
: _gr(gr), _cost(cost), _tour(tour), _notused(notused),
|
||||
_ins_cost(gr, 0), _ins_pos(gr, -1)
|
||||
{
|
||||
// Compute insertion cost and position for the unused nodes
|
||||
for (unsigned int i=0; i<_notused.size(); ++i) {
|
||||
Node u = _notused[i];
|
||||
Cost min_cost = costDiff(_tour.back(), _tour.front(), u);
|
||||
int min_pos = 0;
|
||||
for (unsigned int j=1; j<_tour.size(); ++j) {
|
||||
Cost curr_cost = costDiff(_tour[j-1], _tour[j], u);
|
||||
if (curr_cost < min_cost) {
|
||||
min_cost = curr_cost;
|
||||
min_pos = j;
|
||||
}
|
||||
}
|
||||
_ins_cost[u] = min_cost;
|
||||
_ins_pos[u] = min_pos;
|
||||
}
|
||||
}
|
||||
|
||||
Cost select() {
|
||||
|
||||
// Select an used node with minimum insertion cost
|
||||
Cost min_cost = 0;
|
||||
int min_node = -1;
|
||||
for (unsigned int i=0; i<_notused.size(); ++i) {
|
||||
Cost curr_cost = _ins_cost[_notused[i]];
|
||||
if (curr_cost < min_cost || min_node == -1) {
|
||||
min_cost = curr_cost;
|
||||
min_node = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the selected node from the unused vector
|
||||
Node sn = _notused[min_node];
|
||||
_notused[min_node] = _notused.back();
|
||||
_notused.pop_back();
|
||||
|
||||
// Insert the selected node into the tour
|
||||
const int ipos = _ins_pos[sn];
|
||||
_tour.insert(_tour.begin() + ipos, sn);
|
||||
|
||||
// Update the insertion cost and position of the remaining nodes
|
||||
for (unsigned int i=0; i<_notused.size(); ++i) {
|
||||
Node u = _notused[i];
|
||||
Cost curr_cost = _ins_cost[u];
|
||||
int curr_pos = _ins_pos[u];
|
||||
|
||||
int ipos_prev = ipos == 0 ? _tour.size()-1 : ipos-1;
|
||||
int ipos_next = ipos == int(_tour.size())-1 ? 0 : ipos+1;
|
||||
Cost nc1 = costDiff(_tour[ipos_prev], _tour[ipos], u);
|
||||
Cost nc2 = costDiff(_tour[ipos], _tour[ipos_next], u);
|
||||
|
||||
if (nc1 <= curr_cost || nc2 <= curr_cost) {
|
||||
// A new position is better than the old one
|
||||
if (nc1 <= nc2) {
|
||||
curr_cost = nc1;
|
||||
curr_pos = ipos;
|
||||
} else {
|
||||
curr_cost = nc2;
|
||||
curr_pos = ipos_next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (curr_pos == ipos) {
|
||||
// The minimum should be found again
|
||||
curr_cost = costDiff(_tour.back(), _tour.front(), u);
|
||||
curr_pos = 0;
|
||||
for (unsigned int j=1; j<_tour.size(); ++j) {
|
||||
Cost tmp_cost = costDiff(_tour[j-1], _tour[j], u);
|
||||
if (tmp_cost < curr_cost) {
|
||||
curr_cost = tmp_cost;
|
||||
curr_pos = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (curr_pos > ipos) {
|
||||
++curr_pos;
|
||||
}
|
||||
}
|
||||
|
||||
_ins_cost[u] = curr_cost;
|
||||
_ins_pos[u] = curr_pos;
|
||||
}
|
||||
|
||||
return min_cost;
|
||||
}
|
||||
|
||||
private:
|
||||
const FullGraph &_gr;
|
||||
const CostMap &_cost;
|
||||
std::vector<Node> &_tour;
|
||||
std::vector<Node> &_notused;
|
||||
FullGraph::NodeMap<Cost> _ins_cost;
|
||||
FullGraph::NodeMap<int> _ins_pos;
|
||||
};
|
||||
|
||||
// Implementation of the random selection rule
|
||||
class RandomSelection {
|
||||
public:
|
||||
RandomSelection(const FullGraph &, const CostMap &,
|
||||
std::vector<Node> &, std::vector<Node> ¬used)
|
||||
: _notused(notused) {}
|
||||
|
||||
Node select() const {
|
||||
const int index = rnd[_notused.size()];
|
||||
Node n = _notused[index];
|
||||
_notused[index] = _notused.back();
|
||||
_notused.pop_back();
|
||||
return n;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Node> &_notused;
|
||||
};
|
||||
|
||||
|
||||
// Implementation of the default insertion method
|
||||
class DefaultInsertion {
|
||||
private:
|
||||
Cost costDiff(Node u, Node v, Node w) const {
|
||||
return
|
||||
_cost[_gr.edge(u, w)] +
|
||||
_cost[_gr.edge(v, w)] -
|
||||
_cost[_gr.edge(u, v)];
|
||||
}
|
||||
|
||||
public:
|
||||
DefaultInsertion(const FullGraph &gr, const CostMap &cost,
|
||||
std::vector<Node> &tour, Cost &total_cost) :
|
||||
_gr(gr), _cost(cost), _tour(tour), _total(total_cost) {}
|
||||
|
||||
void insert(Node n) const {
|
||||
int min = 0;
|
||||
Cost min_val =
|
||||
costDiff(_tour.front(), _tour.back(), n);
|
||||
|
||||
for (unsigned int i=1; i<_tour.size(); ++i) {
|
||||
Cost tmp = costDiff(_tour[i-1], _tour[i], n);
|
||||
if (tmp < min_val) {
|
||||
min = i;
|
||||
min_val = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
_tour.insert(_tour.begin()+min, n);
|
||||
_total += min_val;
|
||||
}
|
||||
|
||||
private:
|
||||
const FullGraph &_gr;
|
||||
const CostMap &_cost;
|
||||
std::vector<Node> &_tour;
|
||||
Cost &_total;
|
||||
};
|
||||
|
||||
// Implementation of a special insertion method for the cheapest
|
||||
// selection rule
|
||||
class CheapestInsertion {
|
||||
TEMPLATE_GRAPH_TYPEDEFS(FullGraph);
|
||||
public:
|
||||
CheapestInsertion(const FullGraph &, const CostMap &,
|
||||
std::vector<Node> &, Cost &total_cost) :
|
||||
_total(total_cost) {}
|
||||
|
||||
void insert(Cost diff) const {
|
||||
_total += diff;
|
||||
}
|
||||
|
||||
private:
|
||||
Cost &_total;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}; // namespace lemon
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user