Construct LP from matrix using GRBnewmodel, GRBaddvars, and GRBaddconstr
回答済みHi, I am trying to use the C API to build an LP from scratch. I want to solve
`max{c' * x : Ax <= b, x >= 0}`.
In particular, I am using Julia and calling the `GRBnewmodel`, `GRBaddvars`, and `GRBaddconstr` functions for problem data `A`, `b`, and `c`. To verify my construction, I compare against solving the same problem in `JuMP`. My code below shows that I am making an error in constructing the problem using the C interface. Can you please help me identify what is going wrong? Are there any examples of creating a model using the C API in a flexible way like this? I don't want to load from an LP file.
Any help would be appreciated!
#=
maximize c' * x
subject to A * x <= b
x >= 0
=#
using Gurobi
using JuMP
function solve_lp_direct(A::Matrix{Tf}, b::Vector{Tf}, c::Vector{Tf}) where Tf<:Cdouble
setup_time = @elapsed begin
# initialize model
start_time = time()
env_p = Ref{Ptr{Cvoid}}()
error = GRBloadenv(env_p, "lp.log")
env = env_p[]
model_p = Ref{Ptr{Cvoid}}()
error = GRBnewmodel(
env,
model_p,
"lp",
0,
C_NULL,
C_NULL,
C_NULL,
C_NULL,
C_NULL
)
model = model_p[]
m, n = size(A)
# maximize
error = GRBsetintattr(model, GRB_INT_ATTR_MODELSENSE, GRB_MAXIMIZE)
# output
optimstatus = Ref{Cint}()
objval = Ref{Cdouble}()
sol = ones(Tf, n)
# variables and objective
error = GRBaddvars(
model, # model
n, # : numvars
0, # : numnz
C_NULL, # : *vbeg
C_NULL, # : *vind
C_NULL, # : *vval
c, # : *obj
zeros(Cdouble, n), # : *lb
fill(+Inf, n), # : *ub
C_NULL, # : *vtype
C_NULL# : **varnames
)
# constraint
for i in 1:size(A,1)
Ai = A[i,:]
cind = findall(Ai .!= 0.0)
numnz = Cint(length(cind))
cval = Ai[cind]
cind .-= 1
cind = Cint.(cind)
sense = GRB_LESS_EQUAL
rhs = b[i]
error = GRBaddconstr(
model, # : *model
numnz, # : numnz
cind, # : *cind
cval, # : *cval
sense, # : sense
rhs, # : rhs
C_NULL, # : *constrname
)
@assert(error == 0)
end
end# begin
println("model setup = $(setup_time)")
solve_time = @elapsed error = GRBoptimize(model)
println("model solve = $(solve_time)")
# error = GRBwrite(model, "lp.lp");
error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, optimstatus);
error = GRBgetdblattr(model, GRB_DBL_ATTR_OBJVAL, objval);
error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, n, sol);
return sol
end
function solve_lp_jump(A::Matrix{Tf}, b::Vector{Tf}, c::Vector{Tf}) where Tf<:Cdouble
setup_time = @elapsed begin
m, n = size(A)
M = Model(Gurobi.Optimizer)
@variable(M, x[1:n] .>= 0)
@objective(M, Max, c'*x)
@constraint(M, A*x .<= b)
end
println("model setup = $setup_time")
solve_time = optimize!(M)
println("model solve = $(solve_time)")
returnvalue.(x)
end
m = 50
n = 100
A = randn(Cdouble, m, n)
b = randn(Cdouble, m)
c = randn(Cdouble, n)
@time sol1 = solve_lp_direct(copy(A), copy(b), copy(c));
@time sol2 = solve_lp_jump(copy(A), copy(b), copy(c));
sum(abs.(sol1-sol2))
-
正式なコメント
This post is more than two years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum, or try Gurobot, our chatbot interface offering instant, expert-level support. -
Discussing on the JuMP forum: https://discourse.julialang.org/t/slow-model-construction-in-jump/95455/4
The C calls don't free memory with GRBfreemodel or GRBfreeenv.
1
投稿コメントは受け付けていません。
コメント
2件のコメント