Current status on the problem (what I've done)
I'm working on a NLP problem and I got a formulation of the problem, together with the necessary constraints, but I think it needs some adjustments to ensure feasibility and efficiency.
I was using the NLP-solver 'Ipopt' but switched to 'SCIP' and 'Bonmin' because of the binary variables I'm using. SCIP seems to have a lot of trouble with finding a solution as it keeps on running. I can limit the time and then stop it: it gives me a more or less optimal solution but the result shows that my constraints are not enforcing what I want. The Bonmin-solver gives me an error ('solver didn't exit normally'), but on other problems I have, Bonmin works just fine. This makes me think that my constraints are overcomplicated or not stated correctly. Therefore this question.
The problem formulation (what I want)
We have $n$ items ($i=1, 2, \dots, n$) and every item has (constant) parameters $D_i =$ demand and $P_i =$ price. We rank the items on the demand-parameter, so $D_i \ge D_{i+1}$. After this, we calculate a new parameter $c_i$ per item as the cumulative demand, so $c_i= \sum_{j=1}^i D_i$ for $i = 1, 2, \dots, n$. And we know that $c_n = 1$ and $ c_i \le c_{i+1}$.
Now we want to assign a variable $x$ to ever item $i$ where we have the constraint that $x_i \ge x_{i+1}$ Then a nonlinear function $g$ is applied with arguments $x_i, c_i, D_i$ and $P_i$ and this function needs to be minimized with the constraint $$\sum_{i=1}^n D_ix_i = \beta \sum_{i=1}^n D_i$$, where $0 \le \beta \lt 1$. $\beta$ is a fixed parameter.
BUT.
We want to split up the items in $3$ classes based on the variable $c_i$ (the cumulative demand). We want to do this by assigning two boundaries $b_1, b_2$ that can split up the items with the simple logical expression: "if $c_i \le b_1$ then class 1, if $b_1 \lt c_i \le b_2$ then class 2, else class 3". Then every class gets one of the 3 $x$-variables : $x_1, x_2, x_3$. So we don't have a $x_i$-variable but only $3$ variables $x_1, x_2$ and $x_3$.
Now we always want 3 classes and $x_1$ is always assigned to class 1, $x_2$ to class 2 and $x_3$ to class 3.
Let
$0 \le x_3 \le x_2 \le x_1 \le 1-\delta$, where $\delta$ is small value like $0.0001$.
$0 + \epsilon \le b_1 \le b_2 - \epsilon \le 1-\epsilon$ where $\epsilon$ is high enough to make sure there are $3$ classes.
To formulate it mathematically, I'm using binary variables and create a new variable $z_i$.
Objective function
$$\min_{x_1, x_2, x_3, b_1, b_2} g(D_i, P_i, z_i)$$
Constraints
- $\sum_{i=1}^n D_iz_i = \beta \sum_{i=1}^n D_i$
- $z_i = a_{i1}x_1 + a_{i2}x_2 +a_{i3}x_3$
- $b_1-c_i \le a_{i1}M$
- $c_i -b_2 \le a_{i3}M$
- $a_{i1}+a_{i2}+a_{i3} = 1$
- $c_i-b_1 \le Mk_{i1}$
- $b_2 - c_i \le Mk_{i2}$
- $k_{i1}+ k_{i2} - 1 \le a_{i2}$
- $b_1 \le b_2 - \epsilon$
- $x_3 \le x_2 \le x_1$
, where $M$ is a large constant.
Variables
$a_{i1}, a_{i2}, a_{i3} \in \{0, 1\}$ and initialized to $0$,
$0 \le x_1, x_2, x_3 \lt 1$,
$b_1, b_2 \in [0+\epsilon, 1-\epsilon]$
$k_{i1}, k_{i2} \in \{0, 1\}$ and initialized to $0$,
$z_i$
Which constraints need to be adjusted or added to ensure everything I want? It doesn’t enforces $z_i \ge z_{i+1}$ which is something I want. But how can I write a constraint that enforces this? And how can I generally improve the mathematical formulation?