Skip to content

Commit fd9587e

Browse files
authored
Filter Parameters in conflicts (#174)
* Filter Parameters in conflicts * test parameters in conflict * [no ci] bump version
1 parent 049737b commit fd9587e

File tree

4 files changed

+138
-7
lines changed

4 files changed

+138
-7
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ParametricOptInterface"
22
uuid = "0ce4ce61-57bf-432b-a095-efac525d185e"
33
authors = ["Tomás Gutierrez <[email protected]>"]
4-
version = "0.10.1"
4+
version = "0.11.0"
55

66
[deps]
77
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"

src/MOI_wrapper.jl

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ function MOI.is_empty(model::Optimizer)
100100
isempty(model.multiplicative_parameters_pp) &&
101101
isempty(model.dual_value_of_parameters) &&
102102
model.number_of_parameters_in_model == 0 &&
103+
isempty(model.parameters_in_conflict) &&
103104
isempty(model.ext)
104105
end
105106

@@ -135,6 +136,7 @@ function MOI.empty!(model::Optimizer{T}) where {T}
135136
empty!(model.dual_value_of_parameters)
136137
#
137138
model.number_of_parameters_in_model = 0
139+
empty!(model.parameters_in_conflict)
138140
empty!(model.ext)
139141
return
140142
end
@@ -1594,13 +1596,75 @@ end
15941596
#
15951597

15961598
function MOI.compute_conflict!(model::Optimizer)
1597-
return MOI.compute_conflict!(model.optimizer)
1599+
empty!(model.parameters_in_conflict)
1600+
MOI.compute_conflict!(model.optimizer)
1601+
if MOI.get(model.optimizer, MOI.ConflictStatus()) == MOI.CONFLICT_FOUND
1602+
for (F, S) in keys(model.affine_constraint_cache.dict)
1603+
affine_constraint_cache_inner = model.affine_constraint_cache[F, S]
1604+
for (inner_ci, pf) in affine_constraint_cache_inner
1605+
if MOI.get(
1606+
model.optimizer,
1607+
MOI.ConstraintConflictStatus(),
1608+
inner_ci,
1609+
) == MOI.NOT_IN_CONFLICT
1610+
continue
1611+
end
1612+
for term in pf.p
1613+
push!(model.parameters_in_conflict, term.variable)
1614+
end
1615+
end
1616+
end
1617+
for (F, S) in keys(model.quadratic_constraint_cache.dict)
1618+
quadratic_constraint_cache_inner =
1619+
model.quadratic_constraint_cache[F, S]
1620+
for (inner_ci, pf) in quadratic_constraint_cache_inner
1621+
if MOI.get(
1622+
model.optimizer,
1623+
MOI.ConstraintConflictStatus(),
1624+
inner_ci,
1625+
) == MOI.NOT_IN_CONFLICT
1626+
continue
1627+
end
1628+
for term in pf.p
1629+
push!(model.parameters_in_conflict, term.variable)
1630+
end
1631+
for term in pf.pp
1632+
push!(model.parameters_in_conflict, term.variable_1)
1633+
push!(model.parameters_in_conflict, term.variable_2)
1634+
end
1635+
for term in pf.pv
1636+
push!(model.parameters_in_conflict, term.variable_1)
1637+
end
1638+
end
1639+
end
1640+
for (F, S) in keys(model.vector_affine_constraint_cache.dict)
1641+
vector_affine_constraint_cache_inner =
1642+
model.vector_affine_constraint_cache[F, S]
1643+
for (inner_ci, pf) in vector_affine_constraint_cache_inner
1644+
if MOI.get(
1645+
model.optimizer,
1646+
MOI.ConstraintConflictStatus(),
1647+
inner_ci,
1648+
) == MOI.NOT_IN_CONFLICT
1649+
continue
1650+
end
1651+
for term in pf.p
1652+
push!(
1653+
model.parameters_in_conflict,
1654+
term.scalar_term.variable,
1655+
)
1656+
end
1657+
end
1658+
end
1659+
end
1660+
return
15981661
end
15991662

16001663
function MOI.get(
16011664
model::Optimizer,
16021665
attr::MOI.ConstraintConflictStatus,
16031666
ci::MOI.ConstraintIndex{MOI.VariableIndex,<:MOI.Parameter},
16041667
)
1605-
return MOI.MAYBE_IN_CONFLICT
1668+
return MOI.VariableIndex(ci.value) in model.parameters_in_conflict ?
1669+
MOI.MAYBE_IN_CONFLICT : MOI.NOT_IN_CONFLICT
16061670
end

src/ParametricOptInterface.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ mutable struct Optimizer{T,OT<:MOI.ModelLike} <: MOI.AbstractOptimizer
168168
constraints_interpretation::ConstraintsInterpretationCode
169169
save_original_objective_and_constraints::Bool
170170

171+
parameters_in_conflict::Set{MOI.VariableIndex}
172+
171173
# extension data
172174
ext::Dict{Symbol,Any}
173175
function Optimizer(
@@ -228,6 +230,7 @@ mutable struct Optimizer{T,OT<:MOI.ModelLike} <: MOI.AbstractOptimizer
228230
0,
229231
ONLY_CONSTRAINTS,
230232
save_original_objective_and_constraints,
233+
Set{MOI.VariableIndex}(),
231234
Dict{Symbol,Any}(),
232235
)
233236
end

test/moi_tests.jl

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,7 +1605,39 @@ function test_compute_conflict!()
16051605
)
16061606
x, x_ci = MOI.add_constrained_variable(model, MOI.GreaterThan(1.0))
16071607
p, p_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
1608+
p2, p2_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
1609+
p3, p3_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
1610+
p4, p4_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
1611+
p5, p5_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
1612+
p6, p6_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
1613+
p7, p7_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
1614+
p8, p8_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
1615+
p9, p9_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
1616+
p10, p10_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
1617+
p11, p11_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
1618+
p12, p12_ci = MOI.add_constrained_variable(model, MOI.Parameter(2.0))
16081619
ci = MOI.add_constraint(model, 2.0 * x + 3.0 * p, MOI.LessThan(0.0))
1620+
ci2 = MOI.add_constraint(model, 2.0 * x + 3.0 * p2, MOI.LessThan(10.0))
1621+
civ = MOI.add_constraint(
1622+
model,
1623+
MOI.Utilities.vectorize([2.0 * x + 3.0 * p3]),
1624+
MOI.Nonpositives(1),
1625+
)
1626+
civ2 = MOI.add_constraint(
1627+
model,
1628+
MOI.Utilities.vectorize([2.0 * x + 3.0 * p4 - 10.0]),
1629+
MOI.Nonpositives(1),
1630+
)
1631+
# pv
1632+
ci3 = MOI.add_constraint(model, 1.0 * p5 * x + 3.0 * 2, MOI.LessThan(0.0))
1633+
ci4 = MOI.add_constraint(model, 1.0 * p6 * x + 3.0 * 2, MOI.LessThan(10.0))
1634+
# pp
1635+
ci5 = MOI.add_constraint(model, 2.0 * x + 1.0 * p7 * p7, MOI.LessThan(0.0))
1636+
ci6 = MOI.add_constraint(model, 2.0 * x + 1.0 * p8 * p8, MOI.LessThan(10.0))
1637+
# p
1638+
ci7 = MOI.add_constraint(model, 1.0 * p11 * x + 3.0 * p9, MOI.LessThan(0.0))
1639+
ci8 =
1640+
MOI.add_constraint(model, 1.0 * p12 * x + 3.0 * p10, MOI.LessThan(10.0))
16091641
@test MOI.get(model, MOI.ConflictStatus()) ==
16101642
MOI.COMPUTE_CONFLICT_NOT_CALLED
16111643
MOI.Utilities.set_mock_optimize!(
@@ -1617,12 +1649,20 @@ function test_compute_conflict!()
16171649
MOI.NO_SOLUTION,
16181650
MOI.NO_SOLUTION;
16191651
constraint_conflict_status = [
1620-
(MOI.VariableIndex, MOI.Parameter{T}) =>
1621-
[MOI.MAYBE_IN_CONFLICT],
16221652
(MOI.VariableIndex, MOI.GreaterThan{T}) =>
16231653
[MOI.IN_CONFLICT],
1624-
(MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) =>
1625-
[MOI.IN_CONFLICT],
1654+
(MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => [
1655+
MOI.IN_CONFLICT,
1656+
MOI.NOT_IN_CONFLICT,
1657+
MOI.IN_CONFLICT,
1658+
MOI.NOT_IN_CONFLICT,
1659+
MOI.IN_CONFLICT,
1660+
MOI.NOT_IN_CONFLICT,
1661+
MOI.IN_CONFLICT,
1662+
MOI.NOT_IN_CONFLICT,
1663+
],
1664+
(MOI.VectorAffineFunction{T}, MOI.Nonpositives) =>
1665+
[MOI.IN_CONFLICT, MOI.NOT_IN_CONFLICT],
16261666
],
16271667
)
16281668
MOI.set(mock, MOI.ConflictStatus(), MOI.CONFLICT_FOUND)
@@ -1637,6 +1677,30 @@ function test_compute_conflict!()
16371677
@test MOI.get(model, MOI.ConstraintConflictStatus(), p_ci) ==
16381678
MOI.MAYBE_IN_CONFLICT
16391679
@test MOI.get(model, MOI.ConstraintConflictStatus(), ci) == MOI.IN_CONFLICT
1680+
@test MOI.get(model, MOI.ConstraintConflictStatus(), ci2) ==
1681+
MOI.NOT_IN_CONFLICT
1682+
@test MOI.get(model, MOI.ConstraintConflictStatus(), p2_ci) ==
1683+
MOI.NOT_IN_CONFLICT
1684+
@test MOI.get(model, MOI.ConstraintConflictStatus(), p3_ci) ==
1685+
MOI.MAYBE_IN_CONFLICT
1686+
@test MOI.get(model, MOI.ConstraintConflictStatus(), p4_ci) ==
1687+
MOI.NOT_IN_CONFLICT
1688+
@test MOI.get(model, MOI.ConstraintConflictStatus(), p5_ci) ==
1689+
MOI.MAYBE_IN_CONFLICT
1690+
@test MOI.get(model, MOI.ConstraintConflictStatus(), p6_ci) ==
1691+
MOI.NOT_IN_CONFLICT
1692+
@test MOI.get(model, MOI.ConstraintConflictStatus(), p7_ci) ==
1693+
MOI.MAYBE_IN_CONFLICT
1694+
@test MOI.get(model, MOI.ConstraintConflictStatus(), p8_ci) ==
1695+
MOI.NOT_IN_CONFLICT
1696+
@test MOI.get(model, MOI.ConstraintConflictStatus(), p9_ci) ==
1697+
MOI.MAYBE_IN_CONFLICT
1698+
@test MOI.get(model, MOI.ConstraintConflictStatus(), p10_ci) ==
1699+
MOI.NOT_IN_CONFLICT
1700+
@test MOI.get(model, MOI.ConstraintConflictStatus(), p11_ci) ==
1701+
MOI.MAYBE_IN_CONFLICT
1702+
@test MOI.get(model, MOI.ConstraintConflictStatus(), p12_ci) ==
1703+
MOI.NOT_IN_CONFLICT
16401704
return
16411705
end
16421706

0 commit comments

Comments
 (0)