SAS Optimization, and SAS Simulation Studio

turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

Topic Options

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

11-30-2016 01:43 AM

Dear SAS community members,

I need some help in below code. i wrote below code to solve a facility location problem but the result differs from the one i get from Excel solver. Could you please help explaining what is the wrong in the below code:

proc optmodel;

set DC = {'BO','NA','PR','SP','WO'};

set City = {'BO','BR','CO','HA','MN','NA','NH','NL','PO','PR','SP','WO'};

number transoprtationcost {DC,City} = [

0 37 42 82 34

93 65 106 59 68

69 33 105 101 72

98 103 73 27 66

55 20 92 93 60

37 0 72 79 41

128 137 94 63 98

95 113 57 57 71

62 48 104 127 85

42 72 0 68 38

82 79 68 0 47

34 41 38 47 0

];

number fixedcost {DC}=[10000 10000 10000 10000 10000];

number demand {City}=[425 12 43 125 110 86 129 28 66 320 220 182];

number supply {DC}=[2000 2000 2000 2000 2000];

number M= 1000000000;

var X{DC,City} integer >=0;

var Y{DC} binary;

min totalcost = sum {d in DC, c in City}

X[d,c]*transoprtationcost[d,c]+sum{d in DC}Y[d]*fixedcost[d];

con supplycons {d in DC}:sum{c in City} X[d,c]<=supply[d];

con demandcons {c in City}:sum{d in DC} X[d,c]>=demand[c];

con conserv {d in DC, c in City}:X[d,c]-M*Y[d]<=0;

con numberofDC:sum {d in DC} Y[d]=1;

solve;

print X Y totalcost;

Quit;

Regards,

Ahmed Taher;

Accepted Solutions

Solution

11-30-2016
06:00 AM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to ahmedtaher900

11-30-2016 05:58 AM

Dear All,

after a lot of tries finally i got the right soultion for this problem which will be as follows:

proc optmodel;

set DC = {'BO','NA','PR','SP','WO'};

set City = {'BO','BR','CO','HA','MN','NA','NH','NL','PO','PR','SP','WO'};

number transoprtationcost {DC,City} = [

0 93 69 98 55 37 128 95 62 42 82 34

37 65 33 103 20 0 137 113 48 72 79 41

42 106 105 73 92 72 94 57 104 0 68 38

82 59 101 27 93 79 63 57 127 68 0 47

34 68 72 66 60 41 98 71 85 38 47 0

];

number fixedcost {DC}=[10000 10000 10000 10000 10000];

number demand {City}=[425 12 43 125 110 86 129 28 66 320 220 182];

number supply {DC}=[1746 1746 1746 1746 1746];

number M= 100000;

var X{DC,City} integer >=0;

var Y{DC} binary;

minimize totalcost = sum {d in DC}sum{c in City}

X[d,c]*transoprtationcost[d,c]+sum{n in DC}fixedcost[n]*Y[n];

con supplycons {d in DC}:sum{c in City} X[d,c]<=supply[d];

con demandcons {c in City}:sum{d in DC} X[d,c]>=demand[c];

con conserv {d in DC, c in City}:X[d,c]-M*Y[d]<=0;

/*con numberofDC:sum {d in DC} Y[d]=1;*/

solve;

print X totalcost;

Quit;

All Replies

Solution

11-30-2016
06:00 AM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to ahmedtaher900

11-30-2016 05:58 AM

Dear All,

after a lot of tries finally i got the right soultion for this problem which will be as follows:

proc optmodel;

set DC = {'BO','NA','PR','SP','WO'};

set City = {'BO','BR','CO','HA','MN','NA','NH','NL','PO','PR','SP','WO'};

number transoprtationcost {DC,City} = [

0 93 69 98 55 37 128 95 62 42 82 34

37 65 33 103 20 0 137 113 48 72 79 41

42 106 105 73 92 72 94 57 104 0 68 38

82 59 101 27 93 79 63 57 127 68 0 47

34 68 72 66 60 41 98 71 85 38 47 0

];

number fixedcost {DC}=[10000 10000 10000 10000 10000];

number demand {City}=[425 12 43 125 110 86 129 28 66 320 220 182];

number supply {DC}=[1746 1746 1746 1746 1746];

number M= 100000;

var X{DC,City} integer >=0;

var Y{DC} binary;

minimize totalcost = sum {d in DC}sum{c in City}

X[d,c]*transoprtationcost[d,c]+sum{n in DC}fixedcost[n]*Y[n];

con supplycons {d in DC}:sum{c in City} X[d,c]<=supply[d];

con demandcons {c in City}:sum{d in DC} X[d,c]>=demand[c];

con conserv {d in DC, c in City}:X[d,c]-M*Y[d]<=0;

/*con numberofDC:sum {d in DC} Y[d]=1;*/

solve;

print X totalcost;

Quit;

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to ahmedtaher900

11-30-2016 01:53 PM

I have a couple of suggestions for improvement.

1. An arbitrarily large value like 100000 for M can cause numerical difficulties for optimization solvers. In this case, the supplycons constraint implies that X[d,c] <= supply[d], so you can instead use the following tighter constraint:

```
con conserv {d in DC, c in City}:X[d,c]-supply[d]*Y[d]<=0;
```

2. You can in fact avoid the conserv constraint altogether if you tighten the supplycons constraint as follows:

```
con supplycons {d in DC}:sum{c in City} X[d,c]<=supply[d]*Y[d];
```

The resulting model (without conserv and with the new supplycons) is tighter, smaller, and more numerically stable. For your small instance, even the original model solves quickly. But these best practices can make a big difference for larger instances.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to RobPratt

01-04-2017 02:42 PM

Dear Rob,

First of all happy new year.

I have a question regarding the above code I was asking how to add a constraints or a logical link to this code that force the source to ship only quantities that are divided by 5.

Regards,

Thanks

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to ahmedtaher900

01-04-2017 03:12 PM - edited 01-04-2017 03:13 PM

Do you want each X[d,c] to be a multiple of 5, or sum{c in City} X[d,c] to be a multiple of 5 for each d, or something else?

In any case, you can introduce a family of integer variables Z[] and constraints that force the expression to equal 5*Z[].

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to ahmedtaher900

01-04-2017 03:30 PM

Thanks a lot for your quick reply, however I didn't get the point. Would you please give me more explanation? For your question to be more clear in my question I want each X[d,c] to be a multiple of 5

Regards,

Ahmed Taher

Regards,

Ahmed Taher

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to ahmedtaher900

01-04-2017 03:39 PM

```
var Z{DC,City} integer >= 0;
con Five {d in DC, c in City}:
X[d,c] = 5*Z[d,c];
```

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to RobPratt

01-05-2017 01:36 AM

Thanks a lot Man. You are the hero of these communities.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to ahmedtaher900

01-05-2017 09:55 AM

Glad to help. By the way, here is an alternative approach that declares X as an implicit variable instead:

```
/*var X{DC,City} integer >=0;*/
var Z{DC,City} integer >= 0;
/*con Five {d in DC, c in City}:*/
/* X[d,c] = 5*Z[d,c];*/
impvar X {d in DC, c in City} = 5*Z[d,c];
```

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to RobPratt

01-17-2017 07:47 AM

I need your help again in the below code. my issue is that i know the logical thinking of how to solve the issue so I know the how to solve it mathematically but since I'm not that godd in SAS programming I am asking for you kind help in programming. in the below code

I want to add constraint that says that I need __ DC 1 and DC 2 are open by default__ , and I need the optimization to choose the best DC from

also I want to add a level of service constraint that says 75% of demand should be within 50 miles of a DC and the max average distance from a DC is <= 60 mile.

Your help is always appreciated.

Proc optmodel; set Plants = {'Plant 1','Contractor'}; set CentralWH = {'DC 1', 'DC 2', 'Potential DC 3', 'Potential DC 4', 'Potential DC 5'}; set RegionalWH = {'SO 1','SO 2','SO 3','SO 4','SO 5','SO 6','SO 7','SO 8'}; number outbounddist {Plants,CentralWH} = [ 77 48 41 57 94 54 33 21 94 44 ]; number inbounddist {CentralWH,RegionalWH} = [ 62 55 114 106 51 76 122 80 63 92 90 50 88 47 136 47 76 85 56 65 129 40 89 100 42 128 74 70 45 56 81 131 77 135 118 59 124 93 41 94 ]; number fixedcostWH {CentralWH} = [100 100 80 70 60]; number varcostWH {CentralWH} = [10 10 25 30 50]; number varcostplant {Plants} = [10 50]; number Demand {RegionalWH} = [121 96 166 175 210 130 180 160]; number Supply {Plants} = [1250 200]; var X {Plants,CentralWH} integer >=0; var Z {CentralWH,RegionalWH} integer >=0; var Y {CentralWH} binary; min totalcost = sum {p in Plants,c in CentralWH} X[p,c]*1.5*outbounddist[p,c]+ sum {p in Plants,c in CentralWH} X[p,c]*varcostplant[p]+ sum {c in CentralWH,r in RegionalWH} Z[c,r]*1*inbounddist[c,r]+ sum {c in CentralWH,r in RegionalWH} Z[c,r]*varcostWH[c]+ sum {c in CentralWH} Y[c]*fixedcostWH[c]; con supplycons {p in Plants}: sum {c in CentralWH} X[p,c]<=Supply[p]; /*con supplycons1{p in Plants}: sum {c in CentralWH} X[p,'DC 1']>=1;*/ /*con supplycons2{p in Plants}: sum {c in CentralWH} X[p,'DC 2']>=1;*/ con demandcons {r in RegionalWH}: sum {c in CentralWH} Z[c,r]>=Demand[r]; con nonstock {c in CentralWH}: sum {p in Plants}X[p,c]-sum {r in RegionalWH}Z[c,r]=0; con conserva {p in Plants,c in CentralWH}:X[p,c]-Y[c]*Supply[p]<=0; con numberofDC : sum {c in CentralWH} Y[c]>=1; solve; print X Y Z totalcost; quit;

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to ahmedtaher900

01-17-2017 09:15 AM

Sorry man for a lot of question.

Also i want to ask what if i want to add a constraint says that in case of demand shortage there will be a penality of X$ will be charged to the plants for each item shortage.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to ahmedtaher900

01-20-2017 10:12 AM

To force DC 1 and DC 2 to be open, you can declare a constraint:

```
con FixOpen {c in {'DC 1','DC 2'}}:
Y[c] = 1;
```

Or use the FIX statement:

```
for {c in {'DC 1','DC 2'}}
fix Y[c] = 1;
```

To force exactly one potential DC to be open:

```
con ExactlyOnePotentialOpen:
sum {c in {'Potential DC 3','Potential DC 4','Potential DC 5'}} Y[c] = 1;
```

Alternatively, you can scan for 'Potential' as the first word in the name:

```
con ExactlyOnePotentialOpen:
sum {c in CentralWH: scan(c,1) = 'Potential'} Y[c] = 1;
```

For the other constraints you want, can you please write out the mathematical expressions? The benefit of an optimization modeling language is that the corresponding constraint declarations will look very similar to the mathematics.