<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Euler Problem 83</title>
	<atom:link href="http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/</link>
	<description>Daily posts of Excel tips…and other stuff</description>
	<lastBuildDate>Wed, 08 Feb 2012 23:58:05 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<item>
		<title>By: JoshG</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/#comment-40034</link>
		<dc:creator>JoshG</dc:creator>
		<pubDate>Fri, 26 Jun 2009 15:53:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=2621#comment-40034</guid>
		<description>&lt;p&gt;Michael,&lt;br&gt;
So let me get this straight:  Dick learns something completely new, goes through general steps that would be helpful in understanding it, and comes up with a workable solution.  Several people with more experience offer helpful suggestions, and some idiot calls it crappy?  Sheesh.  &lt;/p&gt;
&lt;p&gt;-Josh&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Michael,<br />
So let me get this straight:  Dick learns something completely new, goes through general steps that would be helpful in understanding it, and comes up with a workable solution.  Several people with more experience offer helpful suggestions, and some idiot calls it crappy?  Sheesh.  </p>
<p>-Josh</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michael</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/#comment-40027</link>
		<dc:creator>Michael</dc:creator>
		<pubDate>Fri, 26 Jun 2009 02:50:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=2621#comment-40027</guid>
		<description>&lt;p&gt;Josh -&lt;/p&gt;
&lt;p&gt;See this thread.  7th comment.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.dailydoseofexcel.com/archives/2009/06/16/reading-xml-files-in-vba/#comments&quot; rel=&quot;nofollow&quot;&gt;http://www.dailydoseofexcel.com/archives/2009/06/16/reading-xml-files-in-vba/#comments&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;...mrt&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Josh -</p>
<p>See this thread.  7th comment.</p>
<p><a href="http://www.dailydoseofexcel.com/archives/2009/06/16/reading-xml-files-in-vba/#comments" rel="nofollow">http://www.dailydoseofexcel.com/archives/2009/06/16/reading-xml-files-in-vba/#comments</a></p>
<p>&#8230;mrt</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: JoshG</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/#comment-40025</link>
		<dc:creator>JoshG</dc:creator>
		<pubDate>Thu, 25 Jun 2009 22:38:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=2621#comment-40025</guid>
		<description>&lt;p&gt;I hate replying to my own posts, but I am apparently brain dead.  I should try reading the whole problem.  0.1 seconds for #82.&lt;/p&gt;
&lt;p&gt;-Josh&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I hate replying to my own posts, but I am apparently brain dead.  I should try reading the whole problem.  0.1 seconds for #82.</p>
<p>-Josh</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: JoshG</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/#comment-40024</link>
		<dc:creator>JoshG</dc:creator>
		<pubDate>Thu, 25 Jun 2009 22:20:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=2621#comment-40024</guid>
		<description>&lt;p&gt;Michael,&lt;br&gt;
Yeah, I have to pause for a minute whenever I use Split() because I tend to use one-based arrays, though I don&#039;t use Option Base 1 (what&#039;s a few extra bytes of wasted memory?).  I had not known about Join() though.  I can immediately think of a half dozen places in previous projects where that would have come in handy...&lt;/p&gt;
&lt;p&gt;Good luck with #82.  Let me know if you have any questions / problems.  I just adapted the code for #82 and it took a ridiculous 15 seconds.  Surely I can do better than that.  At least it gave me the right answer though.&lt;/p&gt;
&lt;p&gt;Ha, link for sure.  I just wasn&#039;t sure if posting links was allowed or not, but it seems to be.&lt;/p&gt;
&lt;p&gt;Who calls it crappy?  The articles, tips and discussions here are always top-notch.  &lt;/p&gt;
&lt;p&gt;-Josh&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Michael,<br />
Yeah, I have to pause for a minute whenever I use Split() because I tend to use one-based arrays, though I don&#8217;t use Option Base 1 (what&#8217;s a few extra bytes of wasted memory?).  I had not known about Join() though.  I can immediately think of a half dozen places in previous projects where that would have come in handy&#8230;</p>
<p>Good luck with #82.  Let me know if you have any questions / problems.  I just adapted the code for #82 and it took a ridiculous 15 seconds.  Surely I can do better than that.  At least it gave me the right answer though.</p>
<p>Ha, link for sure.  I just wasn&#8217;t sure if posting links was allowed or not, but it seems to be.</p>
<p>Who calls it crappy?  The articles, tips and discussions here are always top-notch.  </p>
<p>-Josh</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michael</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/#comment-40017</link>
		<dc:creator>Michael</dc:creator>
		<pubDate>Thu, 25 Jun 2009 00:51:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=2621#comment-40017</guid>
		<description>&lt;p&gt;Hi Doug -&lt;/p&gt;
&lt;p&gt;True in a spreadsheet...not true in VBA for application.worksheetfunction.min.  If you haven&#039;t dimensioned beyond the area of interest, you get subscript errors.  And since it&#039;s min, you have to initialize those at a high value.  Using max, not a problem.&lt;/p&gt;
&lt;p&gt;...mrt&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Hi Doug -</p>
<p>True in a spreadsheet&#8230;not true in VBA for application.worksheetfunction.min.  If you haven&#8217;t dimensioned beyond the area of interest, you get subscript errors.  And since it&#8217;s min, you have to initialize those at a high value.  Using max, not a problem.</p>
<p>&#8230;mrt</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Doug Jenkins</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/#comment-40016</link>
		<dc:creator>Doug Jenkins</dc:creator>
		<pubDate>Wed, 24 Jun 2009 23:37:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=2621#comment-40016</guid>
		<description>&lt;p&gt;Michael, I don&#039;t have time tp read the thread in detail now, but I&#039;ll just pass on a tip that I picked up at the Project Euler forum: there is no need to surround the matrix with large numbers, blank cells will do just as well because blanks are ignored by the MIN() function.  As long as there is at least one blank column or row on each side of the matrix you can use the same formula everywhere.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Michael, I don&#8217;t have time tp read the thread in detail now, but I&#8217;ll just pass on a tip that I picked up at the Project Euler forum: there is no need to surround the matrix with large numbers, blank cells will do just as well because blanks are ignored by the MIN() function.  As long as there is at least one blank column or row on each side of the matrix you can use the same formula everywhere.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michael</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/#comment-40011</link>
		<dc:creator>Michael</dc:creator>
		<pubDate>Wed, 24 Jun 2009 21:11:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=2621#comment-40011</guid>
		<description>&lt;p&gt;Hi Josh -&lt;/p&gt;
&lt;p&gt;One thing I learned about Split() is that it ignores Option Base 1. It&#039;s always zero-based.  There are probably other functions like that, but it bit me back on #67.  It&#039;s counterpart is Join().  I learned about that here, too.&lt;/p&gt;
&lt;p&gt;I&#039;m going to walk down your code learning and looking for the lines to change to do #82.  &lt;/p&gt;
&lt;p&gt;WordPress is actually very nice outside the VB tags.  If you copy the &lt;a href=&quot;http://URL&quot; rel=&quot;nofollow&quot;&gt;http://URL&lt;/a&gt; from your browser and paste it in, it makes it into a link.  Playing with fire here, but I&#039;d bet it tries to turn that into a link ;-)&lt;/p&gt;
&lt;p&gt;I&#039;m check here so often the DDoE ought to be the HDoE.  I&#039;m impressed with what Dick puts into it and dismayed that some call it &quot;crappy.&quot;&lt;/p&gt;
&lt;p&gt;...mrt&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Hi Josh -</p>
<p>One thing I learned about Split() is that it ignores Option Base 1. It&#8217;s always zero-based.  There are probably other functions like that, but it bit me back on #67.  It&#8217;s counterpart is Join().  I learned about that here, too.</p>
<p>I&#8217;m going to walk down your code learning and looking for the lines to change to do #82.  </p>
<p>WordPress is actually very nice outside the VB tags.  If you copy the <a href="http://URL" rel="nofollow">http://URL</a> from your browser and paste it in, it makes it into a link.  Playing with fire here, but I&#8217;d bet it tries to turn that into a link <img src='http://www.dailydoseofexcel.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>I&#8217;m check here so often the DDoE ought to be the HDoE.  I&#8217;m impressed with what Dick puts into it and dismayed that some call it &#8220;crappy.&#8221;</p>
<p>&#8230;mrt</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: JoshG</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/#comment-40010</link>
		<dc:creator>JoshG</dc:creator>
		<pubDate>Wed, 24 Jun 2009 20:03:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=2621#comment-40010</guid>
		<description>&lt;p&gt;Michael,&lt;br&gt;
It&#039;s interesting you should mention timings.  I&#039;ve found that the first time I run this program, it takes anywhere from 0.2-0.4 seconds.  All subsequent runs in the same session settle down to 0.1 seconds.  I&#039;m not sure if it has to do with reading the text file, or what.  Your program settled in at 0.4 seconds for me.  &lt;/p&gt;
&lt;p&gt;I recently got a &quot;tech refresh&quot; in January when I spilled water on my old laptop and blew out the motherboard.  I swore to my wife that it was an accident, but I&#039;m not sure she believed me.  &lt;/p&gt;
&lt;p&gt;I&#039;d recommend reading the Wikipedia article on the binary heap first.  It&#039;s not too long or technical, which meant I could understand it without much trouble.  I don&#039;t know about you, but I have trouble visualizing abstract algorithms like Dijkstra.  I didn&#039;t understand it until I found a nice applet online that had a step-by-step demonstration.  I don&#039;t know the rules for posting links, but the third Google search result for &quot;Dijkstra Applet&quot; is a good one.&lt;/p&gt;
&lt;p&gt;I think that this was the first time that I had used the Split function, which I&#039;m pretty sure I learned about from this site.  Previously, I had used an unholy combination of Len / Mid /counters to look for commas and pick out the text of interest.  What a mess - Split is much better.&lt;/p&gt;
&lt;p&gt;-Josh&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Michael,<br />
It&#8217;s interesting you should mention timings.  I&#8217;ve found that the first time I run this program, it takes anywhere from 0.2-0.4 seconds.  All subsequent runs in the same session settle down to 0.1 seconds.  I&#8217;m not sure if it has to do with reading the text file, or what.  Your program settled in at 0.4 seconds for me.  </p>
<p>I recently got a &#8220;tech refresh&#8221; in January when I spilled water on my old laptop and blew out the motherboard.  I swore to my wife that it was an accident, but I&#8217;m not sure she believed me.  </p>
<p>I&#8217;d recommend reading the Wikipedia article on the binary heap first.  It&#8217;s not too long or technical, which meant I could understand it without much trouble.  I don&#8217;t know about you, but I have trouble visualizing abstract algorithms like Dijkstra.  I didn&#8217;t understand it until I found a nice applet online that had a step-by-step demonstration.  I don&#8217;t know the rules for posting links, but the third Google search result for &#8220;Dijkstra Applet&#8221; is a good one.</p>
<p>I think that this was the first time that I had used the Split function, which I&#8217;m pretty sure I learned about from this site.  Previously, I had used an unholy combination of Len / Mid /counters to look for commas and pick out the text of interest.  What a mess &#8211; Split is much better.</p>
<p>-Josh</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michael</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/#comment-40008</link>
		<dc:creator>Michael</dc:creator>
		<pubDate>Wed, 24 Jun 2009 18:04:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=2621#comment-40008</guid>
		<description>&lt;p&gt;Hi Josh -&lt;/p&gt;
&lt;p&gt;Neat.  I don&#039;t understand most of it yet.  I&#039;ll put it next to the Wiki article and walk through it.  I pasted it into the VBE, changed your substitutions and corrected the path, and it worked fine.  You have a fast machine!&lt;/p&gt;
&lt;p&gt;Your code ran in 0.328125 seconds, mine slightly slower in 0.375 on my office PC.  The good news for me is that I get a &quot;tech refresh&quot; next week.  Hopefully I&#039;ll catch up ;-)&lt;/p&gt;
&lt;p&gt;Nice to have a VBA Dijkstra model.  Thank you.  I like your way of reading the file in much better than my several loop method.  Germane to a discussion elsewhere here on DDoE, I too would have thought MatrixRow had to be a variant before this week.&lt;/p&gt;
&lt;p&gt;Thank you for contributing.&lt;/p&gt;
&lt;p&gt;...mrt&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Hi Josh -</p>
<p>Neat.  I don&#8217;t understand most of it yet.  I&#8217;ll put it next to the Wiki article and walk through it.  I pasted it into the VBE, changed your substitutions and corrected the path, and it worked fine.  You have a fast machine!</p>
<p>Your code ran in 0.328125 seconds, mine slightly slower in 0.375 on my office PC.  The good news for me is that I get a &#8220;tech refresh&#8221; next week.  Hopefully I&#8217;ll catch up <img src='http://www.dailydoseofexcel.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Nice to have a VBA Dijkstra model.  Thank you.  I like your way of reading the file in much better than my several loop method.  Germane to a discussion elsewhere here on DDoE, I too would have thought MatrixRow had to be a variant before this week.</p>
<p>Thank you for contributing.</p>
<p>&#8230;mrt</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: JoshG</title>
		<link>http://www.dailydoseofexcel.com/archives/2009/06/23/euler-problem-83/#comment-40007</link>
		<dc:creator>JoshG</dc:creator>
		<pubDate>Wed, 24 Jun 2009 15:29:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.dailydoseofexcel.com/?p=2621#comment-40007</guid>
		<description>&lt;p&gt;That&#039;s an interesting approach.  I had to print out the matrix at each step to understand what was going on, but now I get it.  As I had mentioned, I used Dijkstra&#039;s algorithm which was new to me at the time.  I&#039;m not sure that my feeble attempt to explain it was adequate, but Wikipedia has a pretty good explanation.  Each point in the matrix is a node (think road intersection) and the numeric values are the cost to get to each node (think distance along that road).  Also new to me was a priority queue for keeping track of which node currently had the lowest cost, which I implemented with a binary heap.  &lt;/p&gt;
&lt;p&gt;I try not to use global variables much for the PE problems since I have one massive workbook with my solutions to all problems, but for whatever reason I used several here.  Array:Matrix holds the original values from the text file, Array:NodeValues holds the current lowest cost to reach each node, Array:VisitedNodes keeps track of which nodes have been visited, Array:HeapPositions keeps track, for each node, of its position in the heap.  Here&#039;s the code, and I hope I made all of the bracket corrections correctly.&lt;/p&gt;
&lt;div style=&quot;overflow: auto; white-space: nowrap;&quot; class=&quot;codecolorer-container vb default&quot;&gt;&lt;div style=&quot;white-space: nowrap;&quot; class=&quot;vb codecolorer&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;Public&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Const&lt;/span&gt; MatrixSize &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt; = 80&lt;br&gt;
&lt;span class=&quot;kw1&quot;&gt;Public&lt;/span&gt; Matrix() &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Integer&lt;/span&gt;&lt;br&gt;
&lt;span class=&quot;kw1&quot;&gt;Public&lt;/span&gt; NodeValues() &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, VisitedNodes() &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Boolean&lt;/span&gt;, HeapPositions() &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt; Euler83()&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; a &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Integer&lt;/span&gt;, b &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Integer&lt;/span&gt;, C &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, StartTime &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Single&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; FileNameToOpen &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;String&lt;/span&gt;, TextString &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;String&lt;/span&gt;, MatrixRow() &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;String&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; BinHeap() &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, HeapLen &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;BinHeap keeps track of the row / column positions&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039; &#160; Corresponding values are stored in NodeValues&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;Starts out as a 6400x2 array&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039; &#160; Column 1 corresponds to the matrix row&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039; &#160; Column 2 corresponds to the matrix column&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;br&gt;
&#160; &#160; StartTime = Timer&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;ReDim&lt;/span&gt; NodeValues(1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize, 1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize) &#160; &#160; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;sum of the distance to reach this point&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;ReDim&lt;/span&gt; VisitedNodes(1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize, 1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize)&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;ReDim&lt;/span&gt; Matrix(1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize, 1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize)&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;read in the file &lt;br&gt;
&lt;/span&gt; &#160; &#160;FileNameToOpen = ThisWorkbook.Path &amp; &lt;span class=&quot;st0&quot;&gt;&quot;matrix.txt&quot;&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; FileNameToOpen = vbNullString &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;empty&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;Exit&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Open&lt;/span&gt; FileNameToOpen &lt;span class=&quot;kw1&quot;&gt;For&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Input&lt;/span&gt; Access Read &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; #1 &#160; &#160;&lt;br&gt;
&#160; &#160; a = 0&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Do&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;While&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Not&lt;/span&gt; EOF(1)&lt;br&gt;
&#160; &#160; &#160; &#160; a = a + 1&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Line&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Input&lt;/span&gt; #1, TextString&lt;br&gt;
&#160; &#160; &#160; &#160; MatrixRow = Split(TextString, &lt;span class=&quot;st0&quot;&gt;&quot;,&quot;&lt;/span&gt;)&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;For&lt;/span&gt; b = 1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; Matrix(a, b) = MatrixRow(b - 1)&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Next&lt;/span&gt; b&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Loop&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Close&lt;/span&gt; #1&lt;br&gt;
&lt;br&gt;
&#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;reset matrices&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;For&lt;/span&gt; a = 1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;For&lt;/span&gt; b = 1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; NodeValues(a, b) = 1000000 &#160;&lt;span class=&quot;co1&quot;&gt;&#039;more or less infinity&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160; &#160; &#160;VisitedNodes(a, b) = &lt;span class=&quot;kw1&quot;&gt;False&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Next&lt;/span&gt; b&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Next&lt;/span&gt; a&lt;br&gt;
&#160; &#160; NodeValues(1, 1) = Matrix(1, 1)&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;set up the heap&lt;br&gt;
&lt;/span&gt; &#160; &#160;HeapLen = MatrixSize * MatrixSize - 1&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;ReDim&lt;/span&gt; BinHeap(0 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; HeapLen, 0 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; 1) &#160; &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;first dimension is row, second is column&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;ReDim&lt;/span&gt; HeapPositions(1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize, 1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize) &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;where each node is located in the heap&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;set up the heap with the upper-left element first&lt;br&gt;
&lt;/span&gt; &#160; &#160;C = 0&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;For&lt;/span&gt; a = 1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;For&lt;/span&gt; b = 1 &lt;span class=&quot;kw1&quot;&gt;To&lt;/span&gt; MatrixSize&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; HeapPositions(a, b) = C&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; BinHeap(C, 0) = a&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; BinHeap(C, 1) = b&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; C = C + 1&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Next&lt;/span&gt; b&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Next&lt;/span&gt; a&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;find the unvisited node with the lowest cost - in the case of the binary heap it&#039;s the first element&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;the first element is at position zero&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;Do&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Until&lt;/span&gt; BinHeap(0, 0) = MatrixSize &lt;span class=&quot;kw1&quot;&gt;And&lt;/span&gt; BinHeap(0, 1) = MatrixSize &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;exit when you&#039;re at the goal node&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;Call&lt;/span&gt; UpdateNode83(BinHeap(0, 0), BinHeap(0, 1), 0, 1, BinHeap, HeapLen) &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;move to the right&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;Call&lt;/span&gt; UpdateNode83(BinHeap(0, 0), BinHeap(0, 1), 0, -1, BinHeap, HeapLen) &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;move to the left&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;Call&lt;/span&gt; UpdateNode83(BinHeap(0, 0), BinHeap(0, 1), -1, 0, BinHeap, HeapLen) &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;move up&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;Call&lt;/span&gt; UpdateNode83(BinHeap(0, 0), BinHeap(0, 1), 1, 0, BinHeap, HeapLen) &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;move down&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;br&gt;
&#160; &#160; &#160; &#160; VisitedNodes(BinHeap(0, 0), BinHeap(0, 1)) = &lt;span class=&quot;kw1&quot;&gt;True&lt;/span&gt; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;mark node as visited&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;move the last element to the top of the heap&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;BinHeap(0, 0) = BinHeap(HeapLen, 0)&lt;br&gt;
&#160; &#160; &#160; &#160; BinHeap(0, 1) = BinHeap(HeapLen, 1)&lt;br&gt;
&#160; &#160; &#160; &#160; HeapPositions(BinHeap(0, 0), BinHeap(0, 1)) = 0&lt;br&gt;
&#160; &#160; &#160; &#160; HeapLen = HeapLen - 1&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;move the element down as necessary&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;Call&lt;/span&gt; PercolateDown(0, BinHeap, HeapLen)&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Loop&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; Debug.&lt;span class=&quot;kw1&quot;&gt;Print&lt;/span&gt; NodeValues(MatrixSize, MatrixSize), Timer - StartTime&lt;br&gt;
&lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt; UpdateNode83(CurRow &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, CurCol &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, RowOffset &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, ColOffset &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, BinHeap() &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, _&lt;br&gt;
&#160; &#160; &#160; &#160;HeapLen &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;)&lt;br&gt;
&lt;span class=&quot;co1&quot;&gt;&#039;Checks the updated cost of each neighbor and updates as necessary&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; NewRow &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, NewCol &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;On&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;GoTo&lt;/span&gt; ErrorTime&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; NewRow = CurRow + RowOffset&lt;br&gt;
&#160; &#160; NewCol = CurCol + ColOffset&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; VisitedNodes(NewRow, NewCol) = &lt;span class=&quot;kw1&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt; &#160; &#160; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;have not visited that node&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;On&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;GoTo&lt;/span&gt; 0 &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;disable error handling since the only error I want to trap is if you&#039;re off the edge&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;check the cost&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; NodeValues(CurRow, CurCol) + Matrix(NewRow, NewCol) LT NodeValues(NewRow, NewCol) &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;new cost is less thn current cost&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160; &#160; &#160;NodeValues(NewRow, NewCol) = NodeValues(CurRow, CurCol) + Matrix(NewRow, NewCol) &#160; &#160; &#160; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;update cost&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160; &#160; &#160;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Call&lt;/span&gt; PercolateUp(HeapPositions(NewRow, NewCol), BinHeap, HeapLen) &#160; &lt;span class=&quot;co1&quot;&gt;&#039;update the heap&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Exit&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt;&lt;br&gt;
ErrorTime:&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; Err.Number = 9 &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;subscript out of range - off the edge of the matrix&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;Exit&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Else&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; MsgBox Err &amp; Chr(13) &amp; &lt;span class=&quot;kw1&quot;&gt;Error&lt;/span&gt;(Err)&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt; PercolateUp(HeapPos &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, BinHeap() &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, HeapLen &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;)&lt;br&gt;
&lt;span class=&quot;co1&quot;&gt;&#039;Element a(i) has children a(2i+1) and a(2i+2) and parent a(floor((i-1)/2))&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; ParentPos &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; TempRow &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, TempCol &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, TempHeapPos &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; ParentPos = Int((HeapPos - 1) / 2) &#160; &#160; &#160; &#160; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;these are the positions in the BinHeap array&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;see if the child is smaller than the parent&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; NodeValues(BinHeap(HeapPos, 0), BinHeap(HeapPos, 1)) LT _ &lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;NodeValues(BinHeap(ParentPos, 0), BinHeap(ParentPos, 1)) &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;swap values&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;TempRow = BinHeap(HeapPos, 0)&lt;br&gt;
&#160; &#160; &#160; &#160; TempCol = BinHeap(HeapPos, 1)&lt;br&gt;
&#160; &#160; &#160; &#160; TempHeapPos = HeapPositions(BinHeap(HeapPos, 0), BinHeap(HeapPos, 1))&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;br&gt;
&#160; &#160; &#160; &#160; BinHeap(HeapPos, 0) = BinHeap(ParentPos, 0)&lt;br&gt;
&#160; &#160; &#160; &#160; BinHeap(HeapPos, 1) = BinHeap(ParentPos, 1)&lt;br&gt;
&#160; &#160; &#160; &#160; HeapPositions(TempRow, TempCol) = HeapPositions(BinHeap(ParentPos, 0), BinHeap(ParentPos, 1))&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;br&gt;
&#160; &#160; &#160; &#160; HeapPositions(BinHeap(ParentPos, 0), BinHeap(ParentPos, 1)) = TempHeapPos&lt;br&gt;
&#160; &#160; &#160; &#160; BinHeap(ParentPos, 0) = TempRow&lt;br&gt;
&#160; &#160; &#160; &#160; BinHeap(ParentPos, 1) = TempCol &#160; &#160; &#160; &#160;&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;if you&#039;re not at the top of the tree, recurse&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; ParentPos != 0 &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Call&lt;/span&gt; PercolateUp(ParentPos, BinHeap, HeapLen)&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
&lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt; PercolateDown(HeapPos &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, BinHeap() &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, HeapLen &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;)&lt;br&gt;
&lt;span class=&quot;co1&quot;&gt;&#039;Element a(i) has children a(2i+1) and a(2i+2) and parent a(floor((i-1)/2))&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; ChildPos &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, a &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Dim&lt;/span&gt; TempRow &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, TempCol &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;, TempHeapPos &lt;span class=&quot;kw1&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Long&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; 2 * HeapPos + 2 GT HeapLen &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Exit&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt; &#160; &#160; &#160; &#160; &#160;&lt;span class=&quot;co1&quot;&gt;&#039;no children to check&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; 2 * HeapPos + 1 = HeapLen &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;only one child&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;a = 1&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Else&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;find the smaller child&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; NodeValues(BinHeap(2 * HeapPos + 1, 0), BinHeap(2 * HeapPos + 1, 1)) LT _&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;NodeValues(BinHeap(2 * HeapPos + 2, 0), BinHeap(2 * HeapPos + 2, 1)) &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; a = 1&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Else&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; a = 2&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; ChildPos = 2 * HeapPos + a&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt;&lt;br&gt;
&#160; &#160; &lt;br&gt;
&#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;see if the child is smaller than the parent&lt;br&gt;
&lt;/span&gt; &#160; &#160;&lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; NodeValues(BinHeap(HeapPos, 0), BinHeap(HeapPos, 1)) GT _&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;NodeValues(BinHeap(ChildPos, 0), BinHeap(ChildPos, 1)) &lt;span class=&quot;kw1&quot;&gt;Then&lt;/span&gt;&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;co1&quot;&gt;&#039;swap values&lt;br&gt;
&lt;/span&gt; &#160; &#160; &#160; &#160;TempRow = BinHeap(HeapPos, 0)&lt;br&gt;
&#160; &#160; &#160; &#160; TempCol = BinHeap(HeapPos, 1)&lt;br&gt;
&#160; &#160; &#160; &#160; TempHeapPos = HeapPositions(BinHeap(HeapPos, 0), BinHeap(HeapPos, 1))&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;br&gt;
&#160; &#160; &#160; &#160; BinHeap(HeapPos, 0) = BinHeap(ChildPos, 0)&lt;br&gt;
&#160; &#160; &#160; &#160; BinHeap(HeapPos, 1) = BinHeap(ChildPos, 1)&lt;br&gt;
&#160; &#160; &#160; &#160; HeapPositions(TempRow, TempCol) = HeapPositions(BinHeap(ChildPos, 0), BinHeap(ChildPos, 1))&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;br&gt;
&#160; &#160; &#160; &#160; HeapPositions(BinHeap(ChildPos, 0), BinHeap(ChildPos, 1)) = TempHeapPos&lt;br&gt;
&#160; &#160; &#160; &#160; BinHeap(ChildPos, 0) = TempRow&lt;br&gt;
&#160; &#160; &#160; &#160; BinHeap(ChildPos, 1) = TempCol&lt;br&gt;
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&lt;br&gt;
&#160; &#160; &#160; &#160; &lt;span class=&quot;kw1&quot;&gt;Call&lt;/span&gt; PercolateDown(ChildPos, BinHeap, HeapLen)&lt;br&gt;
&#160; &#160; &lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;If&lt;/span&gt; &#160; &#160;&lt;br&gt;
&lt;span class=&quot;kw1&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;Sub&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The chief advantage of this method is that each node is checked at most once.  Th chief disadvantage is that it is needlessly complicated.  It runs in about a tenth of a second on my machine.&lt;/p&gt;
&lt;p&gt;-Josh&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>That&#8217;s an interesting approach.  I had to print out the matrix at each step to understand what was going on, but now I get it.  As I had mentioned, I used Dijkstra&#8217;s algorithm which was new to me at the time.  I&#8217;m not sure that my feeble attempt to explain it was adequate, but Wikipedia has a pretty good explanation.  Each point in the matrix is a node (think road intersection) and the numeric values are the cost to get to each node (think distance along that road).  Also new to me was a priority queue for keeping track of which node currently had the lowest cost, which I implemented with a binary heap.  </p>
<p>I try not to use global variables much for the PE problems since I have one massive workbook with my solutions to all problems, but for whatever reason I used several here.  Array:Matrix holds the original values from the text file, Array:NodeValues holds the current lowest cost to reach each node, Array:VisitedNodes keeps track of which nodes have been visited, Array:HeapPositions keeps track, for each node, of its position in the heap.  Here&#8217;s the code, and I hope I made all of the bracket corrections correctly.</p>
<div style="overflow: auto; white-space: nowrap;" class="codecolorer-container vb default">
<div style="white-space: nowrap;" class="vb codecolorer"><span class="kw1">Public</span> <span class="kw1">Const</span> MatrixSize <span class="kw1">As</span> <span class="kw1">Long</span> = 80<br />
<span class="kw1">Public</span> Matrix() <span class="kw1">As</span> <span class="kw1">Integer</span><br />
<span class="kw1">Public</span> NodeValues() <span class="kw1">As</span> <span class="kw1">Long</span>, VisitedNodes() <span class="kw1">As</span> <span class="kw1">Boolean</span>, HeapPositions() <span class="kw1">As</span> <span class="kw1">Long</span></p>
<p><span class="kw1">Sub</span> Euler83()<br />
&nbsp; &nbsp; <span class="kw1">Dim</span> a <span class="kw1">As</span> <span class="kw1">Integer</span>, b <span class="kw1">As</span> <span class="kw1">Integer</span>, C <span class="kw1">As</span> <span class="kw1">Long</span>, StartTime <span class="kw1">As</span> <span class="kw1">Single</span><br />
&nbsp; &nbsp; <span class="kw1">Dim</span> FileNameToOpen <span class="kw1">As</span> <span class="kw1">String</span>, TextString <span class="kw1">As</span> <span class="kw1">String</span>, MatrixRow() <span class="kw1">As</span> <span class="kw1">String</span><br />
&nbsp; &nbsp; <span class="kw1">Dim</span> BinHeap() <span class="kw1">As</span> <span class="kw1">Long</span>, HeapLen <span class="kw1">As</span> <span class="kw1">Long</span> &nbsp; &nbsp; &nbsp;<span class="co1">&#8216;BinHeap keeps track of the row / column positions<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">&#8216; &nbsp; Corresponding values are stored in NodeValues<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">&#8216;Starts out as a 6400&#215;2 array<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">&#8216; &nbsp; Column 1 corresponds to the matrix row<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">&#8216; &nbsp; Column 2 corresponds to the matrix column<br />
</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; StartTime = Timer<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">ReDim</span> NodeValues(1 <span class="kw1">To</span> MatrixSize, 1 <span class="kw1">To</span> MatrixSize) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">&#8216;sum of the distance to reach this point<br />
</span> &nbsp; &nbsp;<span class="kw1">ReDim</span> VisitedNodes(1 <span class="kw1">To</span> MatrixSize, 1 <span class="kw1">To</span> MatrixSize)<br />
&nbsp; &nbsp; <span class="kw1">ReDim</span> Matrix(1 <span class="kw1">To</span> MatrixSize, 1 <span class="kw1">To</span> MatrixSize)<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">&#8216;read in the file <br />
</span> &nbsp; &nbsp;FileNameToOpen = ThisWorkbook.Path &amp;amp; <span class="st0">&#8220;matrix.txt&#8221;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">If</span> FileNameToOpen = vbNullString <span class="kw1">Then</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;empty<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">Exit</span> <span class="kw1">Sub</span><br />
&nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span></p>
<p>&nbsp; &nbsp; <span class="kw1">Open</span> FileNameToOpen <span class="kw1">For</span> <span class="kw1">Input</span> Access Read <span class="kw1">As</span> #1 &nbsp; &nbsp;<br />
&nbsp; &nbsp; a = 0<br />
&nbsp; &nbsp; <span class="kw1">Do</span> <span class="kw1">While</span> <span class="kw1">Not</span> EOF(1)<br />
&nbsp; &nbsp; &nbsp; &nbsp; a = a + 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Line</span> <span class="kw1">Input</span> #1, TextString<br />
&nbsp; &nbsp; &nbsp; &nbsp; MatrixRow = Split(TextString, <span class="st0">&#8220;,&#8221;</span>)<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">For</span> b = 1 <span class="kw1">To</span> MatrixSize<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Matrix(a, b) = MatrixRow(b &#8211; 1)<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Next</span> b<br />
&nbsp; &nbsp; <span class="kw1">Loop</span><br />
&nbsp; &nbsp; <span class="kw1">Close</span> #1</p>
<p>&nbsp; &nbsp; <span class="co1">&#8216;reset matrices<br />
</span> &nbsp; &nbsp;<span class="kw1">For</span> a = 1 <span class="kw1">To</span> MatrixSize<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">For</span> b = 1 <span class="kw1">To</span> MatrixSize<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NodeValues(a, b) = 1000000 &nbsp;<span class="co1">&#8216;more or less infinity<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;VisitedNodes(a, b) = <span class="kw1">False</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Next</span> b<br />
&nbsp; &nbsp; <span class="kw1">Next</span> a<br />
&nbsp; &nbsp; NodeValues(1, 1) = Matrix(1, 1)<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">&#8216;set up the heap<br />
</span> &nbsp; &nbsp;HeapLen = MatrixSize * MatrixSize &#8211; 1<br />
&nbsp; &nbsp; <span class="kw1">ReDim</span> BinHeap(0 <span class="kw1">To</span> HeapLen, 0 <span class="kw1">To</span> 1) &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;first dimension is row, second is column<br />
</span> &nbsp; &nbsp;<span class="kw1">ReDim</span> HeapPositions(1 <span class="kw1">To</span> MatrixSize, 1 <span class="kw1">To</span> MatrixSize) &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;where each node is located in the heap<br />
</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span class="co1">&#8216;set up the heap with the upper-left element first<br />
</span> &nbsp; &nbsp;C = 0<br />
&nbsp; &nbsp; <span class="kw1">For</span> a = 1 <span class="kw1">To</span> MatrixSize<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">For</span> b = 1 <span class="kw1">To</span> MatrixSize<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HeapPositions(a, b) = C<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BinHeap(C, 0) = a<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BinHeap(C, 1) = b<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; C = C + 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Next</span> b<br />
&nbsp; &nbsp; <span class="kw1">Next</span> a<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">&#8216;find the unvisited node with the lowest cost &#8211; in the case of the binary heap it&#8217;s the first element<br />
</span> &nbsp; &nbsp;<span class="co1">&#8216;the first element is at position zero<br />
</span> &nbsp; &nbsp;<span class="kw1">Do</span> <span class="kw1">Until</span> BinHeap(0, 0) = MatrixSize <span class="kw1">And</span> BinHeap(0, 1) = MatrixSize &nbsp; &nbsp; <span class="co1">&#8216;exit when you&#8217;re at the goal node<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">Call</span> UpdateNode83(BinHeap(0, 0), BinHeap(0, 1), 0, 1, BinHeap, HeapLen) &nbsp; &nbsp; <span class="co1">&#8216;move to the right<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">Call</span> UpdateNode83(BinHeap(0, 0), BinHeap(0, 1), 0, -1, BinHeap, HeapLen) &nbsp; &nbsp;<span class="co1">&#8216;move to the left<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">Call</span> UpdateNode83(BinHeap(0, 0), BinHeap(0, 1), -1, 0, BinHeap, HeapLen) &nbsp; &nbsp;<span class="co1">&#8216;move up<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">Call</span> UpdateNode83(BinHeap(0, 0), BinHeap(0, 1), 1, 0, BinHeap, HeapLen) &nbsp; &nbsp; <span class="co1">&#8216;move down<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; VisitedNodes(BinHeap(0, 0), BinHeap(0, 1)) = <span class="kw1">True</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;mark node as visited<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;move the last element to the top of the heap<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;BinHeap(0, 0) = BinHeap(HeapLen, 0)<br />
&nbsp; &nbsp; &nbsp; &nbsp; BinHeap(0, 1) = BinHeap(HeapLen, 1)<br />
&nbsp; &nbsp; &nbsp; &nbsp; HeapPositions(BinHeap(0, 0), BinHeap(0, 1)) = 0<br />
&nbsp; &nbsp; &nbsp; &nbsp; HeapLen = HeapLen &#8211; 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;move the element down as necessary<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">Call</span> PercolateDown(0, BinHeap, HeapLen)<br />
&nbsp; &nbsp; <span class="kw1">Loop</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; Debug.<span class="kw1">Print</span> NodeValues(MatrixSize, MatrixSize), Timer &#8211; StartTime<br />
<span class="kw1">End</span> <span class="kw1">Sub</span></p>
<p><span class="kw1">Sub</span> UpdateNode83(CurRow <span class="kw1">As</span> <span class="kw1">Long</span>, CurCol <span class="kw1">As</span> <span class="kw1">Long</span>, RowOffset <span class="kw1">As</span> <span class="kw1">Long</span>, ColOffset <span class="kw1">As</span> <span class="kw1">Long</span>, BinHeap() <span class="kw1">As</span> <span class="kw1">Long</span>, _<br />
&nbsp; &nbsp; &nbsp; &nbsp;HeapLen <span class="kw1">As</span> <span class="kw1">Long</span>)<br />
<span class="co1">&#8216;Checks the updated cost of each neighbor and updates as necessary<br />
</span> &nbsp; &nbsp;<span class="kw1">Dim</span> NewRow <span class="kw1">As</span> <span class="kw1">Long</span>, NewCol <span class="kw1">As</span> <span class="kw1">Long</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">On</span> <span class="kw1">Error</span> <span class="kw1">GoTo</span> ErrorTime<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; NewRow = CurRow + RowOffset<br />
&nbsp; &nbsp; NewCol = CurCol + ColOffset<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">If</span> VisitedNodes(NewRow, NewCol) = <span class="kw1">False</span> <span class="kw1">Then</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">&#8216;have not visited that node<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">On</span> <span class="kw1">Error</span> <span class="kw1">GoTo</span> 0 &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;disable error handling since the only error I want to trap is if you&#8217;re off the edge<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">&#8216;check the cost<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">If</span> NodeValues(CurRow, CurCol) + Matrix(NewRow, NewCol) LT NodeValues(NewRow, NewCol) <span class="kw1">Then</span> &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;new cost is less thn current cost<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NodeValues(NewRow, NewCol) = NodeValues(CurRow, CurCol) + Matrix(NewRow, NewCol) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">&#8216;update cost<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Call</span> PercolateUp(HeapPositions(NewRow, NewCol), BinHeap, HeapLen) &nbsp; <span class="co1">&#8216;update the heap<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">End</span> <span class="kw1">If</span><br />
&nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">Exit</span> <span class="kw1">Sub</span><br />
ErrorTime:<br />
&nbsp; &nbsp; <span class="kw1">If</span> Err.Number = 9 <span class="kw1">Then</span> &nbsp; &nbsp; &nbsp;<span class="co1">&#8216;subscript out of range &#8211; off the edge of the matrix<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">Exit</span> <span class="kw1">Sub</span><br />
&nbsp; &nbsp; <span class="kw1">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; MsgBox Err &amp;amp; Chr(13) &amp;amp; <span class="kw1">Error</span>(Err)<br />
&nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
<span class="kw1">End</span> <span class="kw1">Sub</span></p>
<p><span class="kw1">Sub</span> PercolateUp(HeapPos <span class="kw1">As</span> <span class="kw1">Long</span>, BinHeap() <span class="kw1">As</span> <span class="kw1">Long</span>, HeapLen <span class="kw1">As</span> <span class="kw1">Long</span>)<br />
<span class="co1">&#8216;Element a(i) has children a(2i+1) and a(2i+2) and parent a(floor((i-1)/2))<br />
</span> &nbsp; &nbsp;<span class="kw1">Dim</span> ParentPos <span class="kw1">As</span> <span class="kw1">Long</span><br />
&nbsp; &nbsp; <span class="kw1">Dim</span> TempRow <span class="kw1">As</span> <span class="kw1">Long</span>, TempCol <span class="kw1">As</span> <span class="kw1">Long</span>, TempHeapPos <span class="kw1">As</span> <span class="kw1">Long</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; ParentPos = Int((HeapPos &#8211; 1) / 2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">&#8216;these are the positions in the BinHeap array<br />
</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span class="co1">&#8216;see if the child is smaller than the parent<br />
</span> &nbsp; &nbsp;<span class="kw1">If</span> NodeValues(BinHeap(HeapPos, 0), BinHeap(HeapPos, 1)) LT _ <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NodeValues(BinHeap(ParentPos, 0), BinHeap(ParentPos, 1)) <span class="kw1">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;swap values<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;TempRow = BinHeap(HeapPos, 0)<br />
&nbsp; &nbsp; &nbsp; &nbsp; TempCol = BinHeap(HeapPos, 1)<br />
&nbsp; &nbsp; &nbsp; &nbsp; TempHeapPos = HeapPositions(BinHeap(HeapPos, 0), BinHeap(HeapPos, 1))<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; BinHeap(HeapPos, 0) = BinHeap(ParentPos, 0)<br />
&nbsp; &nbsp; &nbsp; &nbsp; BinHeap(HeapPos, 1) = BinHeap(ParentPos, 1)<br />
&nbsp; &nbsp; &nbsp; &nbsp; HeapPositions(TempRow, TempCol) = HeapPositions(BinHeap(ParentPos, 0), BinHeap(ParentPos, 1))<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; HeapPositions(BinHeap(ParentPos, 0), BinHeap(ParentPos, 1)) = TempHeapPos<br />
&nbsp; &nbsp; &nbsp; &nbsp; BinHeap(ParentPos, 0) = TempRow<br />
&nbsp; &nbsp; &nbsp; &nbsp; BinHeap(ParentPos, 1) = TempCol &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;if you&#8217;re not at the top of the tree, recurse<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">If</span> ParentPos != 0 <span class="kw1">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Call</span> PercolateUp(ParentPos, BinHeap, HeapLen)<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
&nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
<span class="kw1">End</span> <span class="kw1">Sub</span></p>
<p><span class="kw1">Sub</span> PercolateDown(HeapPos <span class="kw1">As</span> <span class="kw1">Long</span>, BinHeap() <span class="kw1">As</span> <span class="kw1">Long</span>, HeapLen <span class="kw1">As</span> <span class="kw1">Long</span>)<br />
<span class="co1">&#8216;Element a(i) has children a(2i+1) and a(2i+2) and parent a(floor((i-1)/2))<br />
</span> &nbsp; &nbsp;<span class="kw1">Dim</span> ChildPos <span class="kw1">As</span> <span class="kw1">Long</span>, a <span class="kw1">As</span> <span class="kw1">Long</span><br />
&nbsp; &nbsp; <span class="kw1">Dim</span> TempRow <span class="kw1">As</span> <span class="kw1">Long</span>, TempCol <span class="kw1">As</span> <span class="kw1">Long</span>, TempHeapPos <span class="kw1">As</span> <span class="kw1">Long</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">If</span> 2 * HeapPos + 2 GT HeapLen <span class="kw1">Then</span> <span class="kw1">Exit</span> <span class="kw1">Sub</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">&#8216;no children to check<br />
</span> &nbsp; &nbsp;<span class="kw1">If</span> 2 * HeapPos + 1 = HeapLen <span class="kw1">Then</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;only one child<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;a = 1<br />
&nbsp; &nbsp; <span class="kw1">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;find the smaller child<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">If</span> NodeValues(BinHeap(2 * HeapPos + 1, 0), BinHeap(2 * HeapPos + 1, 1)) LT _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NodeValues(BinHeap(2 * HeapPos + 2, 0), BinHeap(2 * HeapPos + 2, 1)) <span class="kw1">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a = 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a = 2<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ChildPos = 2 * HeapPos + a<br />
&nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="co1">&#8216;see if the child is smaller than the parent<br />
</span> &nbsp; &nbsp;<span class="kw1">If</span> NodeValues(BinHeap(HeapPos, 0), BinHeap(HeapPos, 1)) GT _<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NodeValues(BinHeap(ChildPos, 0), BinHeap(ChildPos, 1)) <span class="kw1">Then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">&#8216;swap values<br />
</span> &nbsp; &nbsp; &nbsp; &nbsp;TempRow = BinHeap(HeapPos, 0)<br />
&nbsp; &nbsp; &nbsp; &nbsp; TempCol = BinHeap(HeapPos, 1)<br />
&nbsp; &nbsp; &nbsp; &nbsp; TempHeapPos = HeapPositions(BinHeap(HeapPos, 0), BinHeap(HeapPos, 1))<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; BinHeap(HeapPos, 0) = BinHeap(ChildPos, 0)<br />
&nbsp; &nbsp; &nbsp; &nbsp; BinHeap(HeapPos, 1) = BinHeap(ChildPos, 1)<br />
&nbsp; &nbsp; &nbsp; &nbsp; HeapPositions(TempRow, TempCol) = HeapPositions(BinHeap(ChildPos, 0), BinHeap(ChildPos, 1))<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; HeapPositions(BinHeap(ChildPos, 0), BinHeap(ChildPos, 1)) = TempHeapPos<br />
&nbsp; &nbsp; &nbsp; &nbsp; BinHeap(ChildPos, 0) = TempRow<br />
&nbsp; &nbsp; &nbsp; &nbsp; BinHeap(ChildPos, 1) = TempCol<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">Call</span> PercolateDown(ChildPos, BinHeap, HeapLen)<br />
&nbsp; &nbsp; <span class="kw1">End</span> <span class="kw1">If</span> &nbsp; &nbsp;<br />
<span class="kw1">End</span> <span class="kw1">Sub</span></div>
</div>
<p>The chief advantage of this method is that each node is checked at most once.  Th chief disadvantage is that it is needlessly complicated.  It runs in about a tenth of a second on my machine.</p>
<p>-Josh</p>
]]></content:encoded>
	</item>
</channel>
</rss>

