@@ -26,6 +26,10 @@ function MOI.supports_constraint(
26
26
27
27
return false
28
28
end
29
+ function MOI. supports_constraint (
30
+ :: Model , :: Type{MOI.SingleVariable} , :: Type{MOI.Integer} )
31
+ return true
32
+ end
29
33
30
34
function MOI. supports (
31
35
:: Model ,
@@ -202,6 +206,16 @@ function Base.write(io::IO, model::Model{T}) where {T}
202
206
for i in eachindex (psd)
203
207
_print_constraint (length (nonneg) + i, true , psd[i])
204
208
end
209
+
210
+ # Integrality constraints.
211
+ # Based on the extension: http://www.opt.tu-darmstadt.de/scipsdp/downloads/data_format.txt
212
+ integer_cons = model_cons (MOI. SingleVariable, MOI. Integer)
213
+ if length (integer_cons) > 0
214
+ println (io, " *INTEGER" )
215
+ for con_idx in integer_cons
216
+ println (io, " *$(con_function (con_idx). variable. value) " )
217
+ end
218
+ end
205
219
return
206
220
end
207
221
@@ -242,6 +256,9 @@ function Base.read!(io::IO, model::Model{T}) where T
242
256
end
243
257
end
244
258
objective_read = false
259
+ integer_read = false
260
+ scalar_vars = nothing
261
+ intvar_idx = Int[]
245
262
c = nothing
246
263
funcs = nothing
247
264
MOI. set (model, MOI. ObjectiveSense (), MOI. MIN_SENSE)
@@ -251,14 +268,28 @@ function Base.read!(io::IO, model::Model{T}) where T
251
268
if startswith (line, ' "' )
252
269
continue
253
270
end
271
+ # The lines starting with * should also be skipped
272
+ # according to http://plato.asu.edu/ftp/sdpa_format.txt.
273
+ if startswith (line, ' *' )
274
+ # Exceptions for integer variables
275
+ if startswith (line, " *INTEGER" )
276
+ integer_read = true
277
+ elseif integer_read
278
+ if ! num_variables_read
279
+ error (" The number of variables should be given before *INTEGER section." )
280
+ end
281
+ push! (intvar_idx, parse (Int, strip (line[2 : end ])))
282
+ end
283
+ continue
284
+ end
254
285
if ! num_variables_read
255
286
if isempty (line)
256
287
continue
257
288
end
258
289
num_variables_read = true
259
290
# According to http://plato.asu.edu/ftp/sdpa_format.txt,
260
291
# additional text after the number of variables should be ignored.
261
- MOI. add_variables (model, parse (Int, split (line)[1 ]))
292
+ scalar_vars = MOI. add_variables (model, parse (Int, split (line)[1 ]))
262
293
elseif num_blocks === nothing
263
294
if isempty (line)
264
295
continue
@@ -288,7 +319,7 @@ function Base.read!(io::IO, model::Model{T}) where T
288
319
obj = zero (MOI. ScalarAffineFunction{T})
289
320
for i in eachindex (c)
290
321
if ! iszero (c[i])
291
- push! (obj. terms, MOI. ScalarAffineTerm (c[i], MOI . VariableIndex (i) ))
322
+ push! (obj. terms, MOI. ScalarAffineTerm (c[i], scalar_vars[i] ))
292
323
end
293
324
end
294
325
MOI. set (model, MOI. ObjectiveFunction {typeof(obj)} (), obj)
@@ -320,14 +351,17 @@ function Base.read!(io::IO, model::Model{T}) where T
320
351
else
321
352
if ! iszero (coef)
322
353
push! (funcs[block]. terms, MOI. VectorAffineTerm (k,
323
- MOI. ScalarAffineTerm (coef, MOI . VariableIndex ( matrix) )))
354
+ MOI. ScalarAffineTerm (coef, scalar_vars[ matrix] )))
324
355
end
325
356
end
326
357
end
327
358
end
328
359
for block in 1 : num_blocks
329
360
MOI. add_constraint (model, funcs[block], block_sets[block])
330
361
end
362
+ for var_idx in intvar_idx
363
+ MOI. add_constraint (model, MOI. SingleVariable (scalar_vars[var_idx]), MOI. Integer ())
364
+ end
331
365
return
332
366
end
333
367
0 commit comments