# Enforcing Variable Allocation Priorities in JuMP Model

**URL:** <https://discourse.julialang.org/t/enforcing-variable-allocation-priorities-in-jump-model/108806>\
**Category:** Optimization (Mathematical)\
**Tags:** jump, optimization\
**Created:** [January 14, 2024, 11:47pm UTC](https://discourse.julialang.org/t/enforcing-variable-allocation-priorities-in-jump-model/108806 "2024-01-14T23:47:11Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lemma](https://avatars.discourse-cdn.com/v4/letter/l/e0b2c6/32.png) [@Lemma](https://discourse.julialang.org/u/Lemma)\
**Post date:** [January 14, 2024, 11:47pm UTC](https://discourse.julialang.org/t/enforcing-variable-allocation-priorities-in-jump-model/108806/1 "2024-01-14T23:47:11Z")

</div>

Hello Everyone,

I’m working on an optimization problem in Julia’s JuMP and need help with correctly prioritizing the allocation of certain variables in a constraint. My primary constraint is as follows:

C \cdot x + S \cdot z + SN \cdot zn - CO \cdot y - E = 0

Here are the rules for the allocation of variables `z`, `zn`, and `y`:

1. Only one of `z`, `zn`, and `y` can be non-zero at a time.
2. `z` should only be non-zero if `zn` cannot satisfy the constraint.
3. `zn` is tried first if C \cdot x - E \< 0 but if it is unable to satisfy the constraint then `z` is activated instead. If C \cdot x - E \> 0 then `y` becomes active (i.e. non-zero).

I’ve implemented the following constraints in JuMP, but I am unsure if they correctly enforce the priority of `zn` over `z` and other rules:

```julia
using JuMP
model = Model()
@variables(model, begin
    0 <= x <= Xmax
    0 <= y <= Ymax
    0 <= z <= Zmax
    0 <= zn <= ZNmax
    b, Bin
    bz, Bin
    bzn, Bin
end)

@constraints(model, begin
    C * x + S * z + SN * zn - CO * y - E == 0
     y <= Ymax *b 
    z <= Zmax*(1 - b)
    zn <= ZNmax*(1 - b)
    z <= Zmax * bz
    zn <= ZNmax * bzn
    bz <= bzn # This is to prioritise allocation of z over zn
end)

```

I am confused whether the constraints `z <= Zmax * (1 - b)` and `zn <= ZNmax * (1 - b)` could inadvertently cause both `z` and `zn` to be active simultaneously, potentially making the model infeasible or conflicting with other constraints.

My specific questions are:

- Does the use of binary variables `b`, `bz`, and `bzn` effectively model the prioritization of `zn` over `z`?
- Are the constraints involving the binary variables appropriately formulated to reflect the stated rules, especially considering the potential for simultaneous activation of `z` and `zn`? Should I introduce a constraint `b + bz + bzn ≤ 1` and replace the constraints `z ≤ Zmax (1-b)` and `zn ≤ ZNmax (1-b)`?

Thanks in advance for your help!

---

<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 15, 2024, 1:21am UTC](https://discourse.julialang.org/t/enforcing-variable-allocation-priorities-in-jump-model/108806/2 "2024-01-15T01:21:05Z")

</div>

Hi @Lemma, welcome to the forum.

Do you have data for the constants?

One approach is to use an objective function like `Min, 2 * b_z + b_zn` so that `zn` will be used before `z`.

Here’s how I would write it:

```julia
using JuMP
model = Model()
@variables(model, begin
    0 <= x <= Xmax
    0 <= y <= Ymax
    0 <= z <= Zmax
    0 <= zn <= ZNmax
    b_y, Bin
    b_z, Bin
    b_zn, Bin
end)
@constraints(model, begin
    C * x + S * z + SN * zn - CO * y - E == 0
    b_z + b_zn + b_y == 1
    y <= Ymax * b_y
    z <= Zmax * b_z
    zn <= ZNmax * b_zn
end)
@objective(model, Min, 2 * b_z + b_zn)

```

---

<div class="post-metadata">

**Author:** ![Lemma](https://avatars.discourse-cdn.com/v4/letter/l/e0b2c6/32.png) [@Lemma](https://discourse.julialang.org/u/Lemma)\
**Post date:** [January 15, 2024, 7:29am UTC](https://discourse.julialang.org/t/enforcing-variable-allocation-priorities-in-jump-model/108806/3 "2024-01-15T07:29:11Z")

</div>

Thank you

In reality, these are vectors of constraints. The variables and constraints need to be defined for different time periods, and I’m not sure whether the logic of bringing the binary variables into the objective function can be made to work, as we need to ensure this prioritization at each time period. Isn’t there a way to make the prioritization of allocating variable zn over z work within the constraints alone?

I can try to produce data for constants if it is difficult to advise without it. We can assume upper bounds of all variables to be 1, if it helps.

---

<div class="post-metadata">

**Author:** ![Lemma](https://avatars.discourse-cdn.com/v4/letter/l/e0b2c6/32.png) [@Lemma](https://discourse.julialang.org/u/Lemma)\
**Post date:** [January 15, 2024, 9:29pm UTC](https://discourse.julialang.org/t/enforcing-variable-allocation-priorities-in-jump-model/108806/4 "2024-01-15T21:29:57Z")

</div>

I’ve provided detailed data to better illustrate the intricacies involved. I recognize that the actual constraint is more complicated than it might initially appear. Thus, I am not entirely sure if providing further detailed information will simplify or complicate the process of seeking help!

The heart of this problem lies in the constraint:

\begin{align} & C\_{t} \left( x - \sum\_{j=1}^{t} z\_{j} \right) +\sum\_{i=2}^{t} CN\_{i, t-i+1} \left( y\_i - \sum\_{j=i}^{t} zn\_{j} \right) \nonumber \\ & + S\_{t} \cdot z\_{t} + SN\_{t} \cdot zn\_{t} - CO\_{t} \cdot y\_{t} - E\_t = 0 \quad \forall t \end{align}

In this formulation:

- CN\_{i, t-i+1} represents values derived from a specific position, determined at the time i and assessed at the later time t.

- As stated earlier only one of y\_{t}, zn\_{t} and z\_{t} can be non-zero at a time.

- A prioritization rule is applied to the variables zn\_{t} and z\_{t}. The model initially attempts to satisfy the constraint using zn\_{t}. However, if zn\_{t} proves inadequate, the model then resorts to z\_{t}, necessitating zn\_{t} to be set to zero.

\textbf{Other Constraints:}

\sum\_{j=i}^{t} zn\_{j} \leq y\_i \quad \forall i \\ \sum\_{j=1}^{t} z\_{j} \leq x \quad \forall t

\begin{alignat}{2} & y\_{t} && \leq b\_{t} \quad && \forall t \\ & zn\_{t} && \leq bzn\_{t} \quad && \forall t \\ & z\_{t} && \leq bz\_{t} \quad && \forall t \end{alignat}

\begin{equation} b\_{t} + bzn\_{t} + bz\_{t} \leq 1 \quad \forall t \end{equation}

At t=1, we can assume that all variables except x takes zero value or more conveniently define the constraint differently for t=1 from t\>1. For t=1, we can define this constraint as: C\_{1} \cdot x - E\_{1} = 0

Here is some Julia code to for data:

```julia

CO_t = [101952.54, 108607.57, 104110.54, 101795.33, 96946.19, 105835.76, 97503.49, 115670.92, 118546.51, 95337.66]
S_t = [121669.00, 111155.80, 112721.78, 127023.87, 92841.44, 93485.17, 90808.74, 123304.79, 121126.27, 124800.49]
SN_t = [139144.73, 131966.34, 118459.17, 131221.17, 104730.98, 125596.84, 105734.13, 137786.76, 120873.93, 116586.48]
C_t = [6322.78, 8871.17, 7280.75, 7842.17, 5093.95, 8088.18, 8060.48, 8084.67, 9718.74, 8409.10]
E_t = [5000.0, 5555.56, 6111.11, 6666.67, 7222.22, 7777.78, 8333.33, 8888.89, 9444.44, 10000.0]
CN2 = [4061.56, 5092.99, 3375.76, 5303.79, 6717.18, 4274.28, 5669.64, 3527.19, 5865.31, 4157.62] # i =2
CN3 = [3732.77, 5346.05, 3080.43, 6315.76, 3018.78, 5711.27, 4080.03, 5940.78, 6848.75] # i =3
CN4 = [3995.01, 5304.63, 5368.17, 5289.01, 3892.33, 6811.00, 4788.50, 6385.63, 5425.57] # i =4
CN5 = [5797.92, 4189.75, 6255.19, 4586.02, 6524.41, 5325.09, 6526.94, 3076.77]
CN6 = [5770.13, 5901.02, 5005.30, 6824.33, 5575.96, 4695.42]

```

In the model, the selection of data from the CN arrays depends on the time period (t) and the status of the corresponding y variables. Specifically:

- At time t = 2 , if the variable y\_{2} is positive, then we utilize the data from the array CN2.

- Similarly, at time t = 5, if y\_{5} is positive, we use the data from CN5.

A key expression in the constraint is:

\sum\_{i=2}^{t} CN\_{i, t-i+1} \left( y\_i - \sum\_{j=i}^{t} zn\_{j} \right)

which dynamically incorporates values from the CN arrays based on the time period t and the state of y\_i and zn\_j variables.

For instance, when evaluated at t = 5 with the conditions that only y\_{2} and y\_{5} are positive (and treating them as 1 for simplicity), while all zn variables are zero, the expression calculates to 11101.71. This result is derived as follows:

- From the array CN2, we take the value at the 4th position (accounting for i = 2 at t = 5)), which is 5303.79.

- From the array CN5, we select the value at the 1st position (since i = 5 at t = 5), which is 5797.92.

By summing these two values, 5303.79+ 5797.92, we obtain the total of 11101.71.

Please let me know if it is still unclear or if it is not possible to model prioritisation constraint using integer programming techniques?

---

<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 15, 2024, 10:30pm UTC](https://discourse.julialang.org/t/enforcing-variable-allocation-priorities-in-jump-model/108806/5 "2024-01-15T22:30:44Z")

</div>

What do `z` and `zn` represent, practically speaking, in the model?

If `z` is a regular power station and `zn` is some emergency generator, then the prioritization should happen automatically with their objective costs.

I don’t now if you can easily enforce a constraint like “if x makes the problem infeasible, use y.”

Perhaps someone else has an idea though.

---

<div class="post-metadata">

**Author:** ![Lemma](https://avatars.discourse-cdn.com/v4/letter/l/e0b2c6/32.png) [@Lemma](https://discourse.julialang.org/u/Lemma)\
**Post date:** [January 15, 2024, 11:17pm UTC](https://discourse.julialang.org/t/enforcing-variable-allocation-priorities-in-jump-model/108806/6 "2024-01-15T23:17:44Z")

</div>

The objective is defined as: \text{Minimize } Z = MV \cdot x.

These variables z\_{t} and zn\_{t} represent the sales of initial and new assets, respectively. We sell and generate revenue equal to S\_{t} or SN\_{t} at time t, depending on whether the initial or new asset is sold. Sales are made when the return from the assets is less than the expenses E\_{t} at time t.  
If C\_{t} \left( x - \sum\_{j=1}^{t} z\_{j} \right) +\sum\_{i=2}^{t} CN\_{i, t-i+1} \left( y\_i - \sum\_{j=i}^{t} zn\_{j} \right) \nonumber - E\_t \< 0 then sales are made. If it is greater than zero then purchases are made. The expression in brackets represent amount of asset available (post-sale).

The variable y\_{t} represents purchases at a cost of CO\_{t} at time t. We purchase assets at a cost of CO\_{t} when the revenue from assets exceeds expenses E\_{t}. The question is: Can we prioritize the sale of new assets over initial assets, but make it mutually exclusive?

If mutual exclusivity was not required, I guess this could be achieved by adding the constraint:bz\_{t} \leq bzn\_{t}.

I have now also posted this question on the OR Stack Exchange in case someone there knows the answer: [combinatorial optimization - Priotization rules for variable allocation in linear programming - Operations Research Stack Exchange](https://or.stackexchange.com/questions/11526/priotization-rules-for-variable-allocation-in-linear-programming)

---

<div class="post-metadata">

**Author:** ![Lemma](https://avatars.discourse-cdn.com/v4/letter/l/e0b2c6/32.png) [@Lemma](https://discourse.julialang.org/u/Lemma)\
**Post date:** [January 15, 2024, 11:58pm UTC](https://discourse.julialang.org/t/enforcing-variable-allocation-priorities-in-jump-model/108806/7 "2024-01-15T23:58:58Z")

</div>

Is a big-M type of approach not possible for this problem?

---

<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 16, 2024, 10:20pm UTC](https://discourse.julialang.org/t/enforcing-variable-allocation-priorities-in-jump-model/108806/8 "2024-01-16T22:20:12Z")

</div>

One thing to consider is that constraints can only enforce feasibility. They can’t be used to incentivize the model to prefer one solution over another.

If the solution is infeasible unless it uses `z`, then that works. But if it can satisfy either by using `z` or by using `zn`, then this seems like something that should go in the objective.
