Skip to content

Commit

Permalink
remove setobjective in favor of objective attributes, closes #110
Browse files Browse the repository at this point in the history
  • Loading branch information
mlubin committed Oct 13, 2017
1 parent da2bd41 commit ef04126
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 82 deletions.
3 changes: 2 additions & 1 deletion LICENSE.md
@@ -1,6 +1,7 @@
The MathOptInterface.jl package is licensed under the MIT "Expat" License:

> Copyright (c) 2017: Miles Lubin.
> Copyright (c) 2017: Miles Lubin and contributors
> Copyright (c) 2017: Google Inc.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
Expand Down
20 changes: 13 additions & 7 deletions docs/src/apimanual.md
Expand Up @@ -106,10 +106,13 @@ end

If `x` is a vector of `VariableReference` objects, then `ScalarAffineFunction([x[1],x[2]],[5.0,-2.3],1.0)` represents the function ``5x_1 - 2.3x_2 + 1``.

Objective functions are assigned to an instance by calling [`setobjective!`](@ref MathOptInterface.setobjective!). For example,
Objective functions are assigned to an instance by setting the [`ObjectiveFunction`](@ref MathOptInterface.ObjectiveFunction) attribute.
The [`ObjectiveSense`](@ref MathOptInterface.ObjectiveSense) attribute is used for setting the optimization sense.
For example,
```julia
x = addvariables!(m, 2)
setobjective!(m, MinSense, ScalarAffineFunction([x[1],x[2]],[5.0,-2.3],1.0))
setattribute!(m, ObjectiveFunction(), ScalarAffineFunction([x[1],x[2]],[5.0,-2.3],1.0))
setattribute!(m, ObjectiveSense(), MinSense)
```
sets the objective to the function just discussed in the minimization sense.

Expand Down Expand Up @@ -142,7 +145,8 @@ The code example below encodes the linear optimization problem:

```julia
x = addvariables!(m, 2)
setobjective!(m, MaxSense, ScalarAffineFunction(x, [3.0,2.0], 0.0))
setattribute!(m, ObjectiveFunction(), ScalarAffineFunction(x, [3.0,2.0], 0.0))
setattribute!(m, ObjectiveSense(), MaxSense)
addconstraint!(m, ScalarAffineFunction(x, [1.0,1.0], 0.0), LessThan(5.0))
addconstraint!(m, SingleVariable(x[1]), GreaterThan(0.0))
addconstraint!(m, SingleVariable(x[2]), GreaterThan(-1.0))
Expand Down Expand Up @@ -300,7 +304,8 @@ function solveknapsack(c::Vector{Float64}, w::Vector{Float64}, C::Float64, solve
x = addvariables!(m, numvar)

# set the objective function
setobjective!(m, MaxSense, ScalarAffineFunction(x, c, 0.0))
setattribute!(m, ObjectiveFunction(), ScalarAffineFunction(x, c, 0.0))
setattribute!(m, ObjectiveSense(), MaxSense)

# add the knapsack constraint
addconstraint!(m, ScalarAffineFunction(x, w, 0.0), LessThan(C))
Expand Down Expand Up @@ -340,7 +345,7 @@ end
"""
IntegerLinearResult
A `struct` returned by `solverintegerlinear` containing solution information.
A `struct` returned by `solveintegerlinear` containing solution information.
The fields are as follows:
- `termination_status`: the `TerminationStatusCode` returned by the solver
Expand All @@ -362,7 +367,7 @@ end
Solve the mixed-integer linear optimization problem: min c'x s.t. `Ale*x` <= `ble`, `Aeq*x` = `beq`, `lb` <= `x` <= `ub`, and`x[i]` is integer for `i` in `integerindices` using the solver specified by `solver`. Returns an `IntegerLinearResult`.
"""
function solverintegerlinear(c, Ale::SparseMatrixCSC, ble, Aeq::SparseMatrixCSC, beq, lb, ub, integerindices, solver)
function solveintegerlinear(c, Ale::SparseMatrixCSC, ble, Aeq::SparseMatrixCSC, beq, lb, ub, integerindices, solver)
if !supportsproblem(solver, ScalarAffineFunction{Float64},
[(ScalarAffineFunction,LessThan{Float64}),
(ScalarAffineFunction,Zeros),
Expand All @@ -381,7 +386,8 @@ function solverintegerlinear(c, Ale::SparseMatrixCSC, ble, Aeq::SparseMatrixCSC,
x = addvariables!(m, numvar)

# set the objective function
setobjective!(m, MinSense, ScalarAffineFunction(x, c, 0.0))
setattribute!(m, ObjectiveFunction(), ScalarAffineFunction(x, c, 0.0))
setattribute!(m, ObjectiveSense(), MinSense)

# add variable bound constraints
for i in 1:numvar
Expand Down
5 changes: 2 additions & 3 deletions docs/src/apireference.md
Expand Up @@ -236,12 +236,11 @@ Functions for getting and setting properties of sets.
dimension
```

## Objectives
## Objective modifications

Functions for adding and modifying objectives.
Functions for modifying objective functions. Use `ObjectiveFunction` and `ObjectiveSense` to set and query the objective function.

```@docs
setobjective!
modifyobjective!
canmodifyobjective
```
7 changes: 0 additions & 7 deletions src/objectives.jl
@@ -1,12 +1,5 @@
# Objectives

"""
setobjective!(m::AbstractInstance, sense::OptimizationSense, func::F)
Set the objective function in the instance `m` to be ``f(x)`` where ``f`` is a function specified by `func` with the objective sense (`MinSense` or `MaxSense`) specified by `sense`.
"""
function setobjective! end

"""
modifyobjective!(m::AbstractInstance, change::AbstractFunctionModification)
Expand Down
46 changes: 28 additions & 18 deletions test/contconic.jl
Expand Up @@ -36,7 +36,8 @@ function lin1test(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float64), rt
@test (MOI.VectorOfVariables,MOI.Nonnegatives) in loc
@test (MOI.VectorAffineFunction{Float64},MOI.Zeros) in loc

MOI.setobjective!(m, MOI.MinSense, MOI.ScalarAffineFunction(v, [-3.0, -2.0, -4.0], 0.0))
MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction(v, [-3.0, -2.0, -4.0], 0.0))
MOI.setattribute!(m, ObjectiveSense(), MOI.MinSense)

MOI.optimize!(m)

Expand Down Expand Up @@ -82,7 +83,8 @@ function lin1atest(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float64), r
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Nonnegatives}()) == 1
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Zeros}()) == 1

MOI.setobjective!(m, MOI.MinSense, MOI.ScalarAffineFunction(v, [-3.0, -2.0, -4.0], 0.0))
MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction(v, [-3.0, -2.0, -4.0], 0.0))
MOI.setattribute!(m, ObjectiveSense(), MOI.MinSense)

MOI.optimize!(m)

Expand Down Expand Up @@ -139,9 +141,8 @@ function lin2test(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float64), rt
x,y,z,s = MOI.addvariables!(m, 4)
@test MOI.getattribute(m, MOI.NumberOfVariables()) == 4


MOI.setobjective!(m, MOI.MinSense, MOI.ScalarAffineFunction([x,y,z], [3.0, 2.0, -4.0], 0.0))

MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction([x,y,z], [3.0, 2.0, -4.0], 0.0))
MOI.setattribute!(m, ObjectiveSense(), MOI.MinSense)

c = MOI.addconstraint!(m, MOI.VectorAffineFunction([1,1,2,3,3], [x,s,y,x,z], [1.0,-1.0,1.0,1.0,1.0], [4.0,3.0,-12.0]), MOI.Zeros(3))

Expand Down Expand Up @@ -203,7 +204,8 @@ function lin2atest(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float64), r
@test MOI.getattribute(m, MOI.NumberOfVariables()) == 4


MOI.setobjective!(m, MOI.MinSense, MOI.ScalarAffineFunction([x,y,z], [3.0, 2.0, -4.0], 0.0))
MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction([x,y,z], [3.0, 2.0, -4.0], 0.0))
MOI.setattribute!(m, ObjectiveSense(), MOI.MinSense)


c = MOI.addconstraint!(m, MOI.VectorAffineFunction([1,1,2,3,3], [x,s,y,x,z], [1.0,-1.0,1.0,1.0,1.0], [4.0,3.0,-12.0]), MOI.Zeros(3))
Expand Down Expand Up @@ -345,7 +347,8 @@ function soc1test(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float64), rt

x,y,z = MOI.addvariables!(m, 3)

MOI.setobjective!(m, MOI.MaxSense, MOI.ScalarAffineFunction([y,z],[1.0,1.0],0.0))
MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction([y,z],[1.0,1.0],0.0))
MOI.setattribute!(m, ObjectiveSense(), MOI.MaxSense)

ceq = MOI.addconstraint!(m, MOI.VectorAffineFunction([1],[x],[1.0],[-1.0]), MOI.Zeros(1))
csoc = MOI.addconstraint!(m, MOI.VectorOfVariables([x,y,z]), MOI.SecondOrderCone(3))
Expand Down Expand Up @@ -398,7 +401,8 @@ function soc1atest(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float64), r

x,y,z = MOI.addvariables!(m, 3)

MOI.setobjective!(m, MOI.MaxSense, MOI.ScalarAffineFunction([y,z],[1.0,1.0],0.0))
MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction([y,z],[1.0,1.0],0.0))
MOI.setattribute!(m, ObjectiveSense(), MOI.MaxSense)

ceq = MOI.addconstraint!(m, MOI.VectorAffineFunction([1],[x],[1.0],[-1.0]), MOI.Zeros(1))
csoc = MOI.addconstraint!(m, MOI.VectorAffineFunction([1,2,3],[x,y,z],ones(3),zeros(3)), MOI.SecondOrderCone(3))
Expand Down Expand Up @@ -456,7 +460,8 @@ function soc2test(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float64), rt

x,y,t = MOI.addvariables!(m, 3)

MOI.setobjective!(m, MOI.MinSense, MOI.ScalarAffineFunction([x],[1.0],0.0))
MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction([x],[1.0],0.0))
MOI.setattribute!(m, ObjectiveSense(), MOI.MinSense)

MOI.addconstraint!(m, MOI.VectorAffineFunction([1],[y],[1.0],[-1/sqrt(2)]), MOI.Nonnegatives(1))
MOI.addconstraint!(m, MOI.VectorAffineFunction([1],[t],[-1.0],[1.0]), MOI.Zeros(1))
Expand Down Expand Up @@ -502,7 +507,8 @@ function soc2atest(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float64), r

x,y,t = MOI.addvariables!(m, 3)

MOI.setobjective!(m, MOI.MinSense, MOI.ScalarAffineFunction([x],[1.0],0.0))
MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction([x],[1.0],0.0))
MOI.setattribute!(m, ObjectiveSense(), MOI.MinSense)

MOI.addconstraint!(m, MOI.VectorAffineFunction([1],[y],[-1.0],[1/sqrt(2)]), MOI.Nonpositives(1))
MOI.addconstraint!(m, MOI.VectorAffineFunction([1],[t],[-1.0],[1.0]), MOI.Zeros(1))
Expand Down Expand Up @@ -615,7 +621,8 @@ function soc4test(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float64), rt
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Zeros}()) == 1
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.VectorOfVariables,MOI.SecondOrderCone}()) == 1

MOI.setobjective!(m, MOI.MinSense, MOI.ScalarAffineFunction(x,c,0.0))
MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction(x,c,0.0))
MOI.setattribute!(m, ObjectiveSense(), MOI.MinSense)
MOI.optimize!(m)

@test MOI.cangetattribute(m, MOI.TerminationStatus())
Expand Down Expand Up @@ -677,7 +684,8 @@ function rotatedsoc1test(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.SingleVariable,MOI.EqualTo{Float64}}()) == 2
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.VectorOfVariables,MOI.RotatedSecondOrderCone}()) == 1

MOI.setobjective!(m, MOI.MinSense, MOI.ScalarAffineFunction(x,c,0.0))
MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction(x,c,0.0))
MOI.setattribute!(m, ObjectiveSense(), MOI.MinSense)
MOI.optimize!(m)

@test MOI.cangetattribute(m, MOI.TerminationStatus())
Expand Down Expand Up @@ -761,7 +769,8 @@ function rotatedsoc2test(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.SingleVariable,MOI.GreaterThan{Float64}}()) == 1
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.VectorOfVariables,MOI.RotatedSecondOrderCone}()) == 1

MOI.setobjective!(m, MOI.MinSense, MOI.ScalarAffineFunction(x,c,0.0))
MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction(x,c,0.0))
MOI.setattribute!(m, ObjectiveSense(), MOI.MinSense)
MOI.optimize!(m)

@test MOI.cangetattribute(m, MOI.TerminationStatus())
Expand Down Expand Up @@ -825,8 +834,8 @@ function _sdp0test(solver::MOI.AbstractSolver, vecofvars::Bool, sdpcone; atol=Ba
@test MOI.getattribute(m, MOI.NumberOfConstraints{vecofvars ? MOI.VectorOfVariables : MOI.VectorAffineFunction{Float64}, sdpcone}()) == 1
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}}()) == 1

MOI.setobjective!(m, MOI.MinSense, MOI.ScalarAffineFunction([X[1], X[3]], ones(2), 0.))

MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction([X[1], X[3]], ones(2), 0.))
MOI.setattribute!(m, ObjectiveSense(), MOI.MinSense)
MOI.optimize!(m)

@test MOI.cangetattribute(m, MOI.TerminationStatus())
Expand Down Expand Up @@ -902,7 +911,8 @@ function _sdp1test(solver::MOI.AbstractSolver, vecofvars::Bool, sdpcone; atol=Ba
c1 = MOI.addconstraint!(m, MOI.ScalarAffineFunction([X[1], X[4], X[6], x[1]], [1., 1, 1, 1], 0.), MOI.EqualTo(1.))
c2 = MOI.addconstraint!(m, MOI.ScalarAffineFunction([X; x[2]; x[3]], [1., 2/s, 2/s, 1, 2/s, 1, 1, 1], 0.), MOI.EqualTo(1/2))

MOI.setobjective!(m, MOI.MinSense, MOI.ScalarAffineFunction([X[1:2]; X[4:6]; x[1]], [2., 2/s, 2, 2/s, 2, 1], 0.))
MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction([X[1:2]; X[4:6]; x[1]], [2., 2/s, 2, 2/s, 2, 1], 0.))
MOI.setattribute!(m, ObjectiveSense(), MOI.MinSense)

@test MOI.getattribute(m, MOI.NumberOfConstraints{vecofvars ? MOI.VectorOfVariables : MOI.VectorAffineFunction{Float64}, sdpcone}()) == 1
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}}()) == 2
Expand Down Expand Up @@ -1001,8 +1011,8 @@ function sdp2test(solver::MOI.AbstractSolver; atol=Base.rtoldefault(Float64), rt
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeScaled}()) == 1
@test MOI.getattribute(m, MOI.NumberOfConstraints{MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}}()) == 1

MOI.setobjective!(m, MOI.MaxSense, MOI.ScalarAffineFunction([x[7]], [1.], 0.))

MOI.setattribute!(m, ObjectiveFunction(), MOI.ScalarAffineFunction([x[7]], [1.], 0.))
MOI.setattribute!(m, ObjectiveSense(), MOI.MaxSense)
MOI.optimize!(m)

@test MOI.cangetattribute(m, MOI.TerminationStatus())
Expand Down

0 comments on commit ef04126

Please sign in to comment.