Adding SOS1 constraint problem

I am trying to add a simple SOS1 constraint, but getting the following error

MethodError: no method matching build_constraint(::JuMP.var"#_error#68"{Symbol}, ::Array{VariableRef,2}, ::SOS1)

for

            @constraint(
                premex,
                SOSa[t in TIME],
                [PRODAMOUNT[op_k, u_k, t] for u_k in ["BUHLER1", "BUHLER2"], (op_k, op) in _ORDER_PRODUCTs_ALL] in SOS1()
            )   

What I am doing wrong here?

I am not sure.

The only official use I found of SOS1 is this line inside the tests.

Could you post the full backtrace inside triple backticks here?

Let;'s forget SOS1(), the most important is to figure out how to create constraints for this:

X[i,j,k] , Int, >= 0

Now: for every j and k, but if one i has value > 0 then all others should be =0

How to write this constraint in julia / jump?

If the variables are binary this is easy:

@constraint(model, sum(X[i, j, k] for i in I, j in J, k in K) <= 1)

If the variables are not binary then I do not know a simple and clean way to do it. Maybe SOS1 was your best choice.

Actually I solved it like this:

            @constraint(
                premex,
                BUHLER1_BUHLER2[op_k in keys(_ORDER_PRODUCTs_ALL), t in TIME],
                PRODAMOUNT[op_k, "BUHLER1", t]  => {sum(PRODAMOUNT[op_k, "BUHLER2", t] for op_k in keys(_ORDER_PRODUCTs_ALL)) == 0}
            )   
            
            @constraint(
                premex,
                BUHLER2_BUHLER1[op_k in keys(_ORDER_PRODUCTs_ALL), t in TIME],
                PRODAMOUNT[op_k, "BUHLER2", t]  => {sum(PRODAMOUNT[op_k, "BUHLER1", t] for op_k in keys(_ORDER_PRODUCTs_ALL)) == 0}
            )   

I… maybe I am wrong, but I am not entirely sure this works… what are the {} supposed to mean? Also, => means pair creation, 1 => 2 gives a pair of 1 and 2, it does not mean that 1 should be greater-than-or-equal-to 2.

these are Indicator-constraints: https://jump.dev/JuMP.jl/v0.21.1/constraints/#Indicator-constraints-1

So let’s analyse BUHLER1_BUHLER2 constraint it says:

if PRODAMOUNT[op_k, “BUHLER1”, t] > 0 then every PRODAMOUNT[op_k, “BUHLER2”, t] should be 0

that way we can manipulate (change) other values based on the value we want. Note that left from => should be Boolean, but luckily julia/jump treats all number != 0 as true (LUCKILY :smile: )

Yes I was about to say this. The documentation says this is intended for binary variables. It would be good to confirm this works with the devs first.

Sure, but I am getting right results, when BUHLER1 is chosen there is no BUHLER2 at the same time. So I am happy (finally) with it.

Your problem is that you are passing a matrix (the ::Array{VariableRef,2}).

julia> [i+j for i in 1:2, j in 1:2]
2×2 Array{Int64,2}:
 2  3
 3  4

julia> [i+j for i in 1:2 for j in 1:2]
4-element Array{Int64,1}:
 2
 3
 3
 4

You want something like

@constraint(
    premex,
    SOSa[t in TIME],
    [
        PRODAMOUNT[op_k, u_k, t] 
        for u_k in ["BUHLER1", "BUHLER2"] 
        for (op_k, op) in _ORDER_PRODUCTs_ALL
    ] in SOS1()
)  
2 Likes

Thanks, Oscar, that is exactly what I am looking for! Now I’ve learned that it is possible to nest for loops from your example.

Sorry, but I am learning Julia / Jump just to finish one project started in AMPL by my friend and we have to deliver the final product - a windows application with a user interface and this model and we are already late. So no time for learning, just google it and that is ti. :smile: