BookmarkSubscribeRSS Feed
ccockrum
Calcite | Level 5

Hey, I am needing some help figuring out how to do a multi-part constraint for the proc optmodel.  Here is the data I am working with and trying to structure correctly. The specific part I am struggling with is how to do setup the minimum and maximum production constraints per product per plant.  I've attached an Excel spreadsheet showing the data I am working with and below is my attempt at writing the SAS code correctly. 

 

Proc optmodel;
set Plant = {'Osaka','Nagoya','Yokohama','Nara','Fukuoka'};
set Product = {'Haihai','Sensei','Hiro','Kirito'};

number Supply {Plant} = [673 580 659 662 623] ;
number Demand {Product} = [514 527 495 493];
number VariaCost {Plant,Product} = [
25.25	24.4	25.45	24.6
21.15	22.3	24.8	23.15
22.5	25.35	24.85	23.35
24.05	24.4	21.65	22.35
21.5	23.5	23.5	21.85];
number FixedCost {Plant} = [1434 1249 2527];
number M = 1000000;
number MinUse {Plant,Product} = [
60	98	139	133
71	85	80	55
70	61	56	57
136	145	134	144
109	95	118	145];
number MaxUse {Plant,Product} = [
354	343	369	346
299	324	358	319
347	338	290	340
327	325	280	323
308	300	370	354];

var X {Plant,Product} integer >= 0;
var Y {Plant} binary;

minimize TotalCost = sum {i in Plant} ( sum {j in Product} ( X[i,j]*VariaCost[i,j] ) + Y[i]*FixedCost[i] );

con SupplyConst {i in Plant} : sum {j in Product} X[i,j]<=Supply[i];
con DemandConst {j in Product} : sum {i in Plant} X[i,j]>=Demand[j];
con Producing {i in Plant} : sum {j in Product} X[i,j] <= M * Y[i];
con UseMinimum {i in Plant} : sum {j in Product} X[i,j] >= MinUse[i] * Y[i];




solve;

print TotalCost X;

quit;

Thanks in advance for helping a rookie,

 

Chad

7 REPLIES 7
RobPratt
SAS Super FREQ

From the data in the spreadsheet, it looks like you want:

number FixedCost {Plant,Product} = [

And:

 

var Y {Plant,Product} binary;

 

With corresponding changes in the objective declaration.  And then:

/*con Producing {i in Plant} : sum {j in Product} X[i,j] <= M * Y[i];*/
/*con UseMinimum {i in Plant} : sum {j in Product} X[i,j] >= MinUse[i] * Y[i];*/
con UseMinimum {i in Plant, j in Product}: X[i,j] >= MinUse[i,j] * Y[i,j];
con UseMaximum {i in Plant, j in Product}: X[i,j] <= MaxUse[i,j] * Y[i,j];

You don't need M.

 

ccockrum
Calcite | Level 5

Thanks for the help Rob, I really appreciate it.  I thought I was tracking with you on the changes, but I've hit some errors I'm not sure how to debug. 

at line 91:

minimize TotalCost = sum {i in Plant} ( sum {j in Product} ( X[i,j]*VariaCost[i,j] ) + Y[i]*FixedCost[i] );
ERROR 618-782: The subscript count does not match array 'Y', 1 NE 2.
ERROR 618-782: The subscript count does not match array 'FixedCost', 1 NE 2.


at line 96:

con Producing {i in Plant} : sum {j in Product} X[i,j] <= M * Y[i];
ERROR 618-782: The subscript count does not match array 'Y', 1 NE 2.



at line 97:

con UseMinimum {i in Plant} : sum {j in Product} X[i,j] >= MinUse[i] * Y[i];
ERROR 618-782: The subscript count does not match array 'MinUse', 1 NE 2.
ERROR 618-782: The subscript count does not match array 'Y', 1 NE 2.

 

 

 

and finally:

ERROR: The constraint 'Producing' has an incomplete declaration.

 

Am I correct in assuming that one has to M?

 

 

latest code

 

Proc optmodel;
set Plant = {'Osaka','Nagoya','Yokohama','Nara','Fukuoka'};
set Product = {'Haihai','Sensei','Hiro','Kirito'};

number Supply {Plant} = [673 580 659 662 623] ;
number Demand {Product} = [514 527 495 493];
number VariaCost {Plant,Product} = [
25.25	24.4	25.45	24.6
21.15	22.3	24.8	23.15
22.5	25.35	24.85	23.35
24.05	24.4	21.65	22.35
21.5	23.5	23.5	21.85];
number FixedCost {Plant,Product} = [
1415	1392	803	618
321	755	942	706
1252	1178	1391	1362
1408	1349	901	1386
619	702	1473	1493];
number M = 1000000;
number MinUse {Plant,Product} = [
60	98	139	133
71	85	80	55
70	61	56	57
136	145	134	144
109	95	118	145];
number MaxUse {Plant,Product} = [
354	343	369	346
299	324	358	319
347	338	290	340
327	325	280	323
308	300	370	354];

var X {Plant,Product} integer >= 0;
var Y {Plant,Product} binary;

minimize TotalCost = sum {i in Plant} ( sum {j in Product} ( X[i,j]*VariaCost[i,j] ) + Y[i]*FixedCost[i] );


con SupplyConst {i in Plant} : sum {j in Product} X[i,j]<=Supply[i];
con DemandConst {j in Product} : sum {i in Plant} X[i,j]>=Demand[j];
con Producing {i in Plant} : sum {j in Product} X[i,j] <= M * Y[i];
con UseMinimum {i in Plant} : sum {j in Product} X[i,j] >= MinUse[i] * Y[i];
con UseMinimum {i in Plant, j in Product}: X[i,j] >= MinUse[i,j] * Y[i,j];
con UseMaximum {i in Plant, j in Product}: X[i,j] <= MaxUse[i,j] * Y[i,j];


solve;

print TotalCost X;

quit;
RobPratt
SAS Super FREQ

Those error messages are telling you that you can't use Y[i] and FixedCost[i] because those arrays now require two subscripts each.  You need Y[i,j] and FixedCost[i,j] instead.

 

The Producing and UseMinimum constraints that I commented out are obsolete, and M is now also obsolete because it appears only in Producing.

ccockrum
Calcite | Level 5

 

So I made the change to Y[i,j]

 

 

minimize TotalCost = sum {i in Plant} ( sum {j in Product} ( X[i,j]*VariaCost[i,j] ) + Y[i,j]*FixedCost[i,j] );

But I am still getting these errors on that line of code:

 

ERROR 525-782: The symbol 'j' is unknown.

 

ERROR 618-782: The subscript count does not match array 'Y', 2 NE 1.
ERROR 618-782: The subscript count does not match array 'FixedCost', 2 NE 1.

 

Thanks!

RobPratt
SAS Super FREQ

Your parentheses on the summand are incorrect.  You can use either one of the following:

minimize TotalCost = sum {i in Plant} ( sum {j in Product} ( X[i,j]*VariaCost[i,j]  + Y[i,j]*FixedCost[i,j] ));
minimize TotalCost = sum {i in Plant, j in Product} ( X[i,j]*VariaCost[i,j]  + Y[i,j]*FixedCost[i,j] );
ccockrum
Calcite | Level 5

Okay, I'm following you.  What about the other error, that one is this there.

 86         minimize TotalCost = sum {i in Plant} ( sum {j in Product} ( X[i,j]*VariaCost[i,j]  + Y[i,j]*FixedCost[i,j] ));
                                                                                                       _
                                                                                                       618
 ERROR 618-782: The subscript count does not match array 'Y', 2 NE 1.
 
 86       ! minimize TotalCost = sum {i in Plant} ( sum {j in Product} ( X[i,j]*VariaCost[i,j]  + Y[i,j]*FixedCost[i,j] ));
                                                                                                                      _
                                                                                                                      618
 ERROR 618-782: The subscript count does not match array 'FixedCost', 2 NE 1.
 

Total code now looks like this:

Proc optmodel;
set Plant = {'Osaka','Nagoya','Yokohama','Nara','Fukuoka'};
set Product = {'Haihai','Sensei','Hiro','Kirito'};

number Supply {Plant} = [673 580 659 662 623] ;
number Demand {Product} = [514 527 495 493];
number VariaCost {Plant,Product} = [
25.25	24.4	25.45	24.6
21.15	22.3	24.8	23.15
22.5	25.35	24.85	23.35
24.05	24.4	21.65	22.35
21.5	23.5	23.5	21.85];
number FixedCost {Plant} = [1434 1249 2527];
number M = 1000000;
number MinUse {Plant,Product} = [
60	98	139	133
71	85	80	55
70	61	56	57
136	145	134	144
109	95	118	145];
number MaxUse {Plant,Product} = [
354	343	369	346
299	324	358	319
347	338	290	340
327	325	280	323
308	300	370	354];

var X {Plant,Product} integer >= 0;
var Y {Plant} binary;

minimize TotalCost = sum {i in Plant} ( sum {j in Product} ( X[i,j]*VariaCost[i,j]  + Y[i,j]*FixedCost[i,j] ));

con SupplyConst {i in Plant} : sum {j in Product} X[i,j]<=Supply[i];
con DemandConst {j in Product} : sum {i in Plant} X[i,j]>=Demand[j];



solve;

print TotalCost X;

quit;

 

Thanks for taking another look at this.

RobPratt
SAS Super FREQ

Those additional errors are because you switched back to the old declarations for FixedCost and Y.  Also, you still need the new UseMinimum and UseMaximum constraints.

sas-innovate-white.png

Our biggest data and AI event of the year.

Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.

Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.

 

Register now!

Discussion stats
  • 7 replies
  • 3219 views
  • 0 likes
  • 2 in conversation