Generate indexed constraint, except for certain elements

When you have an indexed constraint, sometimes you want this constraint not to be generated for certain elements of the index domain.

Examples of these cases are:

  • In the constraint you are referring to the previous or the next element. This means that the constraint should not be generated for the first element and the last element, respectively. A simple example of this is a Stock Balance constraint:
    StockLevel(t) = StockLevel(t-1) + AmountProduced(t) – AmountSold(t)
  • You want to create a constraint that is indexed over two indices of the same set for all combinations, except for the situation where the two indices refer to the same element. An example would be a precedence constraint: a task i must be either before or after another task j and this constraint should be created for all i,j such that i≠j

You can achieve this goal by restricting the index domain of the constraint with a domain condition. A domain condition can be introduced with the | operator (the so-called such-that operator). With this operator, AIMMS will only consider those elements (or combination of elements in case of multiple indices) for which the expression after the | operator holds a non-zero value.

For the first example, in case of using the previous element in the constraint, you would like the constraint to be generated for all timeperiods t, except for the first one. This can be expressed in AIMMS by setting the attributes of the constraint as follows:

CONSTRAINT:
   identifier   :  StockBalanceConstraint
   index domain :  t | ord(t) > 1
   definition   :  StockLevel(t) = StockLevel(t-1) 
                                     + AmountProduced(t) 
                                     - AmountSold(t)

The intrinsic ord function returns the position of the element in the set. The domain condition (the part after the | operator) will only have a non-zero value for those elements that are not on the first position of the set. This means that this constraint will be generated for all t, except for the first one.

For the second example, if we have a binary variable TaskStartsBeforeOther(i,j) that gets the value 1 in case task i starts before task j and 0 otherwise, we can model the constraint that for each combination of tasks it must hold that one of the two is started before the other one. This constraint is not valid for the combination where task i is equal to task j. This can be achieved by setting the attributes of the constraint as follows

CONSTRAINT:
   identifier   :  EitherBeforeOrAfter
   index domain :  (i,j) | i <> j
   definition   :  TaskStartsBeforeOther(i,j) 
                     + TaskStartsBeforeOther(j,i) 
                     = 1

No related posts.

About Guido Diepen

Guido has been working at AIMMS since August 2008. He is part of the Professional Services team that helps customers getting the most out of AIMMS for their problems. His background is Integer Linear Programming and he is now also looking more at Constraint Programming.
This entry was posted in Beginner, Technical and tagged , . Bookmark the permalink.

Facebook comments

Leave a Reply

Your email address will not be published. Required fields are marked *

*

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">