How can I fix my code to run using JuMP

Hey, guys.
This is my first time working with both Julia and JuMP. I’m making lot of mistakes, but I finally got my code running fine. Using JuMP in my code would be a plus, so I’m trying to do that, but I am having problems.
At this point, it appears an error because of the equation called “diametro”.

Only exponents of 0, 1, or 2 are currently supported. Are you trying to build a nonlinear problem? Make sure you use @NLconstraint/@NLobjective.

But even doing that, it doesn’t work.

I reduced a lot my code to the case that someone would want to run (it runs correctly without the JuMP elements).

QTD_TRECHOS = 1
CIDADES_ID = [0 1 2 3 4 5 6 7 8 9]
DEMANDAS = [0 64 40.6 51.8 43.3 78 78.3 328.4 66.2 102.4]
DISTANCIAS = [0 47.74 3.86 24.25 37.35 26.94 500 50.36 30.21 36.2]
SUBTRECHOS = [1 9]
lista_custos = [148200.2,214658.73,326579.09,725541.29,889868.75,1062575.24,1229238.98,1403003.36,1876984.47,2410809.48,3089843.99,89955515]
lista_diametros = [75,100,150,200,250,300,350,400,500,600,700,800]
QTD_SUBTRECHOS = 9


model = Model(Cbc.Optimizer)
@variable(model, DELTA[1:length(CIDADES_ID)], Bin)

DN = []
CUSTO = []
DEMANDAS_OTIM_final = []
VAZAO_CAMINHOS = []

for i in 1:QTD_TRECHOS
    CAMINHOS_NUM = [1 2 3 4 5 6 7 8 9
                    3 0 5 0 7 0 0 9 0
                    4 0 6 0 8 0 0 0 0
                    5 0 7 0 9 0 0 0 0
                    6 0 8 0 0 0 0 0 0
                    7 0 9 0 0 0 0 0 0
                    8 0 0 0 0 0 0 0 0
                    9 0 0 0 0 0 0 0 0]
    
    DEMANDAS_OTIM = []
    for i in 1:size(DEMANDAS,2)
        op_mult = DEMANDAS[i]*DELTA[i]
        push!(DEMANDAS_OTIM, op_mult)
    end
    DEMANDAS_OTIM = transpose(DEMANDAS_OTIM)
    push!(DEMANDAS_OTIM_final, DEMANDAS_OTIM)
    
    MATRIZ_CAMINHOS = []
    for j in 1:size(CAMINHOS_NUM,2)
        for i in 1:size(CAMINHOS_NUM,1)
            substituicao = DEMANDAS_OTIM[findfirst(isequal(CAMINHOS_NUM[i,j]),CIDADES_ID)]
            push!(MATRIZ_CAMINHOS,substituicao)
        end
    end
    MATRIZ_CAMINHOS = reshape(MATRIZ_CAMINHOS, size(CAMINHOS_NUM,1), size(CAMINHOS_NUM,2))
    
    VAZAO_CAMINHO = sum(MATRIZ_CAMINHOS, dims=1)
    push!(VAZAO_CAMINHOS, VAZAO_CAMINHO)

    
    for i in 1:size(VAZAO_CAMINHO,2)
        diametro = 0.8 * (((VAZAO_CAMINHO[i])/1000)^(1/2)) * 1000
        if diametro < 100
            diam_nominal1 = 75
            push!(DN, diam_nominal1)
        
        elseif 100 <= diametro <= 400
            diam_nominal1 = 50 * div(diametro, 50, RoundDown)
            push!(DN, diam_nominal1)
        
        elseif diametro > 400
            diam_nominal1 = 100 * div(diametro, 100, RoundDown) 
            push!(DN, diam_nominal1)
        end
    end   
end

for i in 1:length(DN)
    custos = lista_custos[findfirst(isequal(DN[i]),lista_diametros)] * DISTANCIAS[i]
    CUSTO = vcat(CUSTO, custos)
end

CUSTO_TRECHO = []
for i in 1:length(QTD_SUBTRECHOS)
    custo_trecho = sum(CUSTO[SUBTRECHOS[i,1]:SUBTRECHOS[i,2]])
    CUSTO_TRECHO = vcat(CUSTO_TRECHO, custo_trecho)
end


@NLconstraint (model, DELTA[3]+DELTA[5]=1)
@NLconstraint (model, DELTA[1]=1)


@NLobjective (model, Min, CUSTO_TRECHO[i] for i in 1:QTD_TRECHOS)


optim = optimize!(transpModel)

Thank you all for your help!

Hi there,

The main issue is that you are attempting to construct a nonlinear expression outside the JuMP macros.

There are also a bunch of other smaller issues, like @NLconstraint (model, DELTA[3]+DELTA[5]=1) instead of @constraint(model, DELTA[3] + DELTA[5] == 1), or @NLobjective (model, Min, CUSTO_TRECHO[i] for i in 1:QTD_TRECHOS) instead of @NLobjective(model, Min, sum(CUSTO_TRECHO[i] for i in 1:QTD_TRECHOS)).

There are also some potential confusions, like:

for i in 1:QTD_TRECHOS
    DEMANDAS_OTIM = []
    for i in 1:size(DEMANDAS,2)
        op_mult = DEMANDAS[i]*DELTA[i]
        push!(DEMANDAS_OTIM, op_mult)
    end

Here you have a for-loop over i in 1:QTD_TRECHOS, but then you have another for-loop over i in 1:size(DEMANDAS, 2). What I should the DEMANDAS[I] refer to? You can potentially simplify this to DEMANDAS_OTIM = [DEMANDAS[i]*DELTA[i] for i in 1:size(DEMANDAS,2)].

I’d start by simplifying your problem. Get the minimum working first, and then introduce complexity bit-by-bit.

Do you have a formulation on paper of the model? Do you expect your objective function to contain a bunch of nonlinear terms with square roots?

1 Like

Yeah, I thought this nonlinear expression outside would be a problem.

Actually, this nonlinear expression is the only one that appears in my code. Besides that, I only have if’s.
And no, I don’t have a formulation on paper.

I appreciate your tips and help.

Besides that, I only have if’s.

These are also a problem. But it’s hard to understand what model you are trying to implement based only on the code.

I don’t have a formulation on paper

This would help understand what you’re trying to achieve.