BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Tj_chua
Obsidian | Level 7

Hi,

 

Im trying to optimize area utilization (max profit given fix area size). what i have is data on several processing machines types and how much space it consumes and estimated profit if we put out x number of them(while area is size is linearly increasing, profit is not), hopefully i can get best possible number of each type of machine.

 

I have tried loops but realized there are 39Bilion Combinations and output will fill out the hard drive. so basically my loops is comparable to betting on all lottery tickets to win 1.

I stumbled upon Proc optmodel and (read data) and wonder if this was the way to go instead of my loops. 

 

a sample of what i have is:

data have ;
input machine$ count Total_area Total_profit;
cards;
M1 1 50 35
M1 2 100 43
M1 3 150 51
M2 6 50 740
M2 7 140 850
M2 8 160 910
M2 9 180 950
M3 3 135 225
M3 4 180 350
M3 5 225 415
M3 6 270 485
M3 7 315 550
;run;

 

lets say max floor size = 600.

 

there are 3x4x5 possible scenarios:

M1 M2 M3

1    6    3

1    6    4

.

.

to

.

.

3   9   7

 

 

Want: hope fully get something like:

Combination: 2 of M1, 9 of M2, 7 of M3

Max profit of 1551

Total area consumed 595

 

Im hoping you guys can help me out writing the correct code for proc optmodel while im still reading on it.

 

Thankful of any help.

 

1 ACCEPTED SOLUTION

Accepted Solutions
RobPratt
SAS Super FREQ

Here it is in PROC OPTMODEL:

 

proc optmodel;
set <str,num> MACHINE_COUNT;
num area {MACHINE_COUNT};
num profit {MACHINE_COUNT};
read data have into MACHINE_COUNT=[machine count] area profit=total;
set MACHINES = setof {<m,c> in MACHINE_COUNT} m;

var IsMachineCount {MACHINE_COUNT} binary;
max TotalProfit = sum {<m,c> in MACHINE_COUNT} profit[m,c]*IsMachineCount[m,c];
con OneCountPerMachine {m in MACHINES}:
sum {<(m),c> in MACHINE_COUNT} IsMachineCount[m,c] = 1;
con AreaBudget:
sum {<m,c> in MACHINE_COUNT} area[m,c]*IsMachineCount[m,c] <= 600;

solve;
for {<m,c> in MACHINE_COUNT: IsMachineCount[m,c].sol > 0.5}
put m c area[m,c] profit[m,c];
quit;

 

M1 2 100 43
M2 9 180 950
M3 7 315 550

View solution in original post

8 REPLIES 8
Ksharp
Super User

There is no need of SAS/OR. SAS/IML is good enough. If you don't have it , get it by downing SAS University Edition at sas.com.

data have ;
input machine $ count total area;
cards;
M1 1 50 35
M1 2 100 43
M1 3 150 51
M2 6 50 740
M2 7 140 850
M2 8 160 910
M2 9 180 950
M3 3 135 225
M3 4 180 350
M3 5 225 415
M3 6 270 485
M3 7 315 550
;
run;

proc iml;
use have;
read all var {machine count total area};
close;
object = total`;
coef = area`;
b = 600;
rowsense = {L};
cntl = -1;
call milpsolve(rc,objv,x,relgap,object,coef,b,cntl,,rowsense);

key=catx(' ',machine,count);
idx=loc(x=1);
print objv[l='The Max profit'], 
      (key[idx])[l='Combination'],
      (area[idx][+])[l='Total area consumed'],
      rc[l='0 is integer optimal.'] ;

quit;

 

OUTPUT:

The Max profit
525
Combination
M1 1
M1 2
M1 3
M3 5
Total area consumed
544
0 is integer optimal.
0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BTW, total  and area is reversing their position ?

data have ;
input machine $ count area total ;
cards;
M1 1 50 35
M1 2 100 43
M1 3 150 51
M2 6 50 740
M2 7 140 850
M2 8 160 910
M2 9 180 950
M3 3 135 225
M3 4 180 350
M3 5 225 415
M3 6 270 485
M3 7 315 550
;
run;

proc iml;
use have;
read all var {machine count total area};
close;
object = total`;
coef = area`;
b = 600;
rowsense = {L};
cntl = -1;
call milpsolve(rc,objv,x,relgap,object,coef,b,cntl,,rowsense);

key=catx(' ',machine,count);
idx=loc(x=1);
print objv[l='The Max profit'], 
      (key[idx])[l='Combination'],
      (area[idx][+])[l='Total area consumed'],
      rc[l='0 is integer optimal.'] ;

quit;

OUTPUT:

The Max profit
3485
Combination
M1 1
M2 6
M2 7
M2 8
M2 9
Total area consumed
580
0 is integer optimal.
0
Tj_chua
Obsidian | Level 7

Hi @Ksharp,

 

Aprreciate the help Smiley Happy  but

 

1) there can should only be 1 final count for each machine type ( M1 , M2, M3   ).

 

for this case there are 3x4x5 possible combinations.

M1 from 1 to 3, M2 from 6 to 9 and M3 3 to 7.

 

M1 M2 M3

1    6    3

1    6    4

.

.

to

.

.

3   9   7

 

so we want to pick the one with the highest total profit with minum Area used.

 

 

2) I see IML might be able to solve this, unfortunately enough as of I checking we dont have IML license. will try looking at the university edition

 

3) oh right thanks for spotting area and profit labes were of let me just edit that quickly.

Ksharp
Super User

Of Course. You can . Downloading SAS University Edition . It is totally free.

 

data have ;
input machine $ count area total ;
cards;
M1 1 50 35
M1 2 100 43
M1 3 150 51
M2 6 50 740
M2 7 140 850
M2 8 160 910
M2 9 180 950
M3 3 135 225
M3 4 180 350
M3 5 225 415
M3 6 270 485
M3 7 315 550
;
run;

proc iml;
use have;
read all var {machine count total area};
close;
object = total`;
c1=(machine='M1');
c2=(machine='M2');
c3=(machine='M3');
coef = c1`//c2`//c3`//area`;
b = {1,1,1,600};
rowsense = {E,E,E,L};
cntl = -1;
call milpsolve(rc,objv,x,relgap,object,coef,b,cntl,,rowsense);

key=catx(' ',machine,count);
idx=loc(x=1);
print objv[l='The Max profit'], 
      (key[idx])[l='Combination'],
      (area[idx][+])[l='Total area consumed'],
      rc[l='0 is integer optimal.'] ;

quit;

OUTPUT:

The Max profit
1543
Combination
M1 2
M2 9
M3 7
Total area consumed
595
0 is integer optimal.
0
Ksharp
Super User

Use this code , No matter how many levels there are in MACHINE variable.

 

data have ;
input machine $ count area total ;
cards;
M1 1 50 35
M1 2 100 43
M1 3 150 51
M2 6 50 740
M2 7 140 850
M2 8 160 910
M2 9 180 950
M3 3 135 225
M3 4 180 350
M3 5 225 415
M3 6 270 485
M3 7 315 550
;
run;

proc iml;
use have;
read all var {machine count total area};
close;

object = total`;

level=unique(machine); 
c=j(ncol(level),nrow(machine));
do i=1 to ncol(level);
 c[i,]=t(machine=level[i]);
end;
coef = c//area`;

b=j(ncol(level),1);
b = b//{600};

rowsense=j(ncol(level),1,'E');;
rowsense = rowsense//{L};

cntl = -1;
call milpsolve(rc,objv,x,relgap,object,coef,b,cntl,,rowsense);

key=catx(' ',machine,count);
idx=loc(x=1);
print objv[l='The Max profit'], 
      (key[idx])[l='Combination'],
      (area[idx][+])[l='Total area consumed'],
      rc[l='0 is integer optimal.'] ;

quit;
Tj_chua
Obsidian | Level 7

Thanks so much @Ksharp. unfortunately we might have some intallation restrictions so i am unable use IML to use it for the time being.

 

still hope someone may show me how to do it in proc optmodel.

RobPratt
SAS Super FREQ

Here it is in PROC OPTMODEL:

 

proc optmodel;
set <str,num> MACHINE_COUNT;
num area {MACHINE_COUNT};
num profit {MACHINE_COUNT};
read data have into MACHINE_COUNT=[machine count] area profit=total;
set MACHINES = setof {<m,c> in MACHINE_COUNT} m;

var IsMachineCount {MACHINE_COUNT} binary;
max TotalProfit = sum {<m,c> in MACHINE_COUNT} profit[m,c]*IsMachineCount[m,c];
con OneCountPerMachine {m in MACHINES}:
sum {<(m),c> in MACHINE_COUNT} IsMachineCount[m,c] = 1;
con AreaBudget:
sum {<m,c> in MACHINE_COUNT} area[m,c]*IsMachineCount[m,c] <= 600;

solve;
for {<m,c> in MACHINE_COUNT: IsMachineCount[m,c].sol > 0.5}
put m c area[m,c] profit[m,c];
quit;

 

M1 2 100 43
M2 9 180 950
M3 7 315 550

Tj_chua
Obsidian | Level 7

Hi @RobPratt,

thank you so much. just quick question

 

IsMachineCount[m,c].sol mean the solution? and what is the .5 for?

 

how does it handle events of more than 1 optimal solution?can it give us the one with min area utilized for more than 1 solution?

 

Thanks again!

RobPratt
SAS Super FREQ

Yes, the .SOL suffix accesses the solution.  The comparison to 0.5 is a safe way to pick up the variables that take value 1 (instead of 0) in the solution.

 

If there is more than one optimal solution, the MILP solver returns just the first one it finds.  One way to find all optimal solutions is to use the CLP solver with the FINDALLSOLNS option:

   solve with CLP / findallsolns;
   for {s in 1.._NSOL_} do;
      put s=;
      for {<m,c> in MACHINE_COUNT: IsMachineCount[m,c].sol[s] > 0.5}
         put m c area[m,c] profit[m,c];
   end;

For the sample data, there is only one optimal solution.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

Multiple Linear Regression in SAS

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.

Discussion stats
  • 8 replies
  • 2006 views
  • 6 likes
  • 3 in conversation