I am facing a problem to multiply a term in objective function. My objective function is :

\begin{equation} \min \sum_{t=1}^\top p_{t} \cdot (1+r) \cdot y_{t} \end{equation} where $p$ is the price, $y$ is the quantity (decision variable) and $r$ is the price surcharge. $t$ is the index for time periods.

The problem is that the value of $r$ depends on between which interval the value of $y$ (decision variable) lies as shown by the following piecewise function.

\begin{equation} r_t (Y_t) = \begin{cases} % s_0 0 & \mathrm{if }\; Y_t \leq b_0 \\ % s_1 0.05 & \mathrm{if }\; b_0 < Y_t \leq b_1 \\ % s_2 0.1 & \mathrm{if }\; b_1 < Y_t \leq b_2\\[6pt] ... & \mathrm{if }\; ... \end{cases} \end{equation} where $b_0$, $b_1$ etc. are set of quantity intervals = [0, 50, 100, 150,..]

Since we don't have the values of $y$ until at the point where objective function is specified (cause value of decision variables) are only available once we give call to optimize m.optimize(). So, how we could program this in Python interface.


1 Answer 1


There are many ways to do this. Here is a popular one: define a binary variable $x_i$ per interval $[b_i,b_{i+1}]$ and use the following constraints:

\begin{align*} 1&=x_0+x_1+\cdots+x_n \tag{1}\\ 0x_0 + (b_0+\epsilon)x_1 + \cdots+ (b_{n-1}+\epsilon)x_n \le Y_t &\le b_0x_0 + b_1x_1 + \cdots+ b_nx_n \tag{2}\\ r_t &\ge f_i - M_i(1-x_i) \tag{3}\\ x_i &\in \{0,1\} \end{align*}

Constraint $(1)$ enforces the solver to select exactly one interval. Constraint $(2)$ enforces $x_i=1 \; \Longrightarrow \;b_{i-1} < Y_t \le b_i$. For example, if $x_1=1$, $b_0 + \epsilon \le Y_t \le b_1$ ($\epsilon$ is your tolerance). And $(3)$ is a bigM constraint which defines the piecewise linear function $r_t$ accordingly ($f_0 = 0, f_1=0.05,...$). For example, if $x_1=1$, the constraint becomes $r_t \ge f_1 = 0.05$.

Note that the above solution holds for a given $t$. You will need to replicate the idea over your time span $t=1,..,T$.

  • $\begingroup$ Many thanks for the answers. Does someone have a clue how it could be applied in Gurobi Python using model.setPWLObj(). Though they have provided an example but still can't relate how to apply for my case $\endgroup$
    – salidi
    Sep 26, 2021 at 6:21
  • $\begingroup$ This is a minimization of a convex piecewise-linear function, so binary variables should not be needed. $\endgroup$
    – 4er
    Mar 30, 2022 at 14:48
  • $\begingroup$ We do not know if it is convex (it depends on what is hidden behind the $\cdots$) $\endgroup$
    – Kuifje
    Mar 30, 2022 at 15:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.