Re: bpp plus type constrain

2023-10-11 Thread Michael Hennebry

On Wed, 11 Oct 2023, Leonardo Corato wrote:


About the upper bound, I realized the bins could't have been enough, so my
first code was a greedy solution: 1 bin per 1 item.


Two items per bin would also work.


Do you think I should write the full bpp with types, code? Maybe it could
help someone.


I'm not sure what you are asking.
If you are asking whether you should publish your gmpl,
why not?
It couldn't hurt.

BTW you still have not dealt with symmetry.
10 bins can be permuted more than 3 million ways.
15 bins more than a trillion ways.

--
Michael   henne...@mail.cs.ndsu.nodak.edu
"Occasionally irrational explanations are required"  --  Luke Roman



Re: bpp plus type constrain

2023-10-11 Thread Leonardo Corato
Thank you  Michael, I already did, I realized immediately it was a typing
error.
I have to double thank you because you made me understand a thing in which
I was stuck.

About the upper bound, I realized the bins could't have been enough, so my
first code was a greedy solution: 1 bin per 1 item.
I think this could be largely improved, as you showed me, but I still have
to analyze to fully  understand your suggestion.

Do you think I should write the full bpp with types, code? Maybe it could
help someone.

Best regards


Il giorno lun 9 ott 2023 alle ore 18:26 Michael Hennebry <
henne...@web.cs.ndsu.nodak.edu> ha scritto:

> On Fri, 6 Oct 2023, Michael Hennebry wrote:
>
> > YY{y in mouldTypes, b in 1..n, i in I: mo[i]==t} y[t, b] >= x[i, b] ;
>
> Oops. A y where a t was needed.  The corrected version:
> YY{t in mouldTypes, b in 1..n, i in I: mo[i]==t} y[t, b] >= x[i, b] ;
>
>
>


Re: bpp plus type constrain

2023-10-09 Thread Michael Hennebry

On Fri, 6 Oct 2023, Michael Hennebry wrote:


YY{y in mouldTypes, b in 1..n, i in I: mo[i]==t} y[t, b] >= x[i, b] ;


Oops. A y where a t was needed.  The corrected version:
YY{t in mouldTypes, b in 1..n, i in I: mo[i]==t} y[t, b] >= x[i, b] ;

--
Michael   henne...@mail.cs.ndsu.nodak.edu
"Occasionally irrational explanations are required"  --  Luke Roman



Re: bpp plus type constrain

2023-10-06 Thread Michael Hennebry

On Fri, 6 Oct 2023, Michael Hennebry wrote:


Your estimate of the number of bins necessary could be an underestimate.
It does not enforce the only two types in a bin requirement.
For larger problems, I think that that would be necessary.


I think that all that is needed is another else if:
else if exists i1 in 1..i-1 exists i2 in 1..i1  z[i1, j] and z[i2, j] and
 mo[i1] != mo[i2] != mo[i] != mo[i1] then 0
This could be a rather slow way to do it.
I think that, with effort, I could get it down to three levels of loops.

--
Michael   henne...@mail.cs.ndsu.nodak.edu
"Occasionally irrational explanations are required"  --  Luke Roman



Re: bpp plus type constrain

2023-10-06 Thread Michael Hennebry

Your estimate of the number of bins necessary could be an underestimate.
It does not enforce the only two types in a bin requirement.
For larger problems, I think that that would be necessary.

--
Michael   henne...@mail.cs.ndsu.nodak.edu
"Occasionally irrational explanations are required"  --  Luke Roman



Re: bpp plus type constrain

2023-10-06 Thread Michael Hennebry

On Fri, 6 Oct 2023, Leonardo Corato wrote:


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'd misunderstood.
I'd thought that you want no more than two of a given type.

Using an auxillary array is probably easiest:
y[t, b] == 1 iff bin b has an item of type t.
It need not be binary or have an upper bound.
An upper bound of one would not hurt and might help.
An upper bound of two can be inferred from other constraints.

greg{b in 1..n} sum{t in mouldTypes} y[t, b] <= 2 ;

YY{y in mouldTypes, b in 1..n, i in I: mo[i]==t} y[t, b] >= x[i, b] ;

Without y, I think that O(n*|I|**3) constraints might be necessary.
cube{b in 1..n, i1 in I, i2 in I, i3 in I: i1< i2 < i3 and
   mo[i1] != mo[i2] != mo[i3] != moi10] }
x[i1, b] + x[i2, b] + x[i3, b] <= 2 ;
This is the kind of thing I'd be inclined to generate on the fly.

I'm not sure which set is stronger.
They might be equivalent.


Apparently you problems are small enough so that it does not matter much,
but you have rather a lot of symmetry.
That sort of thing plays havoc with branch and bound.


--
Michael   henne...@mail.cs.ndsu.nodak.edu
"Occasionally irrational explanations are required"  --  Luke Roman


Please do not quote boilerplate.

--
Michael   henne...@mail.cs.ndsu.nodak.edu
"Occasionally irrational explanations are required"  --  Luke Roman



Re: bpp plus type constrain

2023-10-06 Thread Graciela Coitinho
Por favor no me envíen más correos, no pertenezco al grupo!!

El El vie, oct. 6, 2023 a la(s) 5:32 p.m., Leonardo Corato 
escribió:

> 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  H27587V2502  P27795
>  2  H27587V2502  P27795
>  9  H27587V2502  P27532
> 10  H27587V2502  P27532
> mold types: 2
> Bin 2 # items: 5 - Total weight: 288 - Filling % 96
> Item Batch  Alloy   Mould
>  5  H27587V2502  P12396
>  6  H27587V2502  P12396
> 11  H27587V2502  P27532
> 12  H27587V2502  P27532
> 15  H27587V2502  P35495
> mold types: 3
> Bin 3 # items: 4 - Total weight: 290 - Filling % 97
> Item Batch  Alloy   Mould
>  3  H27587V2502  P27795
>  4  H27587V2502  P27795
> 13  H27587V2502  P27532
> 14  H27587V2502  P35495
> mold types: 3
> Bin 4 # items: 3 - Total weight: 204 - Filling % 68
> Item Batch  Alloy   Mould
>  7  H27587V2502  P12396
>  8  H27587V2502  P12396
> 16  H27587V2502  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 <
> henne...@web.cs.ndsu.nodak.edu> 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 

Re: bpp plus type constrain

2023-10-06 Thread Leonardo Corato
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  H27587V2502  P27795
 2  H27587V2502  P27795
 9  H27587V2502  P27532
10  H27587V2502  P27532
mold types: 2
Bin 2 # items: 5 - Total weight: 288 - Filling % 96
Item Batch  Alloy   Mould
 5  H27587V2502  P12396
 6  H27587V2502  P12396
11  H27587V2502  P27532
12  H27587V2502  P27532
15  H27587V2502  P35495
mold types: 3
Bin 3 # items: 4 - Total weight: 290 - Filling % 97
Item Batch  Alloy   Mould
 3  H27587V2502  P27795
 4  H27587V2502  P27795
13  H27587V2502  P27532
14  H27587V2502  P35495
mold types: 3
Bin 4 # items: 3 - Total weight: 204 - Filling % 68
Item Batch  Alloy   Mould
 7  H27587V2502  P12396
 8  H27587V2502  P12396
16  H27587V2502  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 <
henne...@web.cs.ndsu.nodak.edu> 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
> >
> > 

Re: bpp plus type constrain

2023-10-05 Thread Michael Hennebry

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 

Re: bpp plus type constrain

2023-10-04 Thread Michael Hennebry

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.


If you want the types to have names, they will have to be a set.
You could just give them indices.
You will need a 2D boolean array indexed by item and type.
Once you have that, the rest should be obvious.

--
Michael   henne...@mail.cs.ndsu.nodak.edu
"Occasionally irrational explanations are required"  --  Luke Roman