0

The decision variable of my optimization problem (which I am aiming at keeping linear) is a placement binary vector, where the value in each position is either 0 or 1 (two different possible locations of item i).

One component of the objective function is this:

XOR

C_T is the const of transferring N items.

k is the iteration in which I am currently solving the problem and k-1 is the current displacement of items (result of solving the last iteration of the problem k-1). I have an initial condition (k=0).

N is "how many positions of x are different between the current displacement (k-1) and the outcome of the optimization problem (future optimal displacement x^k)".

How can I keep this component of the objective function linear? In other words, how can I replace the XOR operator? I thought about using the absolute difference as an alternative but I'm not sure it will help.

Is there a linear way to do this?

I will implement this problem with PuLP in python, maybe there is something that can help over there as well...

2 Answers2

3

My notation is: xprev[i] is the previous solution and x[i] is the current one. I assume xprev[i] is a binary constant and x[i] is a binary variable. Then we can write

   sum(i, |xprev[i]-x[i]|) 
   =sum(i|xprev[i]=0, x[i]) + sum(i|xprev[i]=1, 1-x[i]) 
   =sum(i, x[i]*(1-xprev[i]) + (1-x[i])*xprev[i])  

Both the second and third lines can be implemented directly in Pulp. Note that | in the second line is 'such that'.


Below we have a comment that claims this is wrong. So let's write my expression as B*(1-A)+(1-B)*A. The following truth table can be constructed:

 A   B   A xor B    B*(1-A)+(1-B)*A
 0   0      0          0   +   0  
 0   1      1          1   +   0  
 1   0      1          0   +   1
 1   1      0          0   +   0

Note that A xor B = A*not(B) + not(A)*B is a well-known identity.


Note. Here I used the assumption that xprev[i] (or A) is a constant so things are linear. If both are (boolean) variables (let's call them x and y), then we need to do something differently. We can linearize the construct z = x xor y using four inequalities:

z <= x + y
z >= x - y
z >= y - x
z <= 2 - x - y

This is now linear can be used inside a MIP solver.

Erwin Kalvelagen
  • 15,677
  • 2
  • 14
  • 39
  • This is wrong, though. I'm assuming you're defining XOR as `(A AND (NOT B)) OR ((NOT A) AND B)`, but that does not translate mathematically to what you wrote. For instance, if `OR = +`, then it doesn't work for `A = 1` and `B = 1`. Instead, it's defined as `A OR B = A + B - A*B`. – eduardokapp Dec 14 '21 at 16:35
  • @eduardokapp Come on. `A=B=1` evaluates as `B*(1-A)+(1-B)*A = 0 + 0`. Obviously also `A XOR B = 0` for `A=B=1`. Expressions like this are not uncommon in math programming and I use them a lot. Many of my models would be wrong if this does not work. – Erwin Kalvelagen Dec 14 '21 at 21:07
  • My bad. I didn't say that your expression was wrong, but I thought that you couldn't define OR as a simple + (which you can't). However, now I realize that the OR was "embedded" by the overall logic. Sorry! – eduardokapp Dec 15 '21 at 14:02
0

UPDATE: If what you need to replace is a XOR gate, then you could use a combination of other gates, which are linear, to replace it. Here are some of them https://en.wikipedia.org/wiki/XOR_gate#Alternatives.

Example: A XOR B = (A OR B) AND (NOT A + NOT B). When A and B are binary, that should translate mathematically to:

(A + B - A * B) * ((-A) + (-B) - (-A * -B))

Why not use multiplication?

AND table
0 0 = 0
0 1 = 0
1 0 = 0
1 1 = 1
Multiplication table
0*0 = 0
0*1 = 0
1*0 = 0
1*1 = 1

I think that does it. If it doesn't, then more details are needed I suppose.

eduardokapp
  • 1,612
  • 1
  • 6
  • 28
  • I am sorry, I actually did a mistake. The logical operation is not AND, it should be XOR (which is equivalent to the absolute difference)! Basically I want to count the "bits" (or positions) that changed. – enrico_steez Dec 14 '21 at 12:23
  • @enrico_steez I updated my answer. – eduardokapp Dec 14 '21 at 16:51