Skip to content

Commit 621e06f

Browse files
committed
Update MILP model
1 parent d720455 commit 621e06f

29 files changed

+444
-1736
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
if: ${{ (matrix.os == 'macos-13') || (matrix.os == 'macos-latest') }}
3535
- name: Build
3636
run: |
37-
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
37+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DGENERALIZEDASSIGNMENTSOLVER_USE_CLP=ON
3838
cmake --build build --config Release --parallel
3939
cmake --install build --config Release --prefix install
4040
- name: Run tests
@@ -46,7 +46,7 @@ jobs:
4646
git checkout master
4747
- name: Build
4848
run: |
49-
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
49+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DGENERALIZEDASSIGNMENTSOLVER_USE_CLP=ON
5050
cmake --build build --config Release --parallel
5151
cmake --install build --config Release --prefix install
5252
- name: Run tests

CMakeLists.txt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
cmake_minimum_required(VERSION 3.15.0)
1+
cmake_minimum_required(VERSION 3.28.0)
22

33
project(GeneralizedAssignmentSolver LANGUAGES CXX)
44

5-
option(GENERALIZEDASSIGNMENTSOLVER_USE_CBC "Use CBC" ON)
5+
# Build options.
6+
option(GENERALIZEDASSIGNMENTSOLVER_BUILD_MAIN "Build main" ON)
7+
option(GENERALIZEDASSIGNMENTSOLVER_BUILD_TEST "Build the unit tests" ON)
8+
9+
# Solver options.
10+
option(GENERALIZEDASSIGNMENTSOLVER_USE_CLP "Use CLP" OFF)
11+
option(GENERALIZEDASSIGNMENTSOLVER_USE_CBC "Use CBC" OFF)
12+
option(GENERALIZEDASSIGNMENTSOLVER_USE_HIGHS "Use HIGHS" OFF)
613
option(GENERALIZEDASSIGNMENTSOLVER_USE_GUROBI "Use Gurobi" OFF)
714
option(GENERALIZEDASSIGNMENTSOLVER_USE_CPLEX "Use CPLEX" OFF)
815
option(GENERALIZEDASSIGNMENTSOLVER_USE_KNITRO "Use Knitro" OFF)
@@ -22,4 +29,6 @@ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
2229
# Add sub-directories.
2330
add_subdirectory(extern)
2431
add_subdirectory(src)
25-
add_subdirectory(test)
32+
if(PACKINGSOLVER_BUILD_TEST)
33+
add_subdirectory(test)
34+
endif()

README.md

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
A solver for the generalized assignment problem.
44

5-
This problem is interesting because many different optimization methods can and have been applied to solve it (Branch-and-cut, Branch-and-price, Branch-and-relax, Local search, Constraint programming, Column generation heuristics...). Thus, the main goal of this repository is for me to have reference implementations for classical algorithms and optimization solvers.
6-
75
The variant handled here is the variant:
86
* with a minimization objective (items have costs)
97
* where all items have to be assigned
@@ -14,58 +12,39 @@ It is possible to solve the variant where not all items have to be assigned by a
1412

1513
## Implemented algorithms
1614

17-
### Lower bounds
18-
19-
- Linear relaxation
20-
- solved with CLP `-a linrelax-clp`
21-
- solved with Gurobi `-a "milp-gurobi --only-linear-relaxation"`
22-
- solved with Cplex `-a "milp-cplex --only-linear-relaxation"`
23-
24-
- Lagrangian relaxation of knapsack constraints. The value of this relaxation is the same as the value of the linear relaxation. However, it might be cheaper to compute, especially on large instances.
25-
- solved with volume method `-a lagrelax-knapsack-volume`
26-
- solved with L-BFGS method `-a lagrelax-knapsack-lbfgs`
27-
28-
- Lagrangian relaxation of assignment constraints
29-
- solved with volume method `-a lagrelax-assignment-volume`
30-
- solved with L-BFGS method `-a lagrelax-assignment-lbfgs`
31-
32-
- Column generation `-a "column-generation --linear-programming-solver clp"` `-a "column-generation --linear-programming-solver cplex"`
33-
34-
### Upper bounds
35-
3615
- Polynomial algorithms from "Generalized Assignment Problems" (Martello et al., 1992), options `--desirability cij` `--desirability wij` `--desirability cij*wij` `--desirability -pij/wij` `--desirability wij/ti`:
37-
- Basic greedy `-a "greedy --desirability wij"`
38-
- Greedy with regret measure `-a "greedy-regret --desirability wij"`
39-
- MTHG, basic greedy (+ n shifts) `-a "mthg --desirability wij"`
40-
- MTHG, greedy with regret measure (+ n shifts) `-a "mthg-regret --desirability wij"`
16+
- Basic greedy `--algorithm "greedy --desirability wij"`
17+
- Greedy with regret measure `--algorithm "greedy-regret --desirability wij"`
18+
- MTHG, basic greedy (+ n shifts) `--algorithm "mthg --desirability wij"`
19+
- MTHG, greedy with regret measure (+ n shifts) `--algorithm "mthg-regret --desirability wij"`
4120

42-
- Local search algorithm implemented with [fontanf/localsearchsolver](https://github.com/fontanf/localsearchsolver) `-a "local-search --threads 3"`
21+
- Mixed-Integer Linear Program
22+
- MILP `--algorithm milp --solver highs`
23+
- Linear relaxation `--algorithm linear-relaxation --solver highs`
4324

44-
- Tree search algorithms based on the Dantzig-Wolfe reformulation branching scheme (i.e. column generation heuristics) implemented with [fontanf/columngenerationsolver](https://github.com/fontanf/columngenerationsolver):
45-
- Greedy `-a "column-generation-heuristic-greedy --linear-programming-solver cplex"`
46-
- Limited discrepency search `-a "column-generation-heuristic-limited-discrepancy-search --linear-programming-solver cplex"`
25+
<!--- Constraint programming-->
26+
<!-- - with Gecode `--algorithm constraint-programming-gecode`-->
4727

48-
- Others heuristics:
49-
- Random feasible solution found with a Local search `-a random`
50-
- Local search with LocalSolver `-a localsolver`
28+
<!--- Lagrangian relaxation-->
29+
<!-- - of knapsack constraints. The value of this relaxation is the same as the value of the linear relaxation. However, it might be cheaper to compute, especially on large instances.-->
30+
<!-- - solved with volume method `--algorithm lagrangian-relaxation-knapsack-volume`-->
31+
<!-- - solved with L-BFGS method `--algorithm lagrangian-relaxation-knapsack-lbfgs`-->
32+
<!-- - of assignment constraints-->
33+
<!-- - solved with volume method `--algorithm lagrangian-relaxation-assignment-volume`-->
34+
<!-- - solved with L-BFGS method `--algorithm lagrangian-relaxation-assignment-lbfgs`-->
5135

52-
### Exact algorithms
36+
- Local search algorithm implemented with [fontanf/localsearchsolver](https://github.com/fontanf/localsearchsolver) `--algorithm "local-search --threads 3"`
5337

54-
- Mixed-Integer Linear Programs
55-
- with CBC `-a milp-cbc`
56-
- with CPLEX `-a milp-cplex`
57-
- with Gurobi `-a milp-gurobi`
58-
- with Knitro `-a milp-knitro`
59-
60-
- Constraint programming
61-
- with Gecode `-a constraint-programming-gecode`
62-
- with CPLEX `-a constraint-programming-cplex`
38+
- Tree search algorithms based on the Dantzig-Wolfe reformulation branching scheme (i.e. column generation heuristics) implemented with [fontanf/columngenerationsolver](https://github.com/fontanf/columngenerationsolver):
39+
- Column generation `--algorithm column-generation --linear-programming-solver highs`
40+
- Greedy `--algorithm column-generation-heuristic-greedy --linear-programming-solver highs`
41+
- Limited discrepency search `--algorithm column-generation-heuristic-limited-discrepancy-search --linear-programming-solver highs`
6342

6443
## Usage (command line)
6544

6645
Compile:
6746
```shell
68-
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
47+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DGENERALIZEDASSIGNMENTSOLVER_USE_HIGHS=ON
6948
cmake --build build --config Release --parallel
7049
cmake --install build --config Release --prefix install
7150
```

extern/CMakeLists.txt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ FetchContent_MakeAvailable(Boost)
1515
FetchContent_Declare(
1616
optimizationtools
1717
GIT_REPOSITORY https://github.com/fontanf/optimizationtools.git
18-
GIT_TAG a0973a7dfa64b9d305f75879c80d252e714ce2cf
18+
GIT_TAG e8c379203792fcad764cce239986b325619475fd
1919
#SOURCE_DIR "${PROJECT_SOURCE_DIR}/../optimizationtools/"
2020
EXCLUDE_FROM_ALL)
2121
FetchContent_MakeAvailable(optimizationtools)
@@ -24,28 +24,34 @@ FetchContent_MakeAvailable(optimizationtools)
2424
if(GENERALIZEDASSIGNMENTSOLVER_USE_CBC)
2525
set(MATHOPTSOLVERSCMAKE_USE_CBC ON)
2626
endif()
27+
if(GENERALIZEDASSIGNMENTSOLVER_USE_HIGHS)
28+
set(MATHOPTSOLVERSCMAKE_USE_HIGHS ON)
29+
endif()
2730
if(GENERALIZEDASSIGNMENTSOLVER_USE_CPLEX)
2831
set(MATHOPTSOLVERSCMAKE_USE_CPLEX ON)
2932
endif()
3033
FetchContent_Declare(
3134
mathoptsolverscmake
3235
GIT_REPOSITORY https://github.com/fontanf/mathoptsolverscmake.git
33-
GIT_TAG 4472814a28a40f4d861ccd757e140835c3a31bd0
36+
GIT_TAG f03fa63814eae3a253675ed14dd618a8a0d19a11
3437
#SOURCE_DIR "${PROJECT_SOURCE_DIR}/../mathoptsolverscmake/"
3538
EXCLUDE_FROM_ALL)
3639
FetchContent_MakeAvailable(mathoptsolverscmake)
3740

3841
# Fetch fontanf/columngenerationsolver.
39-
if(GENERALIZEDASSIGNMENTSOLVER_USE_CBC)
42+
if(GENERALIZEDASSIGNMENTSOLVER_USE_CLP)
4043
set(COLUMNGENERATIONSOLVER_USE_CLP ON)
4144
endif()
45+
if(GENERALIZEDASSIGNMENTSOLVER_USE_HIGHS)
46+
set(COLUMNGENERATIONSOLVER_USE_HIGHS ON)
47+
endif()
4248
if(GENERALIZEDASSIGNMENTSOLVER_USE_CPLEX)
4349
set(COLUMNGENERATIONSOLVER_USE_CPLEX ON)
4450
endif()
4551
FetchContent_Declare(
4652
columngenerationsolver
4753
GIT_REPOSITORY https://github.com/fontanf/columngenerationsolver.git
48-
GIT_TAG 17af477eb1ff576ce09b3d9a9c3369bdc7463c62
54+
GIT_TAG 556971624c92c23c961371ce5721ff9eb920a874
4955
#SOURCE_DIR "${PROJECT_SOURCE_DIR}/../columngenerationsolver/"
5056
EXCLUDE_FROM_ALL)
5157
FetchContent_MakeAvailable(columngenerationsolver)

include/generalizedassignmentsolver/algorithms/linear_relaxation_clp.hpp

Lines changed: 0 additions & 26 deletions
This file was deleted.

include/generalizedassignmentsolver/algorithms/milp_cbc.hpp renamed to include/generalizedassignmentsolver/algorithms/milp.hpp

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,19 @@
22

33
#include "generalizedassignmentsolver/solution.hpp"
44

5-
#include <coin/OsiCbcSolverInterface.hpp>
5+
#include "mathoptsolverscmake/milp.hpp"
66

77
namespace generalizedassignmentsolver
88
{
99

10-
struct CoinLP
10+
struct MilpParameters: Parameters
1111
{
12-
CoinLP(const Instance& instance);
12+
/** Solver. */
13+
mathoptsolverscmake::SolverName solver = mathoptsolverscmake::SolverName::Highs;
1314

14-
std::vector<double> column_lower_bounds;
15-
std::vector<double> column_upper_bounds;
16-
std::vector<double> objective;
17-
18-
std::vector<double> row_lower_bounds;
19-
std::vector<double> row_upper_bounds;
20-
CoinPackedMatrix matrix;
21-
};
22-
23-
}
24-
25-
#include <coin/CbcModel.hpp>
26-
27-
namespace generalizedassignmentsolver
28-
{
29-
30-
struct MilpCbcParameters: Parameters
31-
{
3215
/** Maximum number of nodes. */
3316
Counter maximum_number_of_nodes = -1;
3417

35-
/** Stop at first improvement. */
36-
bool stop_at_first_improvement = false;
37-
3818
/** Initial solution. */
3919
const Solution* initial_solution = NULL;
4020

@@ -47,7 +27,6 @@ struct MilpCbcParameters: Parameters
4727
int width = format_width();
4828
os
4929
<< std::setw(width) << std::left << "Maximum number of nodes: " << maximum_number_of_nodes << std::endl
50-
<< std::setw(width) << std::left << "Stop at first improvement: " << maximum_number_of_nodes << std::endl
5130
<< std::setw(width) << std::left << "Has initial solution: " << (initial_solution != nullptr) << std::endl
5231
;
5332
}
@@ -57,16 +36,15 @@ struct MilpCbcParameters: Parameters
5736
nlohmann::json json = Parameters::to_json();
5837
json.merge_patch({
5938
{"MaximumNumberOfNodes", maximum_number_of_nodes},
60-
{"StopAtFirstImprovement", stop_at_first_improvement},
6139
{"HasInitialSolution", (initial_solution != nullptr)},
6240
});
6341
return json;
6442
}
6543
};
6644

67-
struct MilpCbcOutput: Output
45+
struct MilpOutput: Output
6846
{
69-
MilpCbcOutput(
47+
MilpOutput(
7048
const Instance& instance):
7149
Output(instance) { }
7250

@@ -93,8 +71,9 @@ struct MilpCbcOutput: Output
9371
}
9472
};
9573

96-
const MilpCbcOutput milp_cbc(
74+
MilpOutput milp(
9775
const Instance& instance,
98-
const MilpCbcParameters& parameters = {});
76+
const Solution* initial_solution = nullptr,
77+
const MilpParameters& parameters = {});
9978

10079
}

include/generalizedassignmentsolver/algorithms/milp_cplex.hpp

Lines changed: 0 additions & 33 deletions
This file was deleted.

include/generalizedassignmentsolver/algorithms/milp_gurobi.hpp

Lines changed: 0 additions & 34 deletions
This file was deleted.

include/generalizedassignmentsolver/algorithms/random.hpp

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)