Turn on suggestions

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

Showing results for

Options

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

🔒 This topic is **solved** and **locked**.
Need further help from the community? Please
sign in and ask a **new** question.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Posted 03-20-2020 01:30 PM
(967 views)

Rob.

This NLP from the old thread worked fine. It gave me 1 solution with latitude and longitude. Here is the code:

set DIMS=1..2;

set <str> CUSTOMERS;

read data STDOPT.COGModelingData into CUSTOMERS=[Sitename];

num demand {CUSTOMERS};

read data STDOPT.COGModelingData into [Sitename] Demand=SiteParameter1;

NUM Latitude {CUSTOMERS};

read data STDOPT.COGModelingData into [Sitename] Latitude=SiteLatitude;

NUM Longitude {CUSTOMERS};

read data STDOPT.COGModelingData into [Sitename] Longitude=SiteLongitude;

var X {DIMS};

min Z = sum {i in CUSTOMERS} demand[i]*GEODIST(Latitude[i],Longitude[i],X[1],X[2]);

solve;

print X;

I want to expand the logic so that the model gives me "p" number of possible facilities. I am thinking of the logic below. We need to minimize the weighted distance from "p" points to all customers.So, Here is what I did and I know that this is not correct. Your insight would be helpful. set p=1..3; (meaning to say how many sites I want model to find out as answer): here is my code /logic below.

var X {DIMS,p}; -- am sure this is not the right way.

min Z = sum {i in CUSTOMERS,p} demand[i]*GEODIST(Latitude[i],Longitude[i],X[1,p],X[2,p]);

solve; print X;

Also, should we not make sure by way of constraint to make sure the model finds exactly "p" answers.?

1 ACCEPTED SOLUTION

Accepted Solutions

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Rob.

The read data statement reads the lat and lon and demand.

I have few columns like SiteState, SiteBusiness etc that I want to use it for my outputs. I understand that this is not needed for the proc optmodel. So the question is , is it good to create columns in the "create data" step like sitestate, SiteBusines and update it using lat, lon and demand from the original table. But there could be 2 sites with same lat, lon and demand but only thing that is different could be it could be different SiteBusiness. What would you recommend?

6 REPLIES 6

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Here is code to solve the multisource Weber problem, where m is the number of facilities. It is based on the code I posted in the other thread, but you can modify as needed for your data and distance function. Because the multisource problem is nonconvex, I used the multistart option for the NLP solver and also added optional code to post-process the solution to make further local improvements.

```
%let m = 3;
proc optmodel;
set DIMS = 1..2;
set CUSTOMERS;
set FACILITIES = 1..&m;
num a {CUSTOMERS, DIMS};
num demand {CUSTOMERS};
read data cdata into CUSTOMERS=[_N_] {d in DIMS} <a[_N_,d]=col('a'||d)> demand;
num Xlb {d in DIMS} = min {i in CUSTOMERS} a[i,d];
num Xub {d in DIMS} = max {i in CUSTOMERS} a[i,d];
var X {FACILITIES, d in DIMS} >= Xlb[d] <= Xub[d];
var W {CUSTOMERS, FACILITIES} >= 0;
impvar Distance {i in CUSTOMERS, j in FACILITIES} =
sqrt(sum {d in DIMS}(a[i,d]-X[j,d])^2);
min Z = sum {i in CUSTOMERS, j in FACILITIES} W[i,j]*Distance[i,j];
con DemandCon {i in CUSTOMERS}:
sum {j in FACILITIES} W[i,j] = demand[i];
solve with nlp / ms;
print X;
put _OBJ_=;
/* post-processing: assign each customer to closest facility */
set CUSTOMERS_j {FACILITIES} init {};
num minDistance, argminDistance;
for {i in CUSTOMERS} do;
minDistance = constant('BIG');
argminDistance = .;
for {j in FACILITIES} do;
if minDistance > Distance[i,j] then do;
minDistance = Distance[i,j];
argminDistance = j;
end;
end;
for {j in FACILITIES} W[i,j] = 0;
W[i,argminDistance] = demand[i];
CUSTOMERS_j[argminDistance] = CUSTOMERS_j[argminDistance] union {i};
end;
put _OBJ_=;
/* post-processing: solve each facility separately */
min SingleFacilityObjective {j in FACILITIES} =
sum {i in CUSTOMERS_j[j]} demand[i]*Distance[i,j];
problem SingleFacilityProblem {j in FACILITIES} include
{d in DIMS} X[j,d]
SingleFacilityObjective[j];
for {j in FACILITIES} do;
put j=;
use problem SingleFacilityProblem[j];
solve;
end;
put (sum {j in FACILITIES} SingleFacilityObjective[j])=;
print X;
create data Xdata from [j]=FACILITIES {d in DIMS} <col('X'||d)=X[j,d].sol>;
create data assignments from [j i]={j in FACILITIES, i in CUSTOMERS_j[j]} W[i,j]
x1=a[i,1] y1=a[i,2] x2=X[j,1] y2=X[j,2];
quit;
proc sgplot data=assignments;
vector x=x2 y=y2 / xorigin=x1 yorigin=y1 group=j;
run;
```

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Rob.

Thank you once again. I will look into it and will understand completely.

you are awesome

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Rob.

The read data statement reads the lat and lon and demand.

I have few columns like SiteState, SiteBusiness etc that I want to use it for my outputs. I understand that this is not needed for the proc optmodel. So the question is , is it good to create columns in the "create data" step like sitestate, SiteBusines and update it using lat, lon and demand from the original table. But there could be 2 sites with same lat, lon and demand but only thing that is different could be it could be different SiteBusiness. What would you recommend?

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

You have this code:

set <str> CUSTOMERS;

read data STDOPT.COGModelingData into CUSTOMERS=[Sitename];

num demand {CUSTOMERS};

read data STDOPT.COGModelingData into [Sitename] Demand=SiteParameter1;

NUM Latitude {CUSTOMERS};

read data STDOPT.COGModelingData into [Sitename] Latitude=SiteLatitude;

NUM Longitude {CUSTOMERS};

read data STDOPT.COGModelingData into [Sitename] Longitude=SiteLongitude;

It would be simpler to use one READ DATA statement:

set <str> CUSTOMERS;

num demand {CUSTOMERS};

NUM Latitude {CUSTOMERS};

NUM Longitude {CUSTOMERS};

read data STDOPT.COGModelingData into CUSTOMERS=[Sitename]

Demand=SiteParameter1 Latitude=SiteLatitude Longitude=SiteLongitude;

If you have additional customer attributes, you can declare them as additional (string or numeric) parameters:

```
str SiteState {CUSTOMERS};
str SiteBusiness {CUSTOMERS};
```

You can then populate these parameters however you want and use them in a CREATE DATA statement. Alternatively, you can populate the value of a column by evaluating an expression in the CREATE DATA statement itself, without explicitly declaring new parameters, as demonstrated in the documentation.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Rob

THANK YOU. it worked.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

**SAS Innovate 2025** is scheduled for May 6-9 in Orlando, FL. Sign up to be **first to learn** about the agenda and registration!

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.