# Problems with constraint. Alternative for JuMP variable in if statement

**URL:** https://discourse.julialang.org/t/problems-with-constraint-alternative-for-jump-variable-in-if-statement/53563
**Category:** Optimization (Mathematical)
**Created:** [January 18, 2021, 9:28pm UTC](https://discourse.julialang.org/t/problems-with-constraint-alternative-for-jump-variable-in-if-statement/53563 "2021-01-18T21:28:26Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![gustav.asbjorn](https://avatars.discourse-cdn.com/v4/letter/g/34f0e0/32.png) [@gustav.asbjorn](https://discourse.julialang.org/u/gustav.asbjorn)
#### Post date: [January 18, 2021, 9:28pm UTC](https://discourse.julialang.org/t/problems-with-constraint-alternative-for-jump-variable-in-if-statement/53563/1 "2021-01-18T21:28:26Z")

</div>

Hey. So I need to implement the following:

Let’s say that we have 10 workers. If they work in the weekend then they want to work both days of the weekend or none. If they work only one day of the weekend then we add a penalty to the objective function.  
I have made a variable x[w=1:10,d=1:7] which is equal to 1 if worker w works at day d. Another variable is y[w=1:10] of which will be equal to 1 if worker w works one day of the weekend (or maybe the opposite of that if it would make the constraint easier to make).

The problem is; I need a constraint that is equivalent to  
@constraint([w=1:10], y[w] == (x[w,6] + x[w,7] == 1 ? 1 : 0).  
That is: for all workers going from 1 to 10, if working on either day 6 or 7 then y[w]=1 otherwise 0.  
The problem here is that I can’t use JuMP variable in if statements, so I will need to work around that somehow.

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [January 18, 2021, 9:43pm UTC](https://discourse.julialang.org/t/problems-with-constraint-alternative-for-jump-variable-in-if-statement/53563/2 "2021-01-18T21:43:50Z")

</div>

I believe you can do the following trick:

Make `y` a binary variable (if it is not already).

```julia
@constraint([w=1:10], y[w] >= x[w, 6]/2 + x[w, 7]/2)

```

With the constraint above `y` will be `1` if the worker works any days in the weekend.

In the objective function, add the double of the penalty if `y` is `1` and subtract the penalty one time if `x[w, 6]` is one and another time if `x[w, 7]` is one.

```julia
@objective(model, ... + 2*penalty*y[w] - penalty*x[w, 6] - penalty*x[w, 7])

```

This way:

1. The penalty is not added if the worker does not work in the weekend (all extra terms are evaluated to zero).
2. The penalty is not added if the worker works both days of the weekend (`y` term will add the double penalty but it will be removed by both `x` terms).
3. The penalty will be added if the worker works only one day of the weekend (`y` term will add the double penalty but one of the `x` terms will subtract half of it).

P.S.: I forgot again, Welcome to our community! 🎊

---

<div class="post-metadata">

### Author: ![gustav.asbjorn](https://avatars.discourse-cdn.com/v4/letter/g/34f0e0/32.png) [@gustav.asbjorn](https://discourse.julialang.org/u/gustav.asbjorn)
#### Post date: [January 18, 2021, 10:02pm UTC](https://discourse.julialang.org/t/problems-with-constraint-alternative-for-jump-variable-in-if-statement/53563/3 "2021-01-18T22:02:49Z")

</div>

Many thanks for the quick response Henrique!  
Excellent solution, it looks promising!  
This has bothered me all evening. I’m very excited to try it out it the morning.

And thanks for welcoming me!  
Goodnight from here 😊

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [January 18, 2021, 10:16pm UTC](https://discourse.julialang.org/t/problems-with-constraint-alternative-for-jump-variable-in-if-statement/53563/4 "2021-01-18T22:16:32Z")

</div>

You can write XOR using four linear inequalities:

```nohighlight
model = Model()
@variable(model, x[1:2], Bin)
@variable(model, y, Bin)
# Constraint to model:
# y = (x[1] + x[2] == 1 ? 1 : 0)
# Construct truth table:
# x[1] x[2] y
# F F F
# T F T
# F T T
# T T F
@constraints(model, begin
    y <= x[1] + x[2]
    y >= x[1] - x[2]
    y >= x[2] - x[1]
    y <= 2 - x[1] - x[2]
end)

```

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [January 18, 2021, 10:25pm UTC](https://discourse.julialang.org/t/problems-with-constraint-alternative-for-jump-variable-in-if-statement/53563/5 "2021-01-18T22:25:28Z")

</div>

This is basically the same idea, but cleaner. It trades four times the number of constraints for no extra terms in the objective. Maybe the relaxation is better?

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [January 18, 2021, 11:20pm UTC](https://discourse.julialang.org/t/problems-with-constraint-alternative-for-jump-variable-in-if-statement/53563/6 "2021-01-18T23:20:04Z")

</div>

You would have to try it out to see. The benefit of the explicit XOR approach is that it will work if `y` appears elsewhere in the model, not just as a penalty term in the objective.

---

<div class="post-metadata">

### Author: ![gustav.asbjorn](https://avatars.discourse-cdn.com/v4/letter/g/34f0e0/32.png) [@gustav.asbjorn](https://discourse.julialang.org/u/gustav.asbjorn)
#### Post date: [January 19, 2021, 9:18am UTC](https://discourse.julialang.org/t/problems-with-constraint-alternative-for-jump-variable-in-if-statement/53563/7 "2021-01-19T09:18:04Z")

</div>

Very clever solutions. Many thanks!

---

<div class="post-metadata">

### Author: ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)
#### Post date: [January 19, 2021, 11:00am UTC](https://discourse.julialang.org/t/problems-with-constraint-alternative-for-jump-variable-in-if-statement/53563/8 "2021-01-19T11:00:28Z")

</div>

You might also want to have a look at: my constraint solver [GitHub - Wikunia/ConstraintSolver.jl: ConstraintSolver in Julia: Blog posts -\>](https://github.com/Wikunia/ConstraintSolver.jl) which is still in its very early stage.  
In that case:

```julia
@constraint([w=1:10], y[w] == (x[w,6] + x[w,7] == 1 ? 1 : 0)

```

can be expressed as

```julia
@constraint([w=1:10], y[w] := { x[w,6] + x[w,7] == 1 })

```

If it’s very slow or if you encounter other problems I would appreciate when you open an issue with a full example as I’m very eager to improve that solver 😄
