<?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: Calculating shortest distance algorithm in Graphics Programming</title>
    <link>https://communities.sas.com/t5/Graphics-Programming/Calculating-shortest-distance-algorithm/m-p/231981#M8409</link>
    <description>&lt;P&gt;This is called the "Travelling Salesman Problem" or TSP. There have been many SAS posts and papers written about how to solve it in SAS.&amp;nbsp; For a large number of points, you should really use specialized software like SAS/OR or SAS/IML. For your small example, you can use direct enumeration,&amp;nbsp;which you are doing.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This sounds like a school assignment, so rather than completely answering your questions, here are some hints:&lt;/P&gt;
&lt;P&gt;1) Yes, the list of all permulations "double counts" the paths, since one route is in the clockwise direction and the other is counter clockwise. To eliminate one route, do not consider permutations for which the second element is greater than the last element. Thus for 4 cities you would consider 1-&amp;gt;2-&amp;gt;3-&amp;gt;4 but not the reverse permutation 1-&amp;gt;4-&amp;gt;3-&amp;gt;2.&lt;/P&gt;
&lt;P&gt;2) To generate random points in a circle of radius R centered at (x0, y0)&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;/* generate points uniformly inside the disk with boundary 
   circle (x-x0)**2 + (y-y0)**2 = R**2
*/
data obs;
x0=1;  y0=2;  R = 2;  /* parameters */
keep i x y;
twopi = 2 * constant("PI");
do i = 5 to 10;
   theta = twopi * rand("uniform");
   u = rand("uniform");
   x = x0 + R*sqrt(u)*cos(theta);
   y = y0 + R*sqrt(u)*sin(theta);
   output;
end;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 28 Oct 2015 13:10:20 GMT</pubDate>
    <dc:creator>Rick_SAS</dc:creator>
    <dc:date>2015-10-28T13:10:20Z</dc:date>
    <item>
      <title>Calculating shortest distance algorithm</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Calculating-shortest-distance-algorithm/m-p/231794#M8407</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff"&gt;Hi &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff"&gt;I've created some code that simulates 10 coordinates - four of the coordinates are fixed and all coordinates must lie in the plan (1,1), (10,1), (1,10) &amp;amp; (10.10). The starting position is (1,1). The code below calulcates every possible combination of routes whereby the starting coorddinate is (1,1) and the route must reach every point once and return to (1,1). The code calculates all combinations of routes for&amp;nbsp;a given&amp;nbsp;10 coordinates correctly so that the shortest route can be established. However, the code&amp;nbsp;does not&amp;nbsp;remove double counting where the routes.&amp;nbsp;Since the start and end&amp;nbsp;point is (1,1) it&amp;nbsp;includes both two of the same routes. Is there a way to remove this? &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff"&gt;What I really want to do is to produce points radomly within the boundaries of a circle or&amp;nbsp;diameter&amp;nbsp;D and centre (x,y).&amp;nbsp;I want to produce 1000s of 10 coordinate&amp;nbsp;maps within&amp;nbsp;a specified circle and calculate things like:&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff"&gt;The shortest route&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff"&gt;Average distance to centre point&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff"&gt;Mean&amp;nbsp;distance between each coordinate &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff"&gt;etc. &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff"&gt;My version of SAS is &amp;nbsp;9.3 TS Level 1M2 &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff"&gt;I have SAS/STAT and SAS/BASE&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Many thanks&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Here is my code below:&lt;/STRONG&gt;&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;P&gt;data fixed;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; input i x y;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; datalines;&lt;/P&gt;&lt;P&gt;1 1 1&lt;BR /&gt;2 10 10&lt;BR /&gt;3 1 10&lt;BR /&gt;4 10 1&lt;BR /&gt;&amp;nbsp;&lt;BR /&gt;;&lt;/P&gt;&lt;P&gt;data last;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; input i x y;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; datalines;&lt;/P&gt;&lt;P&gt;10 1 1&lt;BR /&gt;;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;data shorter;&lt;BR /&gt;input COL1 $200.;&lt;BR /&gt;datalines;&lt;BR /&gt;run;&lt;BR /&gt;/**/&lt;BR /&gt;/*%macro simulate;*/&lt;BR /&gt;/**/&lt;BR /&gt;/*%do k = 1 %to 1;*/&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;data obs;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; do i= 5 to 10;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x= round(10* ranuni(0),1);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; y= round(10* ranuni(0),1);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; output;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; end;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;data obs;&lt;BR /&gt;set fixed obs;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;data obs2;&lt;BR /&gt;set obs;&lt;BR /&gt;coord=catt(x,',',y);&lt;BR /&gt;retain start ;&lt;BR /&gt;if _n_= 1 then start= coord;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;/* flip the column to a row to get the ordered pairs in one record to permute later*/&lt;/P&gt;&lt;P&gt;proc transpose data=obs2 out=coordtrans;&lt;BR /&gt;by start;&lt;BR /&gt;var coord;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/* you could trop some of the variables n, nfact, j. also the COL1 or start will have your first pair&lt;/P&gt;&lt;P&gt;so you also have it available as an end */&lt;/P&gt;&lt;P&gt;&amp;nbsp;data next(drop = n nfact j);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; set coordtrans;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; array c Col2-col10; /* change the 5 to the number of pairs used*/&lt;BR /&gt;&amp;nbsp;&amp;nbsp; n=dim(c);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; nfact=fact(n);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; do j=1 to nfact;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call lexperm(j,&amp;nbsp; of c[*]);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; output;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; end;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;data next;&lt;BR /&gt;set next;&lt;BR /&gt;COL11 = COL1;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;data test;&lt;BR /&gt;set next;&lt;/P&gt;&lt;P&gt;dist1 = 0;&lt;/P&gt;&lt;P&gt;%macro distance;&lt;/P&gt;&lt;P&gt;%do i = 2 %to 11;&lt;BR /&gt;%let j = %eval(&amp;amp;i-1);&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;x1 = input(put(scan(COL&amp;amp;j,1,','),2.),2.);&lt;BR /&gt;x2 = input(put(scan(COL&amp;amp;i,1,','),2.),2.);&lt;BR /&gt;y1 = input(put(scan(COL&amp;amp;j,2,','),2.),2.);&lt;BR /&gt;y2 = input(put(scan(COL&amp;amp;i,2,','),2.),2.);&lt;/P&gt;&lt;P&gt;format dist&amp;amp;i 8.1;&lt;/P&gt;&lt;P&gt;dist&amp;amp;i = sqrt((y2-y1)**2+(x2-x1)**2) + dist&amp;amp;j ;&lt;/P&gt;&lt;P&gt;drop x1 x2 y1 y2 dist&amp;amp;j;&lt;/P&gt;&lt;P&gt;%end;&lt;/P&gt;&lt;P&gt;%mend;&lt;/P&gt;&lt;P&gt;%distance;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;proc sort data = test; by dist11; run;&lt;/P&gt;</description>
      <pubDate>Tue, 27 Oct 2015 10:41:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Calculating-shortest-distance-algorithm/m-p/231794#M8407</guid>
      <dc:creator>brophymj</dc:creator>
      <dc:date>2015-10-27T10:41:40Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating shortest distance algorithm</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Calculating-shortest-distance-algorithm/m-p/231820#M8408</link>
      <description>&lt;P&gt;Sounds like Graph problem.&lt;/P&gt;
&lt;P&gt;Search this forum for posts regarding&amp;nbsp;PROC OPTMODEL, SAS/OR and some SAS delivered macros.&lt;/P&gt;</description>
      <pubDate>Tue, 27 Oct 2015 14:07:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Calculating-shortest-distance-algorithm/m-p/231820#M8408</guid>
      <dc:creator>LinusH</dc:creator>
      <dc:date>2015-10-27T14:07:39Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating shortest distance algorithm</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Calculating-shortest-distance-algorithm/m-p/231981#M8409</link>
      <description>&lt;P&gt;This is called the "Travelling Salesman Problem" or TSP. There have been many SAS posts and papers written about how to solve it in SAS.&amp;nbsp; For a large number of points, you should really use specialized software like SAS/OR or SAS/IML. For your small example, you can use direct enumeration,&amp;nbsp;which you are doing.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This sounds like a school assignment, so rather than completely answering your questions, here are some hints:&lt;/P&gt;
&lt;P&gt;1) Yes, the list of all permulations "double counts" the paths, since one route is in the clockwise direction and the other is counter clockwise. To eliminate one route, do not consider permutations for which the second element is greater than the last element. Thus for 4 cities you would consider 1-&amp;gt;2-&amp;gt;3-&amp;gt;4 but not the reverse permutation 1-&amp;gt;4-&amp;gt;3-&amp;gt;2.&lt;/P&gt;
&lt;P&gt;2) To generate random points in a circle of radius R centered at (x0, y0)&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;/* generate points uniformly inside the disk with boundary 
   circle (x-x0)**2 + (y-y0)**2 = R**2
*/
data obs;
x0=1;  y0=2;  R = 2;  /* parameters */
keep i x y;
twopi = 2 * constant("PI");
do i = 5 to 10;
   theta = twopi * rand("uniform");
   u = rand("uniform");
   x = x0 + R*sqrt(u)*cos(theta);
   y = y0 + R*sqrt(u)*sin(theta);
   output;
end;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 28 Oct 2015 13:10:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Calculating-shortest-distance-algorithm/m-p/231981#M8409</guid>
      <dc:creator>Rick_SAS</dc:creator>
      <dc:date>2015-10-28T13:10:20Z</dc:date>
    </item>
  </channel>
</rss>

