## distance in weber multisource

Rob:

here is the code that you had. i am having 2 questions (a) in the create data step, i was trying various options to print the distance between the customer and its assigned facility. One of the example, is fro Miami to Newark, where the distance should have been 1,268 (miles) but it gave me 3,493. I used Distance[i,j] to come up with this number. I also tried using GEODIST to calculate the distance between the final X and customers but it did not work either. (b) Is there a way to specify to the model to pick a facility that is no more than 500 miles  or any prefixed number. I was thinking to have this constraint like this in NLP :- con radius{i in CUSTOMERS, j in FACILITIES}: Distance[i,j] <= 500;

Will that be ok. I ran the model but it gave me same result as without the constraint "radius"

``````%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;``````

i

1 ACCEPTED SOLUTION

Accepted Solutions

## Re: distance in weber multisource

You should not sum over DIMS.  That was for the Euclidean distance.  Also, the default units for GEODIST are kilometers.  To get miles instead, use the 'M' option.

5 REPLIES 5

## Re: distance in weber multisource

Please provide the code you used, especially the declaration of Distance and the CREATE DATA statement.

The radius constraint you suggested looks correct but won't yield the results you want if the Distance calculation is wrong.  A more efficient approach is to use sparse modeling.

## Re: distance in weber multisource

Rob

Thank you. I will do sparse modeling.

Here is the code:

impvar Distance {i in CUSTOMERS, j in FACILITIES} = sum{d in DIMS} GEODIST(a[i,1],a[i,2],X[j,1],X[j,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];
con radius{i in CUSTOMERS, j in FACILITIES}: Distance[i,j] <= 500;
solve with nlp / ms=(maxtime=10) timetype=real;
**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 STDOPT.WinnersCOG from [j]=FACILITIES {d in DIMS} <col('X'||d)=X[j,d].sol>;

create data STDOPT.COG_Output from [j i]={j in FACILITIES, i in CUSTOMERS_j[j]} W[i,j]
Cust_Lat=a[i,1] Cust_Lon=a[i,2] Fac_Lat=X[j,1] Fac_Lon=X[j,2] Distance[i,j]
SiteState=SiteState[i] SiteRegion=SiteRegion[i] SiteComment1=SiteComment1[i];

quit;

## Re: distance in weber multisource

Please let me know if my distance calculation is not correct.

## Re: distance in weber multisource

You should not sum over DIMS.  That was for the Euclidean distance.  Also, the default units for GEODIST are kilometers.  To get miles instead, use the 'M' option.

## Re: distance in weber multisource

perfect .it worked. thank you rob.

for the constraint radius, let me do that and get back to you next week about how it went. thank u for everything

Discussion stats
• 5 replies
• 442 views
• 1 like
• 2 in conversation