Skip to content

Commit 1c4e877

Browse files
committed
Merge branch 'main' of github.com:google/or-tools
2 parents e0c05ab + 5e598c0 commit 1c4e877

21 files changed

Lines changed: 1102 additions & 292 deletions

ortools/algorithms/README.md

Lines changed: 3 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,69 +2,6 @@
22

33
This directory contains data structures and algorithms for various problems.
44

5-
## Set covering
6-
7-
An instance of set covering is composed of two entities: elements and sets; sets
8-
cover a series of elements. The problem of set covering is about finding the
9-
cheapest combination of sets that cover all the elements.
10-
11-
[More information on Wikipedia](https://en.wikipedia.org/wiki/Set_cover_problem).
12-
13-
* Solver: [`set_cover_heuristics.h`](set_cover_heuristics.h).
14-
* Instance representation: [`set_cover_model.h`](set_cover_model.h).
15-
* Instance parser: [`set_cover_reader.h`](set_cover_reader.h).
16-
17-
Create an instance:
18-
19-
```cpp
20-
// If the elements are integers, a subset can be a std::vector<int> (in a pair
21-
// along its cost).
22-
std::vector<std::pair<std::vector<int>, int>> subsets = ...;
23-
24-
SetCoverModel model;
25-
for (const auto [subset, subset_cost] : subsets) {
26-
model.AddEmptySubset(subset_cost)
27-
for (const int element : subset) {
28-
model.AddElementToLastSubset(element);
29-
}
30-
}
31-
SetCoverLedger ledger(&model);
32-
```
33-
34-
Solve it using a MIP solver (guarantees to yield the optimum solution if it has
35-
enough time to run):
36-
37-
```cpp
38-
SetCoverMip mip(&ledger);
39-
mip.SetTimeLimitInSeconds(10);
40-
mip.NextSolution();
41-
SubsetBoolVector best_choices = ledger.GetSolution();
42-
LOG(INFO) << "Cost: " << ledger.cost();
43-
```
44-
45-
A custom combination of heuristics (10,000 iterations of: clearing 10% of the
46-
variables, running a Chvatal greedy descent, using steepest local search):
47-
48-
```cpp
49-
Cost best_cost = std::numeric_limits<Cost>::max();
50-
SubsetBoolVector best_choices = ledger.GetSolution();
51-
for (int i = 0; i < 10000; ++i) {
52-
ledger.LoadSolution(best_choices);
53-
ClearRandomSubsets(0.1 * model.num_subsets().value(), &ledger);
54-
55-
GreedySolutionGenerator greedy(&ledger);
56-
CHECK(greedy.NextSolution());
57-
58-
SteepestSearch steepest(&ledger);
59-
CHECK(steepest.NextSolution(10000));
60-
61-
EXPECT_TRUE(ledger.CheckSolution());
62-
if (ledger.cost() < best_cost) {
63-
best_cost = ledger.cost();
64-
best_choices = ledger.GetSolution();
65-
LOG(INFO) << "Better cost: " << best_cost << " at iteration = " << i;
66-
}
67-
}
68-
ledger.LoadSolution(best_choices);
69-
LOG(INFO) << "Best cost: " << ledger.cost();
70-
```
5+
It used to contain a solver for set covering, which has moved to the
6+
[set_cover](../set_cover)
7+
folder.

ortools/julia/ORTools.jl/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ version = "1.0.0-DEV"
44

55
[deps]
66
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
7+
ORTools_jll = "717719f8-c30c-5086-8f3c-70cd6a1e3a46"
78
ORToolsGenerated = "6b269722-41d3-11ee-be56-0242ac120002"
89
ProtoBuf = "3349acd9-ac6a-5e09-bcdb-63829b23a429"
910
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
module ORTools
2-
# TODO: b/384496822 - Run formatter across entire package
2+
3+
import MathOptInterface as MOI
4+
using ORTools_jll
5+
6+
include("moi_wrapper/Type_wrappers.jl")
7+
include("c_wrapper/c_wrapper.jl")
38
include("moi_wrapper/MOI_wrapper.jl")
49

10+
511
end
Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using ORTools_jll
2+
13
libortools = ORTools_jll.libortools
24

35
# Keep this file in sync with math_opt/core/c_api/solver.h.
@@ -6,54 +8,52 @@ libortools = ORTools_jll.libortools
68
# on the Julia side, as it's only an opaque pointer for this API.
79

810
function MathOptNewInterrupter()
9-
return ccall((:MathOptNewInterrupter, libortools),
10-
Ptr{Cvoid},
11-
())
11+
return ccall((:MathOptNewInterrupter, libortools), Ptr{Cvoid}, ())
1212
end
1313

1414
function MathOptFreeInterrupter(ptr)
15-
return ccall((:MathOptFreeInterrupter, libortools),
16-
Cvoid,
17-
(Ptr{Cvoid},),
18-
ptr)
15+
return ccall((:MathOptFreeInterrupter, libortools), Cvoid, (Ptr{Cvoid},), ptr)
1916
end
2017

2118
function MathOptInterrupt(ptr)
22-
return ccall((:MathOptInterrupt, libortools),
23-
Cvoid,
24-
(Ptr{Cvoid},),
25-
ptr)
19+
return ccall((:MathOptInterrupt, libortools), Cvoid, (Ptr{Cvoid},), ptr)
2620
end
2721

2822
function MathOptIsInterrupted(ptr)
29-
return ccall((:MathOptIsInterrupted, libortools),
30-
Cint,
31-
(Ptr{Cvoid},),
32-
ptr)
23+
return ccall((:MathOptIsInterrupted, libortools), Cint, (Ptr{Cvoid},), ptr)
3324
end
3425

3526
function MathOptFree(ptr)
36-
return ccall((:MathOptFree, libortools),
37-
Cvoid,
38-
(Ptr{Cvoid},),
39-
ptr)
27+
return ccall((:MathOptFree, libortools), Cvoid, (Ptr{Cvoid},), ptr)
4028
end
4129

42-
function MathOptSolve(model, model_size, solver_type, interrupter, solve_result, solve_result_size, status_msg)
43-
return ccall((:MathOptSolve, libortools),
44-
Cint,
45-
(Ptr{Cvoid},
46-
Csize_t,
47-
Cint,
48-
Ptr{Cvoid},
49-
Ptr{Ptr{Cvoid}},
50-
Ptr{Csize_t},
51-
Ptr{Ptr{Cchar}}),
52-
model,
53-
model_size,
54-
solver_type,
55-
interrupter,
56-
solve_result,
57-
solve_result_size,
58-
status_msg)
30+
function MathOptSolve(
31+
model,
32+
model_size,
33+
solver_type,
34+
interrupter,
35+
solve_result,
36+
solve_result_size,
37+
status_msg,
38+
)
39+
return ccall(
40+
(:MathOptSolve, libortools),
41+
Cint,
42+
(
43+
Ptr{Cvoid},
44+
Csize_t,
45+
Cint,
46+
Ptr{Cvoid},
47+
Ptr{Ptr{Cvoid}},
48+
Ptr{Csize_t},
49+
Ptr{Ptr{Cchar}},
50+
),
51+
model,
52+
model_size,
53+
solver_type,
54+
interrupter,
55+
solve_result,
56+
solve_result_size,
57+
status_msg,
58+
)
5959
end
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# TODO: b/407034730 - remove this file.
2+
import MathOptInterface as MOI
3+
include("ORTools.jl")
4+
5+
"""
6+
Solving the following optimization problem:
7+
8+
max x + 2⋅y
9+
10+
subject to: x + y ≤ 1.5
11+
-1 ≤ x ≤ 1.5
12+
0 ≤ y ≤ 1
13+
"""
14+
15+
function main(ARGS)
16+
optimizer = ORTools.Optimizer()
17+
c = [1.0, 2.0]
18+
19+
# Variables definition
20+
x = MOI.add_variables(optimizer, length(c))
21+
22+
# Set the objective
23+
MOI.set(
24+
optimizer,
25+
MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),
26+
MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(c, x), 0.0),
27+
)
28+
29+
MOI.set(optimizer, MOI.ObjectiveSense(), MOI.MAX_SENSE)
30+
31+
# The first constraint (x + y <= 1.5)
32+
C1 = 1.5
33+
MOI.add_constraint(
34+
optimizer,
35+
MOI.ScalarAffineFunction(
36+
[MOI.ScalarAffineTerm(1.0, x[1]), MOI.ScalarAffineTerm(1.0, x[2])],
37+
0.0,
38+
),
39+
MOI.LessThan(C1),
40+
)
41+
42+
## The second constraint (-1 <= x <= 1.5)
43+
MOI.add_constraint(optimizer, MOI.VariableIndex(1), MOI.Interval(-1.0, 1.5))
44+
45+
## The third constraint (0 <= y <= 1)
46+
MOI.add_constraint(optimizer, MOI.VariableIndex(2), MOI.Interval(0.0, 1.0))
47+
48+
print(optimizer)
49+
50+
# Optimize the model
51+
MOI.optimize!(optimizer)
52+
53+
# Print the solution
54+
print(optimizer.solve_result)
55+
56+
return 0
57+
end
58+
59+
# TODO: Understand why the solver stopped.
60+
# TODO: Understand what solution was returned.
61+
# TODO: Query the objective.
62+
# TODO: Query the primal solution.
63+
main(ARGS)

0 commit comments

Comments
 (0)