1+ module MatrixOptInterface
2+
3+ using MathOptInterface
4+ const MOI = MathOptInterface
5+ const MOIU = MathOptInterface. Utilities
6+
7+ export MatrixOptimizer
8+
9+ MOIU. @model (MIPInnerModel,
10+ (MOI. ZeroOne, MOI. Integer),
11+ (MOI. EqualTo, MOI. GreaterThan, MOI. LessThan, MOI. Interval),
12+ (),
13+ (),
14+ (MOI. SingleVariable),
15+ (MOI. ScalarAffineFunction),
16+ (),
17+ ()
18+ )
19+
20+ const Model = MOIU. UniversalFallback{MIPInnerModel{Float64}}
21+
22+ """
23+ Model()
24+ Create an empty instance of MatrixOptInterface.Model.
25+ """
26+ function Model ()
27+ return MOIU. UniversalFallback (MIPInnerModel {Float64} ())
28+ end
29+
30+ function Base. show (io:: IO , :: Model )
31+ print (io, " A MatrixOptInterface Model" )
32+ return
33+ end
34+
35+ # abstract type AbstractLPForm{T} end
36+ struct LPMatrixOptInterfaceForm{T}
37+ direction:: MOI.OptimizationSense
38+ c:: Vector{T}
39+ A:: Matrix{T}
40+ c_lb:: Vector{T}
41+ c_ub:: Vector{T}
42+ v_lb:: Vector{T}
43+ v_ub:: Vector{T}
44+ end
45+ struct LPStandardForm{T}# <: AbstractLPForm{T}
46+ direction:: MOI.OptimizationSense
47+ c:: Vector{T}
48+ A:: Matrix{T}
49+ b:: Vector{T}
50+ end
51+ struct LPCannonicalForm{T}
52+ direction:: MOI.OptimizationSense
53+ c:: Vector{T}
54+ A:: Matrix{T}
55+ b:: Vector{T}
56+ end
57+ struct LPSolverForm{T}
58+ direction:: MOI.OptimizationSense
59+ c:: Vector{T}
60+ A:: Matrix{T}
61+ b:: Vector{T}
62+ senses:: Vector{Char}
63+ v_lb:: Vector{T}
64+ v_ub:: Vector{T}
65+ end
66+ struct MILP{T}
67+ lp
68+ variable_type
69+ end
70+
71+ function MatrixOptInterfaceForm (lp:: MatrixOptInterfaceForm{T} ) where T
72+ return lp
73+ end
74+ function MatrixOptInterfaceForm (lp:: LPStandardForm{T} ) where T
75+ return LPMatrixOptInterfaceForm {T} (
76+ lp. direction,
77+ lp. c,
78+ lp. A,
79+ lp. b,
80+ lp. b,
81+ fill (zero (T), length (lp. c)),
82+ fill (typemax (T), length (lp. c)),
83+ )
84+ end
85+ function MatrixOptInterfaceForm (lp:: LPCannonicalForm{T} ) where T
86+ return LPMatrixOptInterfaceForm {T} (
87+ lp. direction,
88+ lp. c,
89+ lp. A,
90+ fill (typemin (T), length (lp. b)),
91+ lp. b,
92+ fill (typemin (T), length (lp. c)),
93+ fill (typemax (T), length (lp. c)),
94+ )
95+ end
96+ function MatrixOptInterfaceForm (lp:: LPSolverForm{T} ) where T
97+ c_lb = fill (typemin (T), length (lp. b))
98+ c_ub = fill (typemax (T), length (lp. b))
99+ for i in eachindex (lp. b)
100+ if lp. senses[i] == ' <'
101+ c_ub[i] = lp. b[i]
102+ elseif lp. senses[i] == ' >'
103+ c_lb[i] = lp. b[i]
104+ elseif lp. senses[i] == ' ='
105+ c_lb[i] = lp. b[i]
106+ c_ub[i] = lp. b[i]
107+ else
108+ error (" invalid sign $(lp. senses[i]) " )
109+ end
110+ end
111+ return LPMatrixOptInterfaceForm {T} (
112+ lp. direction,
113+ lp. c,
114+ lp. A,
115+ c_lb,
116+ c_ub,
117+ lp. v_lb,
118+ lp. v_ub,
119+ )
120+ end
121+
122+ """
123+ reasobale forms:
124+
125+ A) LP standard form:
126+
127+ opt <c, x>
128+ s.t.
129+ Ax == b
130+ x >= 0
131+
132+ B) LP cannonical form:
133+
134+ opt <c, x>
135+ s.t.
136+ Ax <= b
137+
138+ C) MBP (our standard)
139+ opt <c, x>
140+ s.t.
141+ c_lb <= Ax <= c_ub
142+ v_lb <= x <= v_ub
143+
144+ C) Solver
145+ opt <c, x>
146+ s.t.
147+ Ax sense c_ub
148+ v_lb <= x <= v_ub
149+
150+ Extra
151+ vartype = {'C','I','B'}
152+ sense = {'<','>','='}
153+
154+
155+ """
156+ function MatrixOptimizer (raw_lp)
157+ lp = MatrixOptInterfaceForm (raw_lp)
158+ num_variables = length (lp. c)
159+ num_constraints = length (lp. c_lb)
160+
161+ # use caching
162+ optimizer = Model ()
163+
164+ x = MOI. add_variables (optimizer, num_variables)
165+
166+ objective_function = MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .(lp. c, x), 0.0 )
167+ MOI. set (optimizer, MOI. ObjectiveFunction {MOI.ScalarAffineFunction{Float64}} (),
168+ objective_function)
169+ MOI. set (optimizer, MOI. ObjectiveSense (), lp. sense)
170+
171+ # Add constraints
172+ for i in 1 : num_constraints
173+ add_constraint (optimizer,
174+ MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .(lp. A[i,:], x), 0.0 ),
175+ lp. c_lb[i], lp. c_ub[i])
176+ end
177+
178+ # Add bounds
179+ for i in 1 : num_variables
180+ add_constraint (optimizer,
181+ MOI. SingleVariable (x[i]), lp. v_lb[i], lp. v_ub[i])
182+ end
183+
184+ return optimizer
185+ end
186+
187+ function add_constraint (optimizer, func, lb, ub)
188+ if lb == ub > - Inf
189+ MOI. add_constraint (optimizer, func, MOI. EqualTo (lb))
190+ else
191+ if lb > - Inf && ub < Inf
192+ MOI. add_constraint (optimizer, func, MOI. Interval (lb, ub))
193+ elseif lb > - Inf
194+ MOI. add_constraint (optimizer, func, MOI. GreaterThan (lb))
195+ elseif ub < Inf
196+ MOI. add_constraint (optimizer, func, MOI. LessThan (ub))
197+ end
198+ end
199+ end
200+
201+ end
0 commit comments