Using the values of variable in the objective function before optimizing

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

$$$$\min \sum_{t=1}^\top p_{t} \cdot (1+r) \cdot y_{t}$$$$ 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.

$$$$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}$$$$ 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.

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$$.

• 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 Sep 26, 2021 at 6:21
• This is a minimization of a convex piecewise-linear function, so binary variables should not be needed.
– 4er
Mar 30, 2022 at 14:48
• We do not know if it is convex (it depends on what is hidden behind the $\cdots$) Mar 30, 2022 at 15:03