Skip to content

Commit 364df25

Browse files
authored
New release (#33)
* Add usual constraints from XCSP3 (#29) * Fix AllDifferent with param too * AllDiff and AllEq * Cardinality * Channel * Circuit * Count * Cumulative * Element * Extension * Instantiation * Intention (DistDifferent) * Maximum * Minimum * MDD * NValues * No Overlap * Ordered * Regular * Sum * Test items and fixes * Fix test items * Update Project.toml * Update Project.toml * Update compat * Fix test and printing bug for objectives (#32) * Basic tests for MOI/JuMP * Solve the printing issue for objectives
1 parent 4396243 commit 364df25

File tree

10 files changed

+338
-145
lines changed

10 files changed

+338
-145
lines changed

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "CBLS"
22
uuid = "a3809bfe-37bb-4d48-a667-bac4c6be8d90"
33
authors = ["Jean-Francois Baffier"]
4-
version = "0.2.0"
4+
version = "0.2.1"
55

66
[deps]
77
ConstraintCommons = "e37357d9-0691-492f-a822-e5ea6a920954"
@@ -12,6 +12,7 @@ JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
1212
Lazy = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0"
1313
LocalSearchSolvers = "2b10edaa-728d-4283-ac71-07e312d6ccf3"
1414
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
15+
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
1516
TestItems = "1c621080-faea-4a02-84b6-bbd5e436b8fe"
1617

1718
[compat]

src/CBLS.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ using JuMP
88
using Lazy
99
using LocalSearchSolvers
1010
using MathOptInterface
11+
using Pkg
1112
using TestItems
1213

1314
# Const
@@ -30,7 +31,8 @@ const VAR_TYPES = Union{MOI.ZeroOne, MOI.Integer}
3031
export DiscreteSet
3132

3233
# Export: Constraints
33-
export Error, Predicate
34+
export Error
35+
export Intention, Predicate
3436

3537
export AllDifferent
3638
export AllEqual

src/MOI_wrapper.jl

Lines changed: 149 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
"""
22
JuMP.build_variable(::Function, info::JuMP.VariableInfo, set::T) where T <: MOI.AbstractScalarSet
33
4-
DOCSTRING
4+
Create a variable constrained by a scalar set.
55
6-
# Arguments:
7-
- ``: DESCRIPTION
8-
- `info`: DESCRIPTION
9-
- `set`: DESCRIPTION
6+
# Arguments
7+
- `info::JuMP.VariableInfo`: Information about the variable to be created.
8+
- `set::T where T <: MOI.AbstractScalarSet`: The set defining the constraints on the variable.
9+
10+
# Returns
11+
- `JuMP.VariableConstrainedOnCreation`: A variable constrained by the specified set.
1012
"""
1113
function JuMP.build_variable(
1214
::Function,
@@ -19,12 +21,12 @@ end
1921
"""
2022
Optimizer <: MOI.AbstractOptimizer
2123
22-
DOCSTRING
24+
Defines an optimizer for CBLS.
2325
24-
# Arguments:
25-
- `solver::Solver`: DESCRIPTION
26-
- `status::MOI.TerminationStatusCode`: DESCRIPTION
27-
- `options::Options`: DESCRIPTION
26+
# Fields
27+
- `solver::LS.MainSolver`: The main solver used for local search.
28+
- `int_vars::Set{Int}`: Set of integer variables.
29+
- `compare_vars::Set{Int}`: Set of variables to compare.
2830
"""
2931
mutable struct Optimizer <: MOI.AbstractOptimizer
3032
solver::LS.MainSolver
@@ -35,7 +37,14 @@ end
3537
"""
3638
Optimizer(model = Model(); options = Options())
3739
38-
DOCSTRING
40+
Create an instance of the Optimizer.
41+
42+
# Arguments
43+
- `model`: The model to be optimized.
44+
- `options::Options`: Options for configuring the solver.
45+
46+
# Returns
47+
- `Optimizer`: An instance of the optimizer.
3948
"""
4049
function Optimizer(model = model(); options = Options())
4150
return Optimizer(
@@ -51,52 +60,104 @@ end
5160
@forward Optimizer.solver LS._best_bound, LS.best_value, LS.is_sat, LS.get_value
5261
@forward Optimizer.solver LS.domain_size, LS.best_values, LS._max_cons, LS.update_domain!
5362
@forward Optimizer.solver LS.get_variable, LS.has_solution, LS.sense, LS.sense!
54-
@forward Optimizer.solver LS.time_info, LS.status
63+
@forward Optimizer.solver LS.time_info, LS.status, LS.length_vars
5564

5665
# forward functions from Solver (from Options)
5766
@forward Optimizer.solver LS._verbose, LS.set_option!, LS.get_option
5867

5968
"""
60-
MOI.get(::Optimizer, ::MOI.SolverName) = begin
69+
MOI.get(::Optimizer, ::MOI.SolverName)
70+
71+
Get the name of the solver.
6172
62-
DOCSTRING
73+
# Arguments
74+
- `::Optimizer`: The optimizer instance.
75+
76+
# Returns
77+
- `String`: The name of the solver.
6378
"""
64-
MOI.get(::Optimizer, ::MOI.SolverName) = "LocalSearchSolvers"
79+
MOI.get(::Optimizer, ::MOI.SolverName) = "CBLS"
6580

6681
"""
67-
MOI.set(::Optimizer, ::MOI.Silent, bool = true) = begin
82+
MOI.set(::Optimizer, ::MOI.Silent, bool = true)
83+
84+
Set the verbosity of the solver.
6885
69-
DOCSTRING
86+
# Arguments
87+
- `::Optimizer`: The optimizer instance.
88+
- `::MOI.Silent`: The silent option for the solver.
89+
- `bool::Bool`: Whether to set the solver to silent mode.
7090
71-
# Arguments:
72-
- ``: DESCRIPTION
73-
- ``: DESCRIPTION
74-
- `bool`: DESCRIPTION
91+
# Returns
92+
- `Nothing`
7593
"""
7694
MOI.set(::Optimizer, ::MOI.Silent, bool = true) = @debug "TODO: Silent"
7795

7896
"""
79-
MOI.is_empty(model::Optimizer) = begin
97+
MOI.is_empty(model::Optimizer)
98+
99+
Check if the model is empty.
80100
81-
DOCSTRING
101+
# Arguments
102+
- `model::Optimizer`: The optimizer instance.
103+
104+
# Returns
105+
- `Bool`: True if the model is empty, false otherwise.
82106
"""
83107
MOI.is_empty(model::Optimizer) = LS._is_empty(model.solver)
84108

85109
"""
86-
Copy constructor for the optimizer
110+
MOI.supports_incremental_interface(::Optimizer)
111+
112+
Check if the optimizer supports incremental interface.
113+
114+
# Arguments
115+
- `::Optimizer`: The optimizer instance.
116+
117+
# Returns
118+
- `Bool`: True if the optimizer supports incremental interface, false otherwise.
87119
"""
88120
MOI.supports_incremental_interface(::Optimizer) = true
121+
122+
"""
123+
MOI.copy_to(model::Optimizer, src::MOI.ModelLike)
124+
125+
Copy the source model to the optimizer.
126+
127+
# Arguments
128+
- `model::Optimizer`: The optimizer instance.
129+
- `src::MOI.ModelLike`: The source model to be copied.
130+
131+
# Returns
132+
- `Nothing`
133+
"""
89134
function MOI.copy_to(model::Optimizer, src::MOI.ModelLike)
90135
return MOIU.default_copy_to(model, src)
91136
end
92137

93138
"""
94139
MOI.optimize!(model::Optimizer)
140+
141+
Optimize the model using the optimizer.
142+
143+
# Arguments
144+
- `model::Optimizer`: The optimizer instance.
145+
146+
# Returns
147+
- `Nothing`
95148
"""
96149
MOI.optimize!(optimizer::Optimizer) = solve!(optimizer.solver)
97150

98151
"""
99152
DiscreteSet(values)
153+
154+
Create a discrete set of values.
155+
156+
# Arguments
157+
- `values::Vector{T}`: A vector of values to include in the set.
158+
159+
# Returns
160+
- `DiscreteSet{T}`: A discrete set containing the specified values.
100161
"""
101162
struct DiscreteSet{T <: Number} <: MOI.AbstractScalarSet
102163
values::Vector{T}
@@ -105,22 +166,82 @@ DiscreteSet(values) = DiscreteSet(collect(values))
105166
DiscreteSet(values::T...) where {T <: Number} = DiscreteSet(collect(values))
106167

107168
"""
108-
Base.copy(set::DiscreteSet) = begin
169+
Base.copy(set::DiscreteSet)
170+
171+
Copy a discrete set.
172+
173+
# Arguments
174+
- `set::DiscreteSet`: The discrete set to be copied.
109175
110-
DOCSTRING
176+
# Returns
177+
- `DiscreteSet`: A copy of the discrete set.
111178
"""
112179
Base.copy(set::DiscreteSet) = DiscreteSet(copy(set.values))
113180

114181
"""
115-
MOI.empty!(opt) = begin
182+
MOI.empty!(opt)
116183
117-
DOCSTRING
184+
Empty the optimizer.
185+
186+
# Arguments
187+
- `opt::Optimizer`: The optimizer instance.
188+
189+
# Returns
190+
- `Nothing`
118191
"""
119192
MOI.empty!(opt) = empty!(opt)
120193

194+
"""
195+
MOI.is_valid(optimizer::Optimizer, index::CI{VI, MOI.Integer})
196+
197+
Check if an index is valid for the optimizer.
198+
199+
# Arguments
200+
- `optimizer::Optimizer`: The optimizer instance.
201+
- `index::CI{VI, MOI.Integer}`: The index to be checked.
202+
203+
# Returns
204+
- `Bool`: True if the index is valid, false otherwise.
205+
"""
121206
function MOI.is_valid(optimizer::Optimizer, index::CI{VI, MOI.Integer})
122207
return index.value optimizer.int_vars
123208
end
124209

210+
"""
211+
Base.copy(op::F) where {F <: Function}
212+
213+
Copy a function.
214+
215+
# Arguments
216+
- `op::F`: The function to be copied.
217+
218+
# Returns
219+
- `F`: The copied function.
220+
"""
125221
Base.copy(op::F) where {F <: Function} = op
222+
223+
"""
224+
Base.copy(::Nothing)
225+
226+
Copy a `Nothing` value.
227+
228+
# Arguments
229+
- `::Nothing`: The `Nothing` value to be copied.
230+
231+
# Returns
232+
- `Nothing`: The copied `Nothing` value.
233+
"""
126234
Base.copy(::Nothing) = nothing
235+
236+
"""
237+
Moi.get(::Optimizer, ::MOI.SolverVersion)
238+
239+
Get the version of the solver, here `LocalSearchSolvers.jl`.
240+
"""
241+
function MOI.get(::Optimizer, ::MOI.SolverVersion)
242+
deps = Pkg.dependencies()
243+
local_search_solver_uuid = Base.UUID("2b10edaa-728d-4283-ac71-07e312d6ccf3")
244+
return "v" * string(deps[local_search_solver_uuid].version)
245+
end
246+
247+
MOI.get(opt::Optimizer, ::MOI.NumberOfVariables) = LS.length_vars(opt)

0 commit comments

Comments
 (0)