In [1] the following problem is proposed:
The max constraint has been replaced by a single inequality. This works in this case as we are only interested in \(y\)'s that are forced to be one. Those guys will limit blue shape constraint. The blue shape implication constraint itself is rewritten as a big-M inequality. A good value for \(M\) is not very difficult to establish: the number of colors minus blue minus 1.
For comparison, let's first run the model without the complex "blue" shape constraints (the last two constraints). That gives:
We see that the blue shape (circle) is also selected as orange and yellow.
With the additional constraints, we see:
Now we see the blue shape is a triangle. We only have another triangle of color orange.
The complete GAMS model looks like:
A second exercise would be to write this Python using PuLP.
I'm trying to solve a knapsack-style optimization problem with additional complexity.
Here is a simple example. I'm trying to select 5 items that maximize value. 2 of the items must be orange, one must be blue, one must be yellow, and one must be red. This is straightforward. However, I want to add a constraint that the selected yellow, red, and orange items can only have one shape in common with the selected blue item.
The example data looks like:
item color shape value
A blue circle 0.454
B yellow square 0.570
C red triangle 0.789
D red circle 0.718
E red square 0.828
F orange square 0.709
G blue circle 0.696
H orange square 0.285
I orange square 0.698
J orange triangle 0.861
K blue triangle 0.658
L yellow circle 0.819
M blue square 0.352
N orange circle 0.883
O yellow triangle 0.755
Let's see if we can model this. First we slice and dice the data a bit to make the modeling a bit easier. Here is some derived data:
Note that the set CS(c,s) is complete. However, I will assume that there is a possibility that this set has some missing entries. In other words, I will not assume that all combinations of colors and shapes exist in the data.
Let's introduce the following zero-one variables:\[\begin{align} & x_i = \begin{cases} 1 & \text{if item $i$ is selected}\\ 0 & \text{otherwise}\end{cases} \\ & y_{c,s} = \begin{cases} 1 & \text{if items with color $c$ and shape $s$ are selected}\\ 0 & \text{otherwise} \end{cases}\end{align}\]
My high-level model is:
The max constraint implements the definition of the \(y_{c,s}\) variables: if any of the selected items has color/shape combination \((c,s)\) then \(y_{c,s}=1\) (and else it stays zero). The implication constraint says: if we have a blue shape \(s\), then there can be only one shape of type \(s\) of other color. The model is a bit complicated because I wanted to be precise. No hand-waving. This helps when implementing it.
This is not yet a MIP model, but translation of the above model into a normal MIP is not too difficult.
---- 58 SET i item
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
---- 58 SET c color
blue , yellow, red , orange
---- 58 SET s shape
circle , square , triangle
---- 58 SET ICS(i,c,s)
circle square triangle
A.blue YES
B.yellow YES
C.red YES
D.red YES
E.red YES
F.orange YES
G.blue YES
H.orange YES
I.orange YES
J.orange YES
K.blue YES
L.yellow YES
M.blue YES
N.orange YES
O.yellow YES
---- 58 SET IC(i,c)
blue yellow red orange
A YES
B YES
C YES
D YES
E YES
F YES
G YES
H YES
I YES
J YES
K YES
L YES
M YES
N YES
O YES
---- 58 SET CS(c,s)
circle square triangle
blue YES YES YES
yellow YES YES YES
red YES YES YES
orange YES YES YES
---- 58 PARAMETER value(i): value of item
A 0.454, B 0.570, C 0.789, D 0.718, E 0.828, F 0.709, G 0.696, H 0.285, I 0.698, J 0.861
K 0.658, L 0.819, M 0.352, N 0.883, O 0.755
---- 58 SET YRO(c): excludes blue
yellow, red , orange
Note that the set CS(c,s) is complete. However, I will assume that there is a possibility that this set has some missing entries. In other words, I will not assume that all combinations of colors and shapes exist in the data.
Let's introduce the following zero-one variables:\[\begin{align} & x_i = \begin{cases} 1 & \text{if item $i$ is selected}\\ 0 & \text{otherwise}\end{cases} \\ & y_{c,s} = \begin{cases} 1 & \text{if items with color $c$ and shape $s$ are selected}\\ 0 & \text{otherwise} \end{cases}\end{align}\]
My high-level model is:
High-level Model |
---|
\[\begin{align}\max & \sum_i \color{darkblue}{\mathit{Value}}_i \cdot \color{darkred}x_i \\ &\sum_i \color{darkred}x_i = \color{darkblue}{\mathit{NumItems}}\\ &\sum_{i | \color{darkblue}{\mathit{IC}}(i,c)} \color{darkred}x_i = \color{darkblue}{\mathit{NumColor}}_c && \forall c\\ & \color{darkred}y_{c,s} = \max_{i|\color{darkblue}{\mathit{ICS}}(i,c,s)} \color{darkred}x_i && \forall c,s|\color{darkblue}{\mathit{CS}}(c,s)\\ & \color{darkred}y_{\color{darkblue}{\mathit{blue}},s} = 1 \Rightarrow \sum_{c|\color{darkblue}{\mathit{YRO}}(c)} \color{darkred}y_{c,s} \le 1 && \forall s \\&\color{darkred}x_i, \color{darkred}y_{c,s} \in \{0,1\} \end{align}\] |
The max constraint implements the definition of the \(y_{c,s}\) variables: if any of the selected items has color/shape combination \((c,s)\) then \(y_{c,s}=1\) (and else it stays zero). The implication constraint says: if we have a blue shape \(s\), then there can be only one shape of type \(s\) of other color. The model is a bit complicated because I wanted to be precise. No hand-waving. This helps when implementing it.
This is not yet a MIP model, but translation of the above model into a normal MIP is not too difficult.
Mixed Integer Programming Model |
---|
\[\begin{align}\max & \sum_i \color{darkblue}{\mathit{Value}}_i \cdot \color{darkred}x_i \\ &\sum_i \color{darkred}x_i = \color{darkblue}{\mathit{NumItems}}\\ &\sum_{i | \color{darkblue}{\mathit{IC}}(i,c)} \color{darkred}x_i = \color{darkblue}{\mathit{NumColor}}_c && \forall c\\ & \color{darkred}y_{c,s} \ge \color{darkred}x_i && \forall i,c,s|\color{darkblue}{\mathit{ICS}}(i,c,s)\\ & \sum_{c|\color{darkblue}{\mathit{YRO}}(c)} \color{darkred}y_{c,s} \le 1 + \color{darkblue}M(1-\color{darkred}y_{\color{darkblue}{\mathit{blue}},s}) && \forall s \\&\color{darkred}x_i, \color{darkred}y_{c,s} \in \{0,1\} \end{align}\] |
The max constraint has been replaced by a single inequality. This works in this case as we are only interested in \(y\)'s that are forced to be one. Those guys will limit blue shape constraint. The blue shape implication constraint itself is rewritten as a big-M inequality. A good value for \(M\) is not very difficult to establish: the number of colors minus blue minus 1.
For comparison, let's first run the model without the complex "blue" shape constraints (the last two constraints). That gives:
---- 90 VARIABLE z.L = 4.087 obj
---- 90 VARIABLE x.L select item
E 1.000, G 1.000, J 1.000, L 1.000, N 1.000
---- 90 SET selected
circle square triangle
E.red YES
G.blue YES
J.orange YES
L.yellow YES
N.orange YES
We see that the blue shape (circle) is also selected as orange and yellow.
With the additional constraints, we see:
---- 95 VARIABLE z.L = 4.049 obj
---- 95 VARIABLE x.L select item
E 1.000, J 1.000, K 1.000, L 1.000, N 1.000
---- 95 VARIABLE y.L color/shape combos in solution (bound)
circle square triangle
blue 1.000
yellow 1.000
red 1.000
orange 1.0001.000
---- 95 SET selected
circle square triangle
E.red YES
J.orange YES
K.blue YES
L.yellow YES
N.orange YES
Now we see the blue shape is a triangle. We only have another triangle of color orange.
The complete GAMS model looks like:
$ontext I'm trying to solve a knapsack-style optimization problem with additional complexity. Here is a simple example. I'm trying to select 5 items that maximize value. 2 of the items must be orange, one must be blue, one must be yellow, and one must be red. This is straightforward. However, I want to add a constraint that the selected yellow, red, and orange items can only have one shape in common with the selected blue item. $offtext set i 'item'/A*O/ c 'color'/blue,yellow,red,orange/ s 'shape'/circle,square,triangle/ ; parameters data(i,c,s) 'value'/ A . blue . circle 0.454 B . yellow . square 0.570 C . red . triangle 0.789 D . red . circle 0.718 E . red . square 0.828 F . orange . square 0.709 G . blue . circle 0.696 H . orange . square 0.285 I . orange . square 0.698 J . orange . triangle 0.861 K . blue . triangle 0.658 L . yellow . circle 0.819 M . blue . square 0.352 N . orange . circle 0.883 O . yellow . triangle 0.755 / NumItems 'number of items to select'/5/ NumColor(c) 'required number of each color'/ orange 2 red 1 blue 1 yellow 1 / ; sets YRO(c) '(c): excludes blue'/yellow,red,orange/ ICS(i,c,s) "(i,c,s)" IC(i,c) "(i,c)" CS(c,s) "(c,s)" ; parameter value(i) "(i): value of item"; ICS(i,c,s) = data(i,c,s); IC(i,c) = sum(ICS(i,c,s),1); CS(c,s) = sum(ICS(i,c,s),1); value(i) = sum((c,s),data(i,c,s)); display i,c,s,ICS,IC,CS,value,YRO; binaryvariable x(i) 'select item'; variable z 'obj'; binaryvariable y(c,s) 'color/shape combos in solution (bound)'; equations obj 'objective' count 'count number of selected items' countcolor(c) 'count selected items for each color' shapecol(i,c,s) 'bound on y(c,s)' impl(s) 'rewritten implication' ; obj.. z =e= sum(i, value(i)*x(i)); count.. sum(i, x(i)) =e= numitems; countcolor(c).. sum(IC(i,c), x(i)) =e= numcolor(c); shapecol(ICS(i,c,s)).. y(c,s) =g= x(i); scalar M; M = card(s)-2; impl(s).. sum(yro,y(yro,s)) =l= 1 + M*(1-y("blue",s)); set selected(i,c,s); option optcr=0; model m1 /obj,count,countcolor/; solve m1 maximizing z using mip; selected(i,c,s)$ICS(i,c,s) = x.l(i)>0.5; display z.l,x.l,selected; model m2 /all/; solve m2 maximizing z using mip; selected(i,c,s)$ICS(i,c,s) = x.l(i)>0.5; display z.l,x.l,y.l,selected; |
A second exercise would be to write this Python using PuLP.
References
- How to construct a complex constraint in PuLP Python, https://stackoverflow.com/questions/58770011/how-to-construct-a-complex-constraint-in-pulp-python