# Pyomo: Value assignment for binary variables through constraints

I am currently working on a cost minimisation model for multi-product, multi-period supplier selection with Pyomo. It is a linear model described below.
**Problem statement**
I have no idea how to formulate a restriction that defines the binary decision variables with the values 0 and 1 respectively. Currently, only the calculation of unit level costs works. The binary variables always remain at 0, so no order level costs or supplier level costs are included.
I would be very grateful if someone had an idea to formulate the restrictions for the binary variables.

Sets
The model consists of three sets:

• products: P
• time periods: T
• suppliers: S

Parameters
For simplicity, the model has five parameters:

• Supplier level costs: slc[s]
• Order level costs: olc[s,t]
• Unit level costs: ulc[p,s,t]
• Production capacity: c[p,s,t]
• Demand: d[p,t]

Decision Variables
There are three decision variables:

• Delivery quantity: x[p,s,t]: units of product p ordered in period t from supplier s
• Binary assignment variable: y_1[s] value: "1" if supplier s delivers (independent of product and period), else "0"
• Binary assignment variable: y_2[s,t] value: "1" if supplier s delivers in period t (independent of product), else "0"

Objective Function
minimize Total Costs = Sum_slc + Sum_olc + sum_ulc
with...

• Sum_slc=sum((model.y_1[s]) * model.slc[s] for s in model.S)
• Sum_olc=sum(model.y_2[s,t] * model.olc[s,t] for s in model.S for t in model.T)
• Sum_ulc=sum(model.x[p,s,t] * model.ulc[p,s,t] for p in model.P for s in model.S for t in model.T)

Constraints
Demand constraint: sum(model.x[p,s,t] for s in model.S) == model.d[p,t] Capacity constraint: model.xME[p,s,t] <= model.c[p,s,t]

• You want to impose the implication $\sum_{p} x_{pst} > 0 \Rightarrow y^2_{st} =1$, does that help?
– Sune
Feb 10 at 14:34

## 2 Answers

So problem is to make sure $$y1_{s}$$ and $$y2_{s,t}$$ take values of 1 when supplier $$s$$ delivers $$x_{p,s}^t \gt 0$$
Add constraints:
$$y2_{s,t}\le \sum_p x_{p,s}^t \le My2_{s,t} \ \ \forall t\in T \ \ \forall s$$

$$y1_s\le \sum_t\sum_p x_{s,p}^t \le My1_s$$ where M is a number like $$\sum_p c_{p,s}$$

• Thank you! I had not thought about the Big M method before. This advice has helped me a lot. Feb 13 at 14:45

Sutanu's contribution helped me a lot. In addition, I am posting the source code for modelling the constraints for $$y_{st}$$ to help people with a similar problem.

I used the demand as Big M in order not to choose the value larger than necessary: $$Big\ M=\sum_{p}\sum_{t}d_{p,t}$$

(1) $$y_{st}\le\sum_{p}x_{p,s,t},\forall t\in T,\forall s\in S$$

(2) $$\sum_{p}\ x_{p,s,t}\le M{*y}_{s,t},\ \forall\ t\in\ T,\forall\ s\in\ S$$

The following code creates the corresponding constraints in Pyomo:

(1)

model.constraint_1 = pyo.ConstraintList()
for s in model.S:
for t in model.T:
lhs_1 = model.y_2[s,t]
rhs_1 = sum(model.x[p,s,t] for p in model.P for t in model.T)
model.constraint_1.add(lhs_1<=rhs_1)
model.constraint_1.pprint() #Output command for constraints


(2)

model.constraint_2 = pyo.ConstraintList()
for s in model.S:
for t in model.T:
lhs_2 = sum(model.x[p,s,t] for p in model.P)
rhs_2 = model.y_2[s,t]*sum(model.d[p,t] for p in model.P for t in model.T)
model.constraint_2.add(lhs_2<=rhs_2)
model.constraint_2.pprint() #Output command for constraints