1

I have an integer-valued bounded variable, call it X. (Somewhere around 0<=X<=100)

I want to have a binary variable, call it Y, such that Y=1 if X >= A and X <= B, otherwise Y=0.

The best I've come up with thus far is the following (where T<x> are introduced binary variables, and M is a large number)

(minimize Y)
(X - A) <= M*Ta
(B - X) <= M*Tb
Y <= Ta
Y <= Tb
Y >= Ta + Tb - 1

(In other words, introducing two binary variables that are true if the variable satisfies the lower and upper bounds of the range, respectively, and setting the result to the binary multiplication of those variables)

This... Works, sort of, but has a couple major flaws. In particular, it's not rigorously defined - Y can be 1 even if X is outside the range.

So: is there a better way to do this? In particular: is there a way to rigorously define it, or if not, a way to at least prevent false positives?


Edit: to clarify: A and B are variables, not parameters.

TLW
  • 1,373
  • 9
  • 22

2 Answers2

1

I think the below works.

(I) A * Y <= X <= B * Y + 100 * (1 - Y)

(II) (X - A) <= M * Ta

(III) (B - X) <= M * Tb

(IV) Y >= Ta + Tb - 1

So X < A makes:

(I)Y=0

and (II), (III), (IV) do not matter.

X > B makes:

(I) Y = 0

and (II), (III), (IV) do not matter.

A <= X <= B makes:

(I) Y = 1 or Y = 0

(II) Ta = 1

(III) Tb = 1

(IV) Y = 1

Ioannis
  • 5,238
  • 2
  • 19
  • 31
  • Unfortunately, multiplication of variables means that it is no longer linear. (A*Y, B*Y). However, I might be able to play around with it to avoid that. – TLW Jun 19 '14 at 18:09
  • Sorry, I thought that, by convention, 'A' and 'B' denoted parameters, not variables, because they are first alphabet letters. I am on mobile now but it is possible to linearise products of variables as such. You might want to Google Aimms integer programming tricks for more info. – Ioannis Jun 19 '14 at 19:14
  • Whoops. Sorry, I am inexperienced at linear programming and as such am unfamiliar with conventions - I'll edit the question to make it clear that `A` and `B` are variables. I looked at integer programming tricks, and posted something that seems to work as a solution. Could you look at it when you get a chance? – TLW Jun 19 '14 at 19:28
1

Rewriting loannis's answer in a linear form by expanding out multiplication of binary variables with a continuous variable:

  1. Tc <= M*Y
  2. Tc <= A
  3. Tc >= A - M*(1-Y)
  4. Tc >= 0
  5. Tc <= X
  6. Td <= M*Y
  7. Td <= B
  8. Td >= B - M*(1-Y)
  9. Td >= 0
  10. X <= Td + 100*(1-Y)
  11. (X - A + 1) <= M * Ta
  12. (B - X + 1) <= M * Tb
  13. Y >= Ta + Tb - 1

This seems to work, although I have not yet had the chance to expand it out to prove it. Also, some of these constraints may be unnecessary; I have not checked.


The expansion I did was according to the following rule:

If b is a binary variable, and c is a continuous one, and 0 <= c <= M, then y=b*c is equivalent to the following:

  1. y <= M*b
  2. y <= c
  3. y >= c - M*(1 - b)
  4. y >= 0
TLW
  • 1,373
  • 9
  • 22
  • This is correct (+1). I am wondering though, why do you need such a condition? If `A` and `B` are variables, what is their physical interpretation? It might be that you can formulate the problem overall in a much simpler way, unless `A` and `B` has other attributes not disclosed here. By the way, I would suggest `Z` and `W` instead of `A` and `B`, and also using small letters instead of capitals (capitals are usually used for matrices). – Ioannis Jun 20 '14 at 10:55
  • 1
    By the way, make sure you accept your answer if it solves your problem! – Ioannis Jun 20 '14 at 10:56
  • @loannis - it's for a solver for a nonogram-like puzzle, but on a non-rectangular grid. The simplest way to represent it that I've come across is an integer value for where each block in a clue starts, with a cell being set iff one of the integer values is in the range where it would set the cell. – TLW Jun 27 '14 at 01:26