~spidernet/PermutationFlowShopScheduling

2d06d7c4a45743ac4f93dba581d0c86a0a96eb0c — Gabriele Venturato 1 year, 9 months ago 6eda728 + b12ee8a
Merge branch 'g_localsearch'
77 files changed, 16420 insertions(+), 1 deletions(-)

M .gitignore
A LocalSearch/.gitignore
A LocalSearch/CMakeLists.txt
A LocalSearch/easylocal-3/CHANGELOG
A LocalSearch/easylocal-3/CMakeLists.txt
A LocalSearch/easylocal-3/LICENSE
A LocalSearch/easylocal-3/README.md
A LocalSearch/easylocal-3/cmake/FindTBB.cmake
A LocalSearch/easylocal-3/cmake/easylocal-ide.cmake
A LocalSearch/easylocal-3/include/README.md
A LocalSearch/easylocal-3/include/core.hh
A LocalSearch/easylocal-3/include/debug.hh
A LocalSearch/easylocal-3/include/easylocal.hh
A LocalSearch/easylocal-3/include/helpers.hh
A LocalSearch/easylocal-3/include/helpers/costcomponent.hh
A LocalSearch/easylocal-3/include/helpers/coststructure.hh
A LocalSearch/easylocal-3/include/helpers/deltacostcomponent.hh
A LocalSearch/easylocal-3/include/helpers/kicker.hh
A LocalSearch/easylocal-3/include/helpers/multimodalneighborhoodexplorer.hh
A LocalSearch/easylocal-3/include/helpers/neighborhoodexplorer.hh
A LocalSearch/easylocal-3/include/helpers/outputmanager.hh
A LocalSearch/easylocal-3/include/helpers/parallelkicker.hh
A LocalSearch/easylocal-3/include/helpers/parallelneighborhoodexplorer.hh
A LocalSearch/easylocal-3/include/helpers/statemanager.hh
A LocalSearch/easylocal-3/include/modeling.hh
A LocalSearch/easylocal-3/include/modeling/autostate.hh
A LocalSearch/easylocal-3/include/modeling/change.hh
A LocalSearch/easylocal-3/include/modeling/compiledexpression.hh
A LocalSearch/easylocal-3/include/modeling/expression.hh
A LocalSearch/easylocal-3/include/modeling/expressionstore.hh
A LocalSearch/easylocal-3/include/modeling/operators.hh
A LocalSearch/easylocal-3/include/runners.hh
A LocalSearch/easylocal-3/include/runners/abstractsimulatedannealing.hh
A LocalSearch/easylocal-3/include/runners/firstdescent.hh
A LocalSearch/easylocal-3/include/runners/firstimprovementtabusearch.hh
A LocalSearch/easylocal-3/include/runners/greatdeluge.hh
A LocalSearch/easylocal-3/include/runners/hillclimbing.hh
A LocalSearch/easylocal-3/include/runners/lateacceptancehillclimbing.hh
A LocalSearch/easylocal-3/include/runners/moverunner.hh
A LocalSearch/easylocal-3/include/runners/runner.hh
A LocalSearch/easylocal-3/include/runners/sampletabusearch.hh
A LocalSearch/easylocal-3/include/runners/shiftingpenaltyrunner.hh
A LocalSearch/easylocal-3/include/runners/simulatedannealing.hh
A LocalSearch/easylocal-3/include/runners/simulatedannealingevaluationbased.hh
A LocalSearch/easylocal-3/include/runners/simulatedannealingwithreheating.hh
A LocalSearch/easylocal-3/include/runners/steepestdescent.hh
A LocalSearch/easylocal-3/include/runners/tabusearch.hh
A LocalSearch/easylocal-3/include/solvers.hh
A LocalSearch/easylocal-3/include/solvers/abstractlocalsearch.hh
A LocalSearch/easylocal-3/include/solvers/grasp.hh
A LocalSearch/easylocal-3/include/solvers/multistartsearch.hh
A LocalSearch/easylocal-3/include/solvers/simplelocalsearch.hh
A LocalSearch/easylocal-3/include/solvers/solver.hh
A LocalSearch/easylocal-3/include/solvers/tokenringsearch.hh
A LocalSearch/easylocal-3/include/solvers/variableneighborhooddescent.hh
A LocalSearch/easylocal-3/include/testers.hh
A LocalSearch/easylocal-3/include/testers/componenttester.hh
A LocalSearch/easylocal-3/include/testers/kickertester.hh
A LocalSearch/easylocal-3/include/testers/movetester.hh
A LocalSearch/easylocal-3/include/testers/tester.hh
A LocalSearch/easylocal-3/include/utils.hh
A LocalSearch/easylocal-3/include/utils/FastFunc.hh
A LocalSearch/easylocal-3/include/utils/interruptible.hh
A LocalSearch/easylocal-3/include/utils/parameter.hh
A LocalSearch/easylocal-3/include/utils/random.hh
A LocalSearch/easylocal-3/include/utils/tuple.hh
A LocalSearch/easylocal-3/include/utils/types.hh
A LocalSearch/easylocal-3/misc/doxygen.cfg
A LocalSearch/include/FP_Basics.hh
A LocalSearch/include/FP_Data.hh
A LocalSearch/include/FP_Helpers.hh
A LocalSearch/src/CMakeLists.txt
A LocalSearch/src/FP_Basics.cc
A LocalSearch/src/FP_Data.cc
A LocalSearch/src/FP_Helpers.cc
A LocalSearch/src/FP_Main.cc
A LocalSearch/src/Makefile
M .gitignore => .gitignore +4 -1
@@ 2,4 2,7 @@
*.gch
*.pch
src/FP_Test
.vscode
\ No newline at end of file
EnumGreedy/src/FP_Test
.vscode
.clang-format
LocalSearch/src/FP

A LocalSearch/.gitignore => LocalSearch/.gitignore +2 -0
@@ 0,0 1,2 @@
.idea
cmake-*
\ No newline at end of file

A LocalSearch/CMakeLists.txt => LocalSearch/CMakeLists.txt +3 -0
@@ 0,0 1,3 @@
cmake_minimum_required(VERSION 3.13)
project(FP)
add_subdirectory(src)
\ No newline at end of file

A LocalSearch/easylocal-3/CHANGELOG => LocalSearch/easylocal-3/CHANGELOG +10 -0
@@ 0,0 1,10 @@
3.0 francis

* Code has been rewritten to meet C++11 standard
* Multi-threading support has changed accordingly to the previous point
* Code have been refactored to eliminate source of inefficiency

4.0 lucy

* Moved build system to CMake
* Now libraries get installed in system default paths
\ No newline at end of file

A LocalSearch/easylocal-3/CMakeLists.txt => LocalSearch/easylocal-3/CMakeLists.txt +46 -0
@@ 0,0 1,46 @@
cmake_minimum_required(VERSION 3.8)

project(EasyLocal LANGUAGES CXX)

find_package(Threads REQUIRED)
find_package(Boost 1.58.0 COMPONENTS program_options REQUIRED)
find_package(TBB)

set(subdirs helpers observers runners solvers testers utils modeling)

# Generate list of all files and directories to be added to the library

# Add files from subdirectories
foreach (subdir ${subdirs})
	string(SUBSTRING ${subdir} 0 1 FIRST_LETTER)
	string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
	string(REGEX REPLACE "^.(.*)" "${FIRST_LETTER}\\1" subdir_cap "${subdir}")

  file(GLOB headers ${CMAKE_CURRENT_SOURCE_DIR}/include/${subdir}/*.hh)
	source_group("Header Files\\${subdir_cap}" FILES ${headers})
endforeach (subdir)

file(GLOB headers ${CMAKE_CURRENT_SOURCE_DIR}/include/**/*.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hh)
source_group("Header Files" FILES ${headers})

add_library(EasyLocal INTERFACE)
target_include_directories(EasyLocal INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(EasyLocal INTERFACE Boost::program_options Threads::Threads)

if (TBB_FOUND)
  target_compile_definitions(EasyLocal INTERFACE TBB_AVAILABLE)
  target_link_libraries(EasyLocal INTERFACE TBB::tbb) 
endif (TBB_FOUND)
target_sources(EasyLocal INTERFACE ${headers})
target_compile_features(EasyLocal INTERFACE cxx_std_14)
target_compile_options(EasyLocal INTERFACE "-Wall")


install(
  DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include
  DESTINATION ${CMAKE_INSTALL_PREFIX}/include/easylocal
  PATTERN *
  PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
)



A LocalSearch/easylocal-3/LICENSE => LocalSearch/easylocal-3/LICENSE +60 -0
@@ 0,0 1,60 @@
 Copyright (c) 2001-2015 Sara Ceschia
 						 Luca Di Gaspero 
 						 Andrea Schaerf
						 Tommaso Urli 
 						 University of Udine, Italy 
 
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in
    the documentation and/or other materials provided with the
    distribution.

 3. Neither the name of the copyright holder nor the names of its
    contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

 4. Redistributions of any form whatsoever must retain the following
    acknowledgment: 'This product includes software developed by 
	"Sara Ceschia, Luca Di Gaspero, Andrea Schaerf, Tommaso Urli,
	University of Udine, Italy" (http://satt.diegm.uniud.it/).'
	
 5. The use of the software in source or binary forms that results in
    a scientific publication must be acknowledged by citing the 
	following paper:
	
	Luca Di Gaspero and Andrea Schaerf. EasyLocal++: An object-oriented 
	framework for flexible design of local search algorithms. 
	Software - Practice & Experience, 33(8):733-765, July 2003.
	
	@article{DiSc03,
	  address = {Chirchester, United Kingdom},
	  author = {Di Gaspero, Luca and Schaerf, Andrea},
	  journal = {Software --- Practice \& Experience},
	  month = {July},
	  number = {8},
	  pages = {733--765},
	  publisher = {John Wiley \& Sons},
	  title = {\textsc{EasyLocal++}: An object-oriented framework for flexible design of local search algorithms},
	  volume = {33},
	  year = {2003}
	}

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file

A LocalSearch/easylocal-3/README.md => LocalSearch/easylocal-3/README.md +126 -0
@@ 0,0 1,126 @@
# EasyLocal++

EasyLocal++ is a framework for modeling and solving combinatorial optimization problems through local search metaheuristics. The framework is entirely written in C++ and makes broad use of template metaprogramming to achieve both separation of concerns and performance. 

Typically, to solve a problem, it is sufficient to implement the necessary methods to compute the problem-specific **cost function** and to enumerate the problem-specific **local search moves**. The framework takes care of calling the user-defined hook methods to solve the problem using one of the implemented meta-heuristics (e.g. simulated annealing, tabu search, hill climbing, ...).

This repository contains the last iteration (currently 3.0) of the EasyLocal++ framework. Examples of solvers implemented with EasyLocal++ can be found in `easylocalpp-examples`, while a seed project to use as a starting point for EasyLocal++ projects is in `easylocalpp-seedproject`.

## How to install EasyLocal++

The build system of EasyLocal++ is based on [CMake (Cross Platform Make)](http://www.cmake.org). CMake allows one to **generate build scripts** for most platforms and development environment, including Unix Makefiles, Visual Studio, Xcode, Eclipse, etc. (see [CMake Generators](http://www.cmake.org/cmake/help/v3.0/manual/cmake-generators.7.html) for more information on the supported IDEs).

In general, to avoid mixing temporary CMake files with the project sources, it is advised to create a dedicated `build` subdirectory where all the building activities happen.

### Generating Unix Makefiles

If your would like CMake to generate for you a suite of Unix Makefiles to build EasyLocal++, proceed as follows

	mkdir build
	cd build
	cmake ..
	
then, to build and install EasyLocal on your system, run in `build` the following commands

    make
    make install

`make` will generate a `libEasyLocal.a` static library in the `lib` subdirectory, while `make install` will install both the library and the headers in the `lib` and `include/easylocal` directories under `/usr/local`, which is the recommended option. To replace `/usr/local` with something different, redefine the `CMAKE_INSTALL_PREFIX` variable by passing it to cmake in the following way

	cmake -DCMAKE_INSTALL_PREFIX <prefix> ..

### Generating an Xcode project

If you use Xcode, the commands to generate the EasyLocal++ Xcode project are

    mkdir build
    cd build
    cmake -G Xcode ..
    
this will generate a `EasyLocal.xcodeproj` file in the `build` subdirectory. This project is already configured to build EasyLocal and install it on the system.

### Generating a Visual Studio solution

Similarly to Xcode, CMake can generate a visual studio solution with the command

	cmake -G "Visual Studio <version>"

## Seed project

TODO.

## Citing EasyLocal++

We have invested a lot of time and effort in creating EasyLocal++, if you find this software useful and if you use it for research purposes we would be grateful if you can cite EasyLocal++ in your publications.

The reference papers about EasyLocal++ are:

1. Luca Di Gaspero and Andrea Schaerf. EasyLocal++: An object-oriented framework for flexible design of local search algorithms.  Software — Practice & Experience, 33(8):733–765, July 2003. 
2. Luca Di Gaspero and Andrea Schaerf. Writing local search algorithms using EasyLocal++. In S. Voß and D.L. Woodruff, editors,  Optimization Software Class Libraries, OR/CS. Kluwer Academic Publisher, Boston (MA), USA, 2002.

## License

 Copyright (c) 2001-2015 Sara Ceschia, Luca Di Gaspero, Andrea Schaerf, Tommaso Urli - 
 University of Udine, Italy 
 
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in
    the documentation and/or other materials provided with the
    distribution.

 3. Neither the name of the copyright holder nor the names of its
    contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

 4. Redistributions of any form whatsoever must retain the following
    acknowledgment: 'This product includes software developed by 
	"Sara Ceschia, Luca Di Gaspero, Andrea Schaerf, Tommaso Urli,
	University of Udine, Italy" (http://satt.diegm.uniud.it/).'
	
 5. The use of the software in source or binary forms that results in
    a scientific publication must be acknowledged by citing the 
	following paper:
	
	Luca Di Gaspero and Andrea Schaerf. EasyLocal++: An object-oriented 
	framework for flexible design of local search algorithms. 
	Software - Practice & Experience, 33(8):733-765, July 2003.
	
	
	  
```
#!latex

@article{DiSc03,
	    address = {Chirchester, United Kingdom},
	    author = {Di Gaspero, Luca and Schaerf, Andrea},
	    journal = {Software --- Practice \& Experience},
	    month = {July},
	    number = {8},
	    pages = {733--765},
	    publisher = {John Wiley \& Sons},
	    title = {\textsc{EasyLocal++}: An object-oriented framework for flexible design of local search algorithms},
	    volume = {33},
	    year = {2003}
	  }
```


 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

A LocalSearch/easylocal-3/cmake/FindTBB.cmake => LocalSearch/easylocal-3/cmake/FindTBB.cmake +534 -0
@@ 0,0 1,534 @@
#.rst:
# FindTBB
# -------
#
# Find Intel's Threading Building Blocks (TBB) include path and libraries.
#
# This module reads hints about search locations from variables:
#
# ::
#
#    TBB_ROOT                         - Root directory of pre-built TBB package.
#                                       Can be an environment variable instead. It is
#                                       derived from the found TBB_INCLUDE_DIR if unset.
#    TBB_ARCH_PLATFORM                - Environment variable which can be used to specify
#                                       architecture and platform specific library path
#                                       suffix (excluding "/lib/" suffix or prefix).
#                                       For MSVC, the appropriate link library path of the
#                                       official pre-built download package from the TBB
#                                       web site is chosen by this module. The path suffix
#                                       derived from this variable takes precedence.
#
# This module considers the following CMake variables set by find_package:
#
# ::
#
#    TBB_FIND_COMPONENTS              - Case-insensitive names of requested libraries:
#                                       tbb, [tbb]malloc, [tbb]malloc_proxy
#    TBB_FIND_REQUIRED_<C>            - Whether TBB library component <C> is required.
#                                       TBB is considered to be not found when at least
#                                       one required library or its include path is missing.
#                                       When no TBB_FIND_COMPONENTS are specified, only the
#                                       threading library "tbb" is required.
#    TBB_FIND_REQUIRED                - Raise FATAL_ERROR when required components not found.
#    TBB_FIND_QUIETLY                 - Suppress all other (status) messages.
#
# The TBB_DEBUG variable can be set to TRUE before find_package(TBB) to
# enable verbose output which helps to debug the processing of this module:
#
# ::
#
#    set(TBB_DEBUG TRUE)
#    find_package(TBB)
#
# This module defines the following variables:
#
# ::
#
#    TBB_FOUND                        - Whether TBB libraries were found.
#    TBB_INCLUDE_DIR                  - TBB library include path where tbb/tbb_stddef.h is located.
#                                       Used as HINTS for find_path of TBB_<C>_INCLUDE_DIR.
#    TBB_INCLUDE_DIRS                 - Include paths of found TBB libraries.
#    TBB_LIBRARIES                    - File paths of found TBB libraries.
#    TBB_VERSION                      - Version for use in VERSION_LESS et al. comparisons.
#    TBB_VERSION_MAJOR                - Major library version number.
#    TBB_VERSION_MINOR                - Minor library version number.
#    TBB_VERSION_STRING               - Version string for output messages.
#    TBB_INTERFACE_VERSION            - API version number.
#    TBB_COMPATIBLE_INTERFACE_VERSION - The oldest major version still supported.
#
# Additionally, for each requested component, this module defines the following variables:
#
# ::
#
#    TBB_TBB_FOUND                    - Whether TBB threading library was found.
#    TBB_TBB_INCLUDE_DIR              - Include path of TBB threading library.
#    TBB_TBB_INCLUDE_DIRS             - Include paths for use of TBB library.
#    TBB_TBB_LIBRARIES                - TBB threading library and transitive link dependencies.
#    TBB_TBB_LIBRARY_RELEASE          - File path of optimized TBB link library.
#    TBB_TBB_LIBRARY_DEBUG            - File path of TBB link library with debug symbols.
#    TBB_TBB_LIBRARY                  - File paths of both "optimized" and "debug" TBB threading link libraries.
#                                       When only one of these is found, this variable is set to either
#                                       TBB_TBB_LIBRARY_RELEASE or TBB_TBB_LIBRARY_DEBUG.
#
#    TBB_MALLOC_FOUND                 - Whether TBB malloc library was found.
#    TBB_MALLOC_INCLUDE_DIR           - Include path of TBB malloc library.
#    TBB_MALLOC_INCLUDE_DIRS          - Include paths for use of TBB malloc library.
#    TBB_MALLOC_LIBRARIES             - TBB malloc library and transitive link dependencies.
#    TBB_MALLOC_LIBRARY_RELEASE       - File path of optimized TBB malloc link library.
#    TBB_MALLOC_LIBRARY_DEBUG         - File path of TBB malloc link library with debug symbols.
#    TBB_MALLOC_LIBRARY               - File paths of both "optimized" and "debug" TBB malloc link libraries.
#                                       When only one of these is found, this variable is set to either
#                                       TBB_MALLOC_LIBRARY_RELEASE or TBB_MALLOC_LIBRARY_DEBUG.
#
#    TBB_MALLOC_PROXY_FOUND           - Whether TBB malloc proxy library was found.
#    TBB_MALLOC_PROXY_INCLUDE_DIR     - Include path of TBB malloc proxy library.
#    TBB_MALLOC_PROXY_INCLUDE_DIRS    - Include paths for use of TBB malloc proxy library.
#    TBB_MALLOC_PROXY_LIBRARIES       - TBB malloc proxy library and transitive link dependencies.
#    TBB_MALLOC_PROXY_LIBRARY_RELEASE - File path of optimized TBB malloc proxy link library.
#    TBB_MALLOC_PROXY_LIBRARY_DEBUG   - File path of TBB malloc proxy link library with debug symbols.
#    TBB_MALLOC_PROXY_LIBRARY         - File paths of both "optimized" and "debug" TBB malloc proxy link libraries.
#                                       When only one of these is found, this variable is set to either
#                                       TBB_MALLOC_PROXY_LIBRARY_RELEASE or TBB_MALLOC_PROXY_LIBRARY_DEBUG.
#
# of these, the following variables are added as advanced cache entries:
#
# ::
#
#    TBB_INCLUDE_DIR
#    TBB_<C>_INCLUDE_DIR
#    TBB_<C>_LIBRARY_RELEASE
#    TBB_<C>_LIBRARY_DEBUG
#
# This module further defines the following import targets with the IMPORTED and INTERFACE
# properties set appropriately such that only a target_link_libraries command is required
# to declare the dependency of another target on the respective TBB library component.
# The use of these import targets instead of above defined variables is recommended.
#
# ::
#
#    TBB::tbb          - TBB threading library.
#    TBB::malloc       - TBB malloc library.
#    TBB::malloc_proxy - TBB malloc proxy library.
#
# Example usage:
#
# ::
#
#    find_package(TBB REQUIRED COMPONENTS tbb OPTIONAL_COMPONENTS malloc)
#
#    add_executable(foo foo.cc)
#    target_link_libraries(foo TBB::tbb)
#    if (TARGET TBB::malloc)
#    # or if (TBB_MALLOC_FOUND)
#      target_link_libraries(foo TBB::malloc)
#    endif ()
#
# This module was written by Andreas Schuh for CMake BASIS with inspiration
# from the FindTBB module which was originally part of the Object-oriented
# Graphics Rendering Engine (OGRE) project with modifications by Robert Maynard.

#=============================================================================
# Copyright 2016 Andreas Schuh <andreas.schuh.84@gmail.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
#  License text for the above reference.)

if (NOT TBB_FIND_QUIETLY)
  set(_TBB_FIND_STATUS "Looking for TBB")
  if (TBB_FIND_COMPONENTS)
    set(_TBB_FIND_STATUS "${_TBB_FIND_STATUS} [${TBB_FIND_COMPONENTS}]")
  endif ()
  if (NOT TBB_FIND_REQUIRED)
    set(_TBB_FIND_STATUS "${_TBB_FIND_STATUS} (optional)")
  endif ()
  message(STATUS "${_TBB_FIND_STATUS}...")
endif ()

# ------------------------------------------------------------------------------
# Default required/optional components
if (NOT TBB_FIND_COMPONENTS)
  set(TBB_FIND_COMPONENTS tbb malloc malloc_proxy)
  set(TBB_FIND_REQUIRED_tbb          TRUE)
  set(TBB_FIND_REQUIRED_malloc       FALSE)
  set(TBB_FIND_REQUIRED_malloc_proxy FALSE)
endif ()

# ------------------------------------------------------------------------------
# Normalize component names
set(_TBB_FIND_COMPONENTS)
foreach (__TBB_COMPONENT IN LISTS TBB_FIND_COMPONENTS)
  string(TOUPPER "${__TBB_COMPONENT}" _TBB_COMPONENT)
  string(REGEX REPLACE "^TBB_?([A-Z_]+)$" "\\1" _TBB_COMPONENT "${_TBB_COMPONENT}")
  if (_TBB_COMPONENT MATCHES "^(TBB|MALLOC|MALLOC_PROXY)$")
    set(_TBB_${_TBB_COMPONENT}_NAME ${__TBB_COMPONENT})
    list(APPEND _TBB_FIND_COMPONENTS ${_TBB_COMPONENT})
    if (TBB_FIND_REQUIRED_${__TBB_COMPONENT})
      set(_TBB_FIND_REQUIRED_${_TBB_COMPONENT} TRUE)
    else ()
      set(_TBB_FIND_REQUIRED_${_TBB_COMPONENT} FALSE)
    endif ()
  else ()
    message(FATAL_ERROR "Unknown TBB library component: ${__TBB_COMPONENT}\n"
                        "Valid component names are: tbb, [tbb]malloc, [tbb]malloc_proxy")
  endif ()
endforeach ()
unset(__TBB_COMPONENT)

if (TBB_DEBUG)
  message("** FindTBB: Components = [${_TBB_FIND_COMPONENTS}]")
endif ()

# ------------------------------------------------------------------------------
# Names of headers and libraries for each component
set(_TBB_TBB_LIB_NAMES_RELEASE          tbb)
set(_TBB_TBB_LIB_NAMES_DEBUG            tbb_debug)
set(_TBB_TBB_INC_NAMES                  tbb/tbb.h)

set(_TBB_MALLOC_LIB_NAMES_RELEASE       tbbmalloc)
set(_TBB_MALLOC_LIB_NAMES_DEBUG         tbbmalloc_debug)
set(_TBB_MALLOC_INC_NAMES               tbb/tbb.h)

set(_TBB_MALLOC_PROXY_LIB_NAMES_RELEASE tbbmalloc_proxy)
set(_TBB_MALLOC_PROXY_LIB_NAMES_DEBUG   tbbmalloc_proxy_debug)
set(_TBB_MALLOC_PROXY_INC_NAMES         tbb/tbbmalloc_proxy.h)

# ------------------------------------------------------------------------------
# Transitive link dependencies
set(_TBB_TBB_LIB_LINK_DEPENDS)
set(_TBB_MALLOC_LIB_LINK_DEPENDS)
set(_TBB_MALLOC_PROXY_LIB_LINK_DEPENDS)

if (UNIX AND NOT APPLE)
  # On Linux, the TBB threading library requires librt.so
  list(APPEND _TBB_TBB_LIB_LINK_DEPENDS rt)
endif ()

# ------------------------------------------------------------------------------
# Construct a set of search paths
set(_TBB_ARCH_PLATFORM $ENV{TBB_ARCH_PLATFORM})

if (NOT TBB_ROOT)
  file(TO_CMAKE_PATH "$ENV{TBB_ROOT}" TBB_ROOT)
endif ()

set(_TBB_INC_PATH_SUFFIXES include)

set(_TBB_LIB_PATH_SUFFIXES)
if (_TBB_ARCH_PLATFORM)
  list(APPEND _TBB_LIB_PATH_SUFFIXES lib/${_TBB_ARCH_PLATFORM})
  list(APPEND _TBB_LIB_PATH_SUFFIXES ${_TBB_ARCH_PLATFORM}/lib)
endif ()
list(APPEND _TBB_LIB_PATH_SUFFIXES lib)

if (WIN32 AND MSVC AND CMAKE_GENERATOR MATCHES "Visual Studio ([0-9]+)")
  set(_TBB_MSVS_VERSION ${CMAKE_MATCH_1})
  if (CMAKE_CL_64)
    list(APPEND _TBB_LIB_PATH_SUFFIXES lib/intel64/vc${_TBB_MSVS_VERSION})
    list(APPEND _TBB_LIB_PATH_SUFFIXES intel64/vc${_TBB_MSVS_VERSION}/lib)
    list(APPEND _TBB_LIB_PATH_SUFFIXES lib/ia64/vc${_TBB_MSVS_VERSION})
    list(APPEND _TBB_LIB_PATH_SUFFIXES ia64/vc${_TBB_MSVS_VERSION}/lib)
  else ()
    list(APPEND _TBB_LIB_PATH_SUFFIXES lib/ia32/vc${_TBB_MSVS_VERSION})
    list(APPEND _TBB_LIB_PATH_SUFFIXES ia32/vc${_TBB_MSVS_VERSION}/lib)
  endif ()
  unset(_TBB_MSVS_VERSION)
endif ()

if (TBB_DEBUG)
  message("** FindTBB: Initial search paths:")
  message("** FindTBB: - Root directory hints  = [${TBB_ROOT}]")
  message("** FindTBB: - Include path suffixes = [${_TBB_INC_PATH_SUFFIXES}]")
  message("** FindTBB: - Library path suffixes = [${_TBB_LIB_PATH_SUFFIXES}]")
endif ()

# ------------------------------------------------------------------------------
# Find common include directory 
#
# Looking for tbb/tbb_stddef.h because we use this path later to read this file
# in order to extract the version information. The tbb.h header should be in the
# same directory and is searched for separately as part of the "tbb" and "malloc"
# component search. The TBB_INCLUDE_DIR is then used as HINTS.
find_path(TBB_INCLUDE_DIR
  NAMES tbb/tbb_stddef.h
  HINTS ${TBB_ROOT}
  PATH_SUFFIXES ${_TBB_INC_PATH_SUFFIXES}
)

mark_as_advanced(TBB_INCLUDE_DIR)

# ------------------------------------------------------------------------------
# Derive TBB_ROOT from TBB_INCLUDE_DIR if unset
if (TBB_INCLUDE_DIR AND NOT TBB_ROOT)
  if (_TBB_INC_PATH_SUFFIXES MATCHES "[^/;]/[^/;]")
    string(LENGTH "${TBB_INCLUDE_DIR}" _TBB_INCLUDE_DIR_LENGTH)
    foreach (_TBB_INC_PATH_SUFFIX IN LISTS _TBB_INC_PATH_SUFFIXES)
      string(LENGTH "${_TBB_INC_PATH_SUFFIX}" _TBB_INC_PATH_SUFFIX_LENGTH)
      if (_TBB_INC_PATH_SUFFIX_LENGTH GREATER 0)
        math(EXPR _TBB_SUBSTRING_START "${_TBB_INCLUDE_DIR_LENGTH} - ${_TBB_INC_PATH_SUFFIX_LENGTH}")
        string(SUBSTRING "${TBB_INCLUDE_DIR}" _TBB_SUBSTRING_START -1 _TBB_SUBSTRING)
        if (_TBB_SUBSTRING STREQUAL _TBB_INC_PATH_SUFFIX)
          if (_TBB_SUBSTRING_START GREATER 0)
            string(SUBSTRING "${TBB_INCLUDE_DIR}" 0 _TBB_SUBSTRING_START TBB_ROOT)
            string(REGEX REPLACE "/+$" "" TBB_ROOT "${TBB_ROOT}")
          else ()
            set(TBB_ROOT "/")
          endif ()
          break()
        endif ()
      endif ()
    endforeach ()
    unset(_TBB_SUBSTRING)
    unset(_TBB_SUBSTRING_START)
    unset(_TBB_INCLUDE_DIR_LENGTH)
    unset(_TBB_INC_PATH_SUFFIX_LENGTH)
  else ()
    get_filename_component(TBB_ROOT "${TBB_INCLUDE_DIR}" DIRECTORY)
  endif ()
endif ()

if (TBB_DEBUG)
  message("** FindTBB: After initial search of TBB include path")
  message("** FindTBB: - TBB_INCLUDE_DIR = ${TBB_INCLUDE_DIR}")
  message("** FindTBB: - TBB_ROOT        = [${TBB_ROOT}]")
endif ()

# ------------------------------------------------------------------------------
# Find library components
set(TBB_INCLUDE_DIRS)
set(TBB_LIBRARIES)

foreach (_TBB_COMPONENT IN LISTS _TBB_FIND_COMPONENTS)
  if (TBB_DEBUG)
    message("** FindTBB: Looking for component ${_TBB_COMPONENT}...")
  endif ()

  # Find include path and library files of this component
  find_path(TBB_${_TBB_COMPONENT}_INCLUDE_DIR
    NAMES ${_TBB_${_TBB_COMPONENT}_INC_NAMES}
    HINTS ${TBB_INCLUDE_DIR} ${TBB_ROOT}
    PATH_SUFFIXES ${_TBB_INC_PATH_SUFFIXES}
  )

  find_library(TBB_${_TBB_COMPONENT}_LIBRARY_RELEASE
    NAMES ${_TBB_${_TBB_COMPONENT}_LIB_NAMES_RELEASE}
    HINTS ${TBB_ROOT}
    PATH_SUFFIXES ${_TBB_LIB_PATH_SUFFIXES}
  )

  find_library(TBB_${_TBB_COMPONENT}_LIBRARY_DEBUG
    NAMES ${_TBB_${_TBB_COMPONENT}_LIB_NAMES_DEBUG}
    HINTS ${TBB_ROOT}
    PATH_SUFFIXES ${_TBB_LIB_PATH_SUFFIXES}
  )

  if (TBB_DEBUG)
    message("** FindTBB: - TBB_${_TBB_COMPONENT}_INCLUDE_DIR     = ${TBB_${_TBB_COMPONENT}_INCLUDE_DIR}")
    message("** FindTBB: - TBB_${_TBB_COMPONENT}_LIBRARY_RELEASE = ${TBB_${_TBB_COMPONENT}_LIBRARY_RELEASE}")
    message("** FindTBB: - TBB_${_TBB_COMPONENT}_LIBRARY_DEBUG   = ${TBB_${_TBB_COMPONENT}_LIBRARY_DEBUG}")
  endif ()

  # Mark cache entries as advanced
  mark_as_advanced(TBB_${_TBB_COMPONENT}_INCLUDE_DIR)
  mark_as_advanced(TBB_${_TBB_COMPONENT}_LIBRARY_RELEASE)
  mark_as_advanced(TBB_${_TBB_COMPONENT}_LIBRARY_DEBUG)

  # Set TBB_<C>_LIBRARY
  if (TBB_${_TBB_COMPONENT}_LIBRARY_RELEASE AND TBB_${_TBB_COMPONENT}_LIBRARY_DEBUG)
    set(TBB_${_TBB_COMPONENT}_LIBRARY
      optimized ${TBB_${_TBB_COMPONENT}_LIBRARY_RELEASE}
      debug     ${TBB_${_TBB_COMPONENT}_LIBRARY_DEBUG}
    )
  elseif (TBB_${_TBB_COMPONENT}_LIBRARY_RELEASE)
    set(TBB_${_TBB_COMPONENT}_LIBRARY ${TBB_${_TBB_COMPONENT}_LIBRARY_RELEASE})
  elseif (TBB_${_TBB_COMPONENT}_LIBRARY_DEBUG)
    set(TBB_${_TBB_COMPONENT}_LIBRARY ${TBB_${_TBB_COMPONENT}_LIBRARY_DEBUG})
  else ()
    set(TBB_${_TBB_COMPONENT}_LIBRARY TBB_${_TBB_COMPONENT}_LIBRARY-NOTFOUND)
  endif ()

  # Set TBB_<C>_FOUND
  if (TBB_${_TBB_COMPONENT}_INCLUDE_DIR AND TBB_${_TBB_COMPONENT}_LIBRARY)
    set(TBB_${_TBB_COMPONENT}_FOUND TRUE)
  else ()
    set(TBB_${_TBB_COMPONENT}_FOUND FALSE)
  endif ()
  set(TBB_${_TBB_${_TBB_COMPONENT}_NAME}_FOUND ${TBB_${_TBB_COMPONENT}_FOUND})

  if (TBB_${_TBB_COMPONENT}_FOUND)

    # Add transitive dependencies
    set(TBB_${_TBB_COMPONENT}_INCLUDE_DIRS ${TBB_${_TBB_COMPONENT}_INCLUDE_DIR})
    set(TBB_${_TBB_COMPONENT}_LIBRARIES    ${TBB_${_TBB_COMPONENT}_LIBRARY})
    if (_TBB_${_TBB_COMPONENT}_LIB_LINK_DEPENDS)
      list(APPEND TBB_${_TBB_COMPONENT}_LIBRARIES "${_TBB_${_TBB_COMPONENT}_LIB_LINK_DEPENDS}")
    endif ()

    if (TBB_DEBUG)
      message("** FindTBB: - TBB_${_TBB_COMPONENT}_INCLUDE_DIRS    = [${TBB_${_TBB_COMPONENT}_INCLUDE_DIRS}]")
      message("** FindTBB: - TBB_${_TBB_COMPONENT}_LIBRARIES       = [${TBB_${_TBB_COMPONENT}_LIBRARIES}]")
    endif ()

    # Add to TBB_INCLUDE_DIRS and TBB_LIBRARIES
    list(APPEND TBB_INCLUDE_DIRS ${TBB_${_TBB_COMPONENT}_INCLUDE_DIRS})
    list(APPEND TBB_LIBRARIES    ${TBB_${_TBB_COMPONENT}_LIBRARIES})

    # Add TBB::<C> import target
    string(TOLOWER ${_TBB_COMPONENT} _TBB_TARGET_NAME)
    set(_TBB_TARGET_NAME "TBB::${_TBB_TARGET_NAME}")
    add_library(${_TBB_TARGET_NAME} SHARED IMPORTED)

    set_target_properties(${_TBB_TARGET_NAME} PROPERTIES
      INTERFACE_INCLUDE_DIRECTORIES     "${TBB_${_TBB_COMPONENT}_INCLUDE_DIRS}"
      IMPORTED_LINK_INTERFACE_LANGUAGES CXX
      IMPORTED_NO_SONAME                TRUE
    )
    if (_TBB_${_TBB_COMPONENT}_LIB_LINK_DEPENDS)
      set_target_properties(${_TBB_TARGET_NAME} PROPERTIES
        INTERFACE_LINK_LIBRARIES "${_TBB_${_TBB_COMPONENT}_LIB_LINK_DEPENDS}"
      )
    endif ()

    foreach (_TBB_CONFIGURATION IN ITEMS DEBUG RELEASE)
      if (TBB_${_TBB_COMPONENT}_LIBRARY_${_TBB_CONFIGURATION})
        set_property(TARGET ${_TBB_TARGET_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${_TBB_CONFIGURATION})
        if (WIN32)
          set_target_properties(${_TBB_TARGET_NAME} PROPERTIES
            IMPORTED_IMPLIB_${_TBB_CONFIGURATION} "${TBB_${_TBB_COMPONENT}_LIBRARY_${_TBB_CONFIGURATION}}"
          )
          string(REPLACE       "/lib/"   "/bin/" _TBB_LIB_PATH_DLL "${TBB_${_TBB_COMPONENT}_LIBRARY_${_TBB_CONFIGURATION}}")
          string(REGEX REPLACE "\\.lib$" ".dll"  _TBB_LIB_PATH_DLL "${_TBB_LIB_PATH_DLL}")
          if (EXISTS "${_TBB_LIB_PATH_DLL}")
            set_target_properties(${_TBB_TARGET_NAME} PROPERTIES
              IMPORTED_LOCATION_${_TBB_CONFIGURATION} "${_TBB_LIB_PATH_DLL}"
            )
            if (TBB_DEBUG)
              message("** FindTBB: - IMPORTED_LOCATION_${_TBB_CONFIGURATION} = ${_TBB_LIB_PATH_DLL}")
            endif ()
          elseif (TBB_DEBUG)
            message("** FindTBB: Could not determine ${_TBB_CONFIGURATION} DLL path from import library, tried: "
                    "\n\t${_TBB_LIB_PATH_DLL}")
          endif ()
        else ()
          set_target_properties(${_TBB_TARGET_NAME} PROPERTIES
            IMPORTED_LOCATION_${_TBB_CONFIGURATION} "${TBB_${_TBB_COMPONENT}_LIBRARY_${_TBB_CONFIGURATION}}"
          )
        endif ()
      endif ()
    endforeach ()

    if (TBB_DEBUG)
      message("** FindTBB: Looking for component ${_TBB_COMPONENT}... - found")
    endif ()

  else ()

    if (TBB_DEBUG)
      message("** FindTBB: Looking for component ${_TBB_COMPONENT}... - not found")
    endif ()
    unset(TBB_${_TBB_COMPONENT}_INCLUDE_DIRS)
    unset(TBB_${_TBB_COMPONENT}_LIBRARIES)

  endif ()
endforeach ()

if (TBB_INCLUDE_DIRS)
  list(REMOVE_DUPLICATES TBB_INCLUDE_DIRS)
endif ()

if (TBB_DEBUG)
  message("** FindTBB: Include paths and libraries of all found components:")
  message("** FindTBB: - TBB_INCLUDE_DIRS = [${TBB_INCLUDE_DIRS}]")
  message("** FindTBB: - TBB_LIBRARIES    = [${TBB_LIBRARIES}]")
endif ()

# ------------------------------------------------------------------------------
# Extract library version from start of tbb_stddef.h
if (TBB_INCLUDE_DIR)
  if (NOT DEFINED TBB_VERSION_MAJOR OR
      NOT DEFINED TBB_VERSION_MINOR OR
      NOT DEFINED TBB_INTERFACE_VERSION OR
      NOT DEFINED TBB_COMPATIBLE_INTERFACE_VERSION)
    file(READ "${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS LIMIT 2048)
    string(REGEX REPLACE
      ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1"
      TBB_VERSION_MAJOR "${_TBB_VERSION_CONTENTS}"
    )
    string(REGEX REPLACE
      ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1"
      TBB_VERSION_MINOR "${_TBB_VERSION_CONTENTS}"
    )
    string(REGEX REPLACE
      ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1"
      TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}"
    )
    string(REGEX REPLACE
      ".*#define TBB_COMPATIBLE_INTERFACE_VERSION ([0-9]+).*" "\\1"
      TBB_COMPATIBLE_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}"
    )
    unset(_TBB_VERSION_CONTENTS)
  endif ()
  set(TBB_VERSION "${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR}")
  set(TBB_VERSION_STRING "${TBB_VERSION}")
else ()
  unset(TBB_VERSION)
  unset(TBB_VERSION_MAJOR)
  unset(TBB_VERSION_MINOR)
  unset(TBB_VERSION_STRING)
  unset(TBB_INTERFACE_VERSION)
  unset(TBB_COMPATIBLE_INTERFACE_VERSION)
endif ()

if (TBB_DEBUG)
  message("** FindTBB: Version information from ${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h")
  message("** FindTBB: - TBB_VERSION_STRING               = ${TBB_VERSION_STRING}")
  message("** FindTBB: - TBB_VERSION_MAJOR                = ${TBB_VERSION_MAJOR}")
  message("** FindTBB: - TBB_VERSION_MINOR                = ${TBB_VERSION_MINOR}")
  message("** FindTBB: - TBB_INTERFACE_VERSION            = ${TBB_INTERFACE_VERSION}")
  message("** FindTBB: - TBB_COMPATIBLE_INTERFACE_VERSION = ${TBB_COMPATIBLE_INTERFACE_VERSION}")
endif ()

# ------------------------------------------------------------------------------
# Handle QUIET, REQUIRED, and [EXACT] VERSION arguments and set TBB_FOUND
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(TBB
  REQUIRED_VARS TBB_INCLUDE_DIR
  VERSION_VAR   TBB_VERSION
  HANDLE_COMPONENTS
)

if (NOT TBB_FIND_QUIETLY)
  if (TBB_FOUND)
    message(STATUS "${_TBB_FIND_STATUS}... - found v${TBB_VERSION_STRING}")
  else ()
    message(STATUS "${_TBB_FIND_STATUS}... - not found")
  endif ()
endif ()

# ------------------------------------------------------------------------------
# Unset local auxiliary variables
foreach (_TBB_COMPONENT IN ITEMS TBB MALLOC MALLOC_PROXY)
  unset(_TBB_FIND_REQUIRED_${_TBB_COMPONENT})
  unset(_TBB_${_TBB_COMPONENT}_LIB_NAMES_RELEASE)
  unset(_TBB_${_TBB_COMPONENT}_LIB_NAMES_DEBUG)
  unset(_TBB_${_TBB_COMPONENT}_LIB_LINK_DEPENDS)
  unset(_TBB_${_TBB_COMPONENT}_INC_NAMES)
  unset(_TBB_${_TBB_COMPONENT}_NAME)
endforeach ()

unset(_TBB_COMPONENT)
unset(_TBB_TARGET_NAME)
unset(_TBB_FIND_COMPONENTS)
unset(_TBB_FIND_STATUS)
unset(_TBB_INC_PATH_SUFFIXES)
unset(_TBB_LIB_PATH_SUFFIXES)
unset(_TBB_LIB_PATH_DLL)
unset(_TBB_LIB_NAME)
unset(_TBB_ARCH_PLATFORM)
\ No newline at end of file

A LocalSearch/easylocal-3/cmake/easylocal-ide.cmake => LocalSearch/easylocal-3/cmake/easylocal-ide.cmake +12 -0
@@ 0,0 1,12 @@
set(subdirs helpers observers runners solvers testers utils modeling)
foreach (subdir ${subdirs})
	string(SUBSTRING ${subdir} 0 1 FIRST_LETTER)
	string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
	string(REGEX REPLACE "^.(.*)" "${FIRST_LETTER}\\1" subdir_cap "${subdir}")

  source_group("EasyLocal\\${subdir_cap}" REGULAR_EXPRESSION "[Ee]asy[Ll]ocal.*/include/${subdir}/.+\.hh$")
endforeach (subdir)

source_group("EasyLocal" REGULAR_EXPRESSION "[Ee]asy[Ll]ocal.*/include/[^/]+\.hh$")

#source_group("EasyLocal" REGULAR_EXPRESSION "[Ee]asy[Ll]ocal.*/.+\.hh$")

A LocalSearch/easylocal-3/include/README.md => LocalSearch/easylocal-3/include/README.md +1 -0
@@ 0,0 1,1 @@
Here go the header files.

A LocalSearch/easylocal-3/include/core.hh => LocalSearch/easylocal-3/include/core.hh +6 -0
@@ 0,0 1,6 @@
#pragma once

#include "helpers.hh"
#include "runners.hh"
#include "solvers.hh"
#include "utils.hh"

A LocalSearch/easylocal-3/include/debug.hh => LocalSearch/easylocal-3/include/debug.hh +3 -0
@@ 0,0 1,3 @@
#pragma once

#include "testers.hh"

A LocalSearch/easylocal-3/include/easylocal.hh => LocalSearch/easylocal-3/include/easylocal.hh +132 -0
@@ 0,0 1,132 @@
#pragma once

/**
 @file EasyLocal.hh
 @brief Full class inclusions.
 
 This file contains the inclusions of @e all the files for
 the class declarations of the EasyLocal framework.
 
 @author Luca Di Gaspero, Andrea Schaerf - University of Udine, Italy
 @version 1.0
 $Revision$
 $Date$
 @note This version works both with MS Visual C++ and the GNU C++
 compiler. Yet, it is extensively tested only with the GNU compiler.
 */

#include "core.hh"
#include "debug.hh"
//#include "modeling.hh" // NOT INCLUDED UNTIL STABLE

/**
 @mainpage EasyLocalpp: an Object-Oriented framework for Local Search algorithms.
 
 This is EasyLocalpp: a C++ Object-Oriented framework
 aimed at easing the development of Local Search algorithms.
 
 Copyright (C) 2001--2008 Andrea Schaerf, Luca Di Gaspero.
 
 The abstract classes that compose the framework specify and implement
 the invariant part of the algorithm, and are meant to be specialized by
 concrete classes that supply the problem-dependent part.
 The framework provides the full control structures of the algorithms,
 and the user has only to write the problem-specific code. Furthermore,
 the framework comes out with some tools that simplify the analysis of
 the algorithms.
 
 The architecture of EasyLocalpp provides a principled modularization for
 the solution of combinatorial problems by local search, and helps the
 user by deriving a neat conceptual scheme of the application.  It also
 supports the design of combinations of basic techniques and/or
 neighborhood structures.
 
 The core of EasyLocalpp is composed of a set of cooperating classes that
 take care of different aspects of local search. The user's application
 is obtained by writing derived classes for a selected subset of the
 framework ones. Such user-defined classes contain only the specific
 problem description, but no control information for the algorithm. In
 fact, the relationships between classes, and their interactions by
 mutual method invocation, are completely dealt with by the framework.
 
 The classes in the framework are split in five categories, depending
 on the role they play in a local search algorithm. We have identified
 the following sets of classes:
 
 - @ref Data "Data" classes: store the basic data of the algorithm.  They
 encode the @ref State "State"s of the search space, the @ref Move "Move"s,
 and the @ref Input "Input"/@ref Output "Output" data.
 These classes have only data members and no
 methods, except for those accessing their own data.  They have no
 computing capabilities and, generally, no links to other
 classes.
 
 - @ref Helpers "Helpers" perform actions related to some specific aspects of the
 search, such as the generation of an initial random state or the
 exploration of the neighborhood of a given state.
 Helpers do not have their own internal data, but they work on the
 internal state of the @ref Runners "Runners" that invoke them, and interact with
 them through function parameters.
 
 - @ref Runners "Runners" are the algorithmic core of the framework. They are
 responsible for performing a run of a local search technique,
 starting from an initial state and leading to a final one. Each
 runner has many data objects that represent the state of the
 search (current state, best state, current move, number of
 iterations, ...), and it maintains links to all the helpers, which
 are invoked for performing specific tasks on its own data. Example
 of runners are @e tabu @e search and @e simulated @e annealing.
 
 - @ref Kickers "Kickers" implement intensification and/or diversification
 strategies based on macro-moves in larger neighborhoods composed
 by sequences of basic moves.
 
 - @ref Solvers "Solvers" control the search by generating the initial solutions,
 and deciding how, and in which sequence, runners have to be
 activated. In addition, they communicate with the external environment,
 by getting the input and delivering the output. They are linked to one or more runners
 (for simple or composite search, respectively) and to some of the
 helpers.
 
 Other components of EasyLocalpp are:
 
 - @ref Observers "Observers" are a set of classes for inspecting the behavior of
 the local search algorithm. They are listeners to the local search events and
 they output the progress of the local search to an output stream.
 
 - @ref Testers "Testers" represent a simple predefined interface of the user
 program. They can be used to help the developers in debugging their
 code, adjusting the techniques, and tuning the parameters.
 The testers are not used anymore whenever the program is embedded in
 a larger application, or if the users develop an @e ad @e hoc
 interface for their programs.
 
 - @ref Utils "Utils" are a set of utility classes that provide a set of miscellaneous
 services.
 
 - @ref UnitTesting "Unit Testing" components provide a set of basic automatic checks
 for the user developed classes.
 
 @page Data Data classes
 
 The data classes are used for template instantiation, and hence they
 have no actual code. They serve for storing the following information:
 
 - @anchor Input @a Input: input data of the problem.
 - @anchor Output @a Output: output as it has to be delivered to the user.
 - @anchor State @a State: an element of the search space.
 - @anchor Move @a Move: a local move. The class move needs to have the operators == and < defined.
 - @anchor CFType @a CFType: the cost function type. This template is by default
 instantiated to @c int, representing an integer (discrete) cost function.
 However it can be redefined by the user to allow for real-valued cost
 functions or cost functions of arbitrary types (provided that the basic
 arithmetic and comparison operators will be defined).
 
 In a few applications, @a State and @a Output classes may
 coincide but, in general, the @e search @e space, -which is explored
 by the algorithm- is only an indirect (not necessarily complete)
 representation of the @e output @e space -which is related to the
 problem specification.
 */



A LocalSearch/easylocal-3/include/helpers.hh => LocalSearch/easylocal-3/include/helpers.hh +45 -0
@@ 0,0 1,45 @@
#pragma once

/**
 @defgroup Helpers Helpers
 
 @brief Helpers perform actions related to some specific aspects of the search and have to be
 partially implemented by the user.
 
 EasyLocalpp defines a number of helper classes that are not related
 hierarchically, but they are linked to @ref Runners, @ref Solvers, @ref Testers
 and to each other through references. The helpers are the following ones:
 
 - StateManager: is responsible for all operations on the state that are
 independent of the neighborhood definition (i.e., from the @ref Move "Moves").
 
 - CostComponent: is responsible for computing a component of the cost function
 on a given @ref State. The class is able to handle both @e hard and @e soft cost components.
 
 - OutputManager:
 is responsible for translating between elements of the search space
 and output solutions.  It also delivers other output information of
 the search, and stores and retrieves solutions from files.  This is
 the only helper that deals with the @ref Output class.  All
 other helpers work only on the @ref State class, which
 represents the elements of the search space used by the algorithms.
 
 - NeighborhoodExplorer: handles all the features concerning neighborhood exploration in an @e iterator
 fashion.
 
 - DeltaCostComponent: is responsible for computing the difference of the cost function due to the application
 of a @ref Move on a given @ref State.
 
 - ShiftingPenaltyManager: is responsible for the adaptive modification of the weights of the
 cost function, according to the @e shifting @e penalty mechanism. For each component of the
 cost function, it maintains an independent weight, which varies depending on the number of
 violations and according to a customizable scheme.
 */

#include "helpers/costcomponent.hh"
#include "helpers/deltacostcomponent.hh"
#include "helpers/kicker.hh"
#include "helpers/neighborhoodexplorer.hh"
#include "helpers/outputmanager.hh"
#include "helpers/statemanager.hh"


A LocalSearch/easylocal-3/include/helpers/costcomponent.hh => LocalSearch/easylocal-3/include/helpers/costcomponent.hh +118 -0
@@ 0,0 1,118 @@
#pragma once

#include <iostream>
#include <vector>
#include "helpers/coststructure.hh"

namespace EasyLocal
{

namespace Core
{

/** The responsibility of this class is to compute a component of cost based on the information contained in a state. It doesn't handle delta costs (i.e., variations of the cost functions due to a move), as they are treated in @ref DeltaCostComponent.
     All cost components for a given (@Input, @State) pair are statically registered in the system and they are accessible with an index.
     @brief The class CostComponent manages one single component of the cost, either hard or soft.
     @tparam Input the class representing the problem input
     @tparam State the class representing the problem's state
     @tparam CFtype the type of the cost function (typically int)
     @ingroup Helpers
     */
template <class Input, class State, class CFtype = int>
class CostComponent 
{
public:
  /** @copydoc Printable::Print() */
  virtual void Print(std::ostream &os = std::cout) const;

  /** Computes this component of cost with respect to a given state not considering its weight.
       @param st the @ref State to be evaluated
       @return the computed cost, regardless of its weight
       */
  virtual CFtype ComputeCost(const State &st) const = 0;

  /** Computes this component of cost with respect to a given state.
       @param st the @ref State to be evaluated
       @return the computed cost, multiplied by its weight
       @remarks internally calls @ref ComputeCost and multiplies the result by the weight of the cost component.
       */
  CFtype Cost(const State &st) const { return weight * ComputeCost(st); }

  /** Prints the violations relative to this cost component with respect to the specified state.
       @param st the @State to be evaluated
       @param os the output stream where the description has to be printed
       */
  virtual void PrintViolations(const State &st, std::ostream &os = std::cout) const = 0;

  /** Gets the weight of this cost component.
       @return the weight of this cost component
       */
  CFtype Weight() const { return weight; }

  /** Sets a new weight for this cost component.
       @param w the new weight
       */
  void SetWeight(const CFtype &w) { weight = w; }

  /** Sets this cost component to be hard. */
  void SetHard() { is_hard = true; }

  /** Sets this cost component to be soft. */
  void SetSoft() { is_hard = false; }

  /** Tells whether this cost component is a hard cost component.
       @return true if this cost component is hard, false otherwise
       */
  bool IsHard() const { return is_hard; }

  /** Tells if this cost component is soft a soft cost component.
       @return true if this cost component is soft, false otherwise
       */
  bool IsSoft() const { return !is_hard; }

  /** Name of this cost component (for debug). */
  const std::string name;

  /** Destructor. */
  virtual ~CostComponent()
  {
  }

  const size_t hash;

protected:
  /** Constructor.
       @param in @ref Input object
       @param weight weight of the cost component
       @param is_hard a flag which tells if the cost component is hard or soft
       @param name name of the cost component (for debug reasons)
       */
  CostComponent(const Input &in, const CFtype &weight, bool is_hard, std::string name);

  /** Input object. */
  const Input &in;

  /** Weight of the cost component. */
  CFtype weight;

  /** Flag that tells if the cost component is soft or hard */
  bool is_hard;

protected:
};

/** IMPLEMENTATION */

template <class Input, class State, typename CFtype>
CostComponent<Input, State, CFtype>::CostComponent(const Input &in, const CFtype &weight, bool is_hard, std::string name)
    : name(name), hash(std::hash<std::string>()(typeid(this).name() + name)), in(in), weight(weight), is_hard(is_hard)
{
}

template <class Input, class State, typename CFtype>
void CostComponent<Input, State, CFtype>::Print(std::ostream &os) const
{
  os << "Cost Component " << name << ": weight " << weight << (is_hard ? "*" : "") << std::endl;
}
} // namespace Core
} // namespace EasyLocal

A LocalSearch/easylocal-3/include/helpers/coststructure.hh => LocalSearch/easylocal-3/include/helpers/coststructure.hh +573 -0
@@ 0,0 1,573 @@
#pragma once

#include "utils/types.hh"

namespace EasyLocal
{

namespace Core
{

// FIXME: it is likely that the semantics of equality and inequality in case of hybrid comparison (i.e., CostStructure against scalar) is not meaningful. Probably it can be safely removed.

template <typename T>
struct DefaultCostStructure
{
  typedef T CFtype;

  DefaultCostStructure() : total(0), violations(0), objective(0), all_components(0), weighted(0.0), is_weighted(false) {}
  DefaultCostStructure(CFtype total, CFtype violations, CFtype objective, const std::vector<CFtype> &all_components) : total(total), violations(violations), objective(objective), all_components(all_components), weighted(total), is_weighted(false) {}
  DefaultCostStructure(CFtype total, double weighted, CFtype violations, CFtype objective, const std::vector<CFtype> &all_components) : total(total), violations(violations), objective(objective), all_components(all_components), weighted(weighted), is_weighted(true) {}

  CFtype total, violations, objective;
  std::vector<CFtype> all_components;
  double weighted;

  bool is_weighted;

  DefaultCostStructure &operator+=(const DefaultCostStructure &other)
  {
    this->total += other.total;
    this->violations += other.violations;
    this->objective += other.objective;
    if (this->all_components.size() < other.all_components.size())
      this->all_components.resize(other.all_components.size(), 0);
    for (size_t i = 0; i < other.all_components.size(); i++)
      this->all_components[i] += other.all_components[i];
    return *this;
  }

  DefaultCostStructure &operator-=(const DefaultCostStructure &other)
  {
    this->total -= other.total;
    this->violations -= other.violations;
    this->objective -= other.objective;
    if (this->all_components.size() < other.all_components.size())
      this->all_components.resize(other.all_components.size(), 0);
    for (size_t i = 0; i < other.all_components.size(); i++)
      this->all_components[i] -= other.all_components[i];
    return *this;
  }

  const CFtype &operator[](size_t i) const
  {
    return all_components[i];
  }

  size_t size() const
  {
    return all_components.size();
  }
};

template <typename CFtype>
DefaultCostStructure<CFtype> operator+(const DefaultCostStructure<CFtype> &cs1, const DefaultCostStructure<CFtype> &cs2)
{
  DefaultCostStructure<CFtype> res = cs1;
  res += cs2;
  return res;
}

template <typename CFtype>
DefaultCostStructure<CFtype> operator-(const DefaultCostStructure<CFtype> &cs1, const DefaultCostStructure<CFtype> &cs2)
{
  DefaultCostStructure<CFtype> res = cs1;
  res -= cs2;
  return res;
}

template <class CFtype>
bool operator<(const DefaultCostStructure<CFtype> &cs1, const DefaultCostStructure<CFtype> &cs2)
{
  if (cs1.is_weighted && cs2.is_weighted)
    return LessThan(cs1.weighted, cs2.weighted);
  return LessThan(cs1.total, cs2.total);
}

template <class CFtype, typename OtherType>
bool operator<(OtherType c1, const DefaultCostStructure<CFtype> &cs2)
{
  if (cs2.is_weighted)
    return LessThan((double)c1, cs2.weighted);
  return LessThan(static_cast<CFtype>(c1), cs2.total);
}

template <class CFtype>
bool operator<(double c1, const DefaultCostStructure<CFtype> &cs2)
{
  if (cs2.is_weighted)
    return LessThan(c1, cs2.weighted);
  return LessThan(c1, static_cast<double>(cs2.total));
}

template <class CFtype, typename OtherType>
bool operator<(const DefaultCostStructure<CFtype> &cs1, OtherType c2)
{
  if (cs1.is_weighted)
    return LessThan(cs1.weighted, (double)c2);
  return LessThan(cs1.total, static_cast<CFtype>(c2));
}

template <class CFtype>
bool operator<(const DefaultCostStructure<CFtype> &cs1, double c2)
{
  if (cs1.is_weighted)
    return LessThan(cs1.weighted, c2);
  return LessThan(static_cast<double>(cs1.total), c2);
}

template <class CFtype>
bool operator<=(const DefaultCostStructure<CFtype> &cs1, const DefaultCostStructure<CFtype> &cs2)
{
  if (cs1.is_weighted && cs2.is_weighted)
    return LessThanOrEqualTo(cs1.weighted, cs2.weighted);
  return LessThanOrEqualTo(cs1.total, cs2.total);
}

template <class CFtype, typename OtherType>
bool operator<=(OtherType c1, const DefaultCostStructure<CFtype> &cs2)
{
  if (cs2.is_weighted)
    return LessThanOrEqualTo((double)c1, cs2.weighted);
  return LessThanOrEqualTo(static_cast<CFtype>(c1), cs2.total);
}

template <class CFtype>
bool operator<=(double c1, const DefaultCostStructure<CFtype> &cs2)
{
  if (cs2.is_weighted)
    return LessThanOrEqualTo(c1, cs2.weighted);
  return LessThanOrEqualTo(c1, static_cast<double>(cs2.total));
}

template <class CFtype, typename OtherType>
bool operator<=(const DefaultCostStructure<CFtype> &cs1, OtherType c2)
{
  if (cs1.is_weighted)
    return LessThanOrEqualTo(cs1.weighted, (double)c2);
  return LessThanOrEqualTo(cs1.total, static_cast<CFtype>(c2));
}

template <class CFtype>
bool operator<=(const DefaultCostStructure<CFtype> &cs1, double c2)
{
  if (cs1.is_weighted)
    return LessThanOrEqualTo(cs1.weighted, c2);
  return LessThanOrEqualTo(static_cast<double>(cs1.total), c2);
}

template <class CFtype>
bool operator==(const DefaultCostStructure<CFtype> &cs1, const DefaultCostStructure<CFtype> &cs2)
{
  if (cs1.is_weighted && cs2.is_weighted)
    return EqualTo(cs1.weighted, cs2.weighted);
  return EqualTo(cs1.total, cs2.total);
}

template <class CFtype, typename OtherType>
bool operator==(OtherType c1, const DefaultCostStructure<CFtype> &cs2)
{
  if (cs2.is_weighted)
    return EqualTo((double)c1, cs2.weighted);
  return EqualTo(static_cast<CFtype>(c1), cs2.total);
}

template <class CFtype>
bool operator==(double c1, const DefaultCostStructure<CFtype> &cs2)
{
  if (cs2.is_weighted)
    return EqualTo(c1, cs2.weighted);
  return EqualTo(c1, static_cast<double>(cs2.total));
}

template <class CFtype, typename OtherType>
bool operator==(const DefaultCostStructure<CFtype> &cs1, OtherType c2)
{
  if (cs1.is_weighted)
    return EqualTo(cs1.weighted, (double)c2);
  return EqualTo(cs1.total, static_cast<CFtype>(c2));
}

template <class CFtype, typename OtherType>
bool operator==(const DefaultCostStructure<CFtype> &cs1, double c2)
{
  if (cs1.is_weighted)
    return EqualTo(cs1.weighted, c2);
  return EqualTo(static_cast<double>(cs1.total), c2);
}

template <class CFtype>
bool operator>=(const DefaultCostStructure<CFtype> &cs1, const DefaultCostStructure<CFtype> &cs2)
{
  return !(cs1 < cs2);
}

template <class CFtype, class OtherType>
bool operator>=(OtherType c1, const DefaultCostStructure<CFtype> &cs2)
{
  return !(c1 < cs2);
}

template <class CFtype, typename OtherType>
bool operator>=(const DefaultCostStructure<CFtype> &cs1, OtherType c2)
{
  return !(cs1 < c2);
}

template <class CFtype>
bool operator>(const DefaultCostStructure<CFtype> &cs1, const DefaultCostStructure<CFtype> &cs2)
{
  return !(cs1 <= cs2);
}

template <class CFtype, typename OtherType>
bool operator>(OtherType c1, const DefaultCostStructure<CFtype> &cs2)
{
  return !(c1 <= cs2);
}

template <class CFtype, typename OtherType>
bool operator>(const DefaultCostStructure<CFtype> &cs1, OtherType c2)
{
  return !(cs1 <= c2);
}

template <class CFtype>
bool operator!=(const DefaultCostStructure<CFtype> &cs1, const DefaultCostStructure<CFtype> &cs2)
{
  return !(cs1 == cs2);
}

template <class CFtype, typename OtherType>
bool operator!=(OtherType c1, const DefaultCostStructure<CFtype> &cs2)
{
  return !(c1 == cs2);
}

template <class CFtype, typename OtherType>
bool operator!=(const DefaultCostStructure<CFtype> &cs1, OtherType c2)
{
  return !(cs1 == c2);
}

template <typename CFtype>
std::ostream &operator<<(std::ostream &os, const DefaultCostStructure<CFtype> &cc)
{
  os << cc.total << " (viol: " << cc.violations << ", obj: " << cc.objective << ", comps: {";
  for (size_t i = 0; i < cc.all_components.size(); i++)
  {
    if (i > 0)
      os << ", ";
    os << cc.all_components[i];
  }
  os << "})";

  return os;
}

template <typename T>
struct HierarchicalCostStructure
{
  typedef T CFtype;

  HierarchicalCostStructure() : total(0), violations(0), objective(0), all_components(0), weighted(0.0), is_weighted(false) {}
  HierarchicalCostStructure(CFtype total, CFtype violations, CFtype objective, const std::vector<CFtype> &all_components) : total(total), violations(violations), objective(objective), all_components(all_components), weighted(total), is_weighted(false) {}
  HierarchicalCostStructure(CFtype total, double weighted, CFtype violations, CFtype objective, const std::vector<CFtype> &all_components) : total(total), violations(violations), objective(objective), all_components(all_components), weighted(weighted), is_weighted(true) {}

  CFtype total, violations, objective;
  std::vector<CFtype> all_components;
  double weighted;

  bool is_weighted;

  HierarchicalCostStructure &operator+=(const HierarchicalCostStructure &other)
  {
    this->total += other.total;
    this->violations += other.violations;
    this->objective += other.objective;
    if (this->all_components.size() < other.all_components.size())
      this->all_components.resize(other.all_components.size(), 0);
    for (size_t i = 0; i < other.all_components.size(); i++)
      this->all_components[i] += other.all_components[i];
    return *this;
  }

  HierarchicalCostStructure &operator-=(const HierarchicalCostStructure &other)
  {
    this->total -= other.total;
    this->violations -= other.violations;
    this->objective -= other.objective;
    if (this->all_components.size() < other.all_components.size())
      this->all_components.resize(other.all_components.size(), 0);
    for (size_t i = 0; i < other.all_components.size(); i++)
      this->all_components[i] -= other.all_components[i];
    return *this;
  }

  const CFtype &operator[](size_t i) const
  {
    return all_components[i];
  }

  size_t size() const
  {
    return all_components.size();
  }
};

template <typename CFtype>
HierarchicalCostStructure<CFtype> operator+(const HierarchicalCostStructure<CFtype> &cs1, const HierarchicalCostStructure<CFtype> &cs2)
{
  HierarchicalCostStructure<CFtype> res = cs1;
  res += cs2;
  return res;
}

template <typename CFtype>
HierarchicalCostStructure<CFtype> operator-(const HierarchicalCostStructure<CFtype> &cs1, const HierarchicalCostStructure<CFtype> &cs2)
{
  HierarchicalCostStructure<CFtype> res = cs1;
  res -= cs2;
  return res;
}

template <class CFtype>
bool operator<(const HierarchicalCostStructure<CFtype> &cs1, const HierarchicalCostStructure<CFtype> &cs2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs1.size(); i++)
    if (LessThan(cs1[i], cs2[i]))
      return true;
    else if (GreaterThan(cs1[i], cs2[i]))
      return false;
  return false;
}

template <class CFtype, typename OtherType>
bool operator<(OtherType c1, const HierarchicalCostStructure<CFtype> &cs2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs2.size(); i++)
    if (LessThan(static_cast<CFtype>(c1), cs2[i]))
      return true;
    else if (GreaterThan(static_cast<CFtype>(c1), cs2[i]))
      return false;
  return false;
}

template <class CFtype>
bool operator<(double c1, const HierarchicalCostStructure<CFtype> &cs2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs2.size(); i++)
    if (LessThan(c1, static_cast<double>(cs2[i])))
      return true;
    else if (GreaterThan(c1, static_cast<double>(cs2[i])))
      return false;
  return false;
}

template <class CFtype, typename OtherType>
bool operator<(const HierarchicalCostStructure<CFtype> &cs1, OtherType c2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs1.size(); i++)
    if (LessThan(cs1[i], static_cast<CFtype>(c2)))
      return true;
    else if (GreaterThan(cs1[i], static_cast<CFtype>(c2)))
      return false;
  return false;
}

template <class CFtype>
bool operator<(const HierarchicalCostStructure<CFtype> &cs1, double c2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs1.size(); i++)
    if (LessThan(static_cast<double>(cs1[i]), c2))
      return true;
    else if (GreaterThan(static_cast<double>(cs1[i]), c2))
      return false;
  return false;
}

template <class CFtype>
bool operator<=(const HierarchicalCostStructure<CFtype> &cs1, const HierarchicalCostStructure<CFtype> &cs2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs1.size(); i++)
    if (LessThan(cs1[i], cs2[i]))
      return true;
    else if (GreaterThan(cs1[i], cs2[i]))
      return false;
  return true;
}

template <class CFtype, typename OtherType>
bool operator<=(OtherType c1, const HierarchicalCostStructure<CFtype> &cs2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs2.size(); i++)
    if (LessThan(static_cast<CFtype>(c1), cs2[i]))
      return true;
    else if (GreaterThan(static_cast<CFtype>(c1), cs2[i]))
      return false;
  return true;
}

template <class CFtype>
bool operator<=(double c1, const HierarchicalCostStructure<CFtype> &cs2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs2.size(); i++)
    if (LessThan(c1, static_cast<double>(cs2[i])))
      return true;
    else if (GreaterThan(c1, static_cast<double>(cs2[i])))
      return false;
  return true;
}

template <class CFtype, typename OtherType>
bool operator<=(const HierarchicalCostStructure<CFtype> &cs1, OtherType c2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs1.size(); i++)
    if (LessThan(cs1[i], static_cast<CFtype>(c2)))
      return true;
    else if (GreaterThan(cs1[i], static_cast<CFtype>(c2)))
      return false;
  return true;
}

template <class CFtype>
bool operator<=(const HierarchicalCostStructure<CFtype> &cs1, double c2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs1.size(); i++)
    if (LessThan(static_cast<double>(cs1[i]), c2))
      return true;
    else if (GreaterThan(static_cast<double>(cs1[i]), c2))
      return false;
  return true;
}

template <class CFtype>
bool operator==(const HierarchicalCostStructure<CFtype> &cs1, const HierarchicalCostStructure<CFtype> &cs2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs1.size(); i++)
    if (!EqualTo(cs1[i], cs2[i]))
      return false;
  return true;
}

template <class CFtype, typename OtherType>
bool operator==(OtherType c1, const HierarchicalCostStructure<CFtype> &cs2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs2.size(); i++)
    if (!EqualTo(static_cast<CFtype>(c1), cs2[i]))
      return false;
  return true;
}

template <class CFtype>
bool operator==(double c1, const HierarchicalCostStructure<CFtype> &cs2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs2.size(); i++)
    if (!EqualTo(c1, static_cast<double>(cs2[i])))
      return false;
  return true;
}

template <class CFtype, typename OtherType>
bool operator==(const HierarchicalCostStructure<CFtype> &cs1, OtherType c2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs1.size(); i++)
    if (!EqualTo(cs1[i], static_cast<CFtype>(c2)))
      return false;
  return true;
}

template <class CFtype>
bool operator==(const HierarchicalCostStructure<CFtype> &cs1, double c2)
{
  // TODO: consider also the weighted case
  for (size_t i = 0; i < cs1.size(); i++)
    if (!EqualTo(static_cast<double>(cs1[i]), c2))
      return false;
  return true;
}

template <class CFtype>
bool operator>=(const HierarchicalCostStructure<CFtype> &cs1, const HierarchicalCostStructure<CFtype> &cs2)
{
  return !(cs1 < cs2);
}

template <class CFtype, class OtherType>
bool operator>=(OtherType c1, const HierarchicalCostStructure<CFtype> &cs2)
{
  return !(c1 < cs2);
}

template <class CFtype, typename OtherType>
bool operator>=(const HierarchicalCostStructure<CFtype> &cs1, OtherType c2)
{
  return !(cs1 < c2);
}

template <class CFtype>
bool operator>(const HierarchicalCostStructure<CFtype> &cs1, const HierarchicalCostStructure<CFtype> &cs2)
{
  return !(cs1 <= cs2);
}

template <class CFtype, typename OtherType>
bool operator>(OtherType c1, const HierarchicalCostStructure<CFtype> &cs2)
{
  return !(c1 <= cs2);
}

template <class CFtype, typename OtherType>
bool operator>(const HierarchicalCostStructure<CFtype> &cs1, OtherType c2)
{
  return !(cs1 <= c2);
}

template <class CFtype>
bool operator!=(const HierarchicalCostStructure<CFtype> &cs1, const HierarchicalCostStructure<CFtype> &cs2)
{
  return !(cs1 == cs2);
}

template <class CFtype, typename OtherType>
bool operator!=(OtherType c1, const HierarchicalCostStructure<CFtype> &cs2)
{
  return !(c1 == cs2);
}

template <class CFtype, typename OtherType>
bool operator!=(const HierarchicalCostStructure<CFtype> &cs1, OtherType c2)
{
  return !(cs1 == c2);
}

template <typename CFtype>
std::ostream &operator<<(std::ostream &os, const HierarchicalCostStructure<CFtype> &cc)
{
  os << cc.total << " (viol: " << cc.violations << ", obj: " << cc.objective << ", comps: {";
  for (size_t i = 0; i < cc.all_components.size(); i++)
  {
    if (i > 0)
      os << ", ";
    os << cc.all_components[i];
  }
  os << "})";

  return os;
}
} // namespace Core
} // namespace EasyLocal

A LocalSearch/easylocal-3/include/helpers/deltacostcomponent.hh => LocalSearch/easylocal-3/include/helpers/deltacostcomponent.hh +123 -0
@@ 0,0 1,123 @@
#pragma once

#include <stdexcept>

//#include "easylocal/helpers/coststructure.hh"
#include "helpers/costcomponent.hh"

namespace EasyLocal
{

namespace Core
{

/** A class for managing the variations of a single component of the cost function. Some of the methods are MustDef.
     @ingroup Helpers
     */
template <class Input, class State, class Move, typename CFtype = int>
class DeltaCostComponent 
{
public:
  /** Returns the (complete) CostComponent associated with the DeltaCostComponent object.
       @return the @ref CostComponent
       */
  const CostComponent<Input, State, CFtype> &GetCostComponent() const { return cc; }

  /** @copydoc Printable::Print() */
  virtual void Print(std::ostream &os = std::cout) const;

  /** @copydoc CostComponent::IsHard() */
  bool IsHard() const { return cc.IsHard(); }

  /** @copydoc CostComponent::IsSoft() */
  bool IsSoft() const { return cc.IsSoft(); }

  /** Returns the variation in the cost function induced by the move according to this cost component.
       @param st state to evaluate
       @param mv move to evaluate
       */
  virtual CFtype DeltaCost(const State &st, const Move &mv) const;

  /** Returns whether the delta function is implemented, or the complete cost component is used. */
  virtual bool IsDeltaImplemented() const { return true; }

  /** A symbolic name of the DeltaCostComponent. */
  const std::string name;

protected:
  /** Constructor.
       @brief Constructs a DeltaCostComponent providing an input object, the related CostComponent and a name
       @param in an Input object
       @param cc a related CostComponent
       @param name the name assigned to the object
       */
  DeltaCostComponent(const Input &in, CostComponent<Input, State, CFtype> &cc, std::string name);

  /** Computes the variation of the cost on a given @ref State due to a specific @ref Move.
       @param st the starting State upon which the variation of the cost has to be computed
       @param mv the Move which would be applied to the State st in order to compute the variation
       @return the cost variation by applying Move mv on State st
       */
  virtual CFtype ComputeDeltaCost(const State &st, const Move &mv) const = 0;

  /** The @ref Input object. */
  const Input &in;
  
  virtual ~DeltaCostComponent() {}

public:
  /** The @ref CostComponent associated with the DeltaCostComponent. */
  const CostComponent<Input, State, CFtype> &cc;
};

/** IMPLEMENTATION */

template <class Input, class State, class Move, class CFtype>
DeltaCostComponent<Input, State, Move, CFtype>::DeltaCostComponent(const Input &i, CostComponent<Input, State, CFtype> &e_cc, std::string name)
    : name(name), in(i), cc(e_cc)
{
}

template <class Input, class State, class Move, class CFtype>
void DeltaCostComponent<Input, State, Move, CFtype>::Print(std::ostream &os) const
{
  os << "  DeltaCost Component: " + this->name << std::endl;
}

template <class Input, class State, class Move, class CFtype>
CFtype DeltaCostComponent<Input, State, Move, CFtype>::DeltaCost(const State &st,
                                                                 const Move &mv) const
{
  return this->cc.Weight() * ComputeDeltaCost(st, mv);
}

template <class Input, class State, class Move, class CostStructure>
class NeighborhoodExplorer;

/** An adapter class for using a (full) @ref CostComponent in place of a @ref DeltaCostComponent. It is used by the @ref NeighborhoodExplorer to wrap the unimplemented deltas.
     @ingroup Helpers
     */
template <class Input, class State, class Move, class CostStructure>
class DeltaCostComponentAdapter : public DeltaCostComponent<Input, State, Move, typename CostStructure::CFtype>
{
public:
  typedef typename CostStructure::CFtype CFtype;

  /** Constructor. */
  DeltaCostComponentAdapter(const Input &in, CostComponent<Input, State, CFtype> &cc, const NeighborhoodExplorer<Input, State, Move, CostStructure> &ne) : DeltaCostComponent<Input, State, Move, CFtype>(in, cc, "DeltaAdapter" + cc.name), ne(ne) {}

  /** @copydoc DeltaCostComponent::IsDeltaImplemented() */
  virtual bool IsDeltaImplemented() const { return false; }

protected:
  /** @copydoc DeltaCostComponent::ComputeDeltaCost() */
  virtual CFtype ComputeDeltaCost(const State &st, const Move &mv) const
  {
    State new_st = st;
    ne.MakeMove(new_st, mv);
    return this->cc.ComputeCost(new_st) - this->cc.ComputeCost(st);
  }
  const NeighborhoodExplorer<Input, State, Move, CostStructure> &ne;
};
} // namespace Core
} // namespace EasyLocal

A LocalSearch/easylocal-3/include/helpers/kicker.hh => LocalSearch/easylocal-3/include/helpers/kicker.hh +564 -0
@@ 0,0 1,564 @@
#pragma once

#include "helpers/neighborhoodexplorer.hh"

namespace EasyLocal
{
namespace Core
{
template <class State, class Move, class CostStructure = DefaultCostStructure<int>>
struct Kick : public std::vector<std::pair<EvaluatedMove<Move, CostStructure>, State>>
{
public:
  static Kick empty;
};

template <class State, class Move, class CostStructure>
Kick<State, Move, CostStructure> Kick<State, Move, CostStructure>::empty;

template <class State, class Move, class CostStructure>
std::ostream &operator<<(std::ostream &os, const Kick<State, Move, CostStructure> &k)
{
  os << "{";
  for (size_t i = 0; i < k.size(); i++)
  {
    if (i > 0)
      os << ", ";
    os << k[i].first.move;
  }
  os << "}";
  return os;
}

template <class Input, class State, class Move, class CostStructure = DefaultCostStructure<int>>
class Kicker;

template <class Input, class State, class Move, class CostStructure>
class FullKickerIterator : public std::iterator<std::input_iterator_tag, Kick<State, Move, CostStructure>>
{
  friend class Kicker<Input, State, Move, CostStructure>;

public:
  typedef typename Kicker<Input, State, Move, CostStructure>::MoveRelatedness MoveRelatedness;

  FullKickerIterator operator++(int) // postfix
  {
    FullKickerIterator pi = *this;
    if (end)
      throw std::logic_error("Attempting to go after last kick");
    end = !NextKick();
    kick_count++;
    return pi;
  }
  FullKickerIterator &operator++() // prefix
  {
    if (end)
      throw std::logic_error("Attempting to go after last kick");
    end = !NextKick();
    kick_count++;
    return *this;
  }
  const Kick<State, Move, CostStructure> &operator*() const
  {
    return kick;
  }
  Kick<State, Move, CostStructure> &operator*()
  {
    return kick;
  }
  const Kick<State, Move, CostStructure> *operator->() const
  {
    return &kick;
  }
  Kick<State, Move, CostStructure> *operator->()
  {
    return &kick;
  }
  bool operator==(const FullKickerIterator<Input, State, Move, CostStructure> &it2) const
  {
    if (end && it2.end)
      return true;
    return (end == it2.end && length == it2.length && kick_count == it2.kick_count && &start_state == &it2.start_state);
  }
  bool operator!=(const FullKickerIterator<Input, State, Move, CostStructure> &it2)
  {
    if (end && it2.end)
      return false;
    return (end != it2.end || length != it2.length || kick_count != it2.kick_count || &start_state != &it2.start_state);
  }

protected:
  void FirstKick()
  {
    kick.assign(length, std::make_pair(EvaluatedMove<Move, CostStructure>(false), start_state));

    int cur = 0;
    bool backtracking = false;

    // stop only when a complete kicker has been generated, or throw an @ref EmptyNeighborhood
  loop:
    while (cur < (int)length)
    {
      if (cur == -1)
        throw EmptyNeighborhood();

      // reset state before generating each move
      kick[cur].second = cur > 0 ? kick[cur - 1].second : start_state;

      if (!backtracking)
      {
        try
        {
          ne.FirstMove(kick[cur].second, kick[cur].first.move);
          while (cur > 0 && !RelatedMoves(kick[cur - 1].first.move, kick[cur].first.move))
          {
            if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
            {
              backtracking = true;
              cur--;
              goto loop;
            }
          }
          backtracking = false;
          ne.MakeMove(kick[cur].second, kick[cur].first.move);
          cur++;
          goto loop;
        }
        catch (EmptyNeighborhood e)
        {
          backtracking = true;
          cur--;
          goto loop;
        }
      }
      else // backtracking (we only need to generate NextMoves)
      {
        do
        {
          if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
          {
            backtracking = true;
            cur--;
            goto loop;
          }
        } while (cur > 0 && !RelatedMoves(kick[cur - 1].first.move, kick[cur].first.move));
        backtracking = false;
        ne.MakeMove(kick[cur].second, kick[cur].first.move);
        cur++;
        goto loop;
      }
    }
  }

  bool NextKick()
  {
    // go to last move, then start generating with backtracking
    int cur = length - 1;
    bool backtracking = true;

    // stop only when a complete kicker has been generated, or throw an @ref EmptyNeighborhood
  loop:
    while (cur < (int)length)
    {
      if (cur == -1)
        return false;

      // reset state before generating each move
      kick[cur].second = cur > 0 ? kick[cur - 1].second : start_state;

      if (!backtracking)
      {
        try
        {
          ne.FirstMove(kick[cur].second, kick[cur].first.move);
          while (cur > 0 && !RelatedMoves(kick[cur - 1].first.move, kick[cur].first.move))
          {
            if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
            {
              backtracking = true;
              kick[cur].first.is_valid = false;
              cur--;
              goto loop;
            }
          }
          backtracking = false;
          ne.MakeMove(kick[cur].second, kick[cur].first.move);
          kick[cur].first.is_valid = false;
          cur++;
          goto loop;
        }
        catch (EmptyNeighborhood e)
        {
          backtracking = true;
          cur--;
          goto loop;
        }
      }
      else // backtracking (we only need to generate NextMoves)
      {
        do
        {
          if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
          {
            backtracking = true;
            kick[cur].first.is_valid = false;
            cur--;
            goto loop;
          }
        } while (cur > 0 && !RelatedMoves(kick[cur - 1].first.move, kick[cur].first.move));
        backtracking = false;
        ne.MakeMove(kick[cur].second, kick[cur].first.move);
        kick[cur].first.is_valid = false;
        cur++;
        goto loop;
      }
    }
    return true;
  }

protected:
  FullKickerIterator(size_t length, const NeighborhoodExplorer<Input, State, Move, CostStructure> &ne, const State &state, const MoveRelatedness &RelatedMoves, bool end = false)
      : length(length), ne(ne), start_state(state), kick_count(0), end(end), RelatedMoves(RelatedMoves)
  {
    if (end)
      return;
    try
    {
      FirstKick();
    }
    catch (EmptyNeighborhood)
    {
      end = true;
    }
  }
  const size_t length;
  const NeighborhoodExplorer<Input, State, Move, CostStructure> &ne;
  const State &start_state;
  Kick<State, Move, CostStructure> kick;
  size_t kick_count;
  bool end;
  const MoveRelatedness &RelatedMoves;
};

template <class Input, class State, class Move, class CostStructure>
class SampleKickerIterator : public std::iterator<std::input_iterator_tag, Kick<State, Move, CostStructure>>
{
  friend class Kicker<Input, State, Move, CostStructure>;

public:
  typedef typename Kicker<Input, State, Move, CostStructure>::MoveRelatedness MoveRelatedness;

  SampleKickerIterator operator++(int) // postfix
  {
    SampleKickerIterator pi = *this;
    if (end)
      throw std::logic_error("Attempting to go after last kick");
    kick_count++;
    end = kick_count >= samples;
    if (!end)
    {
      RandomKick();
    }
    return pi;
  }
  SampleKickerIterator &operator++() // prefix
  {
    if (end)
      throw std::logic_error("Attempting to go after last kick");
    kick_count++;
    end = kick_count >= samples;
    if (!end)
    {
      RandomKick();
    }
    return *this;
  }
  const Kick<State, Move, CostStructure> &operator*() const
  {
    return kick;
  }
  Kick<State, Move, CostStructure> &operator*()
  {
    return kick;
  }
  const Kick<State, Move, CostStructure> *operator->() const
  {
    return &kick;
  }
  Kick<State, Move, CostStructure> *operator->()
  {
    return &kick;
  }
  bool operator==(const SampleKickerIterator<Input, State, Move, CostStructure> &it2) const
  {
    if (end && it2.end)
      return true;
    return (end == it2.end && length == it2.length && kick_count == it2.kick_count && &start_state == &it2.start_state);
  }
  bool operator!=(const SampleKickerIterator<Input, State, Move, CostStructure> &it2)
  {
    if (end && it2.end)
      return false;
    return (end != it2.end || length != it2.length || kick_count != it2.kick_count || &start_state != &it2.start_state);
  }

protected:
  void RandomKick()
  {
    kick.assign(length, std::make_pair(EvaluatedMove<Move, CostStructure>(false), start_state));
    std::vector<Move> initial_kick_moves(length, Move());
    std::vector<bool> initial_set(length, false);

    int cur = 0;
    bool backtracking = false;

    // stop only when a complete kicker has been generated, or throw an @ref EmptyNeighborhood
  loop:
    while (cur < (int)length)
    {
      if (cur == -1)
        throw EmptyNeighborhood();

      // reset state before generating each move
      kick[cur].second = cur > 0 ? kick[cur - 1].second : start_state;

      if (!backtracking)
      {
        try
        {
          ne.RandomMove(kick[cur].second, kick[cur].first.move);
          kick[cur].first.is_valid = false;

          if (!initial_set[cur])
          {
            initial_kick_moves[cur] = kick[cur].first.move;
            initial_set[cur] = true;
          }

          while (cur > 0 && !RelatedMoves(kick[cur - 1].first.move, kick[cur].first.move))
          {
            if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
              ne.FirstMove(kick[cur].second, kick[cur].first.move);
            if (kick[cur].first.move == initial_kick_moves[cur])
            {
              backtracking = true;
              cur--;
              goto loop;
            }
          }
          backtracking = false;
          ne.MakeMove(kick[cur].second, kick[cur].first.move);
          cur++;
          goto loop;
        }
        catch (EmptyNeighborhood e)
        {
          backtracking = true;
          cur--;
          goto loop;
        }
      }
      else // backtracking (we only need to generate moves following the first)
      {
        do
        {
          if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
            ne.FirstMove(kick[cur].second, kick[cur].first.move);
          if (kick[cur].first.move == initial_kick_moves[cur])
          {
            backtracking = true;
            cur--;
            goto loop;
          }
        } while (cur > 0 && !RelatedMoves(kick[cur - 1].first.move, kick[cur].first.move));
        backtracking = false;
        ne.MakeMove(kick[cur].second, kick[cur].first.move);
        kick[cur].first.is_valid = false;
        cur++;
        goto loop;
      }
    }
  }

  SampleKickerIterator(size_t length, const NeighborhoodExplorer<Input, State, Move, CostStructure> &ne, const State &state, size_t samples, const MoveRelatedness &RelatedMoves, bool end = false)
      : length(length), ne(ne), start_state(state), kick_count(0), samples(samples), end(end), RelatedMoves(RelatedMoves)
  {
    if (end)
      return;
    try
    {
      RandomKick();
    }
    catch (EmptyNeighborhood)
    {
      end = true;
    }
  }
  const size_t length;
  const NeighborhoodExplorer<Input, State, Move, CostStructure> &ne;
  const State &start_state;
  Kick<State, Move, CostStructure> kick;
  size_t kick_count, samples;
  bool end;
  const MoveRelatedness &RelatedMoves;
};

/** A kicker is a special kind of neighborhood explorer, which can generate sequences of moves of arbitrary length. It is used to provide diversification or intensification strategies.
     */
template <class Input, class State, class Move, class CostStructure>
class Kicker
{
public:
  typedef Move MoveType;
  typedef typename CostStructure::CFtype CFtype;
  typedef CostStructure CostStructureType;

  typedef typename std::function<bool(const Move &m1, const Move &m2)> MoveRelatedness;

  /** Constructor.
       @param ne the @ref NeighborhoodExplorer used to generate the @ref Move
       */
  Kicker(StateManager<Input, State, CostStructure>& sm, NeighborhoodExplorer<Input, State, Move, CostStructure> &ne, const MoveRelatedness &RelatedMoves = AllMovesRelated) : sm(sm), ne(ne), RelatedMoves(RelatedMoves) {}

  /** The modality of the @ref Move (warning: not the length of the @ref Move sequences) */
  virtual size_t Modality() const
  {
    return ne.Modality();
  }

  /** Virtual destructor. */
  virtual ~Kicker() {}

  /** Generates the first improving kick.
       @param st current @ref State
       @param kick the sequence of @ref Move to generate
       @param length length of the kick
       @throws @ref EmptyNeighborhood if no kick can be found
       @return the cost of applying the kick to the @ref State
       */
  virtual std::pair<Kick<State, Move, CostStructure>, CostStructure> SelectFirst(size_t length, const State &st) const
  {
    for (FullKickerIterator<Input, State, Move, CostStructure> it = begin(length, st); it != end(length, st); ++it)
    {
      CostStructure cost(0, 0, 0, std::vector<CFtype>(sm.CostComponents(), 0));
      for (int i = 0; i < it->size(); i++)
      {
        if (!(*it)[i].first.is_valid)
        {
          (*it)[i].first.cost = this->ne.DeltaCostFunctionComponents((*it)[i].second, (*it)[i].first.move);
          (*it)[i].first.is_valid = true;
        }
        cost += (*it)[i].first.cost;
      }
      if (cost < 0)
        return std::make_pair(*it, cost);
    }
    return std::make_pair(Kick<State, Move, CostStructure>::empty, CostStructure(std::numeric_limits<CFtype>::infinity(), std::numeric_limits<CFtype>::infinity(), std::numeric_limits<CFtype>::infinity(), std::vector<CFtype>(sm.CostComponents(), std::numeric_limits<CFtype>::infinity())));
  }

  /** Generates the best kick.
       @param st current @ref State
       @param kick the sequence of @ref Move to generate
       @param length length of the kick
       @throws @ref EmptyNeighborhood if no kick can be found
       @return the cost of applying the kick to the @ref State
       */
  virtual std::pair<Kick<State, Move, CostStructure>, CostStructure> SelectBest(size_t length, const State &st) const
  {
    Kick<State, Move, CostStructure> best_kick;
    CostStructure best_cost;
    unsigned int number_of_bests = 0;
    for (FullKickerIterator<Input, State, Move, CostStructure> it = begin(length, st); it != end(length, st); ++it)
    {
      CostStructure cost(0, 0, 0, std::vector<CFtype>(sm.CostComponents(), 0));
      for (int i = 0; i < it->size(); i++)
      {
        if (!(*it)[i].first.is_valid)
        {
          (*it)[i].first.cost = ne.DeltaCostFunctionComponents((*it)[i].second, (*it)[i].first.move);
          (*it)[i].first.is_valid = true;
        }
        cost += (*it)[i].first.cost;
      }
      if (number_of_bests == 0)
      {
        best_kick = *it;
        best_cost = cost;
        number_of_bests = 1;
      }
      else if (cost < best_cost)
      {
        best_kick = *it;
        best_cost = cost;
        number_of_bests = 1;
      }
      else if (cost == best_cost)
      {
        if (Random::Uniform<unsigned int>(0, number_of_bests) == 0) // accept the move with probability 1 / (1 + number_of_bests)
          best_kick = *it;
        number_of_bests++;
      }
    }
    return std::make_pair(best_kick, best_cost);
  }

  virtual std::pair<Kick<State, Move, CostStructure>, CostStructure> SelectRandom(size_t length, const State &st) const
  {
    SampleKickerIterator<Input, State, Move, CostStructure> random_it = sample_begin(length, st, 1);
    CostStructure cost(0, 0, 0, std::vector<CFtype>(sm.CostComponents(), 0));
    for (int i = 0; i < random_it->size(); i++)
    {
      if (!(*random_it)[i].first.is_valid)
      {
        (*random_it)[i].first.cost = ne.DeltaCostFunctionComponents((*random_it)[i].second, (*random_it)[i].first.move);
        (*random_it)[i].first.is_valid = true;
      }
      cost += (*random_it)[i].first.cost;
    }
    return std::make_pair(*random_it, cost);
  }

  /** Executes a kick on a state.
       @param st the @ref State to modify
       @param kick the sequence of @ref Move to apply
       */
  virtual void MakeKick(State &st, const Kick<State, Move, CostStructure> &kick) const
  {
    st = kick[kick.size() - 1].second;
  }

  FullKickerIterator<Input, State, Move, CostStructure> begin(size_t length, const State &st) const
  {
    return FullKickerIterator<Input, State, Move, CostStructure>(length, ne, st, RelatedMoves);
  }

  FullKickerIterator<Input, State, Move, CostStructure> end(size_t length, const State &st) const
  {
    return FullKickerIterator<Input, State, Move, CostStructure>(length, ne, st, RelatedMoves, true);
  }

  SampleKickerIterator<Input, State, Move, CostStructure> sample_begin(size_t length, const State &st, size_t samples) const
  {
    return SampleKickerIterator<Input, State, Move, CostStructure>(length, ne, st, samples, RelatedMoves);
  }

  SampleKickerIterator<Input, State, Move, CostStructure> sample_end(size_t length, const State &st, size_t samples) const
  {
    return SampleKickerIterator<Input, State, Move, CostStructure>(length, ne, st, samples, RelatedMoves, true);
  }

protected:
  StateManager<Input, State, CostStructure> &sm;
  /** The @ref NeighborhoodExplorer used */
  NeighborhoodExplorer<Input, State, Move, CostStructure> &ne;

  /** The functor for checking for move relatedness */
  const MoveRelatedness &RelatedMoves;

  static MoveRelatedness AllMovesRelated;
};

template <class Input, class State, class Move, class CostStructure>
typename Kicker<Input, State, Move, CostStructure>::MoveRelatedness Kicker<Input, State, Move, CostStructure>::AllMovesRelated = [](const Move &, const Move &) { return true; };
} // namespace Core
} // namespace EasyLocal

A LocalSearch/easylocal-3/include/helpers/multimodalneighborhoodexplorer.hh => LocalSearch/easylocal-3/include/helpers/multimodalneighborhoodexplorer.hh +1014 -0
@@ 0,0 1,1014 @@
#pragma once

#include "helpers/neighborhoodexplorer.hh"
#include <functional>
#include "utils/FastFunc.hh"
#include "utils/tuple.hh"

#include <boost/any.hpp>
#include <typeindex>
#include <unordered_map>
#include <functional>

namespace EasyLocal
{
  
  namespace Core
  {
    
    /** Template class to incapsulate a boolean flag that marks a @ref Move active or inactive in the context of a @ref MultimodalNeighborhoodExplorer. */
    template <class Move>
    class ActiveMove : public Move
    {
    public:
      bool active;
      
      /** Get the raw @ref Move inside this object. */
      Move &RawMove()
      {
        return *this;
      }
    };
    
    /** Input operator for @ref ActiveMove, just forwards to input operator for @ref Move.
     @param is input stream, by default @c std::cin
     @param m @ref Move to read
     */
    template <typename Move>
    std::istream &operator>>(std::istream &is, ActiveMove<Move> &m)
    {
      is >> static_cast<Move &>(m);
      return is;
    }
    
    /** Output operator for @ref ActiveMove, just forwards to output operator for @ref Move.
     @param os output stream, by default @c std::cout
     @param m @ref Move to print
     */
    template <typename Move>
    std::ostream &operator<<(std::ostream &os, const ActiveMove<Move> &m)
    {
      if (m.active)
        os << static_cast<const Move &>(m);
      return os;
    }
    
    /** Equality operator for @ref ActiveMove, forwards to equality operator for @ref Move and checks for same @c active flag.
     @param mv1 first @ref Move
     @param mv2 second @ref Move
     @return true if the two raw @ref Move are the same and the @active flag is the equal
     */
    template <class Move>
    bool operator==(const ActiveMove<Move> &mv1, const ActiveMove<Move> &mv2)
    {
      if (!mv1.active && !mv2.active)
        return true;
      else if (mv1.active != mv2.active)
        return false;
      else
        return static_cast<Move>(mv1) == static_cast<Move>(mv2);
    }
    
    /** Ordering operator for @ActiveMove, forwards to ordering operator for @ref Move and checks for same @c active flag.
     @param mv1 first @ref Move
     @param mv2 second @ref Move
     @return true if the first @ref Move comes first than the second @ref Move or the first @c active flag is "smaller" than the second
     */
    template <class Move>
    bool operator<(const ActiveMove<Move> &mv1, const ActiveMove<Move> &mv2)
    {
      if (!mv1.active && !mv2.active)
        return false;
      else if (mv1.active < mv2.active)
        return true;
      else if (mv1.active > mv2.active)
        return false;
      else
        return static_cast<Move>(mv1) < static_cast<Move>(mv2);
    }
    
    /* This namespace will hide impelementation components */
    namespace Impl
    {
      
      /** Creates a callable fast-function with a given signature */
#ifndef MSVC
      template <typename T, typename return_type, typename... params>
      FastFunc<return_type(params...)>
      makeFastFunc(T *obj, return_type (T::*f)(params...) const)
      {
        return FastFunc<return_type(params...)>(obj, f);
      }
#else
      template <typename T, typename return_type, typename... params>
      std::function<return_type(params...)>
      makeFunction2(T *obj, return_type (T::*f)(params...) const)
      {
        auto mf = std::mem_fn<return_type(params...) const>(f);
        return std::bind(mf, obj, std::placeholders::_1, std::placeholders::_2);
      }
      template <typename T, typename return_type, typename... params>
      std::function<return_type(params...)>
      makeFunction3(T *obj, return_type (T::*f)(params...) const)
      {
        auto mf = std::mem_fn<return_type(params...) const>(f);
        return std::bind(mf, obj, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
      }
#endif
      
      /** Helper class for dispatching tuples and applying functions to tuple elements. General recursion case.
       * This version will handle procedures (i.e., functions returning void). */
      template <class State, class FuncsTuple, class MovesTuple, size_t N>
      struct VTupleDispatcher
      {
        static void execute_at(long level, const State &st, const FuncsTuple &funcs, MovesTuple &moves)
        {
          if (level == 0)
          {
            const auto &f = std::get<0>(funcs);
            auto &this_move = std::get<0>(moves).get();
            f(st, this_move);
          }
          else
          {
            auto moves_tail = tuple_tail(moves);
            const auto funcs_tail = tuple_tail(funcs);
            VTupleDispatcher<State, decltype(funcs_tail), decltype(moves_tail), N - 1>::execute_at(--level, st, funcs_tail, moves_tail);
          }
        }
        static void execute_at(long level, State &st, const FuncsTuple &funcs, const MovesTuple &moves)
        {
          if (level == 0)
          {
            const auto &f = std::get<0>(funcs);
            const auto &this_move = std::get<0>(moves).get();
            f(st, this_move);
          }
          else
          {
            const auto moves_tail = tuple_tail(moves);
            const auto funcs_tail = tuple_tail(funcs);
            VTupleDispatcher<State, decltype(funcs_tail), decltype(moves_tail), N - 1>::execute_at(--level, st, funcs_tail, moves_tail);
          }
        }
      };
      
      /** Helper class for dispatching tuples and applying functions to tuple elements. Base recursion case.
       * This version will handle procedures (i.e., functions returning void). */
      template <class State, class FuncsTuple, class MovesTuple>
      struct VTupleDispatcher<State, FuncsTuple, MovesTuple, 0>
      {
        static void execute_at(long level, const State &st, const FuncsTuple &funcs, MovesTuple &moves)
        {
          if (level == 0)
          {
            const auto &f = std::get<0>(funcs);
            auto &this_move = std::get<0>(moves).get();
            f(st, this_move);
          }
          else
            throw std::logic_error("End of tuple recursion");
        }
        static void execute_at(long level, State &st, const FuncsTuple &funcs, const MovesTuple &moves)
        {
          if (level == 0)
          {
            const auto &f = std::get<0>(funcs);
            const auto this_move = std::get<0>(moves);
            f(st, this_move);
          }
          else
            throw std::logic_error("End of tuple recursion");
        }
      };
      
      /** Helper class for dispatching tuples and applying functions to tuple elements. General recursion case.
       * This version will handle functions. */
      template <class ReturnType, class State, class FuncsTuple, class MovesTuple, size_t N>
      struct TupleDispatcher
      {
        static ReturnType execute_at(long level, const State &st, const FuncsTuple &funcs, MovesTuple &moves)
        {
          if (level == 0)
          {
            const auto &f = std::get<0>(funcs);
            auto &this_move = std::get<0>(moves).get();
            return f(st, this_move);
          }
          else
          {
            auto moves_tail = tuple_tail(moves);
            const auto funcs_tail = tuple_tail(funcs);
            return TupleDispatcher<ReturnType, State, decltype(funcs_tail), decltype(moves_tail), N - 1>::execute_at(--level, st, funcs_tail, moves_tail);
          }
        }
        static ReturnType execute_at(long level, const State &st, const FuncsTuple &funcs, const MovesTuple &moves, const std::vector<double> &weights)
        {
          if (level == 0)
          {
            const auto &f = std::get<0>(funcs);
            const auto &this_move = std::get<0>(moves).get();
            return f(st, this_move, weights);
          }
          else
          {
            const auto moves_tail = tuple_tail(moves);
            const auto funcs_tail = tuple_tail(funcs);
            return TupleDispatcher<ReturnType, State, decltype(funcs_tail), decltype(moves_tail), N - 1>::execute_at(--level, st, funcs_tail, moves_tail, weights);
          }
        }
        static ReturnType execute_at(long level, const State &st, const FuncsTuple &funcs)
        {
          if (level == 0)
          {
            const auto &f = std::get<0>(funcs);
            return f(st);
          }
          else
          {
            MovesTuple mt;
            const auto moves_tail = tuple_tail(mt);
            const auto funcs_tail = tuple_tail(funcs);
            return TupleDispatcher<ReturnType, State, decltype(funcs_tail), decltype(moves_tail), N - 1>::execute_at(--level, st, funcs_tail);
          }
        }
      };
      /** Helper class for dispatching tuples and applying functions to tuple elements. Base recursion case.
       * This version will handle functions. */
      template <class ReturnType, class State, class FuncsTuple, class MovesTuple>
      struct TupleDispatcher<ReturnType, State, FuncsTuple, MovesTuple, 0>
      {
        static ReturnType execute_at(long level, const State &st, const FuncsTuple &funcs, MovesTuple &moves)
        {
          if (level == 0)
          {
            const auto &f = std::get<0>(funcs);
            auto &this_move = std::get<0>(moves).get();
            return f(st, this_move);
          }
          else
            throw std::logic_error("End of tuple recursion");
        }
        static ReturnType execute_at(long level, const State &st, const FuncsTuple &funcs, const MovesTuple &moves, const std::vector<double> &weights)
        {
          if (level == 0)
          {
            const auto &f = std::get<0>(funcs);
            const auto &this_move = std::get<0>(moves).get();
            return f(st, this_move, weights);
          }
          else
            throw std::logic_error("End of tuple recursion");
        }
        static ReturnType execute_at(long level, const State &st, const FuncsTuple &funcs)
        {
          if (level == 0)
          {
            const auto &f = std::get<0>(funcs);
            return f(st);
          }
          else
            throw std::logic_error("End of tuple recursion");
        }
      };
      
      /** Helper class for dispatching move tuples. General recursion case.
       * This version will handle functions. */
      template <class MovesTuple, size_t N>
      struct MoveDispatcher
      {
        static void set_all_activity(MovesTuple &moves, bool value)
        {
          auto &this_move = std::get<0>(moves).get();
          this_move.active = value;
          auto moves_tail = tuple_tail(moves);
          MoveDispatcher<decltype(moves_tail), N - 1>::set_all_activity(moves_tail, value);
        }
        static void set_activity_at(long level, MovesTuple &moves, bool value)
        {
          if (level == 0)
          {
            auto &this_move = std::get<0>(moves).get();
            this_move.active = value;
          }
          else
          {
            auto moves_tail = tuple_tail(moves);
            MoveDispatcher<decltype(moves_tail), N - 1>::set_activity_at(--level, moves_tail, value);
          }
        }
        static void copy_move_at(long level, MovesTuple &target, const MovesTuple &source)
        {
          if (level == 0)
          {
            auto &this_target = std::get<0>(target).get();
            const auto &this_source = std::get<0>(target).get();
            this_target = this_source;
          }
          else
          {
            auto target_tail = tuple_tail(target);
            auto source_tail = tuple_tail(source);
            MoveDispatcher<decltype(target_tail), N - 1>::copy_move_at(--level, target_tail, source_tail);
          }
        }
        static bool equal_at(long level, MovesTuple moves_1, MovesTuple moves_2)
        {
          if (level == 0)
          {
            const auto &this_move_1 = std::get<0>(moves_1).get();
            const auto &this_move_2 = std::get<0>(moves_2).get();
            return this_move_1 == this_move_2;
          }
          else
          {
            auto moves_1_tail = tuple_tail(moves_1);
            auto moves_2_tail = tuple_tail(moves_2);
            return MoveDispatcher<decltype(moves_1_tail), N - 1>::equal_at(--level, moves_1_tail, moves_2_tail);
          }
        }
        static bool are_related(long level, const MovesTuple &moves, const std::unordered_map<std::type_index, boost::any> &related_funcs)
        {
          if (level == 0)
          {
            const auto &this_move = std::get<0>(moves).get();
            const auto &next_move = std::get<1>(moves).get();
            auto it = related_funcs.find(std::type_index(typeid(std::function<bool(const decltype(this_move) &, const decltype(next_move) &)>)));
            if (it == related_funcs.end())
              return true;
            else
              return boost::any_cast<std::function<bool(const decltype(this_move) &, const decltype(next_move) &)>>(it->second)(this_move, next_move);
          }
          else
          {
            auto moves_tail = tuple_tail(moves);
            return MoveDispatcher<decltype(moves_tail), N - 1>::are_related(--level, moves_tail, related_funcs);
          }
        }
        static size_t get_first_active(const MovesTuple &moves, long level)
        {
          const auto &this_move = std::get<0>(moves).get();
          if (this_move.active)
            return level;
          else
          {
            auto moves_tail = tuple_tail(moves);
            return MoveDispatcher<decltype(moves_tail), N - 1>::get_first_active(moves_tail, ++level);
          }
        }
      };
      
      /** Helper class for dispatching move tuples. Base recursion case.
       * This version will handle functions. */
      template <class MovesTuple>
      struct MoveDispatcher<MovesTuple, 0>
      {
        static void set_all_activity(MovesTuple &moves, bool value)
        {
          auto &this_move = std::get<0>(moves).get();
          this_move.active = value;
        }
        static void set_activity_at(long level, MovesTuple &moves, bool value)
        {
          if (level == 0)
          {
            auto &this_move = std::get<0>(moves).get();
            this_move.active = value;
          }
          else
            throw std::logic_error("End of tuple recursion");
        }
        static void copy_move_at(long level, MovesTuple &target, const MovesTuple &source)
        {
          if (level == 0)
          {
            auto &this_target = std::get<0>(target).get();
            const auto &this_source = std::get<0>(target).get();
            this_target = this_source;
          }
          else
            throw std::logic_error("End of tuple recursion");
        }
        static bool equal_at(long level, MovesTuple moves_1, MovesTuple moves_2)
        {
          if (level == 0)
          {
            const auto &this_move_1 = std::get<0>(moves_1).get();
            const auto &this_move_2 = std::get<0>(moves_2).get();
            return this_move_1 == this_move_2;
          }
          else
            throw std::logic_error("End of tuple recursion");
        }
        static bool are_related(long level, const MovesTuple &moves, const std::unordered_map<std::type_index, boost::any> &related_funcs)
        {
          throw std::logic_error("End of tuple recursion");
        }
        static size_t get_first_active(const MovesTuple &moves, long level)
        {
          const auto &this_move = std::get<0>(moves).get();
          if (this_move.active)
            return level;
          else
            throw std::logic_error("End of tuple recursion");
        }
      };
    } // namespace Impl
    
    /** Given a set of base neighborhood explorers, this class will create a multimodal (i.e., compound) neighborhood explorer
     that explores the set union of all neighborhoods.
     @brief The SetUnion MultimodalNeighborhoodExplorer manages the set union of different neighborhoods.
     @tparam Input the class representing the problem input
     @tparam State the class representing the problem's state
     @tparam CFtype the type of the cost function
     @tparam BaseNeighborhoodExplorers a sequence of base neighborhood explorer classes
     @ingroup Helpers
     */
    template <class Input, class State, class CostStructure, class... BaseNeighborhoodExplorers>
    class SetUnionNeighborhoodExplorer : public NeighborhoodExplorer<Input, State, std::tuple<ActiveMove<typename BaseNeighborhoodExplorers::MoveType>...>, CostStructure>
    {
    protected:
      /** Tuple type representing the combination of @c BaseNeighborhoodExplorers' @ref Move. */
      typedef std::tuple<ActiveMove<typename BaseNeighborhoodExplorers::MoveType>...> MoveTypes;
      
      /** Tuple type representing references to @c BaseNeighborhoodExplorers' @ref Move (because we need to set them). */
      typedef std::tuple<std::reference_wrapper<ActiveMove<typename BaseNeighborhoodExplorers::MoveType>>...> MoveTypeRefs;
      
      /** Tuple type representing const references to @c BaseNeighborhoodExplorers' @ref Move. */
      typedef std::tuple<std::reference_wrapper<const ActiveMove<typename BaseNeighborhoodExplorers::MoveType>>...> MoveTypeCRefs;
      
      /** Tuple type representing references to @c BaseNeighborhoodExplorers. */
      typedef std::tuple<std::reference_wrapper<BaseNeighborhoodExplorers>...> NeighborhoodExplorerTypes;
      
      /** Modality of the NeighborhoodExplorer, i.e., the number of @ref NeighborhoodExplorer composing this one.  */
      virtual size_t Modality() const { return sizeof...(BaseNeighborhoodExplorers); }
      
    public:
      /** Constructor, takes a variable number of base NeighborhoodExplorers.
       @param in a pointer to an input object.
       @param sm a pointer to a compatible state manager.
       @param name the name associated to the NeighborhoodExplorer
       @param nhes the list of basic neighborhood explorer objects (according to the template list)
       @param bias a set of weights fo biasing the random move drawing
       */
      SetUnionNeighborhoodExplorer(const Input &in, StateManager<Input, State, CostStructure> &sm, std::string name, BaseNeighborhoodExplorers &... nhes, const std::vector<double> &bias = std::vector<double>(0))
      : NeighborhoodExplorer<Input, State, MoveTypes, CostStructure>(in, sm, name),
      nhes(std::make_tuple(std::reference_wrapper<BaseNeighborhoodExplorers>(nhes)...)),
#ifndef MSVC
      // this uses fastfunc
      first_move_funcs(std::make_tuple(Impl::makeFastFunc(&nhes, &BaseNeighborhoodExplorers::FirstMove)...)),
      random_move_funcs(std::make_tuple(Impl::makeFastFunc(&nhes, &BaseNeighborhoodExplorers::RandomMove)...)),
      next_move_funcs(std::make_tuple(Impl::makeFastFunc(&nhes, &BaseNeighborhoodExplorers::NextMove)...)),
      make_move_funcs(std::make_tuple(Impl::makeFastFunc(&nhes, &BaseNeighborhoodExplorers::MakeMove)...)),
      delta_cost_function_funcs(std::make_tuple(Impl::makeFastFunc(dynamic_cast<NeighborhoodExplorer<Input, State, typename BaseNeighborhoodExplorers::MoveType, CostStructure> *>(&nhes), &NeighborhoodExplorer<Input, State, typename BaseNeighborhoodExplorers::MoveType, CostStructure>::DeltaCostFunctionComponents)...))
#else
      first_move_funcs(std::make_tuple(Impl::makeFunction2(&nhes, &BaseNeighborhoodExplorers::FirstMove)...)),
      random_move_funcs(std::make_tuple(Impl::makeFunction2(&nhes, &BaseNeighborhoodExplorers::RandomMove)...)),
      next_move_funcs(std::make_tuple(Impl::makeFunction2(&nhes, &BaseNeighborhoodExplorers::NextMove)...)),
      make_move_funcs(std::make_tuple(Impl::makeFunction2(&nhes, &BaseNeighborhoodExplorers::MakeMove)...)),
      delta_cost_function_funcs(std::make_tuple(Impl::makeFunction3(dynamic_cast<NeighborhoodExplorer<Input, State, typename BaseNeighborhoodExplorers::MoveType, CostStructure> *>(&nhes), &NeighborhoodExplorer<Input, State, typename BaseNeighborhoodExplorers::MoveType, CostStructure>::DeltaCostFunctionComponents)...))
#endif
      {
        if (bias.empty())
        {
          // If not otherwise specified, initialize the probabilities as 1 / Modality
          this->bias = std::vector<double>(this->Modality(), 1.0 / (double)this->Modality());
        }
        
        else if (bias.size() != this->Modality())
          throw std::logic_error("Multimodal move random distribution (i.e., bias) not matching the neighborhood modality");
        else
          this->bias = bias;
      }
      
    protected:
      /** Instantiated base NeighborhoodExplorers. */
      NeighborhoodExplorerTypes nhes;
      
#ifndef MSVC
      typedef std::tuple<Impl::FastFunc<void(const State &, typename BaseNeighborhoodExplorers::MoveType &)>...> _Void_ConstState_Move;
      typedef std::tuple<Impl::FastFunc<bool(const State &, typename BaseNeighborhoodExplorers::MoveType &)>...> _Bool_ConstState_Move;
      typedef std::tuple<Impl::FastFunc<void(State &, const typename BaseNeighborhoodExplorers::MoveType &)>...> _Void_State_ConstMove;
      typedef std::tuple<Impl::FastFunc<CostStructure(const State &, const typename BaseNeighborhoodExplorers::MoveType &, const std::vector<double> &weights)>...> _CostStructure_ConstState_ConstMove;
      
#else
      typedef std::tuple<std::function<void(const State &, typename BaseNeighborhoodExplorers::MoveType &)>...> _Void_ConstState_Move;
      typedef std::tuple<std::function<bool(const State &, typename BaseNeighborhoodExplorers::MoveType &)>...> _Bool_ConstState_Move;
      typedef std::tuple<std::function<void(State &, const typename BaseNeighborhoodExplorers::MoveType &)>...> _Void_State_ConstMove;
      typedef std::tuple<std::function<CostStructure(const State &, const typename BaseNeighborhoodExplorers::MoveType &, const std::vector<double> &weights)>...> _CostStructure_ConstState_ConstMove;
#endif
      _Void_ConstState_Move first_move_funcs, random_move_funcs;
      _Bool_ConstState_Move next_move_funcs;
      _Void_State_ConstMove make_move_funcs;
      _CostStructure_ConstState_ConstMove delta_cost_function_funcs;
      
      std::vector<double> bias;
      
    public:
      /** @copydoc NeighborhoodExplorer::FirstMove */
      virtual void FirstMove(const State &st, MoveTypes &moves) const
      {
        MoveTypeRefs r_moves = to_refs(moves);
        
        for (size_t i = 0; i < Modality(); i++)
        {
          try
          {
            Impl::VTupleDispatcher<State, _Void_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(i, st, first_move_funcs, r_moves);
            Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(i, r_moves, true);
            return;
          }
          catch (EmptyNeighborhood)
          {
            Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(i, r_moves, false);
          }
        }
        throw EmptyNeighborhood();
      }
      
      /** @copydoc NeighborhoodExplorer::RandomMove */
      virtual void RandomMove(const State &st, MoveTypes &moves) const
      {
        MoveTypeRefs r_moves = to_refs(moves);
        Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_all_activity(r_moves, false);
        
        // Select random neighborhood explorer with bias (don't assume that they sum up to one)
        double total_bias = 0.0;
        double pick;
        unsigned int selected = 0;
        
        for (size_t i = 0; i < bias.size(); i++)
          total_bias += bias[i];
        pick = Random::Uniform<double>(0.0, total_bias);
        
        // Subtract bias until we're on the right neighborhood explorer
        while (pick > bias[selected])
        {
          pick -= bias[selected];
          selected++;
        }
        
        for (size_t i = selected; i < Modality(); i++)
        {
          try
          {
            Impl::VTupleDispatcher<State, _Void_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(i, st, random_move_funcs, r_moves);
            Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(i, r_moves, true);
            return;
          }
          catch (EmptyNeighborhood)
          {
            Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(i, r_moves, false);
          }
        }
        for (size_t i = 0; i < selected; i++)
        {
          try
          {
            Impl::VTupleDispatcher<State, _Void_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(i, st, random_move_funcs, r_moves);
            Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(i, r_moves, true);
            return;
          }
          catch (EmptyNeighborhood)
          {
            Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(i, r_moves, false);
          }
        }
        throw EmptyNeighborhood();
      }
      
      /** @copydoc NeighborhoodExplorer::NextMove */
      virtual bool NextMove(const State &st, MoveTypes &moves) const
      {
        MoveTypeRefs r_moves = to_refs(moves);
        const MoveTypeCRefs cr_moves = to_crefs(moves);
        
        size_t i = Impl::MoveDispatcher<MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::get_first_active(cr_moves, 0);
        bool next_move_exists = false;
        
        while (true)
        {
          next_move_exists = Impl::TupleDispatcher<bool, State, _Bool_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(i, st, next_move_funcs, r_moves);
          if (next_move_exists)
          {
            Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(i, r_moves, true);
            return true;
          }
          else
          {
            Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(i, r_moves, false);
            for (i = i + 1; i < Modality(); i++)
            {
              try
              {
                Impl::VTupleDispatcher<State, _Void_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(i, st, first_move_funcs, r_moves);
                Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(i, r_moves, true);
                return true;
              }
              catch (EmptyNeighborhood)
              {
                Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(i, r_moves, false);
              }
            }
            return false;
          }
        }
        return false;
      }
      
      /** @copydoc NeighborhoodExplorer::MakeMove */
      virtual void MakeMove(State &st, const MoveTypes &moves) const
      {
        const MoveTypeCRefs cr_moves = to_crefs(moves);
        size_t i = Impl::MoveDispatcher<MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::get_first_active(cr_moves, 0);
        
        Impl::VTupleDispatcher<State, _Void_State_ConstMove, MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(i, st, make_move_funcs, cr_moves);
      }
      
      /** @copydoc NeighborhoodExplorer::DeltaCostFunctionComponents */
      virtual CostStructure DeltaCostFunctionComponents(const State &st, const MoveTypes &moves, const std::vector<double> &weights = std::vector<double>(0)) const
      {
        const MoveTypeCRefs cr_moves = to_crefs(moves);
        size_t i = Impl::MoveDispatcher<MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::get_first_active(cr_moves, 0);
        return Impl::TupleDispatcher<CostStructure, State, _CostStructure_ConstState_ConstMove, MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(i, st, delta_cost_function_funcs, cr_moves, weights);
      }
    };
    
    /** Given a set of base neighborhood explorers, this class will create a multimodal (i.e., compound) neighborhood explorer
     that explores the set union of all neighborhoods.
     @brief The SetUnion MultimodalNeighborhoodExplorer manages the set union of different neighborhoods.
     @tparam Input the class representing the problem input
     @tparam State the class representing the problem's state
     @tparam CFtype the type of the cost function
     @tparam BaseNeighborhoodExplorers a sequence of base neighborhood explorer classes
     @ingroup Helpers
     */
    template <class Input, class State, class CostStructure, class... BaseNeighborhoodExplorers>
    class CartesianProductNeighborhoodExplorer : public NeighborhoodExplorer<Input, State, std::tuple<ActiveMove<typename BaseNeighborhoodExplorers::MoveType>...>, CostStructure>
    {
    protected:
      /** Tuple type representing the combination of @c BaseNeighborhoodExplorers' @ref Move. */
      typedef std::tuple<ActiveMove<typename BaseNeighborhoodExplorers::MoveType>...> MoveTypes;
      
      /** Tuple type representing references to @c BaseNeighborhoodExplorers' @ref Move (because we need to set them). */
      typedef std::tuple<std::reference_wrapper<ActiveMove<typename BaseNeighborhoodExplorers::MoveType>>...> MoveTypeRefs;
      
      /** Tuple type representing const references to @c BaseNeighborhoodExplorers' @ref Move. */
      typedef std::tuple<std::reference_wrapper<const ActiveMove<typename BaseNeighborhoodExplorers::MoveType>>...> MoveTypeCRefs;
      
      /** Tuple type representing references to @c BaseNeighborhoodExplorers. */
      typedef std::tuple<std::reference_wrapper<BaseNeighborhoodExplorers>...> NeighborhoodExplorerTypes;
      
      /** Modality of the NeighborhoodExplorer, i.e., the number of @ref NeighborhoodExplorer composing this one.  */
      virtual size_t Modality() const { return sizeof...(BaseNeighborhoodExplorers); }
      
    public:
      typedef typename CostStructure::CFtype CFtype;
      
      /** Constructor, takes a variable number of base NeighborhoodExplorers.
       @param in a pointer to an input object.
       @param sm a pointer to a compatible state manager.
       @param name the name associated to the NeighborhoodExplorer
       @param nhes the list of basic neighborhood explorer objects (according to the template list)
       */
      CartesianProductNeighborhoodExplorer(const Input &in, StateManager<Input, State, CostStructure> &sm, std::string name, BaseNeighborhoodExplorers &... nhes)
      : NeighborhoodExplorer<Input, State, MoveTypes, CostStructure>(in, sm, name),
      nhes(std::make_tuple(std::reference_wrapper<BaseNeighborhoodExplorers>(nhes)...)),
#ifndef MSVC
      first_move_funcs(std::make_tuple(Impl::makeFastFunc(&nhes, &BaseNeighborhoodExplorers::FirstMove)...)),
      random_move_funcs(std::make_tuple(Impl::makeFastFunc(&nhes, &BaseNeighborhoodExplorers::RandomMove)...)),
      next_move_funcs(std::make_tuple(Impl::makeFastFunc(&nhes, &BaseNeighborhoodExplorers::NextMove)...)),
      make_move_funcs(std::make_tuple(Impl::makeFastFunc(&nhes, &BaseNeighborhoodExplorers::MakeMove)...)),
      delta_cost_function_funcs(std::make_tuple(Impl::makeFastFunc(dynamic_cast<NeighborhoodExplorer<Input, State, typename BaseNeighborhoodExplorers::MoveType, CostStructure> *>(&nhes), &NeighborhoodExplorer<Input, State, typename BaseNeighborhoodExplorers::MoveType, CostStructure>::DeltaCostFunctionComponents)...))
#else
      first_move_funcs(std::make_tuple(Impl::makeFunction2(&nhes, &BaseNeighborhoodExplorers::FirstMove)...)),
      random_move_funcs(std::make_tuple(Impl::makeFunction2(&nhes, &BaseNeighborhoodExplorers::RandomMove)...)),
      next_move_funcs(std::make_tuple(Impl::makeFunction2(&nhes, &BaseNeighborhoodExplorers::NextMove)...)),
      make_move_funcs(std::make_tuple(Impl::makeFunction2(&nhes, &BaseNeighborhoodExplorers::MakeMove)...)),
      delta_cost_function_funcs(std::make_tuple(Impl::makeFunction3(dynamic_cast<NeighborhoodExplorer<Input, State, typename BaseNeighborhoodExplorers::MoveType, CostStructure> *>(&nhes), &NeighborhoodExplorer<Input, State, typename BaseNeighborhoodExplorers::MoveType, CostStructure>::DeltaCostFunctionComponents)...))
#endif
      {
      }
      
    protected:
      /** Instantiated base NeighborhoodExplorers. */
      NeighborhoodExplorerTypes nhes;
      
      typedef std::tuple<Impl::FastFunc<void(const State &, typename BaseNeighborhoodExplorers::MoveType &)>...> _Void_ConstState_Move;
      typedef std::tuple<Impl::FastFunc<bool(const State &, typename BaseNeighborhoodExplorers::MoveType &)>...> _Bool_ConstState_Move;
      typedef std::tuple<Impl::FastFunc<void(State &, const typename BaseNeighborhoodExplorers::MoveType &)>...> _Void_State_ConstMove;
      typedef std::tuple<Impl::FastFunc<CostStructure(const State &, const typename BaseNeighborhoodExplorers::MoveType &, const std::vector<double> &weights)>...> _CostStructure_ConstState_ConstMove;
      
      _Void_ConstState_Move first_move_funcs, random_move_funcs;
      _Bool_ConstState_Move next_move_funcs;
      _Void_State_ConstMove make_move_funcs;
      _CostStructure_ConstState_ConstMove delta_cost_function_funcs;
      
      std::unordered_map<std::type_index, boost::any> related_funcs;
      
    public:
      /** Adds a predicate to determine whether two moves (of different neighborhoods) are related.
       This version wraps the moves in an ActiveMove object structure.
       @param r a relatedness function
       */
      template <typename Move1, typename Move2>
      void AddRelatedFunction(std::function<bool(const Move1 &, const Move2 &)> r)
      {
        std::function<bool(const ActiveMove<Move1> &, const ActiveMove<Move2> &)> ar = [r](const ActiveMove<Move1> &mv1, const ActiveMove<Move2> &mv2) { return r(mv1, mv2); };
        related_funcs[std::type_index(typeid(ar))] = ar;
      }
      
      /** Adds a predicate to determine whether two moves (of different neighborhoods) are related.
       This version requires the moves to be already wrapped in an ActiveMove object structure.
       @param r a relatedness function
       */
      template <typename Move1, typename Move2>
      void AddRelatedFunction(std::function<bool(const ActiveMove<Move1> &, const ActiveMove<Move2> &)> r)
      {
        related_funcs[std::type_index(typeid(r))] = r;
      }
      
      /** @copydoc NeighborhoodExplorer::FirstMove */
      virtual void FirstMove(const State &st, MoveTypes &moves) const
      {
        MoveTypeRefs r_moves = to_refs(moves);
        const MoveTypeCRefs cr_moves = to_crefs(moves);
        const size_t length = sizeof...(BaseNeighborhoodExplorers);
        std::vector<State> states(length, st);
        
        long cur = 0;
        bool backtracking = false;
        
        // stop only when a complete kicker has been generated, or throw an @ref EmptyNeighborhood
      loop:
        while (cur < (int)length)
        {
          if (cur == -1)
            throw EmptyNeighborhood();
          
          // reset state before generating each move
          states[cur] = cur > 0 ? states[cur - 1] : st;
          
          if (!backtracking)
          {
            try
            {
              // ne.FirstMove(kick[cur].second, kick[cur].first.move);
              Impl::VTupleDispatcher<State, _Void_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, st, first_move_funcs, r_moves);
              
              while (cur > 0 && !Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::are_related(cur - 1, r_moves, related_funcs))
              {
                //if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
                if (!Impl::TupleDispatcher<bool, State, _Bool_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], next_move_funcs, r_moves))
                {
                  backtracking = true;
                  Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, false);
                  cur--;
                  goto loop;
                }
              }
              backtracking = false;
              // ne.MakeMove(kick[cur].second, kick[cur].first.move);
              Impl::VTupleDispatcher<State, _Void_State_ConstMove, MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], make_move_funcs, cr_moves);
              Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, true);
              cur++;
              goto loop;
            }
            catch (EmptyNeighborhood e)
            {
              backtracking = true;
              Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, false);
              cur--;
              goto loop;
            }
          }
          else // backtracking (we only need to generate NextMoves)
          {
            do
            {
              //                if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
              if (!Impl::TupleDispatcher<bool, State, _Bool_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], next_move_funcs, r_moves))
              {
                backtracking = true;
                Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, false);
                cur--;
                goto loop;
              }
            } while (cur > 0 && !Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::are_related(cur - 1, r_moves, related_funcs));
            backtracking = false;
            //ne.MakeMove(kick[cur].second, kick[cur].first.move);
            Impl::VTupleDispatcher<State, _Void_State_ConstMove, MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], make_move_funcs, cr_moves);
            Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, true);
            cur++;
            goto loop;
          }
        }
      }
      
      /** @copydoc NeighborhoodExplorer::RandomMove */
      virtual void RandomMove(const State &st, MoveTypes &moves) const
      {
        MoveTypeRefs r_moves = to_refs(moves);
        const MoveTypeCRefs cr_moves = to_crefs(moves);
        const size_t length = sizeof...(BaseNeighborhoodExplorers);
        std::vector<State> states(length, st);
        
        MoveTypes initial_moves;
        MoveTypeRefs r_initial_moves = to_refs(initial_moves);
        //const MoveTypeCRefs cr_initial_moves = to_crefs(initial_moves);
        std::vector<bool> initial_set(length, false);
        
        long cur = 0;
        bool backtracking = false;
        
        // stop only when a complete kicker has been generated, or throw an @ref EmptyNeighborhood
      loop:
        while (cur < (int)length)
        {
          if (cur == -1)
            throw EmptyNeighborhood();
          
          // reset state before generating each move
          states[cur] = cur > 0 ? states[cur - 1] : st;
          
          if (!backtracking)
          {
            try
            {
              const State &c_cur_st = states[cur];
              //ne.RandomMove(kick[cur].second, kick[cur].first.move);
              Impl::VTupleDispatcher<State, _Void_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, c_cur_st, random_move_funcs, r_moves);
              
              if (!initial_set[cur])
              {
                Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::copy_move_at(cur, r_initial_moves, r_moves);
                initial_set[cur] = true;
              }
              
              while (cur > 0 && !Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::are_related(cur - 1, r_moves, related_funcs))
              {
                //if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
                if (!Impl::TupleDispatcher<bool, State, _Bool_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], next_move_funcs, r_moves))
                {
                  // ne.FirstMove(kick[cur].second, kick[cur].first.move);
                  Impl::VTupleDispatcher<State, _Void_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, st, first_move_funcs, r_moves);
                }
                //                  if (kick[cur].first.move == initial_kick_moves[cur])
                if (Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::equal_at(cur, r_moves, r_initial_moves))
                {
                  backtracking = true;
                  Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, false);
                  cur--;
                  goto loop;
                }
              }
              backtracking = false;
              // ne.MakeMove(kick[cur].second, kick[cur].first.move);
              Impl::VTupleDispatcher<State, _Void_State_ConstMove, MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], make_move_funcs, cr_moves);
              Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, true);
              cur++;
              goto loop;
            }
            catch (EmptyNeighborhood e)
            {
              backtracking = true;
              Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, false);
              cur--;
              goto loop;
            }
          }
          else // backtracking (we only need to generate moves following the first)
          {
            do
            {
              //if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
              if (!Impl::TupleDispatcher<bool, State, _Bool_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], next_move_funcs, r_moves))
              {
                // ne.FirstMove(kick[cur].second, kick[cur].first.move);
                Impl::VTupleDispatcher<State, _Void_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, st, first_move_funcs, r_moves);
              }
              // if (kick[cur].first.move == initial_kick_moves[cur])
              if (Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::equal_at(cur, r_moves, r_initial_moves))
              {
                backtracking = true;
                Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, false);
                cur--;
                goto loop;
              }
            } while (cur > 0 && !Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::are_related(cur - 1, r_moves, related_funcs));
            backtracking = false;
            //ne.MakeMove(kick[cur].second, kick[cur].first.move);
            Impl::VTupleDispatcher<State, _Void_State_ConstMove, MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], make_move_funcs, cr_moves);
            Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, true);
            cur++;
            goto loop;
          }
        }
      }
      
      /** @copydoc NeighborhoodExplorer::NextMove */
      virtual bool NextMove(const State &st, MoveTypes &moves) const
      {
        MoveTypeRefs r_moves = to_refs(moves);
        const MoveTypeCRefs cr_moves = to_crefs(moves);
        const size_t length = sizeof...(BaseNeighborhoodExplorers);
        std::vector<State> states(length, st);
        // go to last move, then start generating with backtracking
        long cur = length - 1;
        bool backtracking = true;
        
        // stop only when a complete kicker has been generated, or throw an @ref EmptyNeighborhood
      loop:
        while (cur < (int)length)
        {
          if (cur == -1)
            return false;
          
          // reset state before generating each move
          states[cur] = cur > 0 ? states[cur - 1] : st;
          
          if (!backtracking)
          {
            try
            {
              //ne.FirstMove(kick[cur].second, kick[cur].first.move);
              Impl::VTupleDispatcher<State, _Void_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, st, first_move_funcs, r_moves);
              while (cur > 0 && !Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::are_related(cur - 1, r_moves, related_funcs)) //!RelatedMoves(kick[cur - 1].first.move, kick[cur].first.move))
              {
                //if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
                if (!Impl::TupleDispatcher<bool, State, _Bool_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], next_move_funcs, r_moves))
                {
                  backtracking = true;
                  Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, false);
                  cur--;
                  goto loop;
                }
              }
              backtracking = false;
              //ne.MakeMove(kick[cur].second, kick[cur].first.move);
              Impl::VTupleDispatcher<State, _Void_State_ConstMove, MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], make_move_funcs, cr_moves);
              Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, true);
              cur++;
              goto loop;
            }
            catch (EmptyNeighborhood e)
            {
              backtracking = true;
              Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, false);
              cur--;
              goto loop;
            }
          }
          else // backtracking (we only need to generate NextMoves)
          {
            do
            {
              //if (!ne.NextMove(kick[cur].second, kick[cur].first.move))
              if (!Impl::TupleDispatcher<bool, State, _Bool_ConstState_Move, MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], next_move_funcs, r_moves))
              {
                backtracking = true;
                Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, false);
                cur--;
                goto loop;
              }
            } while (cur > 0 && !Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::are_related(cur - 1, r_moves, related_funcs)); //!RelatedMoves(kick[cur - 1].first.move, kick[cur].first.move));
            backtracking = false;
            //ne.MakeMove(kick[cur].second, kick[cur].first.move);
            Impl::VTupleDispatcher<State, _Void_State_ConstMove, MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(cur, states[cur], make_move_funcs, cr_moves);
            Impl::MoveDispatcher<MoveTypeRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::set_activity_at(cur, r_moves, true);
            cur++;
            goto loop;
          }
        }
        return true;
      }
      
      /** @copydoc NeighborhoodExplorer::MakeMove */
      virtual void MakeMove(State &st, const MoveTypes &moves) const
      {
        const MoveTypeCRefs cr_moves = to_crefs(moves);
        
        for (size_t i = 0; i < Modality(); i++)
          Impl::VTupleDispatcher<State, _Void_State_ConstMove, MoveTypeCRefs, sizeof...(BaseNeighborhoodExplorers) - 1>::execute_at(i, st, make_move_funcs, cr_moves);
      }
      
      /** @copydoc NeighborhoodExplorer::DeltaCostFunctionComponents */
      virtual CostStructure DeltaCostFunctionComponents(const State &st, const MoveTypes &moves, const std::vector<double> &weights = std::vector<double>(0)) const
      {
        const MoveTypeCRefs cr_moves = to_crefs(moves);
        
        CostStructure result;