diff --git a/.bazelrc b/.bazelrc deleted file mode 100644 index aef1e8a..0000000 --- a/.bazelrc +++ /dev/null @@ -1,10 +0,0 @@ -build --compilation_mode=opt -#build --cxxopt=-Wall --cxxopt=-Wextra - -################################################################################ -############################ Optional dependencies ############################# -################################################################################ - -#build --define cbc=true -#build --define cplex=true - diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e670b49..31eea12 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,9 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] python-version: ["3.8"] + env: + STABLE_DATA: ${{ github.workspace }}/data/ + steps: - name: Checkout code uses: actions/checkout@v4 @@ -25,7 +28,10 @@ jobs: python3 -m pip install gdown python3 scripts/download_data.py - name: Build - run: bazel build -- //... + run: | + cmake -S . -B build -DCMAKE_BUILD_TYPE=Release + cmake --build build --config Release --parallel + cmake --install build --config Release --prefix install - name: Run tests run: python3 -u scripts/run_tests.py test_results - name: Checkout main branch @@ -38,4 +44,4 @@ jobs: - name: Run tests run: python3 -u scripts/run_tests.py test_results_ref - name: Process tests - run: python3 ./bazel-stablesolver/external/optimizationtools/scripts/process_tests.py --ref test_results_ref --new test_results + run: python3 -u ./build/_deps/optimizationtools-src/scripts/process_tests.py --ref test_results_ref --new test_results diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..0d02aa9 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.15.0) + +project(StableSolver LANGUAGES CXX) + +option(STABLESOLVER_USE_CBC "Use CPLEX" ON) +option(STABLESOLVER_USE_CPLEX "Use CPLEX" OFF) + +# Require C++11. +set(CMAKE_CXX_STANDARD 11) + +# Enable output of compile commands during generation. +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Set MSVC_RUNTIME_LIBRARY. +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + +# Add sub-directories. +add_subdirectory(extern) +add_subdirectory(src) +add_subdirectory(test) diff --git a/README.md b/README.md index 98bb9ed..2922753 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,14 @@ Download and uncompress the instances in the `data/` folder: Compile: ```shell -bazel build -- //... +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release +cmake --build build --config Release --parallel +cmake --install build --config Release --prefix install +``` + +To enable algorithms using CPLEX, replace the first step by: +``` +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DSTABLESOLVER_USE_CBC=OFF -DSTABLESOLVER_USE_CPLEX=ON ``` Download data: @@ -61,7 +68,7 @@ python3 scripts/download_data.py Examples: ```shell -./bazel-bin/stablesolver/stable/main --verbosity-level 1 --input "data/dimacs1992/brock200_1.clq" --format dimacs1992 --algorithm "local-search-row-weighting-2" --maximum-number-of-iterations 3000 -certificate solution.txt +./install/bin/stablesolver_stable --verbosity-level 1 --input "data/dimacs1992/brock200_1.clq" --format dimacs1992 --algorithm "local-search-row-weighting-2" --maximum-number-of-iterations 3000 --certificate solution.txt ``` ``` ==================================== @@ -126,7 +133,7 @@ Weight: 21 ``` ```shell -./bazel-bin/stablesolver/stable/main --verbosity-level 1 --input "data/dimacs2010/clustering/caidaRouterLevel.graph" --format dimacs2010 --algorithm "local-search-row-weighting-1" --maximum-number-of-iterations 300000 +./install/bin/stablesolver_stable --verbosity-level 1 --input "data/dimacs2010/clustering/caidaRouterLevel.graph" --format dimacs2010 --algorithm "local-search-row-weighting-1" --maximum-number-of-iterations 300000 ``` ``` ===================================== diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt new file mode 100644 index 0000000..26beef1 --- /dev/null +++ b/extern/CMakeLists.txt @@ -0,0 +1,44 @@ +# Enable FetchContent. +include(FetchContent) + +# Fetch boost. +set(BOOST_INCLUDE_LIBRARIES thread filesystem system program_options) +set(BOOST_ENABLE_CMAKE ON) +include(FetchContent) +FetchContent_Declare( + Boost + GIT_REPOSITORY https://github.com/boostorg/boost.git + GIT_TAG boost-1.84.0 + GIT_SHALLOW TRUE +) +FetchContent_MakeAvailable(Boost) + +# Fetch fontanf/optimizationtools. +FetchContent_Declare( + optimizationtools + GIT_REPOSITORY https://github.com/fontanf/optimizationtools.git + GIT_TAG 33a3966ece149d390ec7ce08699669b5267e64aa) + #SOURCE_DIR "${PROJECT_SOURCE_DIR}/../optimizationtools/") +FetchContent_MakeAvailable(optimizationtools) + +# Fetch fontanf/localsearchsolver. +FetchContent_Declare( + localsearchsolver + GIT_REPOSITORY https://github.com/fontanf/localsearchsolver.git + GIT_TAG ecb15ef667d107f25ea51d056368f9c4e15545e2) + #SOURCE_DIR "${PROJECT_SOURCE_DIR}/../localsearchsolver/") +FetchContent_MakeAvailable(localsearchsolver) + +# Fetch fontanf/mathoptsolverscmake. +if(STABLESOLVER_USE_CBC) + set(MATHOPTSOLVERSCMAKE_USE_CBC ON) +endif() +if(STABLESOLVER_USE_CPLEX) + set(MATHOPTSOLVERSCMAKE_USE_CPLEX ON) +endif() +FetchContent_Declare( + mathoptsolverscmake + GIT_REPOSITORY https://github.com/fontanf/mathoptsolverscmake.git + GIT_TAG 56190725f424249a3acd8fce3ff50e08fe675cc6) + #SOURCE_DIR "${PROJECT_SOURCE_DIR}/../mathoptsolverscmake/") +FetchContent_MakeAvailable(mathoptsolverscmake) diff --git a/stablesolver/clique/algorithm_formatter.hpp b/include/stablesolver/clique/algorithm_formatter.hpp similarity index 100% rename from stablesolver/clique/algorithm_formatter.hpp rename to include/stablesolver/clique/algorithm_formatter.hpp diff --git a/stablesolver/clique/algorithms/algorithms.hpp b/include/stablesolver/clique/algorithms/algorithms.hpp similarity index 100% rename from stablesolver/clique/algorithms/algorithms.hpp rename to include/stablesolver/clique/algorithms/algorithms.hpp diff --git a/stablesolver/clique/algorithms/greedy.hpp b/include/stablesolver/clique/algorithms/greedy.hpp similarity index 100% rename from stablesolver/clique/algorithms/greedy.hpp rename to include/stablesolver/clique/algorithms/greedy.hpp diff --git a/stablesolver/clique/algorithms/local_search.hpp b/include/stablesolver/clique/algorithms/local_search.hpp similarity index 100% rename from stablesolver/clique/algorithms/local_search.hpp rename to include/stablesolver/clique/algorithms/local_search.hpp diff --git a/stablesolver/clique/algorithms/milp_cplex.hpp b/include/stablesolver/clique/algorithms/milp_cplex.hpp similarity index 92% rename from stablesolver/clique/algorithms/milp_cplex.hpp rename to include/stablesolver/clique/algorithms/milp_cplex.hpp index 28250b3..a19e95f 100644 --- a/stablesolver/clique/algorithms/milp_cplex.hpp +++ b/include/stablesolver/clique/algorithms/milp_cplex.hpp @@ -1,7 +1,5 @@ #pragma once -#if CPLEX_FOUND - #include "stablesolver/clique/solution.hpp" namespace stablesolver @@ -20,5 +18,3 @@ const Output milp_cplex( } } - -#endif diff --git a/stablesolver/clique/bench.py b/include/stablesolver/clique/bench.py similarity index 100% rename from stablesolver/clique/bench.py rename to include/stablesolver/clique/bench.py diff --git a/stablesolver/clique/instance.hpp b/include/stablesolver/clique/instance.hpp similarity index 100% rename from stablesolver/clique/instance.hpp rename to include/stablesolver/clique/instance.hpp diff --git a/stablesolver/clique/solution.hpp b/include/stablesolver/clique/solution.hpp similarity index 100% rename from stablesolver/clique/solution.hpp rename to include/stablesolver/clique/solution.hpp diff --git a/stablesolver/stable/algorithm.hpp b/include/stablesolver/stable/algorithm.hpp similarity index 100% rename from stablesolver/stable/algorithm.hpp rename to include/stablesolver/stable/algorithm.hpp diff --git a/stablesolver/stable/algorithm_formatter.hpp b/include/stablesolver/stable/algorithm_formatter.hpp similarity index 100% rename from stablesolver/stable/algorithm_formatter.hpp rename to include/stablesolver/stable/algorithm_formatter.hpp diff --git a/stablesolver/stable/algorithms/algorithms.hpp b/include/stablesolver/stable/algorithms/algorithms.hpp similarity index 100% rename from stablesolver/stable/algorithms/algorithms.hpp rename to include/stablesolver/stable/algorithms/algorithms.hpp diff --git a/stablesolver/stable/algorithms/greedy.hpp b/include/stablesolver/stable/algorithms/greedy.hpp similarity index 100% rename from stablesolver/stable/algorithms/greedy.hpp rename to include/stablesolver/stable/algorithms/greedy.hpp diff --git a/stablesolver/stable/algorithms/large_neighborhood_search.hpp b/include/stablesolver/stable/algorithms/large_neighborhood_search.hpp similarity index 100% rename from stablesolver/stable/algorithms/large_neighborhood_search.hpp rename to include/stablesolver/stable/algorithms/large_neighborhood_search.hpp diff --git a/stablesolver/stable/algorithms/local_search.hpp b/include/stablesolver/stable/algorithms/local_search.hpp similarity index 100% rename from stablesolver/stable/algorithms/local_search.hpp rename to include/stablesolver/stable/algorithms/local_search.hpp diff --git a/stablesolver/stable/algorithms/local_search_row_weighting.hpp b/include/stablesolver/stable/algorithms/local_search_row_weighting.hpp similarity index 100% rename from stablesolver/stable/algorithms/local_search_row_weighting.hpp rename to include/stablesolver/stable/algorithms/local_search_row_weighting.hpp diff --git a/stablesolver/stable/algorithms/milp_cbc.hpp b/include/stablesolver/stable/algorithms/milp_cbc.hpp similarity index 92% rename from stablesolver/stable/algorithms/milp_cbc.hpp rename to include/stablesolver/stable/algorithms/milp_cbc.hpp index 156505e..69da37e 100644 --- a/stablesolver/stable/algorithms/milp_cbc.hpp +++ b/include/stablesolver/stable/algorithms/milp_cbc.hpp @@ -1,7 +1,5 @@ #pragma once -#if COINOR_FOUND - #include "stablesolver/stable/algorithm.hpp" namespace stablesolver @@ -21,5 +19,3 @@ const Output milp_1_cbc( } } - -#endif diff --git a/stablesolver/stable/algorithms/milp_cplex.hpp b/include/stablesolver/stable/algorithms/milp_cplex.hpp similarity index 95% rename from stablesolver/stable/algorithms/milp_cplex.hpp rename to include/stablesolver/stable/algorithms/milp_cplex.hpp index 531c8ec..cd4fd4c 100644 --- a/stablesolver/stable/algorithms/milp_cplex.hpp +++ b/include/stablesolver/stable/algorithms/milp_cplex.hpp @@ -1,7 +1,5 @@ #pragma once -#if CPLEX_FOUND - #include "stablesolver/stable/algorithm.hpp" namespace stablesolver @@ -29,5 +27,3 @@ const Output milp_3_cplex( } } - -#endif diff --git a/stablesolver/stable/bench.py b/include/stablesolver/stable/bench.py similarity index 100% rename from stablesolver/stable/bench.py rename to include/stablesolver/stable/bench.py diff --git a/stablesolver/stable/instance.hpp b/include/stablesolver/stable/instance.hpp similarity index 100% rename from stablesolver/stable/instance.hpp rename to include/stablesolver/stable/instance.hpp diff --git a/stablesolver/stable/instance_builder.hpp b/include/stablesolver/stable/instance_builder.hpp similarity index 100% rename from stablesolver/stable/instance_builder.hpp rename to include/stablesolver/stable/instance_builder.hpp diff --git a/stablesolver/stable/reduction.hpp b/include/stablesolver/stable/reduction.hpp similarity index 100% rename from stablesolver/stable/reduction.hpp rename to include/stablesolver/stable/reduction.hpp diff --git a/stablesolver/stable/solution.hpp b/include/stablesolver/stable/solution.hpp similarity index 100% rename from stablesolver/stable/solution.hpp rename to include/stablesolver/stable/solution.hpp diff --git a/scripts/run_tests.py b/scripts/run_tests.py index fe67c9f..65c1258 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -14,10 +14,10 @@ stable_main = os.path.join( - "bazel-bin", - "stablesolver", - "stable", - "main") + "install", + "bin", + "stablesolver_stable") +data_dir = os.environ['STABLE_DATA'] greedy_data = [ @@ -41,7 +41,7 @@ for instance, instance_format in greedy_data: instance_path = os.path.join( - "data", + data_dir, instance) json_output_path = os.path.join( args.directory, @@ -73,7 +73,7 @@ for instance, instance_format in greedy_data: instance_path = os.path.join( - "data", + data_dir, instance) json_output_path = os.path.join( args.directory, @@ -105,7 +105,7 @@ for instance, instance_format in greedy_data: instance_path = os.path.join( - "data", + data_dir, instance) json_output_path = os.path.join( args.directory, @@ -131,10 +131,9 @@ clique_main = os.path.join( - "bazel-bin", - "stablesolver", - "clique", - "main") + "install", + "bin", + "stablesolver_clique") if args.tests is None or "clique-greedy-gwmin" in args.tests: @@ -144,7 +143,7 @@ for instance, instance_format in greedy_data: instance_path = os.path.join( - "data", + data_dir, instance) json_output_path = os.path.join( args.directory, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..3eb982a --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(clique) +add_subdirectory(stable) diff --git a/src/clique/CMakeLists.txt b/src/clique/CMakeLists.txt new file mode 100644 index 0000000..ecdf986 --- /dev/null +++ b/src/clique/CMakeLists.txt @@ -0,0 +1,30 @@ +add_library(StableSolver_clique) +target_sources(StableSolver_clique PRIVATE + instance.cpp + solution.cpp + algorithm_formatter.cpp) +target_include_directories(StableSolver_clique PUBLIC + ${PROJECT_SOURCE_DIR}/include) +target_link_libraries(StableSolver_clique PUBLIC + OptimizationTools::utils + OptimizationTools::containers + OptimizationTools::graph) +add_library(StableSolver::clique ALIAS StableSolver_clique) + +add_subdirectory(algorithms) + +add_executable(StableSolver_clique_main) +target_sources(StableSolver_clique_main PRIVATE + main.cpp) +target_link_libraries(StableSolver_clique_main PUBLIC + StableSolver_clique_greedy + StableSolver_clique_local_search + Boost::program_options) +if(STABLESOLVER_USE_CPLEX) + target_compile_definitions(StableSolver_clique_main PUBLIC + CPLEX_FOUND=1) + target_link_libraries(StableSolver_clique_main PUBLIC + StableSolver_clique_milp_cplex) +endif() +set_target_properties(StableSolver_clique_main PROPERTIES OUTPUT_NAME "stablesolver_clique") +install(TARGETS StableSolver_clique_main) diff --git a/stablesolver/clique/algorithm_formatter.cpp b/src/clique/algorithm_formatter.cpp similarity index 100% rename from stablesolver/clique/algorithm_formatter.cpp rename to src/clique/algorithm_formatter.cpp diff --git a/src/clique/algorithms/CMakeLists.txt b/src/clique/algorithms/CMakeLists.txt new file mode 100644 index 0000000..5c19e34 --- /dev/null +++ b/src/clique/algorithms/CMakeLists.txt @@ -0,0 +1,30 @@ +add_library(StableSolver_clique_greedy) +target_sources(StableSolver_clique_greedy PRIVATE + greedy.cpp) +target_include_directories(StableSolver_clique_greedy PUBLIC + ${PROJECT_SOURCE_DIR}/include) +target_link_libraries(StableSolver_clique_greedy PUBLIC + StableSolver_clique) +add_library(StableSolver::clique::greedy ALIAS StableSolver_clique_greedy) + +if(STABLESOLVER_USE_CPLEX) + add_library(StableSolver_clique_milp_cplex) + target_sources(StableSolver_clique_milp_cplex PRIVATE + milp_cplex.cpp) + target_include_directories(StableSolver_clique_milp_cplex PUBLIC + ${PROJECT_SOURCE_DIR}/include) + target_link_libraries(StableSolver_clique_milp_cplex PUBLIC + StableSolver_clique + MathOptSolversCMake::cplex) + add_library(StableSolver::clique::milp_cplex ALIAS StableSolver_clique_milp_cplex) +endif() + +add_library(StableSolver_clique_local_search) +target_sources(StableSolver_clique_local_search PRIVATE + local_search.cpp) +target_include_directories(StableSolver_clique_local_search PUBLIC + ${PROJECT_SOURCE_DIR}/include) +target_link_libraries(StableSolver_clique_local_search PUBLIC + StableSolver_clique + LocalSearchSolver::localsearchsolver) +add_library(StableSolver::clique::local_search ALIAS StableSolver_clique_local_search) diff --git a/stablesolver/clique/algorithms/greedy.cpp b/src/clique/algorithms/greedy.cpp similarity index 100% rename from stablesolver/clique/algorithms/greedy.cpp rename to src/clique/algorithms/greedy.cpp diff --git a/stablesolver/clique/algorithms/local_search.cpp b/src/clique/algorithms/local_search.cpp similarity index 100% rename from stablesolver/clique/algorithms/local_search.cpp rename to src/clique/algorithms/local_search.cpp diff --git a/stablesolver/clique/algorithms/milp_cplex.cpp b/src/clique/algorithms/milp_cplex.cpp similarity index 79% rename from stablesolver/clique/algorithms/milp_cplex.cpp rename to src/clique/algorithms/milp_cplex.cpp index df81903..8d0d6bb 100644 --- a/stablesolver/clique/algorithms/milp_cplex.cpp +++ b/src/clique/algorithms/milp_cplex.cpp @@ -1,21 +1,22 @@ -#if CPLEX_FOUND - #include "stablesolver/clique/algorithms/milp_cplex.hpp" +#include "stablesolver/clique/algorithm_formatter.hpp" + #include using namespace stablesolver::clique; ILOSTLBEGIN -ILOMIPINFOCALLBACK4(loggingCallback1, +ILOMIPINFOCALLBACK5(loggingCallback1, const Instance&, instance, - MilpCplexParameters&, parameters, + const MilpCplexParameters&, parameters, Output&, output, + AlgorithmFormatter&, algorithm_formatter, IloNumVarArray&, x) { VertexId ub = getBestObjValue(); - algorithm_formatter.update_bound(ub, std::stringstream(""), parameters.info); + algorithm_formatter.update_bound(ub, ""); if (!hasIncumbent()) return; @@ -30,10 +31,7 @@ ILOMIPINFOCALLBACK4(loggingCallback1, if (val[vertex_id] > 0.5) solution.add(vertex_id); } - algorithm_formatter.update_solution( - solution, - std::stringstream(""), - parameters.info); + algorithm_formatter.update_solution(solution, ""); } } @@ -47,7 +45,6 @@ const Output stablesolver::clique::milp_cplex( algorithm_formatter.print_header(); const optimizationtools::AbstractGraph* graph = instance.graph(); - Output output(instance, parameters.info); VertexId n = graph->number_of_vertices(); IloEnv env; @@ -105,7 +102,7 @@ const Output stablesolver::clique::milp_cplex( cplex.setParam(IloCplex::TiLim, parameters.timer.remaining_time()); // Callback - cplex.use(loggingCallback1(env, instance, parameters, output, x)); + cplex.use(loggingCallback1(env, instance, parameters, output, algorithm_formatter, x)); // Optimize cplex.solve(); @@ -121,15 +118,11 @@ const Output stablesolver::clique::milp_cplex( if (cplex.getValue(x[vertex_id]) > 0.5) solution.add(vertex_id); } - algorithm_formatter.update_solution( - solution, - std::stringstream(""), - parameters.info); + algorithm_formatter.update_solution(solution, ""); } algorithm_formatter.update_bound( output.solution.weight(), - std::stringstream(""), - parameters.info); + ""); } else if (cplex.isPrimalFeasible()) { if (output.solution.weight() < cplex.getObjValue() + 0.5) { Solution solution(instance); @@ -139,22 +132,13 @@ const Output stablesolver::clique::milp_cplex( if (cplex.getValue(x[vertex_id]) > 0.5) solution.add(vertex_id); } - algorithm_formatter.update_solution( - solution, - std::stringstream(""), - parameters.info); + algorithm_formatter.update_solution(solution, ""); } Weight ub = cplex.getBestObjValue(); - algorithm_formatter.update_bound( - ub, - std::stringstream(""), - parameters.info); + algorithm_formatter.update_bound(ub, ""); } else { Weight ub = cplex.getBestObjValue(); - algorithm_formatter.update_bound( - ub, - std::stringstream(""), - parameters.info); + algorithm_formatter.update_bound(ub, ""); } env.end(); @@ -162,5 +146,3 @@ const Output stablesolver::clique::milp_cplex( algorithm_formatter.end(); return output; } - -#endif diff --git a/stablesolver/clique/checker.cpp b/src/clique/bench.py similarity index 100% rename from stablesolver/clique/checker.cpp rename to src/clique/bench.py diff --git a/stablesolver/stable/checker.cpp b/src/clique/checker.cpp similarity index 100% rename from stablesolver/stable/checker.cpp rename to src/clique/checker.cpp diff --git a/stablesolver/clique/instance.cpp b/src/clique/instance.cpp similarity index 99% rename from stablesolver/clique/instance.cpp rename to src/clique/instance.cpp index 70993cb..5f28ef0 100644 --- a/stablesolver/clique/instance.cpp +++ b/src/clique/instance.cpp @@ -1,6 +1,7 @@ #include "stablesolver/clique/instance.hpp" #include +#include using namespace stablesolver::clique; diff --git a/stablesolver/clique/main.cpp b/src/clique/main.cpp similarity index 99% rename from stablesolver/clique/main.cpp rename to src/clique/main.cpp index e708c62..a1cfe23 100644 --- a/stablesolver/clique/main.cpp +++ b/src/clique/main.cpp @@ -2,7 +2,9 @@ #include "stablesolver/clique/solution.hpp" #include "stablesolver/clique/algorithms/greedy.hpp" +#if CPLEX_FOUND #include "stablesolver/clique/algorithms/milp_cplex.hpp" +#endif #include "stablesolver/clique/algorithms/local_search.hpp" #include diff --git a/stablesolver/clique/solution.cpp b/src/clique/solution.cpp similarity index 100% rename from stablesolver/clique/solution.cpp rename to src/clique/solution.cpp diff --git a/src/stable/CMakeLists.txt b/src/stable/CMakeLists.txt new file mode 100644 index 0000000..a6d3f0b --- /dev/null +++ b/src/stable/CMakeLists.txt @@ -0,0 +1,40 @@ +add_library(StableSolver_stable) +target_sources(StableSolver_stable PRIVATE + instance.cpp + instance_builder.cpp + solution.cpp + reduction.cpp + algorithm.cpp + algorithm_formatter.cpp) +target_include_directories(StableSolver_stable PUBLIC + ${PROJECT_SOURCE_DIR}/include) +target_link_libraries(StableSolver_stable PUBLIC + OptimizationTools::utils + OptimizationTools::containers) +add_library(StableSolver::stable ALIAS StableSolver_stable) + +add_subdirectory(algorithms) + +add_executable(StableSolver_stable_main) +target_sources(StableSolver_stable_main PRIVATE + main.cpp) +target_link_libraries(StableSolver_stable_main PUBLIC + StableSolver_stable_greedy + StableSolver_stable_local_search + StableSolver_stable_local_search_row_weighting + StableSolver_stable_large_neighborhood_search + Boost::program_options) +if(STABLESOLVER_USE_CBC) + target_compile_definitions(StableSolver_stable_main PUBLIC + CBC_FOUND=1) + target_link_libraries(StableSolver_stable_main PUBLIC + StableSolver_stable_milp_cbc) +endif() +if(STABLESOLVER_USE_CPLEX) + target_compile_definitions(StableSolver_stable_main PUBLIC + CPLEX_FOUND=1) + target_link_libraries(StableSolver_stable_main PUBLIC + StableSolver_stable_milp_cplex) +endif() +set_target_properties(StableSolver_stable_main PROPERTIES OUTPUT_NAME "stablesolver_stable") +install(TARGETS StableSolver_stable_main) diff --git a/stablesolver/stable/algorithm.cpp b/src/stable/algorithm.cpp similarity index 100% rename from stablesolver/stable/algorithm.cpp rename to src/stable/algorithm.cpp diff --git a/stablesolver/stable/algorithm_formatter.cpp b/src/stable/algorithm_formatter.cpp similarity index 100% rename from stablesolver/stable/algorithm_formatter.cpp rename to src/stable/algorithm_formatter.cpp diff --git a/src/stable/algorithms/CMakeLists.txt b/src/stable/algorithms/CMakeLists.txt new file mode 100644 index 0000000..ac8d1c3 --- /dev/null +++ b/src/stable/algorithms/CMakeLists.txt @@ -0,0 +1,62 @@ +add_library(StableSolver_stable_greedy) +target_sources(StableSolver_stable_greedy PRIVATE + greedy.cpp) +target_include_directories(StableSolver_stable_greedy PUBLIC + ${PROJECT_SOURCE_DIR}/include) +target_link_libraries(StableSolver_stable_greedy PUBLIC + StableSolver_stable) +add_library(StableSolver::stable::greedy ALIAS StableSolver_stable_greedy) + +if(STABLESOLVER_USE_CBC) + add_library(StableSolver_stable_milp_cbc) + target_sources(StableSolver_stable_milp_cbc PRIVATE + milp_cbc.cpp) + target_include_directories(StableSolver_stable_milp_cbc PUBLIC + ${PROJECT_SOURCE_DIR}/include) + target_link_libraries(StableSolver_stable_milp_cbc PUBLIC + StableSolver_stable + MathOptSolversCMake::cbc) + add_library(StableSolver::stable::milp_cbc ALIAS StableSolver_stable_milp_cbc) +endif() + +if(STABLESOLVER_USE_CPLEX) + add_library(StableSolver_stable_milp_cplex) + target_sources(StableSolver_stable_milp_cplex PRIVATE + milp_cplex.cpp) + target_include_directories(StableSolver_stable_milp_cplex PUBLIC + ${PROJECT_SOURCE_DIR}/include) + target_link_libraries(StableSolver_stable_milp_cplex PUBLIC + StableSolver_stable + StableSolver_clique_greedy + MathOptSolversCMake::cplex) + add_library(StableSolver::stable::milp_cplex ALIAS StableSolver_stable_milp_cplex) +endif() + +add_library(StableSolver_stable_local_search) +target_sources(StableSolver_stable_local_search PRIVATE + local_search.cpp) +target_include_directories(StableSolver_stable_local_search PUBLIC + ${PROJECT_SOURCE_DIR}/include) +target_link_libraries(StableSolver_stable_local_search PUBLIC + StableSolver_stable + LocalSearchSolver::localsearchsolver) +add_library(StableSolver::stable::local_search ALIAS StableSolver_stable_local_search) + +add_library(StableSolver_stable_local_search_row_weighting) +target_sources(StableSolver_stable_local_search_row_weighting PRIVATE + local_search_row_weighting.cpp) +target_include_directories(StableSolver_stable_local_search_row_weighting PUBLIC + ${PROJECT_SOURCE_DIR}/include) +target_link_libraries(StableSolver_stable_local_search_row_weighting PUBLIC + StableSolver_stable + StableSolver_stable_greedy) +add_library(StableSolver::stable::local_search_row_weighting ALIAS StableSolver_stable_local_search_row_weighting) + +add_library(StableSolver_stable_large_neighborhood_search) +target_sources(StableSolver_stable_large_neighborhood_search PRIVATE + large_neighborhood_search.cpp) +target_include_directories(StableSolver_stable_large_neighborhood_search PUBLIC + ${PROJECT_SOURCE_DIR}/include) +target_link_libraries(StableSolver_stable_large_neighborhood_search PUBLIC + StableSolver_stable) +add_library(StableSolver::stable::large_neighborhood_search ALIAS StableSolver_stable_large_neighborhood_search) diff --git a/stablesolver/stable/algorithms/greedy.cpp b/src/stable/algorithms/greedy.cpp similarity index 100% rename from stablesolver/stable/algorithms/greedy.cpp rename to src/stable/algorithms/greedy.cpp diff --git a/stablesolver/stable/algorithms/large_neighborhood_search.cpp b/src/stable/algorithms/large_neighborhood_search.cpp similarity index 100% rename from stablesolver/stable/algorithms/large_neighborhood_search.cpp rename to src/stable/algorithms/large_neighborhood_search.cpp diff --git a/stablesolver/stable/algorithms/local_search.cpp b/src/stable/algorithms/local_search.cpp similarity index 100% rename from stablesolver/stable/algorithms/local_search.cpp rename to src/stable/algorithms/local_search.cpp diff --git a/stablesolver/stable/algorithms/local_search_row_weighting.cpp b/src/stable/algorithms/local_search_row_weighting.cpp similarity index 100% rename from stablesolver/stable/algorithms/local_search_row_weighting.cpp rename to src/stable/algorithms/local_search_row_weighting.cpp diff --git a/stablesolver/stable/algorithms/milp_cbc.cpp b/src/stable/algorithms/milp_cbc.cpp similarity index 88% rename from stablesolver/stable/algorithms/milp_cbc.cpp rename to src/stable/algorithms/milp_cbc.cpp index fa8d7bd..e94881f 100644 --- a/stablesolver/stable/algorithms/milp_cbc.cpp +++ b/src/stable/algorithms/milp_cbc.cpp @@ -1,7 +1,7 @@ -#if COINOR_FOUND - #include "stablesolver/stable/algorithms/milp_cbc.hpp" +#include "stablesolver/stable/algorithm_formatter.hpp" + #include #include @@ -16,22 +16,26 @@ class SolHandler: public CbcEventHandler SolHandler( const Instance& instance, - MilpCbcParameters& parameters, - Output& output): + const MilpCbcParameters& parameters, + Output& output, + AlgorithmFormatter& algorithm_formatter): CbcEventHandler(), instance_(instance), parameters_(parameters), - output_(output) { } + output_(output), + algorithm_formatter_(algorithm_formatter) { } SolHandler( CbcModel *model, const Instance& instance, MilpCbcParameters& parameters, - Output& output): + Output& output, + AlgorithmFormatter& algorithm_formatter): CbcEventHandler(model), instance_(instance), parameters_(parameters), - output_(output) { } + output_(output), + algorithm_formatter_(algorithm_formatter) { } virtual ~SolHandler() { } @@ -39,15 +43,17 @@ class SolHandler: public CbcEventHandler CbcEventHandler(rhs), instance_(rhs.instance_), parameters_(rhs.parameters_), - output_(rhs.output_) { } + output_(rhs.output_), + algorithm_formatter_(rhs.algorithm_formatter_) { } SolHandler &operator=(const SolHandler &rhs) { if (this != &rhs) { CbcEventHandler::operator=(rhs); //this->instance_ = rhs.instance_; - this->parameters_ = rhs.parameters_; - this->output_ = rhs.output_; + //this->parameters_ = rhs.parameters_; + //this->output_ = rhs.output_; + //this->algorithm_formatter_ = rhs.algorithm_formatter_; } return *this; } @@ -57,8 +63,9 @@ class SolHandler: public CbcEventHandler private: const Instance& instance_; - MilpCbcParameters& parameters_; + const MilpCbcParameters& parameters_; Output& output_; + AlgorithmFormatter& algorithm_formatter_; }; @@ -68,7 +75,7 @@ CbcEventHandler::CbcAction SolHandler::event(CbcEvent whichEvent) return noAction; Weight ub = -model_->getBestPossibleObjValue(); - output_.update_bound(ub, ""); + algorithm_formatter_.update_bound(ub, ""); if ((whichEvent != solution && whichEvent != heuristicSolution)) // no solution found return noAction; @@ -87,7 +94,7 @@ CbcEventHandler::CbcAction SolHandler::event(CbcEvent whichEvent) if (solution_cbc[vertex_id] > 0.5) solution.add(vertex_id); } - output_.update_solution( + algorithm_formatter_.update_solution( solution, ""); } @@ -100,7 +107,7 @@ CbcEventHandler::CbcAction SolHandler::event(CbcEvent whichEvent) //////////////////////////////////////////////////////////////////////////////// const Output stablesolver::stable::milp_1_cbc( - const Instance& original_instance, + const Instance& instance, const MilpCbcParameters& parameters) { Output output(instance); @@ -190,7 +197,7 @@ const Output stablesolver::stable::milp_1_cbc( model.setObjSense(-1); // Callback - SolHandler sh(instance, parameters, output); + SolHandler sh(instance, parameters, output, algorithm_formatter); model.passInEventHandler(&sh); // Reduce printout @@ -248,5 +255,3 @@ const Output stablesolver::stable::milp_1_cbc( algorithm_formatter.end(); return output; } - -#endif diff --git a/stablesolver/stable/algorithms/milp_cplex.cpp b/src/stable/algorithms/milp_cplex.cpp similarity index 89% rename from stablesolver/stable/algorithms/milp_cplex.cpp rename to src/stable/algorithms/milp_cplex.cpp index 8589301..4029f4c 100644 --- a/stablesolver/stable/algorithms/milp_cplex.cpp +++ b/src/stable/algorithms/milp_cplex.cpp @@ -1,7 +1,6 @@ -#if CPLEX_FOUND - #include "stablesolver/stable/algorithms/milp_cplex.hpp" +#include "stablesolver/stable/algorithm_formatter.hpp" #include "stablesolver/clique/algorithms/greedy.hpp" #include @@ -10,10 +9,11 @@ using namespace stablesolver::stable; ILOSTLBEGIN -ILOMIPINFOCALLBACK4(loggingCallback1, +ILOMIPINFOCALLBACK5(loggingCallback1, const Instance&, instance, - MilpCplexParameters&, parameters, + const MilpCplexParameters&, parameters, Output&, output, + AlgorithmFormatter&, algorithm_formatter, IloNumVarArray&, x) { VertexId ub = getBestObjValue(); @@ -38,7 +38,7 @@ ILOMIPINFOCALLBACK4(loggingCallback1, //////////////////////////////////////////////////////////////////////////////// const Output stablesolver::stable::milp_1_cplex( - const Instance& original_instance, + const Instance& instance, const MilpCplexParameters& parameters) { Output output(instance); @@ -89,7 +89,7 @@ const Output stablesolver::stable::milp_1_cplex( cplex.setParam(IloCplex::TiLim, parameters.timer.remaining_time()); // Callback - cplex.use(loggingCallback1(env, instance, parameters, output, x)); + cplex.use(loggingCallback1(env, instance, parameters, output, algorithm_formatter, x)); // Optimize cplex.solve(); @@ -135,8 +135,8 @@ const Output stablesolver::stable::milp_1_cplex( /////////////////////////// Model 2, |V| constraints /////////////////////////// //////////////////////////////////////////////////////////////////////////////// -const Output stablesolver::milp_2_cplex( - const Instance& original_instance, +const Output stablesolver::stable::milp_2_cplex( + const Instance& instance, const MilpCplexParameters& parameters) { Output output(instance); @@ -191,7 +191,7 @@ const Output stablesolver::milp_2_cplex( cplex.setParam(IloCplex::TiLim, parameters.timer.remaining_time()); // Callback - cplex.use(loggingCallback1(env, instance, parameters, output, x)); + cplex.use(loggingCallback1(env, instance, parameters, output, algorithm_formatter, x)); // Optimize cplex.solve(); @@ -237,8 +237,8 @@ const Output stablesolver::milp_2_cplex( /////////////////////////// Model 1, |E| constraints /////////////////////////// //////////////////////////////////////////////////////////////////////////////// -const Output stablesolver::milp_3_cplex( - const Instance& original_instance, +const Output stablesolver::stable::milp_3_cplex( + const Instance& instance, const MilpCplexParameters& parameters) { Output output(instance); @@ -287,37 +287,43 @@ const Output stablesolver::milp_3_cplex( for (const auto& edge: instance.vertex(vertex_id_2).edges) if (vertex_set_1.contains(edge.vertex_id)) vertex_set_2.add(edge.vertex_id); - stablesolver::clique::Instance instance_clique(vertex_set_2.size()); + optimizationtools::AdjacencyListGraphBuilder graph_builder; + for (VertexId vertex_id = 0; vertex_id < vertex_set_2.size(); ++vertex_id) + graph_builder.add_vertex(); // Add edges for (auto it = vertex_set_2.begin(); it != vertex_set_2.end(); ++it) { for (const auto& edge: instance.vertex(*it).edges) { if (edge.vertex_id > *it && vertex_set_2.contains(edge.vertex_id)) { - edge_indices[instance_clique.adjacency_list_graph()->number_of_edges()] = edge.edge_id; - instance_clique.add_edge( + EdgeId edge_id = graph_builder.add_edge( vertex_set_2.position(*it), vertex_set_2.position(vertex_id_2)); + edge_indices[edge_id] = edge.edge_id; } } } + std::shared_ptr graph + = std::shared_ptr( + new optimizationtools::AdjacencyListGraph(graph_builder.build())); + stablesolver::clique::Instance clique_instance(graph); // Solve - auto output_clique = stablesolver::clique::greedy_gwmin(instance_clique); + auto clique_output = stablesolver::clique::greedy_gwmin(clique_instance); // Build constraint IloExpr expr(env); expr += x[vertex_id_1] + x[vertex_id_2]; for (const auto& edge: instance.vertex(vertex_id_1).edges) if (vertex_set_2.contains(edge.vertex_id) - && output_clique.solution.contains(vertex_set_2.position(edge.vertex_id))) + && clique_output.solution.contains(vertex_set_2.position(edge.vertex_id))) edge_set.add(edge.edge_id); for (const auto& edge: instance.vertex(vertex_id_2).edges) if (vertex_set_2.contains(edge.vertex_id) - && output_clique.solution.contains(vertex_set_2.position(edge.vertex_id))) + && clique_output.solution.contains(vertex_set_2.position(edge.vertex_id))) edge_set.add(edge.edge_id); - for (VertexId vertex_id_clique: output_clique.solution.vertices()) { + for (VertexId vertex_id_clique: clique_output.solution.vertices()) { VertexId vertex_id_orig = *(vertex_set_2.begin() + vertex_id_clique); expr += x[vertex_id_orig]; - for (const auto& edge: instance_clique.adjacency_list_graph()->edges(vertex_id_orig)) { - if (output_clique.solution.contains(edge.vertex_id) + for (const auto& edge: clique_instance.adjacency_list_graph()->edges(vertex_id_orig)) { + if (clique_output.solution.contains(edge.vertex_id) && edge.vertex_id > vertex_id_clique) edge_set.add(edge_indices[edge.edge_id]); } @@ -339,7 +345,7 @@ const Output stablesolver::milp_3_cplex( cplex.setParam(IloCplex::TiLim, parameters.timer.remaining_time()); // Callback - cplex.use(loggingCallback1(env, instance, parameters, output, x)); + cplex.use(loggingCallback1(env, instance, parameters, output, algorithm_formatter, x)); // Optimize cplex.solve(); @@ -381,5 +387,3 @@ const Output stablesolver::milp_3_cplex( algorithm_formatter.end(); return output; } - -#endif diff --git a/src/stable/bench.py b/src/stable/bench.py new file mode 100644 index 0000000..e69de29 diff --git a/src/stable/checker.cpp b/src/stable/checker.cpp new file mode 100644 index 0000000..e69de29 diff --git a/stablesolver/stable/instance.cpp b/src/stable/instance.cpp similarity index 99% rename from stablesolver/stable/instance.cpp rename to src/stable/instance.cpp index 90e9045..3037c4e 100644 --- a/stablesolver/stable/instance.cpp +++ b/src/stable/instance.cpp @@ -4,6 +4,7 @@ #include "optimizationtools/containers/indexed_set.hpp" #include +#include using namespace stablesolver::stable; diff --git a/stablesolver/stable/instance_builder.cpp b/src/stable/instance_builder.cpp similarity index 100% rename from stablesolver/stable/instance_builder.cpp rename to src/stable/instance_builder.cpp diff --git a/stablesolver/stable/main.cpp b/src/stable/main.cpp similarity index 93% rename from stablesolver/stable/main.cpp rename to src/stable/main.cpp index 482442e..da1a2f8 100644 --- a/stablesolver/stable/main.cpp +++ b/src/stable/main.cpp @@ -2,8 +2,12 @@ #include "stablesolver/stable/solution.hpp" #include "stablesolver/stable/algorithms/greedy.hpp" +#if CBC_FOUND #include "stablesolver/stable/algorithms/milp_cbc.hpp" +#endif +#if CPLEX_FOUND #include "stablesolver/stable/algorithms/milp_cplex.hpp" +#endif #include "stablesolver/stable/algorithms/local_search.hpp" #include "stablesolver/stable/algorithms/local_search_row_weighting.hpp" #include "stablesolver/stable/algorithms/large_neighborhood_search.hpp" @@ -72,13 +76,21 @@ Output run( } else if (algorithm == "milp-cbc") { MilpCbcParameters parameters; read_args(parameters, vm); - return milp_cbc(instance, parameters); + return milp_1_cbc(instance, parameters); #endif #if CPLEX_FOUND - } else if (algorithm == "milp-cplex") { + } else if (algorithm == "milp-1-cplex") { + MilpCplexParameters parameters; + read_args(parameters, vm); + return milp_1_cplex(instance, parameters); + } else if (algorithm == "milp-2-cplex") { + MilpCplexParameters parameters; + read_args(parameters, vm); + return milp_1_cplex(instance, parameters); + } else if (algorithm == "milp-3-cplex") { MilpCplexParameters parameters; read_args(parameters, vm); - return milp_cplex(instance, parameters); + return milp_1_cplex(instance, parameters); #endif } else if (algorithm == "local-search-row-weighting-1") { LocalSearchRowWeighting1Parameters parameters; diff --git a/stablesolver/stable/reduction.cpp b/src/stable/reduction.cpp similarity index 100% rename from stablesolver/stable/reduction.cpp rename to src/stable/reduction.cpp diff --git a/stablesolver/stable/solution.cpp b/src/stable/solution.cpp similarity index 100% rename from stablesolver/stable/solution.cpp rename to src/stable/solution.cpp diff --git a/stablesolver/BUILD b/stablesolver/BUILD deleted file mode 100644 index 50099d3..0000000 --- a/stablesolver/BUILD +++ /dev/null @@ -1,31 +0,0 @@ -load("@bazel_skylib//lib:selects.bzl", "selects") - -config_setting( - name = "cbc_build", - values = {"define": "cbc=true"}, - visibility = ["//visibility:public"], -) - -selects.config_setting_group( - name = "cbc_linux", - match_all = [":cbc_build", "@bazel_tools//src/conditions:linux"], -) - -selects.config_setting_group( - name = "cbc_windows", - match_all = [":cbc_build", "@bazel_tools//src/conditions:windows"], -) - -config_setting( - name = "cplex_build", - values = {"define": "cplex=true"}, - visibility = ["//visibility:public"], -) - -config_setting( - name = "xpress_build", - values = {"define": "xpress=true"}, - visibility = ["//visibility:public"] -) - -load("//stablesolver:variables.bzl", "STDCPP") diff --git a/stablesolver/clique/BUILD b/stablesolver/clique/BUILD deleted file mode 100644 index bc86ebb..0000000 --- a/stablesolver/clique/BUILD +++ /dev/null @@ -1,36 +0,0 @@ -load("//stablesolver:variables.bzl", "STDCPP") - -cc_library( - name = "clique", - hdrs = [ - "instance.hpp", - "solution.hpp", - "algorithm_formatter.hpp", - ], - srcs = [ - "instance.cpp", - "solution.cpp", - "algorithm_formatter.cpp", - ], - deps = [ - "@optimizationtools//optimizationtools/utils:utils", - "@optimizationtools//optimizationtools/containers:containers", - "@optimizationtools//optimizationtools/graph:graph", - ], - visibility = ["//visibility:public"], -) - -cc_binary( - name = "main", - srcs = ["main.cpp"], - deps = [ - "//stablesolver/clique/algorithms:greedy", - "//stablesolver/clique/algorithms:milp_cplex", - "//stablesolver/clique/algorithms:local_search", - "@boost//:program_options", - ], - linkopts = select({ - "@bazel_tools//src/conditions:windows": [], - "//conditions:default": ["-lpthread"], - }), -) diff --git a/stablesolver/clique/algorithms/BUILD b/stablesolver/clique/algorithms/BUILD deleted file mode 100644 index cfc2649..0000000 --- a/stablesolver/clique/algorithms/BUILD +++ /dev/null @@ -1,33 +0,0 @@ -load("//stablesolver:variables.bzl", "STDCPP", - "CPLEX_COPTS", "CPLEX_DEP") - -cc_library( - name = "greedy", - hdrs = ["greedy.hpp"], - srcs = ["greedy.cpp"], - deps = ["//stablesolver/clique:clique"], - visibility = ["//visibility:public"], -) - -cc_library( - name = "milp_cplex", - hdrs = ["milp_cplex.hpp"], - srcs = ["milp_cplex.cpp"], - deps = [ - "//stablesolver/clique:clique", - ] + CPLEX_DEP, - copts = CPLEX_COPTS, - visibility = ["//visibility:public"], -) - -cc_library( - name = "local_search", - hdrs = ["local_search.hpp"], - srcs = ["local_search.cpp"], - deps = [ - "//stablesolver/clique:clique", - ":greedy", - "@localsearchsolver//localsearchsolver:localsearchsolver", - ], - visibility = ["//visibility:public"], -) diff --git a/stablesolver/clique/algorithms/algorithms.cpp b/stablesolver/clique/algorithms/algorithms.cpp deleted file mode 100644 index 9ed884b..0000000 --- a/stablesolver/clique/algorithms/algorithms.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "stablesolver/clique/algorithms/algorithms.hpp" - -#include - -using namespace stablesolver::clique; -namespace po = boost::program_options; - -LocalSearchParameters read_local_search_args(const std::vector& argv) -{ - LocalSearchParameters parameters; - po::options_description desc("Allowed options"); - desc.add_options() - ("threads,t", po::value(¶meters.number_of_threads), "") - ; - po::variables_map vm; - po::store(po::parse_command_line((Counter)argv.size(), argv.data(), desc), vm); - try { - po::notify(vm); - } catch (const po::required_option& e) { - std::cout << desc << std::endl;; - throw ""; - } - return parameters; -} - -Output stablesolver::clique::run( - std::string algorithm, - const Instance& instance, - std::mt19937_64& generator, - optimizationtools::Info info) -{ - (void)generator; - - std::vector algorithm_args = po::split_unix(algorithm); - std::vector algorithm_argv; - for (Counter i = 0; i < (Counter)algorithm_args.size(); ++i) - algorithm_argv.push_back(const_cast(algorithm_args[i].c_str())); - - if (algorithm.empty() || algorithm_args[0].empty()) { - throw std::invalid_argument("Missing algorithm."); - - } else if (algorithm_args[0] == "greedy-gwmin") { - return greedy_gwmin(instance, info); - } else if (algorithm_args[0] == "greedy-strong") { - return greedy_strong(instance, info); - -#if CPLEX_FOUND - } else if (algorithm_args[0] == "milp-cplex") { - MilpCplexParameters parameters; - parameters.info = info; - return milp_cplex(instance, parameters); -#endif - - } else if (algorithm_args[0] == "local-search") { - auto parameters = read_local_search_args(algorithm_argv); - parameters.info = info; - return local_search(instance, generator, parameters); - - } else { - throw std::invalid_argument( - "Unknown algorithm \"" + algorithm_args[0] + "\"."); - } -} - diff --git a/stablesolver/stable/BUILD b/stablesolver/stable/BUILD deleted file mode 100644 index 075548e..0000000 --- a/stablesolver/stable/BUILD +++ /dev/null @@ -1,44 +0,0 @@ -load("//stablesolver:variables.bzl", "STDCPP") - -cc_library( - name = "stable", - hdrs = [ - "instance.hpp", - "instance_builder.hpp", - "solution.hpp", - "reduction.hpp", - "algorithm.hpp", - "algorithm_formatter.hpp", - ], - srcs = [ - "instance.cpp", - "instance_builder.cpp", - "solution.cpp", - "reduction.cpp", - "algorithm.cpp", - "algorithm_formatter.cpp", - ], - deps = [ - "@optimizationtools//optimizationtools/utils:utils", - "@optimizationtools//optimizationtools/containers:containers", - ], - visibility = ["//visibility:public"], -) - -cc_binary( - name = "main", - srcs = ["main.cpp"], - deps = [ - "//stablesolver/stable/algorithms:greedy", - "//stablesolver/stable/algorithms:milp_cbc", - "//stablesolver/stable/algorithms:milp_cplex", - "//stablesolver/stable/algorithms:local_search", - "//stablesolver/stable/algorithms:local_search_row_weighting", - "//stablesolver/stable/algorithms:large_neighborhood_search", - "@boost//:program_options", - ], - linkopts = select({ - "@bazel_tools//src/conditions:windows": [], - "//conditions:default": ["-lpthread"], - }), -) diff --git a/stablesolver/stable/algorithms/BUILD b/stablesolver/stable/algorithms/BUILD deleted file mode 100644 index 83aede3..0000000 --- a/stablesolver/stable/algorithms/BUILD +++ /dev/null @@ -1,67 +0,0 @@ -load("//stablesolver:variables.bzl", "STDCPP", - "CBC_COPTS", "CBC_DEP", - "CPLEX_COPTS", "CPLEX_DEP") - -cc_library( - name = "greedy", - hdrs = ["greedy.hpp"], - srcs = ["greedy.cpp"], - deps = ["//stablesolver/stable:stable"], - visibility = ["//visibility:public"], -) - -cc_library( - name = "milp_cbc", - hdrs = ["milp_cbc.hpp"], - srcs = ["milp_cbc.cpp"], - deps = [ - "//stablesolver/stable:stable", - ] + CBC_DEP, - copts = CBC_COPTS, - visibility = ["//visibility:public"], -) - -cc_library( - name = "milp_cplex", - hdrs = ["milp_cplex.hpp"], - srcs = ["milp_cplex.cpp"], - deps = [ - "//stablesolver/stable:stable", - "//stablesolver/clique/algorithms:greedy", - ] + CPLEX_DEP, - copts = CPLEX_COPTS, - visibility = ["//visibility:public"], -) - -cc_library( - name = "local_search", - hdrs = ["local_search.hpp"], - srcs = ["local_search.cpp"], - deps = [ - "//stablesolver/stable:stable", - "@localsearchsolver//localsearchsolver:localsearchsolver", - ], - visibility = ["//visibility:public"], -) - -cc_library( - name = "local_search_row_weighting", - hdrs = ["local_search_row_weighting.hpp"], - srcs = ["local_search_row_weighting.cpp"], - deps = [ - "//stablesolver/stable:stable", - ":greedy", - ], - visibility = ["//visibility:public"], -) - -cc_library( - name = "large_neighborhood_search", - hdrs = ["large_neighborhood_search.hpp"], - srcs = ["large_neighborhood_search.cpp"], - deps = [ - "//stablesolver/stable:stable", - ":greedy", - ], - visibility = ["//visibility:public"], -) diff --git a/stablesolver/stable/algorithms/algorithms.cpp b/stablesolver/stable/algorithms/algorithms.cpp deleted file mode 100644 index fd6acb3..0000000 --- a/stablesolver/stable/algorithms/algorithms.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "stablesolver/stable/algorithms/algorithms.hpp" - -#include - -using namespace stablesolver::stable; -namespace po = boost::program_options; - -LocalSearchParameters read_local_search_args(const std::vector& argv) -{ - LocalSearchParameters parameters; - po::options_description desc("Allowed options"); - desc.add_options() - ("threads,t", po::value(¶meters.number_of_threads), "") - ; - po::variables_map vm; - po::store(po::parse_command_line((Counter)argv.size(), argv.data(), desc), vm); - try { - po::notify(vm); - } catch (const po::required_option& e) { - std::cout << desc << std::endl;; - throw ""; - } - return parameters; -} - -LocalSearchRowWeighting1Parameters read_local_search_row_weighting_1_args(const std::vector& argv) -{ - LocalSearchRowWeighting1Parameters parameters; - po::options_description desc("Allowed options"); - desc.add_options() - ("iterations,i", po::value(¶meters.maximum_number_of_iterations), "") - ("iterations-without-improvement,w", po::value(¶meters.maximum_number_of_iterations_without_improvement), "") - ; - po::variables_map vm; - po::store(po::parse_command_line((Counter)argv.size(), argv.data(), desc), vm); - try { - po::notify(vm); - } catch (const po::required_option& e) { - std::cout << desc << std::endl;; - throw ""; - } - return parameters; -} - -LocalSearchRowWeighting2Parameters read_local_search_row_weighting_2_args(const std::vector& argv) -{ - LocalSearchRowWeighting2Parameters parameters; - po::options_description desc("Allowed options"); - desc.add_options() - ("iterations,i", po::value(¶meters.maximum_number_of_iterations), "") - ("iterations-without-improvement,w", po::value(¶meters.maximum_number_of_iterations_without_improvement), "") - ; - po::variables_map vm; - po::store(po::parse_command_line((Counter)argv.size(), argv.data(), desc), vm); - try { - po::notify(vm); - } catch (const po::required_option& e) { - std::cout << desc << std::endl;; - throw ""; - } - return parameters; -} - -LargeNeighborhoodSearchParameters read_large_neighborhood_search_args(const std::vector& argv) -{ - LargeNeighborhoodSearchParameters parameters; - po::options_description desc("Allowed options"); - desc.add_options() - ("iterations,i", po::value(¶meters.maximum_number_of_iterations), "") - ("iterations-without-improvement,w", po::value(¶meters.maximum_number_of_iterations_without_improvement), "") - ; - po::variables_map vm; - po::store(po::parse_command_line((Counter)argv.size(), argv.data(), desc), vm); - try { - po::notify(vm); - } catch (const po::required_option& e) { - std::cout << desc << std::endl;; - throw ""; - } - return parameters; -} - -Output stablesolver::stable::run( - std::string algorithm, - Instance& instance, - std::mt19937_64& generator, - optimizationtools::Info info) -{ - std::vector algorithm_args = po::split_unix(algorithm); - std::vector algorithm_argv; - for (Counter i = 0; i < (Counter)algorithm_args.size(); ++i) - algorithm_argv.push_back(const_cast(algorithm_args[i].c_str())); - - if (algorithm.empty() || algorithm_args[0].empty()) { - throw std::invalid_argument("Missing algorithm."); - - } else if (algorithm_args[0] == "greedy-gwmin") { - GreedyParameters parameters; - parameters.info = info; - return greedy_gwmin(instance, parameters); - } else if (algorithm_args[0] == "greedy-gwmax") { - GreedyParameters parameters; - parameters.info = info; - return greedy_gwmax(instance, parameters); - } else if (algorithm_args[0] == "greedy-gwmin2") { - GreedyParameters parameters; - parameters.info = info; - return greedy_gwmin2(instance, parameters); - } else if (algorithm_args[0] == "greedy-strong") { - GreedyParameters parameters; - parameters.info = info; - return greedy_strong(instance, parameters); - -#if COINOR_FOUND - } else if (algorithm_args[0] == "milp-1-cbc") { - MilpCbcParameters parameters; - parameters.info = info; - return milp_1_cbc(instance, parameters); -#endif -#if CPLEX_FOUND - } else if (algorithm_args[0] == "milp-1-cplex") { - MilpCplexParameters parameters; - parameters.info = info; - return milp_1_cplex(instance, parameters); - } else if (algorithm_args[0] == "milp-2-cplex") { - MilpCplexParameters parameters; - parameters.info = info; - return milp_2_cplex(instance, parameters); - } else if (algorithm_args[0] == "milp-3-cplex") { - MilpCplexParameters parameters; - parameters.info = info; - return milp_3_cplex(instance, parameters); -#endif - - } else if (algorithm_args[0] == "local-search") { - auto parameters = read_local_search_args(algorithm_argv); - parameters.info = info; - return local_search(instance, generator, parameters); - } else if (algorithm_args[0] == "local-search-row-weighting-1") { - auto parameters = read_local_search_row_weighting_1_args(algorithm_argv); - parameters.info = info; - return local_search_row_weighting_1(instance, generator, parameters); - } else if (algorithm_args[0] == "local-search-row-weighting-2") { - auto parameters = read_local_search_row_weighting_2_args(algorithm_argv); - parameters.info = info; - return local_search_row_weighting_2(instance, generator, parameters); - } else if (algorithm_args[0] == "large-neighborhood-search") { - auto parameters = read_large_neighborhood_search_args(algorithm_argv); - parameters.info = info; - return large_neighborhood_search(instance, parameters); - - } else { - throw std::invalid_argument( - "Unknown algorithm \"" + algorithm_args[0] + "\"."); - } -} - diff --git a/stablesolver/variables.bzl b/stablesolver/variables.bzl deleted file mode 100644 index a30d6c3..0000000 --- a/stablesolver/variables.bzl +++ /dev/null @@ -1,34 +0,0 @@ -STDCPP = select({ - "@bazel_tools//src/conditions:windows": ['/std:c++latest'], - "//conditions:default": ["-std=c++14"],}) - -CBC_COPTS = select({ - "//stablesolver:cbc_build": ["-DCBC_FOUND"], - "//conditions:default": []}) -CBC_DEP = select({ - "//stablesolver:cbc_windows": ["@cbc_windows//:cbc"], - "//conditions:default": [] - }) + select({ - "//stablesolver:cbc_linux": ["@cbc_linux//:cbc"], - "//conditions:default": []}) - -CPLEX_COPTS = select({ - "//stablesolver:cplex_build": [ - "-DCPLEX_FOUND", - "-m64", - "-DIL_STD"], - "//conditions:default": []}) -CPLEX_DEP = select({ - "//stablesolver:cplex_build": ["@cplex//:cplex"], - "//conditions:default": []}) - -XPRESS_COPTS = select({ - "//stablesolver:xpress_build": ["-DXPRESS_FOUND"], - "//conditions:default": []}) -XPRESS_DEP = select({ - "//stablesolver:xpress_build": ["@xpress//:xpress"], - "//conditions:default": []}) - -ALL_COPTS = CBC_COPTS + XPRESS_COPTS + CPLEX_COPTS -ALL_DEP = CBC_DEP + XPRESS_DEP + CPLEX_DEP - diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..da280ed --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,6 @@ +enable_testing() + +include(GoogleTest) + +add_subdirectory(clique) +add_subdirectory(stable) diff --git a/test/clique/CMakeLists.txt b/test/clique/CMakeLists.txt new file mode 100644 index 0000000..24c12bf --- /dev/null +++ b/test/clique/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(algorithms) diff --git a/test/clique/algorithms/CMakeLists.txt b/test/clique/algorithms/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/stable/CMakeLists.txt b/test/stable/CMakeLists.txt new file mode 100644 index 0000000..24c12bf --- /dev/null +++ b/test/stable/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(algorithms) diff --git a/test/stable/algorithms/CMakeLists.txt b/test/stable/algorithms/CMakeLists.txt new file mode 100644 index 0000000..e69de29