<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Optimize Traveling Distance in Mathematical Optimization, Discrete-Event Simulation, and OR</title>
    <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309103#M1492</link>
    <description>&lt;P&gt;Thanks for your reply. If i ain't wrong ZIPCITYDISTANCE function works only for US postcodes. Anyway, i&amp;nbsp;have measured the distance between locations by calculating Eucledian distance of the (x y) coordinates. I need to know how to use PROC OPTMODEL&amp;nbsp;to solve this problem. Since it's an urgent request, any help would be highly appreciated.&lt;/P&gt;</description>
    <pubDate>Thu, 03 Nov 2016 18:04:26 GMT</pubDate>
    <dc:creator>Ujjawal</dc:creator>
    <dc:date>2016-11-03T18:04:26Z</dc:date>
    <item>
      <title>Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/308817#M1489</link>
      <description>&lt;P&gt;Hi Experts,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I need to minimize distance to customer location from Portfolio Managers' location. I have the following customer table-&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;TABLE width="260"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="93"&gt;Customers&lt;/TD&gt;
&lt;TD width="74"&gt;Postcode&lt;/TD&gt;
&lt;TD width="93"&gt;Sales&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Riya&lt;/TD&gt;
&lt;TD&gt;110051&lt;/TD&gt;
&lt;TD&gt;98&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Raj&lt;/TD&gt;
&lt;TD&gt;110007&lt;/TD&gt;
&lt;TD&gt;45&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Sam&lt;/TD&gt;
&lt;TD&gt;110032&lt;/TD&gt;
&lt;TD&gt;72&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Sompa&lt;/TD&gt;
&lt;TD&gt;110002&lt;/TD&gt;
&lt;TD&gt;31&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Predy&lt;/TD&gt;
&lt;TD&gt;110003&lt;/TD&gt;
&lt;TD&gt;48&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;David&lt;/TD&gt;
&lt;TD&gt;110005&lt;/TD&gt;
&lt;TD&gt;76&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The following is the table that has Portfolio Manager Information with Territory/Region.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;TABLE width="355"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="93"&gt;PM&lt;/TD&gt;
&lt;TD width="93"&gt;Position&lt;/TD&gt;
&lt;TD width="93"&gt;PM_Postcode&lt;/TD&gt;
&lt;TD width="76"&gt;Territory&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;A&lt;/TD&gt;
&lt;TD&gt;Manager&lt;/TD&gt;
&lt;TD&gt;110007&lt;/TD&gt;
&lt;TD&gt;NorthDelhi&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;B&lt;/TD&gt;
&lt;TD&gt;Analyst&lt;/TD&gt;
&lt;TD&gt;110051&lt;/TD&gt;
&lt;TD&gt;EastDelhi&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;C&lt;/TD&gt;
&lt;TD&gt;Manager&lt;/TD&gt;
&lt;TD&gt;110032&lt;/TD&gt;
&lt;TD&gt;EastDelhi&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;D&lt;/TD&gt;
&lt;TD&gt;Analyst&lt;/TD&gt;
&lt;TD&gt;110003&lt;/TD&gt;
&lt;TD&gt;NorthDelhi&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;There are some constraints - If sale is greater than 50, the customer should be handled by PM who is Manager. Otherwise Analyst. Within each territory, there is a constraint that manager can only handle up to 3&amp;nbsp;customers and analyst only up to 5 customers. I am sorry for a very short sample data to work on this problem. I hope the problem makes sense. I am very new to PROC OPTMODEL so it would be highly appreciated if you could provide the solution with example. Thanks in anticipation!&lt;/P&gt;</description>
      <pubDate>Wed, 02 Nov 2016 18:24:47 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/308817#M1489</guid>
      <dc:creator>Ujjawal</dc:creator>
      <dc:date>2016-11-02T18:24:47Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/308865#M1490</link>
      <description>&lt;P&gt;I presume your objective is, for each customer with over 50 sales, minimize distance to a manager, and for all other customers, to minimize distance to either analysit or manager.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I presume there are some customers in postal codes without analysts or managers.&amp;nbsp; In that case you can't solve this problem without having distances between&amp;nbsp;postal code.&amp;nbsp; Show that data too.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Also,&amp;nbsp;do any&amp;nbsp;postalcodes have&amp;nbsp;both a manager and an analyst?&amp;nbsp; If so, then how do you assign small customers?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 02 Nov 2016 19:53:11 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/308865#M1490</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2016-11-02T19:53:11Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/308939#M1491</link>
      <description>&lt;PRE&gt;
use function ZIPCITYDISTANCE(zip-code-1, zip-code-2)
could get the distance between two zip.

Your question is very tough. I would like to see how Rob could solve it by OR .

&lt;/PRE&gt;</description>
      <pubDate>Thu, 03 Nov 2016 05:57:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/308939#M1491</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2016-11-03T05:57:39Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309103#M1492</link>
      <description>&lt;P&gt;Thanks for your reply. If i ain't wrong ZIPCITYDISTANCE function works only for US postcodes. Anyway, i&amp;nbsp;have measured the distance between locations by calculating Eucledian distance of the (x y) coordinates. I need to know how to use PROC OPTMODEL&amp;nbsp;to solve this problem. Since it's an urgent request, any help would be highly appreciated.&lt;/P&gt;</description>
      <pubDate>Thu, 03 Nov 2016 18:04:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309103#M1492</guid>
      <dc:creator>Ujjawal</dc:creator>
      <dc:date>2016-11-03T18:04:26Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309166#M1494</link>
      <description>&lt;PRE&gt;
" Within each territory, there is a constraint that manager can only handle up to 3 customers and analyst only up to 5 customers."
I don't understand 'territory' . Why ? 'territory' has nothing to do with this constraint ?

Maybe I could use GA to get it, but as Rob mentioned before, OR might be your best choice.



&lt;/PRE&gt;</description>
      <pubDate>Fri, 04 Nov 2016 02:16:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309166#M1494</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2016-11-04T02:16:23Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309207#M1495</link>
      <description>&lt;P&gt;" Within each territory, there is a constraint that manager can only handle up to 3 customers and analyst only up to 5 customers." - I mean to say in each territory i need to maintain the ratio such that manager can serve max 3 customers whose sales or&amp;nbsp;turnover &amp;gt;= (x amount). And Analyst can serve max 5 customers whose sales or&amp;nbsp;turnover&amp;nbsp;&amp;lt; (x amount).&amp;nbsp;By territory, i mean 'Region / City'.&lt;/P&gt;</description>
      <pubDate>Fri, 04 Nov 2016 08:44:19 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309207#M1495</guid>
      <dc:creator>Ujjawal</dc:creator>
      <dc:date>2016-11-04T08:44:19Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309224#M1496</link>
      <description>That territory doesn't mean anything, just could say  manager can serve max 3 customers,and Analyst can serve max 5 customers  ?</description>
      <pubDate>Fri, 04 Nov 2016 10:41:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309224#M1496</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2016-11-04T10:41:54Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309243#M1497</link>
      <description>&lt;P&gt;OK. Here is IML code of GA.&lt;/P&gt;
&lt;P&gt;I also want see the OR code by&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/1636"&gt;@RobPratt﻿&lt;/a&gt;&amp;nbsp;,that might your best shoot.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you have big table GA can't guarantee you to get th optimal solution.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have1;
infile cards truncover expandtabs;
input Customers	$ Postcode $ sales x y;
cards;
Riya	110051	98 34 78 
Raj	110007	45 65 65
Sam	110032	72 78 34 
Sompa	110002	31 21 42
Predy	110003	48 47 78
David	110005	76 74 32
;
run;
 
data have2;
infile cards truncover expandtabs;
input PM $ Position $ PM_Postcode $ Territory : $20. x y;
cards;
A	Manager	110007	NorthDelhi 23 54
B	Analyst	110051	EastDelhi 34 45
C	Manager	110032	EastDelhi 56 56
D	Analyst	110003	NorthDelhi 43 88
;
run;

data customer;
 set have1;
 length position $ 10;
 if sales gt 50 then position='Manager';
  else position='Analyst';
run;
data pm;
 set have2;
 if position='Manager' then do;
  do i=1 to 3;
   output;
  end;
 end;
 else do;
  do i=1 to 5;
   output;
  end;
 end;
drop i;
run;

proc sort data=customer;by position;run;
proc sort data=pm;by position;run;

proc iml;
use customer nobs nobs1;
read all var{position};
read all var{x y} into xy_cust;
read all var _char_ into all1[c=vnames1];
close;
n=uniqueby(position);
need_analyst=n[2]-1;
need_manager=nobs1-n[2]+1;

use pm nobs nobs2;
read all var{position};
read all var{x y} into xy_pm;
read all var _char_ into all2[c=vnames2];
close;
n=uniqueby(position);
have_analyst=n[2]-1;
have_manager=nobs2-n[2]+1;

if nobs1&amp;gt;nobs2 then abort 'ERROR: too many customers.';

start func(x) 
global(have_analyst,have_manager,need_analyst,need_manager,xy_cust,xy_pm); 
t1=x[1:need_analyst];
t2=x[(need_analyst+1):(need_analyst+need_manager)];
if countunique(t1)^=need_analyst |  max(t1)&amp;gt;have_analyst |
   countunique(t2)^=need_manager |  min(t2)&amp;lt;(have_analyst+1)
 then obj=999999;
else obj=sum(abs((xy_pm[x,]-xy_cust)));
 return (obj);
finish;


n=need_analyst+need_manager;
encoding=repeat(1//have_analyst,1,need_analyst)||
repeat((have_analyst+1)//(have_analyst+have_manager),1,need_manager);


id=gasetup(2,n,12345678);
call gasetobj(id,0,"func");
call gasetcro(id,0.95,2);
call gasetmut(id,0.95,3);
call gasetsel(id,100,1,1);
call gainit(id,10000,encoding); 

niter = 1000;  /*change it as bigger as you can*/
do i = 1 to niter;
 call garegen(id);
 call gagetval(value, id);
end;
call gagetmem(mem, value, id, 1);

print value[l = "Min Distance Value:"],
      all1[l="" c=vnames1] (all2[mem,])[l="" c=vnames2] ;
call gaend(id);
quit;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;OUTPUT:&lt;/P&gt;
&lt;ARTICLE id="IDX"&gt;
&lt;TABLE class="table"&gt;&lt;COLGROUP&gt;&lt;COL /&gt;&lt;/COLGROUP&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TH class="c b header" scope="col"&gt;Min Distance Value:&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class="r data"&gt;196&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;/ARTICLE&gt;
&lt;ARTICLE id="IDX1"&gt;
&lt;TABLE class="table"&gt;&lt;COLGROUP&gt;&lt;COL /&gt;&lt;COL /&gt;&lt;COL /&gt;&lt;COL /&gt;&lt;COL /&gt;&lt;COL /&gt;&lt;COL /&gt;&lt;/COLGROUP&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TH class="b header" scope="col"&gt;Customers&lt;/TH&gt;
&lt;TH class="b header" scope="col"&gt;Postcode&lt;/TH&gt;
&lt;TH class="b header" scope="col"&gt;position&lt;/TH&gt;
&lt;TH class="b header" scope="col"&gt;PM&lt;/TH&gt;
&lt;TH class="b header" scope="col"&gt;Position&lt;/TH&gt;
&lt;TH class="b header" scope="col"&gt;PM_Postcode&lt;/TH&gt;
&lt;TH class="b header" scope="col"&gt;Territory&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class="data"&gt;Raj&lt;/TD&gt;
&lt;TD class="data"&gt;110007&lt;/TD&gt;
&lt;TD class="data"&gt;Analyst&lt;/TD&gt;
&lt;TD class="data"&gt;D&lt;/TD&gt;
&lt;TD class="data"&gt;Analyst&lt;/TD&gt;
&lt;TD class="data"&gt;110003&lt;/TD&gt;
&lt;TD class="data"&gt;NorthDelhi&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="data"&gt;Sompa&lt;/TD&gt;
&lt;TD class="data"&gt;110002&lt;/TD&gt;
&lt;TD class="data"&gt;Analyst&lt;/TD&gt;
&lt;TD class="data"&gt;B&lt;/TD&gt;
&lt;TD class="data"&gt;Analyst&lt;/TD&gt;
&lt;TD class="data"&gt;110051&lt;/TD&gt;
&lt;TD class="data"&gt;EastDelhi&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="data"&gt;Predy&lt;/TD&gt;
&lt;TD class="data"&gt;110003&lt;/TD&gt;
&lt;TD class="data"&gt;Analyst&lt;/TD&gt;
&lt;TD class="data"&gt;D&lt;/TD&gt;
&lt;TD class="data"&gt;Analyst&lt;/TD&gt;
&lt;TD class="data"&gt;110003&lt;/TD&gt;
&lt;TD class="data"&gt;NorthDelhi&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="data"&gt;Riya&lt;/TD&gt;
&lt;TD class="data"&gt;110051&lt;/TD&gt;
&lt;TD class="data"&gt;Manager&lt;/TD&gt;
&lt;TD class="data"&gt;A&lt;/TD&gt;
&lt;TD class="data"&gt;Manager&lt;/TD&gt;
&lt;TD class="data"&gt;110007&lt;/TD&gt;
&lt;TD class="data"&gt;NorthDelhi&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="data"&gt;Sam&lt;/TD&gt;
&lt;TD class="data"&gt;110032&lt;/TD&gt;
&lt;TD class="data"&gt;Manager&lt;/TD&gt;
&lt;TD class="data"&gt;C&lt;/TD&gt;
&lt;TD class="data"&gt;Manager&lt;/TD&gt;
&lt;TD class="data"&gt;110032&lt;/TD&gt;
&lt;TD class="data"&gt;EastDelhi&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="data"&gt;David&lt;/TD&gt;
&lt;TD class="data"&gt;110005&lt;/TD&gt;
&lt;TD class="data"&gt;Manager&lt;/TD&gt;
&lt;TD class="data"&gt;C&lt;/TD&gt;
&lt;TD class="data"&gt;Manager&lt;/TD&gt;
&lt;TD class="data"&gt;110032&lt;/TD&gt;
&lt;TD class="data"&gt;EastDelhi&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;/ARTICLE&gt;</description>
      <pubDate>Fri, 04 Nov 2016 13:08:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309243#M1497</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2016-11-04T13:08:42Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309503#M1498</link>
      <description>&lt;P&gt;Thanks&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/18408"&gt;@Ksharp﻿&lt;/a&gt;&amp;nbsp;for taking out time to write this code. You are very helpful. God bless you! I'll test this code tomorrow and would keep you posted about it.&lt;/P&gt;</description>
      <pubDate>Sat, 05 Nov 2016 12:13:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309503#M1498</guid>
      <dc:creator>Ujjawal</dc:creator>
      <dc:date>2016-11-05T12:13:46Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309741#M1499</link>
      <description>Hi, &lt;BR /&gt;&lt;BR /&gt;Thank you so much for your solution. You are very helpful. I appreciate it very much. May god bless you! Would you mind tweaking the code and create data set containing output of optimization? I was exploring create data statement to output the result but it's throwing an error. Couldn't define Array in create data statement. Thanks in anticipation!</description>
      <pubDate>Mon, 07 Nov 2016 14:52:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309741#M1499</guid>
      <dc:creator>Ujjawal</dc:creator>
      <dc:date>2016-11-07T14:52:50Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309774#M1501</link>
      <description>&lt;P&gt;Here is PROC OPTMODEL code, using the same distance metric as&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/18408"&gt;@Ksharp﻿&lt;/a&gt;:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc optmodel;
   set &amp;lt;str&amp;gt; CUSTOMERS;
   num sales {CUSTOMERS};
   num x_c {CUSTOMERS};
   num y_c {CUSTOMERS};
   read data have1 into CUSTOMERS=[customers] sales x_c=x y_c=y;

   set &amp;lt;str&amp;gt; PORTFOLIO_MANAGERS;
   str position {PORTFOLIO_MANAGERS};
   num x_p {PORTFOLIO_MANAGERS};
   num y_p {PORTFOLIO_MANAGERS};
   read data have2 into PORTFOLIO_MANAGERS=[pm] position x_p=x y_p=y;

   set CP_PAIRS = 
      {c in CUSTOMERS, p in PORTFOLIO_MANAGERS: 
      (sales[c] &amp;gt; 50 and position[p] = 'Manager') or (sales[c] &amp;lt;= 50 and position[p] = 'Analyst')};
   num dist {&amp;lt;c,p&amp;gt; in CP_PAIRS} = abs(x_c[c] - x_p[p]) + abs(y_c[c] - y_p[p]);

   var Assign {CP_PAIRS} binary;
   min TotalDistance = sum {&amp;lt;c,p&amp;gt; in CP_PAIRS} dist[c,p] * Assign[c,p];
   con OneManagerPerCustomer {c in CUSTOMERS}:
      sum {&amp;lt;(c),p&amp;gt; in CP_PAIRS} Assign[c,p] = 1;
   con Cardinality {p in PORTFOLIO_MANAGERS}:
      sum {&amp;lt;c,(p)&amp;gt; in CP_PAIRS} Assign[c,p] &amp;lt;= (if position[p] = 'Manager' then 3 else 5);

   solve;
   print Assign;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;SAS Output&lt;/P&gt;
&lt;DIV class="branch"&gt;
&lt;DIV&gt;
&lt;DIV align="center"&gt;
&lt;TABLE class="table" summary="Procedure Optmodel: Solution Summary" frame="box" rules="all" cellspacing="0" cellpadding="5"&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TH class="c b header" colspan="2" scope="colgroup"&gt;Solution Summary&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Solver&lt;/TH&gt;
&lt;TD class="r data"&gt;MILP&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Algorithm&lt;/TH&gt;
&lt;TD class="r data"&gt;Branch and Cut&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Objective Function&lt;/TH&gt;
&lt;TD class="r data"&gt;TotalDistance&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Solution Status&lt;/TH&gt;
&lt;TD class="r data"&gt;Optimal&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Objective Value&lt;/TH&gt;
&lt;TD class="r data"&gt;196&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;&amp;nbsp;&lt;/TH&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Relative Gap&lt;/TH&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Absolute Gap&lt;/TH&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Primal Infeasibility&lt;/TH&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Bound Infeasibility&lt;/TH&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Integer Infeasibility&lt;/TH&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;&amp;nbsp;&lt;/TH&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Best Bound&lt;/TH&gt;
&lt;TD class="r data"&gt;196&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Nodes&lt;/TH&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Iterations&lt;/TH&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Presolve Time&lt;/TH&gt;
&lt;TD class="r data"&gt;0.00&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Solution Time&lt;/TH&gt;
&lt;TD class="r data"&gt;0.00&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;BR /&gt;&lt;A name="IDX6" target="_blank"&gt;&lt;/A&gt;
&lt;DIV&gt;
&lt;DIV align="center"&gt;
&lt;TABLE class="table" summary="Procedure Optmodel: Assign" frame="box" rules="all" cellspacing="0" cellpadding="5"&gt;&lt;COLGROUP&gt; &lt;COL /&gt;&lt;/COLGROUP&gt; &lt;COLGROUP&gt; &lt;COL /&gt; &lt;COL /&gt; &lt;COL /&gt; &lt;COL /&gt;&lt;/COLGROUP&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TH class="c b header" colspan="5" scope="colgroup"&gt;Assign&lt;/TH&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="c headerempty" scope="col"&gt;&amp;nbsp;&lt;/TH&gt;
&lt;TH class="r b header" scope="col"&gt;A&lt;/TH&gt;
&lt;TH class="r b header" scope="col"&gt;B&lt;/TH&gt;
&lt;TH class="r b header" scope="col"&gt;C&lt;/TH&gt;
&lt;TH class="r b header" scope="col"&gt;D&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;David&lt;/TH&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class="r data"&gt;1&lt;/TD&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Predy&lt;/TH&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class="r data"&gt;1&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Raj&lt;/TH&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class="r data"&gt;1&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Riya&lt;/TH&gt;
&lt;TD class="r data"&gt;1&lt;/TD&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Sam&lt;/TH&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class="r data"&gt;1&lt;/TD&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="l rowheader" scope="row"&gt;Sompa&lt;/TH&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class="r data"&gt;1&lt;/TD&gt;
&lt;TD class="r data"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class="r data"&gt;0&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;</description>
      <pubDate>Mon, 07 Nov 2016 17:12:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309774#M1501</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2016-11-07T17:12:07Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309924#M1505</link>
      <description>&lt;PRE&gt;
OK. Here is. Since @Rob post OR code, maybe you should that .



data have1;
infile cards truncover expandtabs;
input Customers	$ Postcode $ sales x y;
cards;
Riya	110051	98 34 78 
Raj	110007	45 65 65
Sam	110032	72 78 34 
Sompa	110002	31 21 42
Predy	110003	48 47 78
David	110005	76 74 32
;
run;
 
data have2;
infile cards truncover expandtabs;
input PM $ Position $ PM_Postcode $ Territory : $20. x y;
cards;
A	Manager	110007	NorthDelhi 23 54
B	Analyst	110051	EastDelhi 34 45
C	Manager	110032	EastDelhi 56 56
D	Analyst	110003	NorthDelhi 43 88
;
run;

data customer;
 set have1;
 length position $ 10;
 if sales gt 50 then position='Manager';
  else position='Analyst';
run;
data pm;
 set have2;
 if position='Manager' then do;
  do i=1 to 3;
   output;
  end;
 end;
 else do;
  do i=1 to 5;
   output;
  end;
 end;
drop i;
run;

proc sort data=customer;by position;run;
proc sort data=pm;by position;run;

proc iml;
use customer nobs nobs1;
read all var{position};
read all var{x y} into xy_cust;
read all var _char_ into all1[c=vnames1];
close;
n=uniqueby(position);
need_analyst=n[2]-1;
need_manager=nobs1-n[2]+1;

use pm nobs nobs2;
read all var{position};
read all var{x y} into xy_pm;
read all var _char_ into all2[c=vnames2];
close;
n=uniqueby(position);
have_analyst=n[2]-1;
have_manager=nobs2-n[2]+1;

if nobs1&amp;gt;nobs2 then abort 'ERROR: too many customers.';

start func(x) 
global(have_analyst,have_manager,need_analyst,need_manager,xy_cust,xy_pm); 
t1=x[1:need_analyst];
t2=x[(need_analyst+1):(need_analyst+need_manager)];
if countunique(t1)^=need_analyst |  max(t1)&amp;gt;have_analyst |
   countunique(t2)^=need_manager |  min(t2)&amp;lt;(have_analyst+1)
 then obj=999999;
else obj=sum(abs((xy_pm[x,]-xy_cust)));
 return (obj);
finish;


n=need_analyst+need_manager;
encoding=repeat(1//have_analyst,1,need_analyst)||
repeat((have_analyst+1)//(have_analyst+have_manager),1,need_manager);


id=gasetup(2,n,12345678);
call gasetobj(id,0,"func");
call gasetcro(id,0.95,2);
call gasetmut(id,0.95,3);
call gasetsel(id,10,1,1);
call gainit(id,10000,encoding); 

niter = 1000;  /*change it as bigger as you can*/
do i = 1 to niter;
 call garegen(id);
 call gagetval(value, id);
end;
call gagetmem(mem, value, id, 1);

want=all1||all2[mem,] ;
vnames1[ncol(vnames1)]='CPosition';
vnames=(vnames1||vnames2);
create want from want[c=vnames] ;
append from want;
close;
print value[l = "Min Distance Value:"];
call gaend(id);
quit;
proc print data=want noobs;run;



&lt;/PRE&gt;</description>
      <pubDate>Tue, 08 Nov 2016 03:05:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/309924#M1505</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2016-11-08T03:05:08Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/310079#M1506</link>
      <description>&lt;P&gt;I should also point out that your problem decomposes&amp;nbsp;into two completely disjoint problems, according to sales and position. &amp;nbsp;A simple way to exploit that structure is to use the &lt;A href="http://support.sas.com/documentation/cdl/en/ormpug/68156/HTML/default/viewer.htm#ormpug_decomp_toc.htm" target="_self"&gt;decomposition algorithm&lt;/A&gt;&amp;nbsp;to detect and solve the two subproblems in parallel:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;   solve with MILP / decomp=(method=concomp);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 08 Nov 2016 14:22:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/310079#M1506</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2016-11-08T14:22:54Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/311778#M1512</link>
      <description>&lt;P&gt;Thanks a ton&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/1636"&gt;@RobPratt﻿&lt;/a&gt;&amp;nbsp;for your solution. At the same time, i apologize for so late reply. Your solution&amp;nbsp;works like a charm on small dataset. I have learnt a lot from your solution as i'm new to PROC OPTMODEL. In my dataset, i have around 30k customers and approx. 700 PMs (including both 'Analyst' and 'Manager'). It throws an error 'Out of memory during solution resolution'. I understand it creates a cartesian product of variables which is quite high. It's using 4 threads during processing. Is there any workaround to fine tune the performance? I can comprimise the solution for making it run. Would you advise any performance tips? To workaround this issue, i have split data into 4 parts based on their region and checking distance within each&amp;nbsp;region separately and later combining all the datasets. But it's not an optimal solution for some of the customers whose location is in the border areas of the region. They might have a nearest distance in the other region. Thanks in anticipation! Any help would be highly appreciated!&lt;/P&gt;</description>
      <pubDate>Tue, 15 Nov 2016 17:02:04 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/311778#M1512</guid>
      <dc:creator>Ujjawal</dc:creator>
      <dc:date>2016-11-15T17:02:04Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/311801#M1513</link>
      <description>The first two things to try are:&lt;BR /&gt;1. Use the SAS memsize option to increase the amount of memory available.&lt;BR /&gt;2. Split your data into two disjoint parts according to sales and position.   Because those two problems are independent, such a split loses no optimality.</description>
      <pubDate>Tue, 15 Nov 2016 18:02:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/311801#M1513</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2016-11-15T18:02:17Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/312088#M1514</link>
      <description>&lt;P&gt;Thanks&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/1636"&gt;@RobPratt﻿&lt;/a&gt;&amp;nbsp;for your suggestion. It works like a charm. You have been very helpful. Well appreciated! &amp;nbsp;I was wondering whether we can add a constraint of max number of 'Manager' and 'Analyst' in your OPTMODEL code. For example, there are 100 high value customers (based on &amp;gt; 50 sale) in a particular region. We require only 34 Managers (=100/3). Suppose we have currently 50 managers in this location so customers should be allocated to max 34 Managers (not 50). It may make some customers&amp;nbsp;are not allocated to the nearest manager.&amp;nbsp;Same logic holds for 'Analyst' as per their customers constraint.&lt;/P&gt;</description>
      <pubDate>Wed, 16 Nov 2016 19:20:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/312088#M1514</guid>
      <dc:creator>Ujjawal</dc:creator>
      <dc:date>2016-11-16T19:20:06Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/312484#M1516</link>
      <description>&lt;P&gt;If I understand correctly, you want to limit the number of managers that are used. &amp;nbsp;In that case, you have&amp;nbsp;a p-median problem in which the managers are the facilities. &amp;nbsp;Explicitly, you can replace the Cardinality constraints in the previous code with the following:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;   var UseManager {PORTFOLIO_MANAGERS} binary;
   con Capacity {p in PORTFOLIO_MANAGERS}:
      sum {&amp;lt;c,(p)&amp;gt; in CP_PAIRS} Assign[c,p] 
   &amp;lt;= (if position[p] = 'Manager' then 3 else 5) * UseManager[p];
   con Cardinality:
      sum {p in PORTFOLIO_MANAGERS} UseManager[p] &amp;lt;= 34;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 17 Nov 2016 23:03:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/312484#M1516</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2016-11-17T23:03:53Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/312726#M1517</link>
      <description>&lt;P&gt;Thank you so much.&amp;nbsp; In this section of code "&lt;SPAN class="token function"&gt;sum&lt;/SPAN&gt; &lt;SPAN class="token punctuation"&gt;{&lt;/SPAN&gt;p &lt;SPAN class="token operator"&gt;in&lt;/SPAN&gt; PORTFOLIO_MANAGERS&lt;SPAN class="token punctuation"&gt;}&lt;/SPAN&gt; UseManager&lt;SPAN class="token punctuation"&gt;[&lt;/SPAN&gt;p&lt;SPAN class="token punctuation"&gt;]&lt;/SPAN&gt; &lt;SPAN class="token operator"&gt;&amp;lt;=&lt;/SPAN&gt; &lt;SPAN class="token number"&gt;34&lt;/SPAN&gt;&lt;SPAN class="token punctuation"&gt;;", i was trying to calculate 34 from the customer's file. I added this code '&amp;nbsp;&lt;STRONG&gt;ceil(sum {c in customers} debt[c] / 3)&lt;/STRONG&gt; '&amp;nbsp;instead of 34. But it does not work.&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 18 Nov 2016 20:43:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/312726#M1517</guid>
      <dc:creator>Ujjawal</dc:creator>
      <dc:date>2016-11-18T20:43:44Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/312737#M1518</link>
      <description>&lt;P&gt;That syntax looks fine. &amp;nbsp;Did you declare and read the debt parameter before trying to use it in the constraint?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Did you get an error message or an unexpected solution?&lt;/P&gt;</description>
      <pubDate>Fri, 18 Nov 2016 21:25:59 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/312737#M1518</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2016-11-18T21:25:59Z</dc:date>
    </item>
    <item>
      <title>Re: Optimize Traveling Distance</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/312797#M1519</link>
      <description>I apologize for confusing you. It's the same sales parameter( changed the parameter name in my code). I have used ceil(sum {c in customers} sales[c] &amp;gt; 50 / 3). I am trying to calculate the number of customers having sales greater than 50.It doesn't return an error but ahows infessible solution. &lt;BR /&gt;&lt;BR /&gt;After all these constraints, a few customers are being ignored in the optimization. For example - there are 500 customers in the customer table. In the final result, it is assigning PMs against 497 customers. When method = comcomp is enabled, it returns 494 customers. Another thing i observed,  when I use method = concomp,  it doesn't return optimization result when there is out of memory. But sas returns the best possible solution when this method is disabled. &lt;BR /&gt;&lt;BR /&gt;</description>
      <pubDate>Sat, 19 Nov 2016 12:50:11 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Optimize-Traveling-Distance/m-p/312797#M1519</guid>
      <dc:creator>Ujjawal</dc:creator>
      <dc:date>2016-11-19T12:50:11Z</dc:date>
    </item>
  </channel>
</rss>

