-
Notifications
You must be signed in to change notification settings - Fork 63
/
cpx_model.jl
138 lines (125 loc) · 4.16 KB
/
cpx_model.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
type Model
env::Env # Cplex environment
lp::Ptr{Void} # Cplex problem (lp)
has_int::Bool # problem has integer variables?
has_qc::Bool # problem has quadratic constraints?
callback::Any
function Model(env::Env, lp::Ptr{Void})
model = new(env, lp, false, false, nothing)
finalizer(model, free_problem)
model
end
end
function Model(env::Env, name::ASCIIString)
@assert is_valid(env)
stat = Array(Cint, 1)
tmp = @cpx_ccall(createprob, Ptr{Void}, (Ptr{Void}, Ptr{Cint}, Ptr{Cchar}), env.ptr, stat, name)
if tmp == C_NULL
throw(CplexError(model.env, stat))
end
return Model(env, tmp)
end
function read_model(model::Model, filename::ASCIIString)
stat = @cpx_ccall(readcopyprob, Cint, (Ptr{Void}, Ptr{Void}, Ptr{Cchar}, Ptr{Cchar}), model.env.ptr, model.lp, filename, C_NULL)
if stat != 0
throw(CplexError(model.env, stat))
end
end
function write_model(model::Model, filename::ASCIIString)
if endswith(filename,".mps")
filetype = "MPS"
elseif endswith(filename,".lp")
filetype = "LP"
else
error("Unrecognized file extension: $filename (Only .mps and .lp are supported)")
end
stat = @cpx_ccall(writeprob, Cint, (Ptr{Void}, Ptr{Void}, Ptr{Cchar}, Ptr{Cchar}), model.env.ptr, model.lp, filename, filetype)
if stat != 0
throw(CplexError(model.env, stat))
end
end
## TODO: deep copy model, reset model
function get_sense(model::Model)
sense_int = @cpx_ccall(getobjsen, Cint, (
Ptr{Void},
Ptr{Void},
),
model.env.ptr, model.lp)
if sense_int == 1
sense = :Min
elseif sense_int == -1
sense = :Max
else
error("CPLEX: problem object or environment does not exist")
end
return sense
end
function set_sense!(model::Model, sense)
if sense == :Min
@cpx_ccall(chgobjsen, Void, (Ptr{Void}, Ptr{Void}, Cint), model.env.ptr, model.lp, 1)
elseif sense == :Max
@cpx_ccall(chgobjsen, Void, (Ptr{Void}, Ptr{Void}, Cint), model.env.ptr, model.lp, -1)
else
error("Unrecognized objective sense $sense")
end
end
function get_obj(model::Model)
nvars = num_var(model)
obj = Array(Cdouble, nvars)
stat = @cpx_ccall(getobj, Cint, (
Ptr{Void},
Ptr{Void},
Ptr{Cdouble},
Cint,
Cint
),
model.env.ptr, model.lp, obj, 0, nvars-1)
if stat != 0
throw(CplexError(model.env, stat))
end
return obj
end
function set_obj!(model::Model, c::Vector)
nvars = num_var(model)
stat = @cpx_ccall(chgobj, Cint, (
Ptr{Void},
Ptr{Void},
Cint,
Ptr{Cint},
Ptr{Cdouble}
),
model.env.ptr, model.lp, nvars, Cint[0:nvars-1], float(c))
if stat != 0
throw(CplexError(model.env, stat))
end
end
set_warm_start!(model::Model, x::Vector{Float64}) = set_warm_start!(model, Cint[1:length(x)], x)
function set_warm_start!(model::Model, indx::IVec, val::FVec)
stat = @cpx_ccall(addmipstarts, Cint, (
Ptr{Void},
Ptr{Void},
Cint,
Cint,
Ptr{Cint},
Ptr{Cint},
Ptr{Cdouble},
Ptr{Cint},
Ptr{Ptr{Cchar}}
),
model.env.ptr, model.lp, 1, length(indx), Cint[0], indx.-1, val, Cint[0], C_NULL)
if stat != 0
throw(CplexError(model.env, stat))
end
end
function free_problem(model::Model)
stat = @cpx_ccall(freeprob, Cint, (Ptr{Void}, Ptr{Void}), model.env.ptr, model.lp)
if stat != 0
throw(CplexError(model.env, stat))
end
end
function close_CPLEX(env::Env)
stat = @cpx_ccall(closeCPLEX, Cint, (Ptr{Void},), env.ptr)
if stat != 0
throw(CplexError(model.env, stat))
end
end