3

I am trying to model the operation of a system component, the component will have two operating modes, let's call them 1 and 2, plus the idle mode 0

There is no limit on idling, but each operating mode will last for exactly 3 time-series points, so x_{i}= 1 means x_{i+1} = x_{i+2} = 1 (cannot post images, please use the link below for the equation) operation mode 1

same goes for operating mode 2.

For example. 011102220 is valid, but 01110220 is not.

111111 or 222222 are not valid, but this is taken care of in other resource related constraints (the system will not have enough resource to operate for more than 3 time-series points), so as long as the issue regarding to forcing three consecutive 1s or 2s in the variable array is address, it should be fine.

Thanks in advance,

sascha
  • 32,238
  • 6
  • 68
  • 110
BeWater
  • 33
  • 3

2 Answers2

4

Runs of length exactly three can be modeled as:

y(t+1) >= y(t)-y(t-1)
y(t+2) >= y(t)-y(t-1)
1-y(t+3) >= y(t)-y(t-1)

where y(t) is a binary variable. Runs of length at least three can be modeled by dropping the last constraint:

y(t+1) >= y(t)-y(t-1)
y(t+2) >= y(t)-y(t-1)
Erwin Kalvelagen
  • 15,677
  • 2
  • 14
  • 39
  • Thanks! However if y(t)=0, y(t-1)=1, then the third constraint will read as y(t+3) <= 0, wouldn't that induce unwanted 0 value lock on y values? (since y(t)=0 and y(t+3)=0, that forces y(t+1) and y(t+2) to be 0, so 10⇒10000 – BeWater Jun 13 '17 at 01:44
  • I am afraid I am not following you. If `y(t)=0, y(t-1)=1` we have `1-y(t+3) >= -1` or `y(t+3) <= 2` which is not binding. – Erwin Kalvelagen Jun 13 '17 at 03:18
  • You are absolutely right! I made a silly error in the calculation. My apologies for the confusion. – BeWater Jun 13 '17 at 03:37
1

Let's simplify the problem somewhat: we assume we have only binary values, meaning, that we only care about 0's and 1's.

Introduce a new auxiliary binary vector start_block. This vector mark beginnings of new blocks.

A non-zero value within this binary-vector is part of the constraints, which define the implication of a block.

Let's call the solution-vector X.

The implication is done in a pairwise manner.

# zero-order logic
start_block[x] -> X[x]
start_block[x] -> X[x+1]
start_block[x] -> X[x+2]

<=> 

# zero-order logic ( a->b <-> !a V b )
!start_block[x] V X[x]
!start_block[x] V X[x+1]
!start_block[x] V X[x+2]

<=>

# linear expression
(1 - start_block[x]) + X[x] >= 1
(1 - start_block[x]) + X[x+1] >= 1  
(1 - start_block[x]) + X[x+2] >= 1 

Do this for the whole decision-variable dimension of X (caring about borders).

Keep in mind, that this only says: if there is a 1 in X, it's part of a block of size >=3. It can be a block of 4. As i don't know your model exactly, that's the most general approach i can offer. Of course you can tune this further for your case!

Generalizing this for integer-variables should not be too hard, but might introduce new auxiliary variables.

sascha
  • 32,238
  • 6
  • 68
  • 110
  • Thanks for the speedy reply! Could you elaborate a bit on the second block of your code? the !start_block v X[x] part, is it making start_block[x] to be 0 to indicate three consecutive 1s in X? – BeWater Jun 12 '17 at 10:38
  • No, it says: if start_block[x] == 1 -> there will be 1's at pos x, x+1, x+2 within X. So it depends on your remainding model how to incorporate this (the general flow is: start-block implies something on X; so probably start_block is the variable to use in the remaining model). In the code-block, only the last part is relevant. The two blocks above are just given to show where it's coming from. – sascha Jun 12 '17 at 10:40
  • If you need some other direction of effects you can always model that (e.g. from X to start_block). But for this special-case of blocks of size at least 3, this direction is very practical. – sascha Jun 12 '17 at 10:52
  • Sorry for the repeated follow up questions, being new to this field, I think I really need to up my skill in boolean algebra. I think the other direction of effect would be what I need (from x = x+1 = x+2 = 1 to force start_block[x] = 1. However if I only consider the other direction of effect, wouldn't I lose the control that 1s in X need to happen in blocks of three? or should I include both directions into the constraint? – BeWater Jun 12 '17 at 11:44
  • It can't be answered with total knowledge of the model. It's left to you how to incorporate this and post constraints on start_block. I don't know if you need other directions. The approach above needs, that you somehow use start_block to introduce non-zero values and the constraints induce the block-effect. As currently formulated, posting no additional constraints on start_block will not have any effect within the model as this direction is non-active then. The other way around, X -> start_vector will also need some constraints acting on start_vector to see some effects. – sascha Jun 12 '17 at 11:52
  • While a bit more general, everyone new to integer-programming should read a guide like [this one](https://download.aimms.com/aimms/download/manuals/AIMMS3OM_IntegerProgrammingTricks.pdf). It might not be the answer to your questions, but give some general idea (especially the either-or and conditional constraints). – sascha Jun 12 '17 at 11:53
  • And a very general remark to the other direction: X -> Y, where X are your 0's and 1's it's hard to do something, as for every X, you don't know if your X is now the start of a block or the end or something in the middle (one would need to check for both directions, left and right). I highly recommend to model a much more simple model first (remove complexity) and observe what's happening. – sascha Jun 12 '17 at 11:55
  • Thanks so much for the help and the insights, much appreciated! – BeWater Jun 12 '17 at 11:58