Re: bpp plus type constrain

Leonardo Corato <[email protected]> Fri, 6 Oct 2023 17:31:53 +0200
Newsgroups gmane.comp.gnu.glpk
Message-ID <CAPXOyi6XSEKmc2yuWvT4OteJNMwgrvYc_xOoqLOe-q2yTKPx7g@mail.gmail.com>
--00000000000050a45306070df181
Content-Type: text/plain; charset="UTF-8"

Thank you very much Michael,
and sorry for missing the maling list and sending the email directly to you.

I applied
s.t. fred{b in 1..n, t in mouldTypes}: sum{i in I: mo[i]==t} x[i, b] <= 2 ;
doesn't limit the types to max 2.

To check whether s.t. fred worked properly, I added some printf statements
between solve and data:

solve;


printf "Min number of bins used: %d \n", obj;
for {j in J: sum{i in I} x[i,j] != 0} {
    printf "Bin %d # items: %d - Total weight: %d - Filling %% %d  \n", j,
sum{i in I} x[i,j], sum{i in I} w[i] * x[i,j], sum{i in I} w[i] * x[i,j] /
cmax * 100 ;
    printf "Item     Batch      Alloy   Mould\n";
    for {i in I: x[i,j]==1} {
        printf "%3d      %s    %d  %s\n",i ,ba[i] ,al[i],mo[i];
    }
        printf "mold types: %d\n", card(setof{i in I: x[i,j]==1} mo[i] );


}


data;


When run, I got:

Min number of bins used: 4
Bin 1 # items: 4 - Total weight: 254 - Filling % 85
Item     Batch      Alloy   Mould
 1      H27587V    2502  P27795
 2      H27587V    2502  P27795
 9      H27587V    2502  P27532
10      H27587V    2502  P27532
mold types: 2
Bin 2 # items: 5 - Total weight: 288 - Filling % 96
Item     Batch      Alloy   Mould
 5      H27587V    2502  P12396
 6      H27587V    2502  P12396
11      H27587V    2502  P27532
12      H27587V    2502  P27532
15      H27587V    2502  P35495
mold types: 3
Bin 3 # items: 4 - Total weight: 290 - Filling % 97
Item     Batch      Alloy   Mould
 3      H27587V    2502  P27795
 4      H27587V    2502  P27795
13      H27587V    2502  P27532
14      H27587V    2502  P35495
mold types: 3
Bin 4 # items: 3 - Total weight: 204 - Filling % 68
Item     Batch      Alloy   Mould
 7      H27587V    2502  P12396
 8      H27587V    2502  P12396
16      H27587V    2502  P35495
mold types: 2
Model has been successfully processed

As you can see in bin 2 and 3 there are 3 mold types, so sadly s.t. fred is
not limiting to 2
I also tried
s.t. cardset{j in J}: card(setof{i in I: x[i,j] == 1} mo[i] ) <= 2;
which is the same  I used in printfs to check how many type of items are in
every bin j, but it seems that this expression can't be used inside an s.t.


Il giorno gio 5 ott 2023 alle ore 21:28 Michael Hennebry <
[email protected]> ha scritto:

> I'm assuming the your e-mail was intended for the list.
> I'm quoting most of it because the list does not have it.
>
> In either case, forget about what I wrote.
> GMPL is more powerful than I remembered.
>
> I think the desired constraint is
> fred{b in 1..n, t in mouldTypes} sum{i in I: mo[i]==t} x[i, b] <= 2 ;
> The above two lines are duplicated at an appropriate point.
> I did not add anything else.
>
> On Thu, 5 Oct 2023, Leonardo Corato wrote:
>
> > Thanks Michael, I understand.
> > But what it is not clear to me is once I have  the type and numbers for
> > type how to do it:
> > let's say there's this *data1.csv* having:
> >
> > ITEM,WEIGHT,ALLOY,BATCH,MOULD
> > 1,85,2502,H27587V,P27795
> > 2,85,2502,H27587V,P27795
> > 3,85,2502,H27587V,P27795
> > 4,85,2502,H27587V,P27795
> > 5,63,2502,H27587V,P12396
> > 6,63,2502,H27587V,P12396
> > 7,63,2502,H27587V,P12396
> > 8,63,2502,H27587V,P12396
> > 9,42,2502,H27587V,P27532
> > 10,42,2502,H27587V,P27532
> > 11,42,2502,H27587V,P27532
> > 12,42,2502,H27587V,P27532
> > 13,42,2502,H27587V,P27532
> > 14,78,2502,H27587V,P35495
> > 15,78,2502,H27587V,P35495
> > 16,78,2502,H27587V,P35495
> >
> >
> > where WEIGHT is the weight I'll use in the bpp example of Andrew
> Makhorin,
> > alloy and batch are descriptive and mould is  the type.
> >
> > My code is:
> > set I;
> > param w{it in I}, > 0;        # Weight of item i (w[i])
> > param al{it in I};            # Alloy
> > param ba{it in I} symbolic;   # Batch
> > param mo{it in I} symbolic;   # Mould
> > table tab_items IN "CSV" "data1.csv" :
> > I <- [ITEM], w ~ WEIGHT, al ~ ALLOY, ba ~ BATCH, mo ~ MOULD;
> >
> > printf{it in I}: "%d %d %s %s \n", it,w[it],ba[it], mo[it];
> >
> > set mouldTypes := setof{it in I} mo[it];
> > # Count the distinct molds
> > param cmt := card(mouldTypes);
> > #display mouldTypes;
> > display cmt;
> >
> > #param itemCounts{ti in mouldTypes};
> > param itemCounts{ti in mouldTypes} := sum{i in I: mo[i] = ti} 1;
> >
> > for {ti in mouldTypes} {
> >   printf "Mould Type: %s, Item Count: %d\n", ti, itemCounts[ti];
> > }
> >
> > # total number of items
> > param m := card(I),>0;
> > printf "Number of items: %d \n", m;
> >
> > # Bin capacity
> > param cmax, > 0;
> >
> > /* We need to estimate an upper bound of the number of bins sufficient
> >  to contain all items. The number of items m can be used, however, it
> >  is not a good idea. To obtain a more suitable estimation an easy
> >  heuristic is used: we put items into a bin while it is possible, and
> >  if the bin is full, we use another bin. The number of bins used in
> >  this way gives us a more appropriate estimation. */
> >
> > param z{i in I, j in 1..m} :=
> > # z[i,j] = 1 if item i is in bin j, otherwise z[i,j] = 0
> >
> >  if i = 1 and j = 1 then 1
> >  # put item 1 into bin 1
> >
> >  else if exists{jj in 1..j-1} z[i,jj] then 0
> >  # if item i is already in some bin, do not put it into bin j
> >
> >  else if sum{ii in 1..i-1} w[ii] * z[ii,j] + w[i] > cmax then 0
> >  # if item i does not fit into bin j, do not put it into bin j
> >
> >  else 1;
> >  # otherwise put item i into bin j
> >
> > check{i in I}: sum{j in 1..m} z[i,j] = 1;
> > # each item must be exactly in one bin
> >
> > check{j in 1..m}: sum{i in I} w[i] * z[i,j] <= cmax;
> > # no bin must be overflowed
> >
> > param n := sum{j in 1..m} if exists{i in I} z[i,j] then 1;
> > /* determine the number of bins used by the heuristic; obviously it is
> >  an upper bound of the optimal solution */
> >
> > set J := 1..n;
> > # set of bins
> >
> > var x{i in I, j in J}, binary;
> > # x[i,j] = 1 means item i is in bin j
>
> I think the desired constraint is
> fred{b in 1..n, t in mouldTypes} sum{i in I: mo[i]==t} x[i, b] <= 2 ;
>
> > var used{j in J}, binary;
> > # used[j] = 1 means bin j contains at least one item
> >
> > s.t. one{i in I}: sum{j in J} x[i,j] = 1;
> > # each item must be exactly in one bin
> >
> > s.t. limMax{j in J}: sum{i in I} w[i] * x[i,j] <= cmax * used[j];
> > # if bin j is used, it must not be overflowed:  can't exceed cmax
> >
> > minimize obj: sum{j in J} used[j];
> > # objective is to minimize the number of bins used
> >
> > solve;
> >
> > data;
> > param cmax := 300;  # max weight
> >
> > end;
> >
> > So now I can see that I have 4 type of moulds,
> > cmt = 4
> > And each one  ha n items:Mould Type: P27795, Item Count: 4
> > Mould Type: P12396, Item Count: 4
> > Mould Type: P27532, Item Count: 5
> > Mould Type: P35495, Item Count: 3
> > For a total of items:
> > Number of items: 16
> >
> > So now I can say I have the params for type:
> > ti,                       #typeitemCounts[ti]   # number of items for
> that
> > type.
> >
> > Now, what it is not clear to me is: if I want max 2 types of n items for
> > each bin how to achieve this goal.
> >
> > e.g in  the same bin I can have 2 of P27795 and 2 of P12396 because the
> > weight is : 85*2+63*2=296<300 and cardinality of #(P27795, P12396) is 2
> >      but I can't have 1 of P12396 and 1 of P12396 and 1 of P27532 because
> > the weight is 85+63+42=190<300, fine, but the cardinality of #(P27795,
> > P12396, ) is 3
> >
> > I tried adding a variable t[ti,j]  like Makhorin did for z[i,j] , in this
> > case meaning 1 when there's a mould type ti in bin j ....but type must be
> > linked to i, because each item can be of just 1 mould type.
> > So I tried with a  t[ti,i], but in this case it is not bound to bin and I
> > need this.
> > So I asked me if I just had to add ti as a third variable in z[i,j,ti]
> but
> > in this latter I would get that i can be of each type while each i is
> just
> > one type.
> > Any tips?
> >
> > Il giorno mer 4 ott 2023 alle ore 20:08 Michael Hennebry <
> > [email protected]> ha scritto:
> >
> >> On Sat, 30 Sep 2023, Leonardo Corato wrote:
> >>
> >>> param m := 6;
> >>> param w :=     1 50, 2 60, 3 30, 4 40, 5 40, 6 40;
> >>> --> param t := 1 A,  2 B , 3 B, 4 C, 5 C, 6 C;
> >>> param c := 100;
> >>>
> >>> end;
> >>>
> >>> I have to add a constraint so that the number of types for every bin is
> >>> limited to maximum 2.
> >>>
> >>> Each bin can contain a number of the same type of items (i.e. A) or
> max 2
> >>> different types (i.e. A and C).
> >>> it is not regarding the number of items, of course, I can have multiple
> >>> items.
>
> --
> Michael   [email protected]
> "Occasionally irrational explanations are required"  --  Luke Roman
>

--00000000000050a45306070df181
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Thank you very much Michael,</div><div>and sorry for =
missing the maling list and sending the email directly to you.</div><div><b=
r></div><div>I applied=C2=A0<br></div><div><font face=3D"monospace">s.t. fr=
ed{b in 1..n, t in mouldTypes}: sum{i in I: mo[i]=3D=3Dt} x[i, b] &lt;=3D 2=
 ;</font><br></div><div>doesn&#39;t limit the types to max 2.<br></div><div=
><br></div><div>To check whether s.t. fred worked properly, I added some pr=
intf statements between solve and data:<br></div><div><br></div><blockquote=
 style=3D"margin:0 0 0 40px;border:none;padding:0px"><div><font face=3D"mon=
ospace">solve;</font></div></blockquote><div><font face=3D"monospace"><br><=
/font></div><blockquote style=3D"margin:0 0 0 40px;border:none;padding:0px"=
><div><font face=3D"monospace">printf &quot;Min number of bins used: %d \n&=
quot;, obj;</font></div><div><font face=3D"monospace">for {j in J: sum{i in=
 I} x[i,j] !=3D 0} {</font></div><div><font face=3D"monospace">=C2=A0 =C2=
=A0 printf &quot;Bin %d # items: %d - Total weight: %d - Filling %% %d =C2=
=A0\n&quot;, j, sum{i in I} x[i,j], sum{i in I} w[i] * x[i,j], sum{i in I} =
w[i] * x[i,j] / cmax * 100 ;</font></div><div><font face=3D"monospace">=C2=
=A0 =C2=A0 printf &quot;Item =C2=A0 =C2=A0 Batch =C2=A0 =C2=A0 =C2=A0Alloy =
=C2=A0 Mould\n&quot;;</font></div><div><font face=3D"monospace">=C2=A0 =C2=
=A0 for {i in I: x[i,j]=3D=3D1} { </font></div><div><font face=3D"monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 printf &quot;%3d =C2=A0 =C2=A0 =C2=A0%s =C2=
=A0 =C2=A0%d =C2=A0%s\n&quot;,i ,ba[i] ,al[i],mo[i];</font></div><div><font=
 face=3D"monospace">=C2=A0 =C2=A0 }=C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0</font>=
</div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 printf &quo=
t;mold types: %d\n&quot;, card(setof{i in I: x[i,j]=3D=3D1} mo[i] );</font>=
</div></blockquote><div><font face=3D"monospace"><br></font></div><blockquo=
te style=3D"margin:0 0 0 40px;border:none;padding:0px"><div><font face=3D"m=
onospace">}</font></div></blockquote><div><font face=3D"monospace"><br></fo=
nt></div><blockquote style=3D"margin:0 0 0 40px;border:none;padding:0px"><d=
iv><font face=3D"monospace">data;</font></div></blockquote><div><br></div><=
div>When run, I got:</div><div><br></div><div><font face=3D"monospace"><spa=
n style=3D"color:rgb(0,0,0)">Min number of bins used: 4 =C2=A0</span><br>Bi=
n 1 # items: 4 - Total weight: 254 - Filling % 85 =C2=A0=C2=A0<br>Item =C2=
=A0=C2=A0=C2=A0=C2=A0Batch =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Alloy =C2=A0=C2=A0=
Mould
<br> =C2=A01 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =
=C2=A0P27795
<br> =C2=A02 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =
=C2=A0P27795
<br> =C2=A09 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =
=C2=A0P27532
<br> 10 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =C2=A0=
P27532
<br>mold types: 2
<br>Bin 2 # items: 5 - Total weight: 288 - Filling % 96 =C2=A0=C2=A0<br>Ite=
m =C2=A0=C2=A0=C2=A0=C2=A0Batch =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Alloy =C2=A0=
=C2=A0Mould
<br> =C2=A05 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =
=C2=A0P12396
<br> =C2=A06 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =
=C2=A0P12396
<br> 11 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =C2=A0=
P27532
<br> 12 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =C2=A0=
P27532
<br> 15 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =C2=A0=
P35495
<br>mold types: 3
<br>Bin 3 # items: 4 - Total weight: 290 - Filling % 97 =C2=A0=C2=A0<br>Ite=
m =C2=A0=C2=A0=C2=A0=C2=A0Batch =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Alloy =C2=A0=
=C2=A0Mould
<br> =C2=A03 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =
=C2=A0P27795
<br> =C2=A04 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =
=C2=A0P27795
<br> 13 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =C2=A0=
P27532
<br> 14 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =C2=A0=
P35495
<br>mold types: 3
<br>Bin 4 # items: 3 - Total weight: 204 - Filling % 68 =C2=A0=C2=A0<br>Ite=
m =C2=A0=C2=A0=C2=A0=C2=A0Batch =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0Alloy =C2=A0=
=C2=A0Mould
<br> =C2=A07 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =
=C2=A0P12396
<br> =C2=A08 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =
=C2=A0P12396
<br> 16 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0H27587V =C2=A0=C2=A0=C2=A02502 =C2=A0=
P35495
<br>mold types: 2
<br>Model has been successfully processed</font><br></div><div><br></div><d=
iv>As you can see in bin 2 and 3 there are 3 mold types, so sadly s.t. fred=
 is not limiting to 2</div><div>I also tried=C2=A0<br><font face=3D"monospa=
ce">s.t. cardset{j in J}: card(setof{i in I: x[i,j] =3D=3D 1} mo[i] ) &lt;=
=3D 2;</font></div><div>which is the same=C2=A0 I used in printfs to check =
how many type of items are in every bin j, but it seems that this expressio=
n can&#39;t be used inside an s.t.=C2=A0</div><div><br></div><br><div class=
=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">Il giorno gio 5 ott =
2023 alle ore 21:28 Michael Hennebry &lt;<a href=3D"mailto:[email protected].=
ndsu.nodak.edu">[email protected]</a>&gt; ha scritto:<br></div=
><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border=
-left:1px solid rgb(204,204,204);padding-left:1ex">I&#39;m assuming the you=
r e-mail was intended for the list.<br>
I&#39;m quoting most of it because the list does not have it.<br>
<br>
In either case, forget about what I wrote.<br>
GMPL is more powerful than I remembered.<br>
<br>
I think the desired constraint is<br>
fred{b in 1..n, t in mouldTypes} sum{i in I: mo[i]=3D=3Dt} x[i, b] &lt;=3D =
2 ;<br>
The above two lines are duplicated at an appropriate point.<br>
I did not add anything else.<br>
<br>
On Thu, 5 Oct 2023, Leonardo Corato wrote:<br>
<br>
&gt; Thanks Michael, I understand.<br>
&gt; But what it is not clear to me is once I have=C2=A0 the type and numbe=
rs for<br>
&gt; type how to do it:<br>
&gt; let&#39;s say there&#39;s this *data1.csv* having:<br>
&gt;<br>
&gt; ITEM,WEIGHT,ALLOY,BATCH,MOULD<br>
&gt; 1,85,2502,H27587V,P27795<br>
&gt; 2,85,2502,H27587V,P27795<br>
&gt; 3,85,2502,H27587V,P27795<br>
&gt; 4,85,2502,H27587V,P27795<br>
&gt; 5,63,2502,H27587V,P12396<br>
&gt; 6,63,2502,H27587V,P12396<br>
&gt; 7,63,2502,H27587V,P12396<br>
&gt; 8,63,2502,H27587V,P12396<br>
&gt; 9,42,2502,H27587V,P27532<br>
&gt; 10,42,2502,H27587V,P27532<br>
&gt; 11,42,2502,H27587V,P27532<br>
&gt; 12,42,2502,H27587V,P27532<br>
&gt; 13,42,2502,H27587V,P27532<br>
&gt; 14,78,2502,H27587V,P35495<br>
&gt; 15,78,2502,H27587V,P35495<br>
&gt; 16,78,2502,H27587V,P35495<br>
&gt;<br>
&gt;<br>
&gt; where WEIGHT is the weight I&#39;ll use in the bpp example of Andrew M=
akhorin,<br>
&gt; alloy and batch are descriptive and mould is=C2=A0 the type.<br>
&gt;<br>
&gt; My code is:<br>
&gt; set I;<br>
&gt; param w{it in I}, &gt; 0;=C2=A0 =C2=A0 =C2=A0 =C2=A0 # Weight of item =
i (w[i])<br>
&gt; param al{it in I};=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # Alloy<br=
>
&gt; param ba{it in I} symbolic;=C2=A0 =C2=A0# Batch<br>
&gt; param mo{it in I} symbolic;=C2=A0 =C2=A0# Mould<br>
&gt; table tab_items IN &quot;CSV&quot; &quot;data1.csv&quot; :<br>
&gt; I &lt;- [ITEM], w ~ WEIGHT, al ~ ALLOY, ba ~ BATCH, mo ~ MOULD;<br>
&gt;<br>
&gt; printf{it in I}: &quot;%d %d %s %s \n&quot;, it,w[it],ba[it], mo[it];<=
br>
&gt;<br>
&gt; set mouldTypes :=3D setof{it in I} mo[it];<br>
&gt; # Count the distinct molds<br>
&gt; param cmt :=3D card(mouldTypes);<br>
&gt; #display mouldTypes;<br>
&gt; display cmt;<br>
&gt;<br>
&gt; #param itemCounts{ti in mouldTypes};<br>
&gt; param itemCounts{ti in mouldTypes} :=3D sum{i in I: mo[i] =3D ti} 1;<b=
r>
&gt;<br>
&gt; for {ti in mouldTypes} {<br>
&gt;=C2=A0 =C2=A0printf &quot;Mould Type: %s, Item Count: %d\n&quot;, ti, i=
temCounts[ti];<br>
&gt; }<br>
&gt;<br>
&gt; # total number of items<br>
&gt; param m :=3D card(I),&gt;0;<br>
&gt; printf &quot;Number of items: %d \n&quot;, m;<br>
&gt;<br>
&gt; # Bin capacity<br>
&gt; param cmax, &gt; 0;<br>
&gt;<br>
&gt; /* We need to estimate an upper bound of the number of bins sufficient=
<br>
&gt;=C2=A0 to contain all items. The number of items m can be used, however=
, it<br>
&gt;=C2=A0 is not a good idea. To obtain a more suitable estimation an easy=
<br>
&gt;=C2=A0 heuristic is used: we put items into a bin while it is possible,=
 and<br>
&gt;=C2=A0 if the bin is full, we use another bin. The number of bins used =
in<br>
&gt;=C2=A0 this way gives us a more appropriate estimation. */<br>
&gt;<br>
&gt; param z{i in I, j in 1..m} :=3D<br>
&gt; # z[i,j] =3D 1 if item i is in bin j, otherwise z[i,j] =3D 0<br>
&gt;<br>
&gt;=C2=A0 if i =3D 1 and j =3D 1 then 1<br>
&gt;=C2=A0 # put item 1 into bin 1<br>
&gt;<br>
&gt;=C2=A0 else if exists{jj in 1..j-1} z[i,jj] then 0<br>
&gt;=C2=A0 # if item i is already in some bin, do not put it into bin j<br>
&gt;<br>
&gt;=C2=A0 else if sum{ii in 1..i-1} w[ii] * z[ii,j] + w[i] &gt; cmax then =
0<br>
&gt;=C2=A0 # if item i does not fit into bin j, do not put it into bin j<br=
>
&gt;<br>
&gt;=C2=A0 else 1;<br>
&gt;=C2=A0 # otherwise put item i into bin j<br>
&gt;<br>
&gt; check{i in I}: sum{j in 1..m} z[i,j] =3D 1;<br>
&gt; # each item must be exactly in one bin<br>
&gt;<br>
&gt; check{j in 1..m}: sum{i in I} w[i] * z[i,j] &lt;=3D cmax;<br>
&gt; # no bin must be overflowed<br>
&gt;<br>
&gt; param n :=3D sum{j in 1..m} if exists{i in I} z[i,j] then 1;<br>
&gt; /* determine the number of bins used by the heuristic; obviously it is=
<br>
&gt;=C2=A0 an upper bound of the optimal solution */<br>
&gt;<br>
&gt; set J :=3D 1..n;<br>
&gt; # set of bins<br>
&gt;<br>
&gt; var x{i in I, j in J}, binary;<br>
&gt; # x[i,j] =3D 1 means item i is in bin j<br>
<br>
I think the desired constraint is<br>
fred{b in 1..n, t in mouldTypes} sum{i in I: mo[i]=3D=3Dt} x[i, b] &lt;=3D =
2 ;<br>
<br>
&gt; var used{j in J}, binary;<br>
&gt; # used[j] =3D 1 means bin j contains at least one item<br>
&gt;<br>
&gt; s.t. one{i in I}: sum{j in J} x[i,j] =3D 1;<br>
&gt; # each item must be exactly in one bin<br>
&gt;<br>
&gt; s.t. limMax{j in J}: sum{i in I} w[i] * x[i,j] &lt;=3D cmax * used[j];=
<br>
&gt; # if bin j is used, it must not be overflowed:=C2=A0 can&#39;t exceed =
cmax<br>
&gt;<br>
&gt; minimize obj: sum{j in J} used[j];<br>
&gt; # objective is to minimize the number of bins used<br>
&gt;<br>
&gt; solve;<br>
&gt;<br>
&gt; data;<br>
&gt; param cmax :=3D 300;=C2=A0 # max weight<br>
&gt;<br>
&gt; end;<br>
&gt;<br>
&gt; So now I can see that I have 4 type of moulds,<br>
&gt; cmt =3D 4<br>
&gt; And each one=C2=A0 ha n items:Mould Type: P27795, Item Count: 4<br>
&gt; Mould Type: P12396, Item Count: 4<br>
&gt; Mould Type: P27532, Item Count: 5<br>
&gt; Mould Type: P35495, Item Count: 3<br>
&gt; For a total of items:<br>
&gt; Number of items: 16<br>
&gt;<br>
&gt; So now I can say I have the params for type:<br>
&gt; ti,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0#typeitemCounts[ti]=C2=A0 =C2=A0# number of items for that=
<br>
&gt; type.<br>
&gt;<br>
&gt; Now, what it is not clear to me is: if I want max 2 types of n items f=
or<br>
&gt; each bin how to achieve this goal.<br>
&gt;<br>
&gt; e.g in=C2=A0 the same bin I can have 2 of P27795 and 2 of P12396 becau=
se the<br>
&gt; weight is : 85*2+63*2=3D296&lt;300 and cardinality of #(P27795, P12396=
) is 2<br>
&gt;=C2=A0 =C2=A0 =C2=A0 but I can&#39;t have 1 of P12396 and 1 of P12396 a=
nd 1 of P27532 because<br>
&gt; the weight is 85+63+42=3D190&lt;300, fine, but the cardinality of #(P2=
7795,<br>
&gt; P12396, ) is 3<br>
&gt;<br>
&gt; I tried adding a variable t[ti,j]=C2=A0 like Makhorin did for z[i,j] ,=
 in this<br>
&gt; case meaning 1 when there&#39;s a mould type ti in bin j ....but type =
must be<br>
&gt; linked to i, because each item can be of just 1 mould type.<br>
&gt; So I tried with a=C2=A0 t[ti,i], but in this case it is not bound to b=
in and I<br>
&gt; need this.<br>
&gt; So I asked me if I just had to add ti as a third variable in z[i,j,ti]=
 but<br>
&gt; in this latter I would get that i can be of each type while each i is =
just<br>
&gt; one type.<br>
&gt; Any tips?<br>
&gt;<br>
&gt; Il giorno mer 4 ott 2023 alle ore 20:08 Michael Hennebry &lt;<br>
&gt; <a href=3D"mailto:[email protected]" target=3D"_blank">he=
[email protected]</a>&gt; ha scritto:<br>
&gt;<br>
&gt;&gt; On Sat, 30 Sep 2023, Leonardo Corato wrote:<br>
&gt;&gt;<br>
&gt;&gt;&gt; param m :=3D 6;<br>
&gt;&gt;&gt; param w :=3D=C2=A0 =C2=A0 =C2=A01 50, 2 60, 3 30, 4 40, 5 40, =
6 40;<br>
&gt;&gt;&gt; --&gt; param t :=3D 1 A,=C2=A0 2 B , 3 B, 4 C, 5 C, 6 C;<br>
&gt;&gt;&gt; param c :=3D 100;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; end;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; I have to add a constraint so that the number of types for eve=
ry bin is<br>
&gt;&gt;&gt; limited to maximum 2.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Each bin can contain a number of the same type of items (i.e. =
A) or max 2<br>
&gt;&gt;&gt; different types (i.e. A and C).<br>
&gt;&gt;&gt; it is not regarding the number of items, of course, I can have=
 multiple<br>
&gt;&gt;&gt; items.<br>
<br>
-- <br>
Michael=C2=A0 =C2=A0<a href=3D"mailto:[email protected]" targ=
et=3D"_blank">[email protected]</a><br>
&quot;Occasionally irrational explanations are required&quot;=C2=A0 --=C2=
=A0 Luke Roman<br>
</blockquote></div></div>

--00000000000050a45306070df181--