# Indicator constraints Not working

**URL:** <https://discourse.julialang.org/t/indicator-constraints-not-working/106687>\
**Category:** Optimization (Mathematical)\
**Tags:** jump, optimization\
**Created:** [November 24, 2023, 4:35pm UTC](https://discourse.julialang.org/t/indicator-constraints-not-working/106687 "2023-11-24T16:35:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![papar](https://avatars.discourse-cdn.com/v4/letter/p/c5a1d2/32.png) [@papar](https://discourse.julialang.org/u/papar)\
**Post date:** [November 24, 2023, 4:35pm UTC](https://discourse.julialang.org/t/indicator-constraints-not-working/106687/1 "2023-11-24T16:35:58Z")

</div>

I’m encountering a problem with an optimization model in Julia where I need to enforce a specific condition using indicator variables. The goal is to ensure that for each time period ( t ) (from 2 to T), either ( y\_{i,t} ) is positive and ( z\_{i,t} ) is zero, or the other way around. Despite several attempts, I’m not achieving the expected behavior.

My initial approach was to use the constraint `@constraint(model,[i=1:n,t=2:T],z[i,t]*y[i,t] == 0)` to prevent both ( y ) and ( z ) from being positive at the same time ( t ). However, this did not work as planned, as I still observe cases where both ( y ) and ( z ) are positive simultaneously.

To address this, I introduced binary variables ( b\_t[t] ) and added constraints like `@constraint(model, [i=1:n, t=2:T], y[i,t] <= 1 - b_t[t])` and `@constraint(model, [i=1:n, t=2:T], z[i,t] <= b_t[t])`. Unfortunately, this approach leads to the model running indefinitely without finding a solution.

Here’s the relevant portion of my Julia code:

```julia
model = Model()
@variables(model, begin
    0 <= x[i=1:n,t=2:T] <= 1
    0 <= y[i=1:n, t=2:T] <= 1
    0 <= z[i=1:n,t=2:T] <= 1
    w[t=2:T], Bin
end)

# Active when w[t] == 1
@constraint(model, [t=2:T], w[t] => {sum(CF[i,t] * x[i,t] for i in 1:n) - L[t] == -sum(PBid[i,t] * y[i,t] for i in 1:n)})

# Active when w[t] == 0
@constraint(model, [t=2:T], !w[t] => {sum(CF[i,t] * x[i,t] for i in 1:n) - L[t] == -sum(PAsk[i,t] * z[i,t] for i in 1:n)})

```

I’m seeking advice on what might be causing these issues or how to implement these constraints correctly in Julia. Any insights or suggestions would be greatly appreciated, as I’m currently unable to progress with this model.

---

<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:** [November 24, 2023, 9:40pm UTC](https://discourse.julialang.org/t/indicator-constraints-not-working/106687/2 "2023-11-24T21:40:51Z")

</div>

You don’t need indicator constraints. Do instead:

```julia
model = Model()
@variables(model, begin
    0 <= x[1:n, 2:T] <= 1
    0 <= y[1:n, 2:T] <= 1
    0 <= z[1:n, 2T] <= 1
    w[1:n, 2:T], Bin
end)
@constraints(model, begin
    [i in 1:n, t in 2:T], y[i, t] <= w[i, t]
    [i in 1:n, t in 2:T], z[i, t] <= 1 - w[i, t]
    [t in 2:T], sum(CF[i,t] * x[i,t] - PBid[i,t] * y[i,t] - PAsk[i,t] * z[i,t] for i in 1:n) == L[t]
end)

```

(Your previous attempts were not working because the indicator constraint enforced the equality constraint, not whether `y` or `z` were zero.)

---

<div class="post-metadata">

**Author:** ![papar](https://avatars.discourse-cdn.com/v4/letter/p/c5a1d2/32.png) [@papar](https://discourse.julialang.org/u/papar)\
**Post date:** [November 25, 2023, 10:32pm UTC](https://discourse.julialang.org/t/indicator-constraints-not-working/106687/3 "2023-11-25T22:32:13Z")

</div>

Thank you for the helpful insights provided earlier. I’ve followed the logic suggested and made some modifications to my Julia model. However, I have a few additional clarifications and would like to confirm the correctness of these modifications:

1. **Adjusting Upper Bound of Variable `y`:**  
My model currently sets the upper bound for variable `y` to 1. If I need to change this upper bound to a different value, say a given number `1500000`, should the constraint be modified to `[i in 1:n, t in 2:T], y[i, t] <= 1500000 * w[i, t]` to reflect this change?

2. **Prioritizing Sales Represented by `y` Over `x`:**  
I’ve introduced variables `z_y` and `z_x` to represent sales from `y` and `x` respectively. The aim is to prioritize sales from `y` before utilizing `x`, especially to satisfy the last constraint of the model. Here’s the modified section of the model for this logic:

3. **Ensuring Either `y` or `x` is Sold, But Not Both:**  
To add another layer of constraint where either `y` or `x` is sold, but not both, with a priority for selling `y`, I’ve introduced binary variables `use_y[i, t]` and `use_x[i, t]`. The constraint I’ve added is as follows:

Any insights or suggestions to validate these modifications or propose better approaches would be greatly appreciated. Thank you!

---

<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:** [November 25, 2023, 10:44pm UTC](https://discourse.julialang.org/t/indicator-constraints-not-working/106687/4 "2023-11-25T22:44:58Z")

</div>

You seem to have a good understanding of the problem and the reformulations, and you seem to be on the right track 😄

1. Yes
2. I’m not really sure what you mean. The constraint looks like it requires more sales of `z_y` than `z_x`, but it doesn’t enforce that you can only sell `x` if you have maxed out the sales of `y`. (That might be the solution though, you should check the result to see if it works.)
3. Yes

---

<div class="post-metadata">

**Author:** ![papar](https://avatars.discourse-cdn.com/v4/letter/p/c5a1d2/32.png) [@papar](https://discourse.julialang.org/u/papar)\
**Post date:** [November 26, 2023, 12:01am UTC](https://discourse.julialang.org/t/indicator-constraints-not-working/106687/5 "2023-11-26T00:01:53Z")

</div>

Thank you again for the previous advice. On (2), I want to enforce that you can only sell `x` if I have maxed out the sales of `y. My earlier method was not correct. How can I enforce this condition?

---

<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:** [November 26, 2023, 7:25pm UTC](https://discourse.julialang.org/t/indicator-constraints-not-working/106687/6 "2023-11-26T19:25:47Z")

</div>

For (2), something like this:

```julia
model = Model()
@variable(model, 0 <= x <= u)
@variable(model, 0 <= y <= u)
# If x > 0 then y == u
@variable(model, z, Bin)
# z == 0 --> 0 <= x <= 0
# z == 1 --> 0 <= x <= u
@constraint(model, x <= u * z)
# z == 0 --> 0 <= y <= u
# z == 1 --> u <= y <= u
@constraint(model, u - y <= u * (1 - z))

```

I find it useful to write out what you want as a logical proposition, like `# If x > 0 then y == u`. Then introduce a binary to model that proposition, like `z`. And then enforce the `then` part dependent on the binary.

---

<div class="post-metadata">

**Author:** ![papar](https://avatars.discourse-cdn.com/v4/letter/p/c5a1d2/32.png) [@papar](https://discourse.julialang.org/u/papar)\
**Post date:** [November 26, 2023, 11:27pm UTC](https://discourse.julialang.org/t/indicator-constraints-not-working/106687/7 "2023-11-26T23:27:43Z")

</div>

Thank you for your guidance. To avoid confusion with the variables in the original question, I replaced `z` with `δ` and set distinct upper bounds for `x` and `y` (`u_x` and `u_y`). Here’s my adjusted code:

```julia
model = Model()
@variable(model, 0 <= x <= u_x)
@variable(model, 0 <= y <= u_y)
@variable(model, δ, Bin) # Using delta as the binary variable

# δ == 0 --> 0 <= x <= 0
# δ == 1 --> 0 <= x <= u_x
@constraint(model, x <= u_x * δ)

# δ == 0 --> 0 <= y <= u_y
# δ == 1 --> u_y <= y <= u_y
@constraint(model, u_y - y <= u_y * (1 - δ))

```

If there’s anything inconsistent with your approach, please let me know.
