To see how you can encode sos type 1 constraints in AMPL, consider this example:
var X {1..5,1..7} integer >= 0, <= 10;
maximize obj:
sum {i in 1..5, j in 1..7} Uniform(1,2) * X[i,j];
subject to con:
sum {i in 1..5, j in 1..7} X[i,j] <= 35;
Additionally, it is required that, for each i in 1…5, at most one of X[i,1], X[i,2], . . . , X[i,7] is > 0. Thus there are 5 sos1 constraints, with 7 variables each. They can be expressed in AMPL by setting values for two user-defined suffixes, sosno
and ref
:
suffix sosno IN;
suffix ref IN;
let {i in 1..5, j in 1..7} X[i,j].sosno := i;
let {i in 1..5, j in 1..7} X[i,j].ref := j;
The general rules for setting these suffix values are as follows:
- Members of each SOS1 set have a different, unique
.sosno
value.
- Within each SOS1 set, members all have different
.ref
values.
Thus for the example, X[i,1].sosno, X[i,2].sosno, . . . , X[i,7].sosno are all equal to i, while X[i,1].ref, X[i,2].ref, . . . , X[i,7].ref are equal to 1, 2, . . . , 7, respectively.
If you have a hard problem, you may want to experiment with different settings of the Gurobi options presos1bigm and presos1enc; see the Gurobi Options listing and the Gurobi documentation of SOS Constraints.
Starting with Gurobi 10.0, you can also write this constraint directly, without any SOS suffixes, as
subj to OnePos {i in 1..5}:
atmost 1 {j in 1..7} (X[i,j] > 0);
The AMPL-Gurobi interface will convert this to linear MIP constraints before sending the problem to Gurobi.