Relaxing integrality on specific index values of a variable

Hi, I have the following variable in my .mod:

var X {CKLLT} >= 0;

Which is defined in the .dat file as:

set CKLLT :=
(commodity1, vehicle, location1, location2, time)
(commodity2, vehicle, location1, location2, time)

As you can see, the variable X is continuous. However, I would like to know if it is possible to force integrality for one of the commodities in the X{CKLLT} set. For example, when C in CKLLT =“commodity2”, the variable X must be integer, but the rest of the X variable solutions where the commodity does not equal “commodity2” can be continuous.

Thanks!

You can define the variables as integer, and then use AMPL’s builtin .relax suffix to specify the ones that should be treated as continuous. For example,

var X {CKLLT} integer >= 0;
let {(c,v,l1,l2,t) in CKLLT: c <> "commodity2"} 
   X[c,v,l1,l2,t].relax := 1;

Ok so I have a similar question (on actually the same project from jkilb above).

We have a variable for demand met D_bar{CLT} where CLT is a tupled set of the allowable combinations of (c, l, t) in CLT where c is commodity, l location, t time.

Likewise we have a parameter d{CLT} for needed demand.

What we want to do is conditionally create D_bar when we declare the variable where if there is never a demand for commodity c at location l, across all t D_bar for that CLT is not created.
We envision it to be something like

D_bar{CLT : sum{t in CLT} d[c,l,t] >0} for all c, l.

I know the syntax is wrong, that is what we are trying to fix, but because both are Indexed on a 3d tuple, I am unsure how to in the declaration of the variable break it into the for all c, l in CLT and sum over t in CLT. We know how to do that in constraint form, but not in variable declaration form.

Given that CLT is a set of triples, and param d is indexed over CLT, you could write

set CL = setof {(c,l,t) in CLT} (c,l);
var D_bar {(c,l) in CL: sum {(c,l,t) in CLT} d[c,l,t] > 0};

This defines a variable D_bar[c,l] corresponding to each commodity and location that has positive total demand over time. Is that what you have in mind?

(For each different “(c,l) in CL”, the expression “sum {(c,l,t) in CLT}” sums over all t such that “(c,l,t) in CLT”. This is called a slice through CLT — see Chapter 6: Compound Sets and Indexing in the AMPL book.)

This helps a lot! I did not know you could parse out tuples with ‘setof’. However, one thing that we must have is D_bar in the set of CLT aka 3d.

For example lets say I have the following tuples with the d (parameter not D_bar):
(C1, L1, 1)-> d[C1,L1,1]=0
(C1, L1, 2)-> d[C1,L1,2]=0
(C1, L1, 3)-> d[C1,L1,3]=5

(C2, L1, 1)-> d[C2,L1,1]=0
(C2, L1, 2)-> d[C2,L1,2]=0
(C2, L1, 3)-> d[C2,L1,3]=0

I would want D_bar to exist for (C1, L1, 1) (C1, L1, 2) (C1, L1, 3) because there exists a demand at L1 for C1 sometime in the planning horizon and the demand can be ‘met’ during any time even if it is before the demand signal.
But I would not want D_bar to exist for (C2, L1, 1) (C2, L1, 2) (C2, L1, 3) because no demand exists across the horizon so it makes no sense to to ‘meet’ demand that cant exist

I tried:
var D_bar {(c,l,t) in CLT: sum {(c,l) in CL} d[c,l,t]>0};
but I keep getting the below error

Caution: 0-dimensional slice
context: var D_bar {(c,l,t) in CLT: sum {(c,l) in >>> CL} <<< d[c,l,t]>0}

Thanks so much for the help you have given so far

Ah we fixed it with this:

set T1 =  setof {(c,l,t) in CLT}  t;
var D_bar {(c,l,t) in CLT: sum {t1 in T1} d[c,l,t1]>0}; 

Thanks so much for your help, there is one other question I have if you guys have the time to help.

When we now conditionally remove some D_bar{CLT} when we sum on (c,l,t) in CLT in the objective or ‘for all’ in a constraint is there a way to catch when D_bar does not have a matching CLT and assign zero. For example we get the following error:

error processing objective Total_Cost:
        invalid subscript D_bar['C2','L1',1] 

Because D_bar[‘C2’,‘L1’,1] correctly no longer exists. Is there a way to assign the value to be zero for these instances?

Thanks for the help.

It’s possible to have a rule that undefined variables are interpreted as 0 wherever they appear in expressions. This makes it more convenient to write some models, but we decided not to include such a rule in AMPL, because it too easily allows wrong models to be accepted. So this leaves two possibilities:

You can define a larger collection of variables, and fix the unwanted ones to zero. For example,

var D_bar {CLT};
subject to Dbar0 {(c,l,t) in CLT: sum {t1 in T1} d[c,l,t1] = 0}:
   D_bar[c,l,t] = 0;

Then you won’t get the invalid subscript error. Before the problem is sent to the solver, AMPL’s presolve phase will eliminate all of the variables that constraint Dbar0 fixes to zero. Unless CLT is a huge set, the extra work of creating extra D_bar variables and then fixing them to zero should not be significant.

Alternatively, you can index over {(c,l,t) in CLT: sum {t1 in T1} d[c,l,t1] > 0} wherever D_bar is used. If that indexing expression is needed more than once or twice, you might make the model easier to read by giving it a name; you could define, say, set CLTpos = {(c,l,t) in CLT: sum {t1 in T1} d[c,l,t1]>0}; and then index over {(c,l,t) in CLTpos} in the model.