I’m working on an optimization problem in Julia where I need to maximize a logarithmic objective function (maximize sum of logs ):
@objective(model, Max, sum(alp[i] * log( p[i]) for i in 1:n))
where alp is vector of ones and p is a variable.
However, I’ve found that Gurobi doesn’t support logarithmic functions directly, and my attempts to access the C API using grb = backend(model) resulted in a “backend couldn’t be found” error.
Could anyone suggest how I might reformulate this objective in a way compatible with Gurobi, or provide guidance on using the Gurobi C API in Julia to handle this type of problem? Any advice on alternative approaches would also be much appreciated.
julia> using JuMP
julia> import Gurobi
julia> n = 3
3
julia> model = direct_model(Gurobi.Optimizer())
A JuMP Model
├ mode: DIRECT
├ solver: Gurobi
├ objective_sense: FEASIBILITY_SENSE
├ num_variables: 0
├ num_constraints: 0
└ Names registered in the model: none
julia> @variable(model, p[i in 1:n] == i)
3-element Vector{VariableRef}:
p[1]
p[2]
p[3]
julia> @variable(model, log_p[1:n])
3-element Vector{VariableRef}:
log_p[1]
log_p[2]
log_p[3]
julia> grb = backend(model)
sense : minimize
number of variables = 0
number of linear constraints = 0
number of quadratic constraints = 0
number of sos constraints = 0
number of non-zero coeffs = 0
number of non-zero qp objective terms = 0
number of non-zero qp constraint terms = 0
julia> column(x::VariableRef) = Gurobi.c_column(grb, index(x))
column (generic function with 1 method)
julia> for i in 1:n
Gurobi.GRBaddgenconstrLog(grb, "log(p[$i])", column(p[i]), column(log_p[i]), "")
end
julia> optimize!(model)
Gurobi Optimizer version 11.0.3 build v11.0.3rc0 (mac64[x86] - Darwin 23.5.0 23F79)
CPU model: Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 0 rows, 6 columns and 0 nonzeros
Model fingerprint: 0xe8e701e1
Model has 3 general constraints
Variable types: 6 continuous, 0 integer (0 binary)
Coefficient statistics:
Matrix range [0e+00, 0e+00]
Objective range [0e+00, 0e+00]
Bounds range [1e+00, 3e+00]
RHS range [0e+00, 0e+00]
Presolve removed 0 rows and 6 columns
Presolve time: 0.00s
Presolve: All rows and columns removed
Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)
Thread count was 1 (of 8 available processors)
Solution count 1: 0
Optimal solution found (tolerance 1.00e-04)
Best objective 0.000000000000e+00, best bound 0.000000000000e+00, gap 0.0000%
User-callback calls 90, time in user-callback 0.00 sec
julia> value.(p)
3-element Vector{Float64}:
1.0
2.0
3.0
julia> value.(log_p)
3-element Vector{Float64}:
0.0
0.6931471805599453
1.0986122886681098
julia> log.(value.(p))
3-element Vector{Float64}:
0.0
0.6931471805599453
1.0986122886681098
Thank you very much! My code is finally working
I guess the important part is to import Gurobi, and not using using Gurobi
I also added this objective function:
I guess the important part is to import Gurobi , and not using using Gurobi
This should have nothing to do with it. If you use import Gurobi, then you need to prefix all calls to Gurobi with Gurobi.. If you use using Gurobi, then all of the GRBxxx symbols are brought into scope and you can use GRBaddgenconstrLog without Gurobi..