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

I am trying to solve an integer nonlinear problem like this:

  • There are five providers (p1, p2, .. p5), at three locations (g, s, t), seeing patients with 2 different types of visits: office visits and video visits.
  • For the next 10 business days, at each location, the demand for these two types of visits are:

 

location g

location s

location t

Office Visit

80

70

90

Video Visit

25

31

27

  • For each provider, they can have as many as 7 office visits, and 3 video visits per day.
  • For each provider, they can work no more than 6 days within the next 10 business days.

 

I am trying to see how to allocate these providers in these locations, to meet the demand most.

 

Here are my codes, and I have 15 variables, represent the number of days for each provider to stay in one location for the next 10 days. For example, p1g means the number of days that provider p1 at location g.

 

proc optmodel;
var p1g<=6 >=0 , p2g<=6>=0, p3g<=6>=0, p4g<=6>=0, p5g<=6>=0 integer;
var p1s<=6>=0, p2s<=6>=0, p3s<=6>=0 ,p4s<=6>=0, p5s<=6>=0 integer;
var p1t<=6>=0,  p2t<=6>=0, p3t<=6>=0, p4t<=6>=0, p5t<=6>=0 integer;

/* declare objective */
impvar OfficeVisit=min(7*(p1g+p2g+p3g+p4g+p5g),80)
  +min(7*(p1s+p2s+p3s+p4s+p5s),70)
  +min(7*(p1t+p2t+p3t+p4t+p5t),90);
impvar VideoVisit=min(3*(p1g+p2g+p3g+p4g+p5g),25)
  +min(3*(p1s+p2s+p3s+p4s+p5s),31)
  +min(3*(p1t+p2t+p3t+p4t+p5t),27);

/*declare constraints*/
con p1g +p1s +p1t<=6;
con p2g +p2s +p2t<=6;
con p3g +p3s +p3t<=6;
con p4g +p4s +p4t<=6;
con p5g +p5s +p5t<=6;

max bts = OfficeVisit + VideoVisit;
solve ;
print p1g p2g p3g p4g p5g p1s p2s p3s p4s p5s p1t p2t p3t p4t p5t;
quit;

1 ACCEPTED SOLUTION

Accepted Solutions
RobPratt
SAS Super FREQ

If you have SAS Viya, you can use the LINEARIZE option to automatically linearize the problem:

 

solve linearize;

 

 
Problem Summary
Objective Sense Maximization
Objective Function bts
Objective Type Nonlinear
   
Number of Variables 15
Bounded Above 0
Bounded Below 0
Bounded Below and Above 15
Free 0
Fixed 0
Binary 0
Integer 3
   
Number of Constraints 5
Linear LE (<=) 5
Linear EQ (=) 0
Linear GE (>=) 0
Linear Range 0
   
Constraint Coefficients 15
 
Solution Summary
Solver MILP
Algorithm Branch and Cut
Objective Function bts
Solution Status Optimal
Objective Value 292
   
Relative Gap 0
Absolute Gap 0
Primal Infeasibility 0
Bound Infeasibility 0
Integer Infeasibility 0
   
Best Bound 292
Nodes 1
Solutions Found 3
Iterations 10
Presolve Time 0.03
Solution Time 0.04


p1g p2g p3g p4g p5g p1s p2s p3s p4s p5s p1t p2t p3t p4t p5t
1.25 1.25 1.25 1.25 6 2.5 2.5 2.5 2.5 0 2.25 2.25 2.25 2.25 0

 

 

But notice that some variables are fractional.  That is because the INTEGER keyword applies only to three of the variables in your VAR statements.  What you intended was instead:

var p1g<=6>=0 integer, p2g<=6>=0 integer, p3g<=6>=0 integer, p4g<=6>=0 integer, p5g<=6>=0 integer;
var p1s<=6>=0 integer, p2s<=6>=0 integer, p3s<=6>=0 integer, p4s<=6>=0 integer, p5s<=6>=0 integer;
var p1t<=6>=0 integer, p2t<=6>=0 integer, p3t<=6>=0 integer, p4t<=6>=0 integer, p5t<=6>=0 integer;

And this yields integer values for all variables:

p1g p2g p3g p4g p5g p1s p2s p3s p4s p5s p1t p2t p3t p4t p5t
6 2 0 0 3 0 4 0 6 0 0 0 6 0 3

 

A more compact and less error-prone approach is to use index sets:

proc optmodel;
   set PROVIDERS = 1..5;
   set LOCATIONS = /g s t/;
   var NumDays {PROVIDERS, LOCATIONS} >= 0 <= 6 integer;

   /* declare objective */
   num officeDemand {LOCATIONS} = [80, 70, 90];
   impvar OfficeVisit = sum {l in LOCATIONS} min(7*sum {p in PROVIDERS} NumDays[p,l], officeDemand[l]);
   num videoDemand {LOCATIONS} = [25, 31, 27];
   impvar VideoVisit = sum {l in LOCATIONS} min(3*sum {p in PROVIDERS} NumDays[p,l], videoDemand[l]);

   /*declare constraints*/
   con ProviderLimit {p in PROVIDERS}: sum {l in LOCATIONS} NumDays[p,l] <= 6;

   max bts = OfficeVisit + VideoVisit;
   solve linearize;
   print NumDays;
quit;

 

NumDays
  g s t
1 6 0 0
2 2 4 0
3 0 0 6
4 0 6 0
5 3 0 3

View solution in original post

2 REPLIES 2
RobPratt
SAS Super FREQ

If you have SAS Viya, you can use the LINEARIZE option to automatically linearize the problem:

 

solve linearize;

 

 
Problem Summary
Objective Sense Maximization
Objective Function bts
Objective Type Nonlinear
   
Number of Variables 15
Bounded Above 0
Bounded Below 0
Bounded Below and Above 15
Free 0
Fixed 0
Binary 0
Integer 3
   
Number of Constraints 5
Linear LE (<=) 5
Linear EQ (=) 0
Linear GE (>=) 0
Linear Range 0
   
Constraint Coefficients 15
 
Solution Summary
Solver MILP
Algorithm Branch and Cut
Objective Function bts
Solution Status Optimal
Objective Value 292
   
Relative Gap 0
Absolute Gap 0
Primal Infeasibility 0
Bound Infeasibility 0
Integer Infeasibility 0
   
Best Bound 292
Nodes 1
Solutions Found 3
Iterations 10
Presolve Time 0.03
Solution Time 0.04


p1g p2g p3g p4g p5g p1s p2s p3s p4s p5s p1t p2t p3t p4t p5t
1.25 1.25 1.25 1.25 6 2.5 2.5 2.5 2.5 0 2.25 2.25 2.25 2.25 0

 

 

But notice that some variables are fractional.  That is because the INTEGER keyword applies only to three of the variables in your VAR statements.  What you intended was instead:

var p1g<=6>=0 integer, p2g<=6>=0 integer, p3g<=6>=0 integer, p4g<=6>=0 integer, p5g<=6>=0 integer;
var p1s<=6>=0 integer, p2s<=6>=0 integer, p3s<=6>=0 integer, p4s<=6>=0 integer, p5s<=6>=0 integer;
var p1t<=6>=0 integer, p2t<=6>=0 integer, p3t<=6>=0 integer, p4t<=6>=0 integer, p5t<=6>=0 integer;

And this yields integer values for all variables:

p1g p2g p3g p4g p5g p1s p2s p3s p4s p5s p1t p2t p3t p4t p5t
6 2 0 0 3 0 4 0 6 0 0 0 6 0 3

 

A more compact and less error-prone approach is to use index sets:

proc optmodel;
   set PROVIDERS = 1..5;
   set LOCATIONS = /g s t/;
   var NumDays {PROVIDERS, LOCATIONS} >= 0 <= 6 integer;

   /* declare objective */
   num officeDemand {LOCATIONS} = [80, 70, 90];
   impvar OfficeVisit = sum {l in LOCATIONS} min(7*sum {p in PROVIDERS} NumDays[p,l], officeDemand[l]);
   num videoDemand {LOCATIONS} = [25, 31, 27];
   impvar VideoVisit = sum {l in LOCATIONS} min(3*sum {p in PROVIDERS} NumDays[p,l], videoDemand[l]);

   /*declare constraints*/
   con ProviderLimit {p in PROVIDERS}: sum {l in LOCATIONS} NumDays[p,l] <= 6;

   max bts = OfficeVisit + VideoVisit;
   solve linearize;
   print NumDays;
quit;

 

NumDays
  g s t
1 6 0 0
2 2 4 0
3 0 0 6
4 0 6 0
5 3 0 3
claridad123
Fluorite | Level 6

@RobPratt thank you so much. I don't have Viya but "solve with LSO" works after I add 'INTEGER' keyword to all variables.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 2 replies
  • 447 views
  • 1 like
  • 2 in conversation