<script>!function(){functiont(t){document.documentElement.setAttribute("data-theme",t)}vare=function(){try{returnnewURLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{returnlocalStorage.getItem("theme")}catch(t){}}();t(null!==e?e:"light")}(),function(){try{constc=newURLSearchParams(window.location.search).entries();for(var[t,e]ofc)if(t.startsWith("docusaurus-data-")){vara=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><divid="__docusaurus"><divrole="region"aria-label="Skip to main content"><aclass="skipToContent_fXgn"href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><navaria-label="Main"class="navbar navbar--fixed-top"><divclass="navbar__inner"><divclass="navbar__items"><buttonaria-label="Toggle navigation bar"aria-expanded="false"class="navbar__toggle clean-btn"type="button"><svgwidth="30"height="30"viewBox="0 0 30 30"aria-hidden="true"><pathstroke="currentColor"stroke-linecap="round"stroke-miterlimit="10"stroke-width="2"d="M4 7h22M4 15h22M4 23h22"></path></svg></button><aclass="navbar__brand"href="/"><bclass="navbar__title text--truncate">mf</b></a><divclass="navbar__item dropdown dropdown--hoverable"><ahref="#"aria-haspopup="true"aria-expanded="false"role="button"class="navbar__link">Additional FI MU materials</a><ulclass="dropdown__menu"><li><aaria-current="page"class="dropdown__link dropdown__link--active"href="/algorithms/">Algorithms</a></li><li><aclass="dropdown__link"href="/c/">C</a></li><li><aclass="dropdown__link"href="/cpp/">C++</a></li></ul></div><aclass="navbar__item navbar__link"href="/contributions/">Contributions</a><aclass="navbar__item navbar__link"href="/talks/">Talks</a></div><divclass="navbar__items navbar__items--right"><aclass="navbar__item navbar__link"href="/blog/">Blog</a><divclass="toggle_vylO colorModeToggle_DEke"><buttonclass="clean-btn toggleButton_gllP toggleButtonDisabled_aARS"type="button"disabled=""title="Switch between dark and light mode (currently light mode)"aria-label="Switch between dark and light mode (currently light mode)"aria-live="polite"><svgviewBox="0 0 24 24"width="24"height="24"class="lightToggleIcon_pyhR"><pathfill="currentColor"d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svgviewBox="0 0 24 24"width="24"height="24"class="darkToggleIcon_wfgR"><pathfill="currentColor"d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg></button></div><divclass="navbarSearchContainer_Bca1"><buttontype="button"class="DocSearch DocSearch-Button"aria-label="Search"><spanclass="DocSearch-Button-Container"><svgwidth="20"height="20"class="DocSearch-Search-Icon"viewBox="0 0 20 20"><pathd="M14.38614.386l4.08774.0877-4.0877-4.0877c-2.
<p>Let's start by the recap of what we've achieved so far:</p>
<ol>
<li>We have implemented a naïve brute-force algorithm that tries to relax paths
as long as there are any paths to be relaxed.</li>
<li>Then we have fixed an issue caused by negative loops that can result in
a non-terminating run of our brute-force method. At this moment we have made
some small arguments why are bounding is enough and doesn't prevent any
shortest path to <em>not be</em> discovered.</li>
<li>Finally we have converted our bounded brute-force algorithm into the
Bellman-Ford algorithm.</li>
<li>We have mentioned the worst-case time complexity of our bounded naïve
approach and also the Bellman-Ford algorithm. Our worst-case depended on the
fact that we assumed the worst possible ordering of the relaxations. However
we could also try to relax in the most ideal ordering which could result in a
faster algorithm and that's how we got to the Dijkstra's algorithm.</li>
</ol>
<p>Now the question is, could we improve the Dijkstra's algorithm to get even
better results? And the answer is <em>maybe</em>!</p>
<p>Dijkstra's algorithm chooses the next cheapest vertex for relaxing. This is good
as long as there is no additional information. However, imagine a roadmap of
some country. If you're in the middle of the map and you want to go south, it
doesn't make much sense for you to go to the north (in the opposite direction),
but a little bit might make sense, so that you can switch to highway and go much
faster.</p>
<p>The important question here is how to <em>influence</em> the algorithm, so that it does
choose the path that <em>makes more sense</em> rather than the one that costs the
least.</p>
<h2class="anchor anchorWithStickyNavbar_LWe7"id="a-description">A* description<ahref="#a-description"class="hash-link"aria-label="Direct link to A* description"title="Direct link to A* description"></a></h2>
<p>The <em>A* algorithm</em> can be considered a modification of Dijkstra's algorithm. The
cost is still the same, we cannot change it, right? However when we pick the
vertices from the heap, we can influence the order by some <em>heuristic</em>. In this
case, we introduce a function that can suggest how feasible the vertex is.</p>
<h2class="anchor anchorWithStickyNavbar_LWe7"id="roadmap-heuristic">Roadmap heuristic<ahref="#roadmap-heuristic"class="hash-link"aria-label="Direct link to Roadmap heuristic"title="Direct link to Roadmap heuristic"></a></h2>
<p>Let's have a look at the heuristic we could use for the roadmap example. There
are roads (the edges) and towns (the vertices). Cost could be an average time to
travel the road. What heuristic could we use to influence our algorithm to
choose a better ordering of the vertices when relaxing?</p>
<p>In the former example we've said that it doesn't make much sense to go in the
opposite direction than our goal is… We could choose the distance from our goal
as the heuristic, e.g. right now we're 100 km away from our goal, using this
road makes us 50 km away and using the other road we will be 200 km away.</p>
<h2class="anchor anchorWithStickyNavbar_LWe7"id="heuristic-for-our-map">Heuristic for our map<ahref="#heuristic-for-our-map"class="hash-link"aria-label="Direct link to Heuristic for our map"title="Direct link to Heuristic for our map"></a></h2>
<p>Our map is a bit simpler, but we can use a very similar principle. We will use
the <em>Manhattan distance</em>, which is defined in a following way:</p>
<p>Since we cannot move in diagonals, it makes sense to maintain the distance in
the actual steps from the goal.</p>
<h2class="anchor anchorWithStickyNavbar_LWe7"id="passing-the-heuristic">Passing the heuristic<ahref="#passing-the-heuristic"class="hash-link"aria-label="Direct link to Passing the heuristic"title="Direct link to Passing the heuristic"></a></h2>
<p>In our case, when we're using C++, we can just template the function that will
calculate the shortest path and pass the heuristic as a parameter.</p>
<h2class="anchor anchorWithStickyNavbar_LWe7"id="implementation">Implementation<ahref="#implementation"class="hash-link"aria-label="Direct link to Implementation"title="Direct link to Implementation"></a></h2>
<p>Actual implementation is very easy once we have the Dijkstra's algorithm:</p>
<h2class="anchor anchorWithStickyNavbar_LWe7"id="running-on-our-map">Running on our map<ahref="#running-on-our-map"class="hash-link"aria-label="Direct link to Running on our map"title="Direct link to Running on our map"></a></h2>
<p>For this algorithm I will also show the example of a call:</p>
<h2class="anchor anchorWithStickyNavbar_LWe7"id="comparison">Comparison<ahref="#comparison"class="hash-link"aria-label="Direct link to Comparison"title="Direct link to Comparison"></a></h2>
<p>Now you may wonder how does it compare to the previous algorithms. Supposedly it
should be faster. Let's add counters and debugging output when we update
distance to our goal. And now if we run our code, we get the following output:</p>
<p>From the output we can easily deduce that for both brute-force and Bellman-Ford,
which are in our case identical, we actually relax three times and for the last
time in the 89th iteration.</p>
<p>Dijkstra's algorithm manages to find the shortest path to our goal already in
the 41st iteration.</p>
<p>And finally after introducing some heuristic, we could find the shortest path
in the 31st iteration.</p>
<divclass="theme-admonition theme-admonition-danger admonition_xJq3 alert alert--danger"><divclass="admonitionHeading_Gvgb"><spanclass="admonitionIcon_Rf37"><svgviewBox="0 0 12 16"><pathfill-rule="evenodd"d="M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"></path></svg></span>danger</div><divclass="admonitionContent_BuS1"><p>Please keep in mind that choosing bad heuristic can actually lead to worse
results than using no heuristic at all.</p></div></div>
<h2class="anchor anchorWithStickyNavbar_LWe7"id="summary">Summary<ahref="#summary"class="hash-link"aria-label="Direct link to Summary"title="Direct link to Summary"></a></h2>
<p>And there we have it. We have made our way from the brute-force algorithm all
the way to more optimal ones. Hopefully we could notice how the small