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
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.
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;
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.
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!
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] );
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.
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 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.