/
functionize.jl
107 lines (85 loc) · 2.71 KB
/
functionize.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# Copyright (c) 2017: Miles Lubin and contributors
# Copyright (c) 2017: Google Inc.
#
# Use of this source code is governed by an MIT-style license that can be found
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.
"""
FunctionizeBridge{T}
`FunctionizeBridge` implements the following reformulations:
* ``\\min \\{x\\}`` into ``\\min\\{1x + 0\\}``
* ``\\max \\{x\\}`` into ``\\max\\{1x + 0\\}``
where `T` is the coefficient type of `1` and `0`.
## Source node
`FunctionizeBridge` supports:
* [`MOI.ObjectiveFunction{MOI.VariableIndex}`](@ref)
## Target nodes
`FunctionizeBridge` creates:
* One objective node: [`MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}`](@ref)
"""
struct FunctionizeBridge{T} <: AbstractBridge end
const Functionize{T,OT<:MOI.ModelLike} =
SingleBridgeOptimizer{FunctionizeBridge{T},OT}
function bridge_objective(
::Type{FunctionizeBridge{T}},
model::MOI.ModelLike,
func::MOI.VariableIndex,
) where {T}
F = MOI.ScalarAffineFunction{T}
MOI.set(model, MOI.ObjectiveFunction{F}(), convert(F, func))
return FunctionizeBridge{T}()
end
function supports_objective_function(
::Type{<:FunctionizeBridge},
::Type{MOI.VariableIndex},
)
return true
end
function MOI.Bridges.added_constrained_variable_types(
::Type{<:FunctionizeBridge},
)
return Tuple{Type}[]
end
function MOI.Bridges.added_constraint_types(::Type{<:FunctionizeBridge})
return Tuple{Type,Type}[]
end
function MOI.Bridges.set_objective_function_type(
::Type{FunctionizeBridge{T}},
) where {T}
return MOI.ScalarAffineFunction{T}
end
# Attributes, Bridge acting as a model
MOI.get(::FunctionizeBridge, ::MOI.NumberOfVariables)::Int64 = 0
function MOI.get(::FunctionizeBridge, ::MOI.ListOfVariableIndices)
return MOI.VariableIndex[]
end
# No variables or constraints are created in this bridge so there is nothing to
# delete.
MOI.delete(::MOI.ModelLike, ::FunctionizeBridge) = nothing
function MOI.set(
::MOI.ModelLike,
::MOI.ObjectiveSense,
::FunctionizeBridge,
::MOI.OptimizationSense,
)
# `FunctionizeBridge` is sense agnostic, therefore, we don't need to change
# anything.
return
end
function MOI.get(
model::MOI.ModelLike,
attr::MOI.Bridges.ObjectiveFunctionValue{MOI.VariableIndex},
::FunctionizeBridge{T},
) where {T}
F = MOI.ScalarAffineFunction{T}
attr_f = MOI.Bridges.ObjectiveFunctionValue{F}(attr.result_index)
return MOI.get(model, attr_f)
end
function MOI.get(
model::MOI.ModelLike,
::MOI.ObjectiveFunction{MOI.VariableIndex},
::FunctionizeBridge{T},
) where {T}
F = MOI.ScalarAffineFunction{T}
func = MOI.get(model, MOI.ObjectiveFunction{F}())
return convert(MOI.VariableIndex, func)
end