Gurobi with Log constranints

Hello,
I am trying to make the log constraints work with Gurobi.jl and JuMP.jl. However, I don’t seem to be able to successfully use the C call function. Anyone who has managed to use them?
I paste a simple example below.
Thanks!

using JuMP # used for mathematical programming
using Gurobi # solver

a = 0.2;
b = 0.5;

m = direct_model(Gurobi.Optimizer());
set_optimizer_attribute(m, "NonConvex", 2);
set_optimizer_attribute(m, "PreSolve", 0);

#  define objects to solve for
@variable(m, costs >= 0.001, start = 1.0);
@variable(m, logCosts >= log(0.001));

#  objective function:
@objective(m, Min, a * costs - b * logCosts);

#  log constraint:
GRBaddgenconstrLog(m, "logCost", 1, 2, "");

optimize!(m);

This is the error I get:

ERROR: MethodError: no method matching unsafe_convert(::Type{Ptr{Nothing}}, ::Model)
Closest candidates are:
  unsafe_convert(::Union{Type{Ptr{Nothing}}, Type{Ptr{Base.Libc.FILE}}}, ::Base.Libc.FILE) at libc.jl:94
  unsafe_convert(::Type{Ptr{T}}, ::SubArray{T, N, P, var"#s79", L} where {var"#s79"<:Tuple{Vararg{Union{Int64, AbstractRange{Int64}}, N} where N}, L}) where {T, N, P} at subarray.jl:426
  unsafe_convert(::Type{Ptr{T}}, ::SubArray{T, N, P, var"#s79", L} where {var"#s79"<:Tuple{Vararg{Union{Int64, AbstractRange{Int64}, Base.ReshapedArray{T, N, A, Tuple{}} where {T, N, A<:AbstractUnitRange}}, N} where N}, L}) where {T, N, P} at reshapedarray.jl:292
  ...
Stacktrace:
 [1] GRBaddgenconstrLog(model::Model, name::String, xvar::Int64, yvar::Int64, options::String)
   @ Gurobi ~/.julia/packages/Gurobi/xvBAY/src/gen100/libgrb_api.jl:528
1 Like

You likely need

grb = backend(m)
GRBaddgenconstrLog(grb, "logCost", 1, 2, "");

Thank you for the reply. This is what I first attempted. However, it does not seem to recognize some of the earlier inputs. Should I just build everything with the direct model and give up the JuMP functionality?

In the example above, the solution does not make sense if I just add it with the grb backend. I get objective function of zero and the solution of the variables at the corner.

grb = backend(m)
GRBaddgenconstrLog(grb, "logCost", 1, 2, "");
optimize!(m)

Similarly, if I use GRBoptimize on grb instead of jump’s optimize.

grb = backend(m)
GRBaddgenconstrLog(grb, "logCost", 1, 2, "");
GRBoptimize(grb)

I played around with when I add the objective function using JuMP’s functionality. I will try to add an objective using the GRB syntax to see if I can make it work.

Sorry to ask such a basic question. I don’t seem to find a simple functioning example online, and I am a bit confused about how the backend interacts with the jump model.

I haven’t tried solving a model with a general constraint.

I don’t seem to find a simple functioning example online

Correct. Gurobi.jl isn’t officially supported by Gurobi, so we’ve largely focused on the features that are supported by JuMP. The full API, while technically accessible via C, isn’t documented or supported.

Here you go:

The missing bit was you needed zero-indexed columns as Cint instead of 1 and 2.

using JuMP
using Gurobi

column(model, x) = Cint(Gurobi.column(backend(model), index(x)) - 1)

model = direct_model(Gurobi.Optimizer())
@variable(model, x >= 0.001)
@variable(model, y <= 2)
@objective(model, Max, x)
# y = log(x)
GRBaddgenconstrLog(backend(model), "logCost", column(model, x), column(model, y), "")
optimize!(model)
value(x), value(y)

Hello, thank you for your patience. I realized I was using Julia indexing and not C indexing… That fixed the problem of the constraint not being recognized. I am still not getting the right solution, as in it does not give me the correct minimum…

This seems more Gurobi-related than JuMP/Gurobi.jl related, though. I will post a functional solution if I manage.

1 Like

EDIT: Oh, wow. Thank you!

1 Like

Working example:

using JuMP # used for mathematical programming
using Gurobi, Ipopt # solver

# function to get the right index (thanks to @odow)
column(model, x) = Cint(Gurobi.column(backend(model), index(x)) - 1)

# Params
a = 0.2;
b = 0.5;

# Gurobi
m = direct_model(Gurobi.Optimizer());
set_optimizer_attribute(m, "NonConvex", 2);

# define objects to solve for
@variable(m, 0.001 <= costs <= 100.0);
@variable(m, logCosts >= log(0.001));

# objective function:
@objective(m, Min, a*costs - b*logCosts);

# log constraint
GRBaddgenconstrLog(backend(m), "logCost", column(m, costs), column(m, logCosts), "FuncPieces=-1 FuncPieceError=1e-6")

# solving the model
optimize!(m)

println([JuMP.value.(costs),JuMP.value.(logCosts)])
1 Like