1
+ # Copyright (c) 2015: Joey Huchette and contributors
2
+ # Copyright (c) 2025: COPT-Public
3
+ #
4
+ # Use of this source code is governed by an MIT-style license that can be found
5
+ # in the LICENSE.md file or at https://opensource.org/licenses/MIT.
6
+
7
+
8
+ function _copt_get_int_attr_multi_obj (model:: Optimizer , index:: Int , name:: String )
9
+ p_value = Ref {Cint} ()
10
+ ret = COPT_MultiObjGetIntAttr (model. prob, Cint (index - 1 ), name, p_value)
11
+ _check_ret (model, ret)
12
+ return p_value[]
13
+ end
14
+
15
+ function _copt_get_dbl_attr_multi_obj (model:: Optimizer , index:: Int , name:: String )
16
+ p_value = Ref {Cdouble} ()
17
+ ret = COPT_MultiObjGetDblAttr (model. prob, Cint (index - 1 ), name, p_value)
18
+ _check_ret (model, ret)
19
+ return p_value[]
20
+ end
21
+
22
+ # ==============================================================================
23
+ # objective function
24
+ # ==============================================================================
25
+ struct MultiObjectiveFunction <: MOI.AbstractModelAttribute
26
+ index:: Int
27
+ end
28
+
29
+ function MOI. set (
30
+ model:: Optimizer ,
31
+ attr:: MultiObjectiveFunction ,
32
+ f:: MOI.ScalarAffineFunction ,
33
+ )
34
+ num_vars = length (model. variable_info)
35
+ obj = zeros (Float64, num_vars)
36
+ for term in f. terms
37
+ col = column (model, term. variable)
38
+ obj[col] += term. coefficient
39
+ end
40
+ ret = COPT_MultiObjSetColObj (model. prob, Cint (attr. index - 1 ), num_vars, C_NULL , obj)
41
+ _check_ret (model, ret)
42
+ ret = COPT_MultiObjSetObjConst (model. prob, Cint (attr. index - 1 ), f. constant)
43
+ _check_ret (model, ret)
44
+ return
45
+ end
46
+
47
+ function _zero_multiobjective (model:: Optimizer , attr:: MultiObjectiveFunction )
48
+ num_vars = length (model. variable_info)
49
+ # COPT returns an error when calling COPT_SetColObj() with no columns.
50
+ if num_vars > 0
51
+ obj = zeros (Float64, num_vars)
52
+ ret = COPT_MultiObjSetColObj (model. prob, Cint (attr. index - 1 ), num_vars, C_NULL , obj)
53
+ _check_ret (model, ret)
54
+ end
55
+ ret = COPT_MultiObjSetObjConst (model. prob, Cint (attr. index - 1 ), f. constant)
56
+ _check_ret (model, ret)
57
+ return
58
+ end
59
+
60
+ function MOI. set (model:: Optimizer , attr:: MultiObjectiveFunction , :: MOI.ObjectiveSense , sense:: MOI.OptimizationSense )
61
+ ret = if sense == MOI. MIN_SENSE
62
+ COPT_MultiObjSetObjSense (model. prob, Cint (attr. index - 1 ), COPT_MINIMIZE)
63
+ elseif sense == MOI. MAX_SENSE
64
+ COPT_MultiObjSetObjSense (model. prob, Cint (attr. index - 1 ), COPT_MAXIMIZE)
65
+ else
66
+ @assert sense == MOI. FEASIBILITY_SENSE
67
+ _zero_multiobjective (model, attr)
68
+ COPT_SetObjSense (model. prob, COPT_MINIMIZE)
69
+ end
70
+ _check_ret (model, ret)
71
+ return
72
+ end
73
+
74
+ function MOI. get (model:: Optimizer , attr:: MultiObjectiveFunction , :: MOI.ObjectiveSense )
75
+ objective_sense = _copt_get_int_attr_multi_obj (model, attr. index, " ObjSense" )
76
+ if objective_sense == COPT_MINIMIZE
77
+ return MOI. MIN_SENSE
78
+ else
79
+ return MOI. MAX_SENSE
80
+ end
81
+ end
82
+
83
+ function MOI. supports (
84
+ model:: Optimizer ,
85
+ :: MOI.ObjectiveFunction{MOI.VectorAffineFunction{Float64}} ,
86
+ )
87
+ return true
88
+ end
89
+
90
+ function MOI. set (
91
+ model:: Optimizer ,
92
+ :: MOI.ObjectiveFunction{F} ,
93
+ f:: F ,
94
+ ) where {F<: MOI.VectorAffineFunction{Float64} }
95
+ for (i, fi) in enumerate (MOI. Utilities. eachscalar (f))
96
+ MOI. set (model, MultiObjectiveFunction (i), fi)
97
+ end
98
+ model. objective_type = _VECTOR_AFFINE
99
+ return
100
+ end
101
+
102
+ function _get_multiobj_linear_part (model:: Optimizer , index:: Int )
103
+ num_col = length (model. variable_info)
104
+ values = Array {Cdouble} (undef, num_col)
105
+ ret = COPT_MultiObjGetColObj (model. prob, Cint (index - 1 ), num_col, C_NULL , values)
106
+ _check_ret (model, ret)
107
+ return values
108
+ end
109
+
110
+ function MOI. get (
111
+ model:: Optimizer ,
112
+ :: MOI.ObjectiveFunction{MOI.VectorAffineFunction{Float64}} ,
113
+ )
114
+ F = MOI. ScalarAffineFunction{Float64}
115
+ f = F[]
116
+ for i in 1 : MOI. get (model, NumberOfObjectives ())
117
+ coefficients = _get_multiobj_linear_part (model, i)
118
+ terms = MOI. ScalarAffineTerm{Float64}[]
119
+ for (index, info) in model. variable_info
120
+ coefficient = coefficients[info. column]
121
+ if ! iszero (coefficient)
122
+ push! (terms, MOI. ScalarAffineTerm (coefficient, index))
123
+ end
124
+ end
125
+ constant = _copt_get_dbl_attr_multi_obj (model, i, " ObjConst" )
126
+ cur_obj = MOI. ScalarAffineFunction (terms, constant[])
127
+ push! (f, cur_obj)
128
+ end
129
+ return MOI. Utilities. operate (vcat, Float64, f... )
130
+ end
131
+
132
+
133
+ # ==============================================================================
134
+ # model-related parameters and attributes
135
+ # ==============================================================================
136
+ struct NumberOfObjectives <: MOI.AbstractModelAttribute end
137
+
138
+ function MOI. get (model:: Optimizer , :: NumberOfObjectives )
139
+ return _copt_get_int_attr (model, " MultiObjs" )
140
+ end
141
+
142
+ struct MultiObjTimeLimit <: MOI.AbstractModelAttribute end
143
+
144
+ function MOI. set (model:: Optimizer , :: MultiObjTimeLimit , value:: Real )
145
+ MOI. set (model, MOI. RawOptimizerAttribute (" MultiObjTimeLimit" ), value)
146
+ return
147
+ end
148
+
149
+ function MOI. get (model:: Optimizer , :: MultiObjTimeLimit )
150
+ return MOI. get (model, MOI. RawOptimizerAttribute (" MultiObjTimeLimit" ))
151
+ end
152
+
153
+ struct MultiObjParamMode <: MOI.AbstractModelAttribute end
154
+
155
+ function MOI. set (model:: Optimizer , :: MultiObjParamMode , value:: Int )
156
+ MOI. set (model, MOI. RawOptimizerAttribute (" MultiObjParamMode" ), value)
157
+ return
158
+ end
159
+
160
+ function MOI. get (model:: Optimizer , :: MultiObjParamMode )
161
+ return MOI. get (model, MOI. RawOptimizerAttribute (" MultiObjParamMode" ))
162
+ end
163
+
164
+
165
+ # ==============================================================================
166
+ # objective-related parameters
167
+ # ==============================================================================
168
+ struct MultiObjectiveParams <: MOI.AbstractModelAttribute
169
+ index:: Int
170
+ name:: String
171
+ end
172
+
173
+ function MOI. set (model:: Optimizer , attr:: MultiObjectiveParams , value)
174
+ if (attr. name == COPT_MULTIOBJ_PRIORITY || attr. name == COPT_MULTIOBJ_WEIGHT ||
175
+ attr. name == COPT_MULTIOBJ_ABSTOL || attr. name == COPT_MULTIOBJ_RELTOL)
176
+ ret = COPT_MultiObjSetObjParam (model. prob, Cint (attr. index - 1 ), attr. name, value)
177
+ _check_ret (model, ret)
178
+ return
179
+ end
180
+
181
+ param_type = _search_param_attr (model, attr. name)
182
+ if param_type == 0
183
+ ret = COPT_MultiObjSetDblParam (model. prob, Cint (attr. index - 1 ), attr. name, value)
184
+ _check_ret (model, ret)
185
+ elseif param_type == 1
186
+ ret = COPT_MultiObjSetIntParam (model. prob, Cint (attr. index - 1 ), attr. name, value)
187
+ _check_ret (model, ret)
188
+ else
189
+ throw (MOI. UnsupportedAttribute (attr. name))
190
+ end
191
+ return
192
+ end
193
+
194
+ function MOI. get (model:: Optimizer , attr:: MultiObjectiveParams )
195
+ if (attr. name == COPT_MULTIOBJ_PRIORITY || attr. name == COPT_MULTIOBJ_WEIGHT ||
196
+ attr. name == COPT_MULTIOBJ_ABSTOL || attr. name == COPT_MULTIOBJ_RELTOL)
197
+ p_value = Ref {Cdouble} ()
198
+ ret = COPT_MultiObjGetObjParam (model. prob, Cint (attr. index - 1 ), attr. name, p_value)
199
+ _check_ret (model, ret)
200
+ return p_value[]
201
+ end
202
+
203
+ param_type = _search_param_attr (model, attr. name)
204
+ if param_type == 0
205
+ p_value = Ref {Cdouble} ()
206
+ ret = COPT_MultiObjGetDblParam (model. prob, Cint (attr. index - 1 ), attr. name, p_value)
207
+ _check_ret (model, ret)
208
+ return p_value[]
209
+ elseif param_type == 1
210
+ p_value = Ref {Cint} ()
211
+ ret = COPT_MultiObjGetIntParam (model. prob, Cint (attr. index - 1 ), attr. name, p_value)
212
+ _check_ret (model, ret)
213
+ return p_value[]
214
+ else
215
+ throw (MOI. UnsupportedAttribute (attr. name))
216
+ end
217
+ end
218
+
219
+ struct MultiObjectivePriority <: MOI.AbstractModelAttribute
220
+ index:: Int
221
+ end
222
+
223
+ function MOI. set (model:: Optimizer , attr:: MultiObjectivePriority , value:: Real )
224
+ MOI. set (model, MultiObjectiveParams (attr. index, " MultiObjPriority" ), value)
225
+ return
226
+ end
227
+
228
+ function MOI. get (model:: Optimizer , attr:: MultiObjectivePriority )
229
+ return MOI. get (model, MultiObjectiveParams (attr. index, " MultiObjPriority" ))
230
+ end
231
+
232
+ struct MultiObjectiveWeight <: MOI.AbstractModelAttribute
233
+ index:: Int
234
+ end
235
+
236
+ function MOI. set (model:: Optimizer , attr:: MultiObjectiveWeight , weight:: Real )
237
+ MOI. set (model, MultiObjectiveParams (attr. index, " MultiObjWeight" ), weight)
238
+ return
239
+ end
240
+
241
+ function MOI. get (model:: Optimizer , attr:: MultiObjectiveWeight )
242
+ return MOI. get (model, MultiObjectiveParams (attr. index, " MultiObjWeight" ))
243
+ end
244
+
245
+ struct MultiObjectiveAbsTol <: MOI.AbstractModelAttribute
246
+ index:: Int
247
+ end
248
+
249
+ function MOI. set (model:: Optimizer , attr:: MultiObjectiveAbsTol , weight:: Real )
250
+ MOI. set (model, MultiObjectiveParams (attr. index, " MultiObjAbsTol" ), weight)
251
+ return
252
+ end
253
+
254
+ function MOI. get (model:: Optimizer , attr:: MultiObjectiveAbsTol )
255
+ return MOI. get (model, MultiObjectiveParams (attr. index, " MultiObjAbsTol" ))
256
+ end
257
+
258
+ struct MultiObjectiveRelTol <: MOI.AbstractModelAttribute
259
+ index:: Int
260
+ end
261
+
262
+ function MOI. set (model:: Optimizer , attr:: MultiObjectiveRelTol , weight:: Real )
263
+ MOI. set (model, MultiObjectiveParams (attr. index, " MultiObjRelTol" ), weight)
264
+ return
265
+ end
266
+
267
+ function MOI. get (model:: Optimizer , attr:: MultiObjectiveRelTol )
268
+ return MOI. get (model, MultiObjectiveParams (attr. index, " MultiObjRelTol" ))
269
+ end
270
+
271
+
272
+ # ==============================================================================
273
+ # objective-related attributes
274
+ # ==============================================================================
275
+
276
+ struct MultiObjectiveValue <: MOI.AbstractModelAttribute
277
+ index:: Int
278
+ end
279
+
280
+ function MOI. get (model:: Optimizer , attr:: MultiObjectiveValue )
281
+ return _copt_get_dbl_attr_multi_obj (model, attr. index, model. solved_as_mip ? " BestObj" : " LpObjval" )
282
+ end
0 commit comments