Skip to content

Commit 3a8bb08

Browse files
Enable modification of objective function coefficients for DualOptimizer (#100)
1 parent a8676f4 commit 3a8bb08

File tree

5 files changed

+82
-12
lines changed

5 files changed

+82
-12
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Dualization"
22
uuid = "191a621a-6537-11e9-281d-650236a99e60"
33
authors = ["guilhermebodin <[email protected]>"]
4-
version = "0.3.3"
4+
version = "0.3.4"
55

66
[deps]
77
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"

src/MOI_wrapper.jl

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ end
8080

8181
function MOI.supports_constraint(
8282
optimizer::DualOptimizer{T},
83-
F::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}},
83+
::Type{<:Union{MOI.VectorOfVariables, MOI.VectorAffineFunction{T}}},
8484
S::Type{<:MOI.AbstractVectorSet}) where T
8585
D = _dual_set_type(S)
8686
if D === nothing
@@ -89,6 +89,21 @@ function MOI.supports_constraint(
8989
return MOI.supports_add_constrained_variables(optimizer.dual_problem.dual_model, D)
9090
end
9191

92+
function MOI.modify(optimizer::DualOptimizer{T},
93+
::MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}},
94+
obj_change::MOI.ScalarCoefficientChange{T}) where T
95+
# We must find the constraint corresponding to the variable in the objective
96+
# function and change its coefficient on the constraint.
97+
ci_to_change = optimizer.dual_problem.primal_dual_map.primal_var_dual_con[obj_change.variable]
98+
sense_change = MOI.get(optimizer.dual_problem.dual_model,
99+
MOI.ObjectiveSense()) == MOI.MAX_SENSE ? one(T) : -one(T)
100+
MOI.set(optimizer.dual_problem.dual_model,
101+
MOI.ConstraintSet(),
102+
ci_to_change,
103+
MOI.EqualTo(sense_change * obj_change.new_coefficient))
104+
return
105+
end
106+
92107
# TODO add this when constrained variables are implemented
93108
#function MOI.supports_add_constrained_variables(
94109
# optimizer::DualOptimizer{T}, S::Type{MOI.Reals}) where T

src/dual_equality_constraints.jl

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@ function add_dual_equality_constraints(dual_model::MOI.ModelLike, primal_model::
1515
all_variables, con_types, T)
1616

1717
# get RHS from objective coeficients
18-
scalar_terms = get_scalar_terms(primal_model,
19-
all_variables, primal_objective)
18+
scalar_terms = get_scalar_terms(primal_objective)
2019

2120
# Add terms from objective:
2221
# Terms from quadratic part
23-
add_scalar_affine_terms_from_quad_obj(scalar_affine_terms, primal_model,
22+
add_scalar_affine_terms_from_quad_obj(scalar_affine_terms,
2423
primal_dual_map.primal_var_dual_quad_slack, primal_objective)
2524
# terms from mixing variables and parameters
26-
add_scalar_affine_terms_from_quad_params(scalar_affine_terms, primal_model,
25+
add_scalar_affine_terms_from_quad_params(scalar_affine_terms,
2726
primal_dual_map.primal_parameter, primal_objective)
2827

2928
for primal_vi in restricted_variables
@@ -44,7 +43,6 @@ end
4443

4544
function add_scalar_affine_terms_from_quad_obj(
4645
scalar_affine_terms::Dict{VI,Vector{MOI.ScalarAffineTerm{T}}},
47-
primal_model::MOI.ModelLike,
4846
primal_var_dual_quad_slack::Dict{VI, VI},
4947
primal_objective::PrimalObjective{T}) where T
5048
for term in primal_objective.obj.quadratic_terms
@@ -68,7 +66,6 @@ end
6866

6967
function add_scalar_affine_terms_from_quad_params(
7068
scalar_affine_terms::Dict{VI,Vector{MOI.ScalarAffineTerm{T}}},
71-
primal_model::MOI.ModelLike,
7269
primal_parameter::Dict{VI, VI},
7370
primal_objective::PrimalObjective{T}) where T
7471
for (key,val) in primal_objective.quad_cross_parameters
@@ -86,9 +83,7 @@ function set_dual_constraint_name(dual_model::MOI.ModelLike, primal_model::MOI.M
8683
return
8784
end
8885

89-
function get_scalar_terms(primal_model::MOI.ModelLike,
90-
variables::Vector{VI},
91-
primal_objective::PrimalObjective{T}) where T
86+
function get_scalar_terms(primal_objective::PrimalObjective{T}) where T
9287

9388
scalar_terms = Dict{VI,T}()
9489
for term in get_affine_terms(primal_objective)
@@ -196,6 +191,6 @@ function set_dot(i::Integer, s::MOI.AbstractVectorSet, T::Type)
196191
vec[i] = one(T)
197192
return MOIU.set_dot(vec, vec, s)
198193
end
199-
function set_dot(i::Integer, s::MOI.AbstractScalarSet, T::Type)
194+
function set_dot(::Integer, ::MOI.AbstractScalarSet, T::Type)
200195
return one(T)
201196
end

test/Tests/test_modify.jl

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
@testset "modify" begin
2+
model = Model(GLPK_DUAL_FACTORY)
3+
@variable(model, x[1:2] >= 0)
4+
@constraint(model, 2x[1] + x[2] <= 4)
5+
@constraint(model, x[1] + 2x[2] <= 4)
6+
@objective(model, Max, 4x[1] + 3x[2])
7+
optimize!(model)
8+
@test objective_value(model) 28/3
9+
set_objective_coefficient(model, x[1], 5.0)
10+
optimize!(model)
11+
@test objective_value(model) 10.6666666666
12+
13+
model = Model(GLPK_DUAL_FACTORY)
14+
@variable(model, x[1:2] >= 0)
15+
@constraint(model, 2x[1] + x[2] <= 4)
16+
@constraint(model, x[1] + 2x[2] <= 4)
17+
@objective(model, Min, -4x[1] + -3x[2])
18+
optimize!(model)
19+
@test objective_value(model) -28/3
20+
set_objective_coefficient(model, x[1], -5.0)
21+
optimize!(model)
22+
@test objective_value(model) -10.6666666666
23+
24+
model = Model(SCS_DUAL_FACTORY)
25+
@variable(model, x[1:2] >= 0)
26+
@constraint(model, 2x[1] + x[2] <= 4)
27+
@constraint(model, x[1] + 2x[2] <= 4)
28+
@objective(model, Max, 4x[1] + 3x[2])
29+
optimize!(model)
30+
@test objective_value(model) 28/3 atol=1e-3
31+
set_objective_coefficient(model, x[1], 5.0)
32+
optimize!(model)
33+
@test objective_value(model) 10.6666666666 atol=1e-3
34+
35+
model = Model(SCS_DUAL_FACTORY)
36+
@variable(model, x[1:2] >= 0)
37+
@constraint(model, 2x[1] + x[2] <= 4)
38+
@constraint(model, x[1] + 2x[2] <= 4)
39+
@objective(model, Min, -4x[1] + -3x[2])
40+
optimize!(model)
41+
@test objective_value(model) -28/3 atol=1e-3
42+
set_objective_coefficient(model, x[1], -5.0)
43+
optimize!(model)
44+
@test objective_value(model) -10.6666666666 atol=1e-3
45+
46+
model = Model(SCS_DUAL_FACTORY)
47+
@variable(model, x)
48+
@variable(model, y)
49+
@variable(model, z)
50+
@constraint(model, x + 2y + 3z >= 4)
51+
@constraint(model, x + y >= 1)
52+
@objective(model, Min, x^2 + x*y + y^2 + y*z + z^2)
53+
optimize!(model)
54+
@test objective_value(model) 1.8571 atol=1e-3
55+
# Now the objective is @objective(model, Min, x^2 + x*y + y^2 + y*z + z^2 - 5x)
56+
set_objective_coefficient(model, x, -5.0)
57+
optimize!(model)
58+
@test objective_value(model) -9.15 atol=1e-3
59+
end

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,4 @@ include("Solvers/scs_test.jl")
9393

9494
include("Tests/test_JuMP_dualize.jl")
9595
include("Tests/test_MOI_wrapper.jl")
96+
include("Tests/test_modify.jl")

0 commit comments

Comments
 (0)