<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mathematical optimization &#8211; stoimen&#039;s web log</title>
	<atom:link href="/tag/mathematical-optimization/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>on web development</description>
	<lastBuildDate>Tue, 13 Feb 2018 08:18:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.0.3</generator>
	<item>
		<title>Computer Algorithms: Longest Increasing Subsequence</title>
		<link>/2012/12/03/computer-algorithms-longest-increasing-subsequence/</link>
		<comments>/2012/12/03/computer-algorithms-longest-increasing-subsequence/#comments</comments>
		<pubDate>Mon, 03 Dec 2012 13:22:08 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[dynamic programming]]></category>
		<category><![CDATA[Graphs]]></category>
		<category><![CDATA[Bellman–Ford algorithm]]></category>
		<category><![CDATA[Directed acyclic graph]]></category>
		<category><![CDATA[Dynamic programming]]></category>
		<category><![CDATA[equal sub-solutions]]></category>
		<category><![CDATA[Facebook Inc]]></category>
		<category><![CDATA[Google Inc.]]></category>
		<category><![CDATA[graph algorithms]]></category>
		<category><![CDATA[Graph theory]]></category>
		<category><![CDATA[Longest increasing subsequence]]></category>
		<category><![CDATA[Mathematical optimization]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Network theory]]></category>
		<category><![CDATA[Operations research]]></category>
		<category><![CDATA[Richard Bellman]]></category>
		<category><![CDATA[Routing algorithms]]></category>
		<category><![CDATA[Shortest path problem]]></category>
		<category><![CDATA[sub-solution]]></category>
		<category><![CDATA[Theoretical computer science]]></category>
		<category><![CDATA[Yahoo! Inc.]]></category>

		<guid isPermaLink="false">/?p=3478</guid>
		<description><![CDATA[Introduction A very common problem in computer programming is finding the longest increasing (decreasing) subsequence in a sequence of numbers (usually integers). Actually this is a typical dynamic programming problem. Dynamic programming can be described as a huge area of computer science problems that can be categorized by the way they can be solved. Unlike &#8230; <a href="/2012/12/03/computer-algorithms-longest-increasing-subsequence/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Longest Increasing Subsequence</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/" rel="bookmark" title="Computer Algorithms: Shortest Path in a Directed Acyclic Graph">Computer Algorithms: Shortest Path in a Directed Acyclic Graph </a></li>
<li><a href="/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">Computer Algorithms: Dijkstra Shortest Path in a Graph </a></li>
<li><a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Computer Algorithms: Bellman-Ford Shortest Path in a Graph </a></li>
<li><a href="/2012/12/10/computer-algorithms-topological-sort-revisited/" rel="bookmark" title="Computer Algorithms: Topological Sort Revisited">Computer Algorithms: Topological Sort Revisited </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>A very common problem in computer programming is finding the longest increasing (decreasing) subsequence in a sequence of numbers (usually integers). Actually this is a typical dynamic programming problem.</p>
<p>Dynamic programming can be described as a huge area of computer science problems that can be categorized by the way they can be solved. Unlike divide and conquer, where we were able to merge the fairly equal sub-solutions in order to receive one single solution of the problem, in dynamic programming we usually try to find an optimal sub-solution and then grow it.</p>
<p>Once we have an optimal sub-solution on each step we try to upgrade it in order to cover the whole problem. Thus a typical member of the dynamic programming class is finding the longest subsequence.</p>
<p>However this problem is interesting because it can be related to graph theory. Let’s find out how.<span id="more-3478"></span></p>
<h2>Overview</h2>
<p>We already know various ways to calculate the shortest paths in a graph. Indeed finding the single-source shortest path is a typical graph problem. To model such kind of solutions we definitely need a graph represented in our solution. </p>
<p>However the single-source shortest path isn’t a straight-forward problem. It depends on many factors. Thus for positive edges <a href="/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">the algorithm of Edsger Dijkstra</a> can be a perfect solution, but when the graph contains negative edges his algorithm is no longer useful. </p>
<p>In the presence of negative edges the Dijkstra’s algorithm doesn’t work and we’d better use the <a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Bellman-Ford algorithm</a>. It is interesting to note, that it was exactly <a href="http://en.wikipedia.org/wiki/Richard_E._Bellman" title="Richard E. Bellman" target="_blank">Richard Bellman</a> who first introduced the term “dynamic programming” in the 1940s.</p>
<p>In fact the Bellman-Ford algorithm was able to detect negative cycles. That’s too important, because in presence of negative cycles the shortest path problem is no longer well defined. </p>
<p>In the other hand when we’re talking about <a href="/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/" title="Computer Algorithms: Shortest Path in a Directed Acyclic Graph">shortest paths in a DAG</a> (Directed Acyclic Graph) we can find a faster (linear) solution. That’s because we’re sure that there are no cycles (not even negative cycles)! </p>
<figure id="attachment_3498" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/1.-Toplogical-Sort.png"><img src="/wp-content/uploads/2012/12/1.-Toplogical-Sort.png" alt="Toplogical Sort" title="Toplogical Sort" width="620" height="399" class="size-full wp-image-3498" srcset="/wp-content/uploads/2012/12/1.-Toplogical-Sort.png 620w, /wp-content/uploads/2012/12/1.-Toplogical-Sort-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Finding the shortest paths in a DAG is closely related to the topological sorting of the DAG. This gives us a linear representation of the vertices of the DAG and we can clearly calculate the distances from the starting node to all other nodes. Note that in a DAG we have one or more nodes that can be considered as starting nodes – which means they don’t have predecessors (incoming edges).</p>
<figure id="attachment_3497" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/2.-Toplogical-Sort-2.png"><img src="/wp-content/uploads/2012/12/2.-Toplogical-Sort-2.png" alt="Toplogical Sort 2" title="Toplogical Sort 2" width="620" height="399" class="size-full wp-image-3497" srcset="/wp-content/uploads/2012/12/2.-Toplogical-Sort-2.png 620w, /wp-content/uploads/2012/12/2.-Toplogical-Sort-2-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Following the words above is pretty hard to find what all these graph algorithms have to do with finding the longest increasing (decreasing) subsequence. Actually this problem is very closely related to the toplogical sort of the DAG and the problem of finding shortest paths in a DAG.</p>
<p>That’s because we can represent our sequence as a DAG. The only thing we must care about is to “connect” with directed edges those elements that form an increasing (decreasing) pair. </p>
<figure id="attachment_3496" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/3.-Integer-Sequence.png"><img src="/wp-content/uploads/2012/12/3.-Integer-Sequence.png" alt="Integer Sequence as a DAG" title="Integer Sequence" width="620" height="399" class="size-full wp-image-3496" srcset="/wp-content/uploads/2012/12/3.-Integer-Sequence.png 620w, /wp-content/uploads/2012/12/3.-Integer-Sequence-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Thus the sequence from our example [1, 8, 2, 7, 3, 4, 1, 6] is going to look like this.</p>
<figure id="attachment_3495" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/4.-Longest-subsequence.png"><img src="/wp-content/uploads/2012/12/4.-Longest-subsequence.png" alt="Longest subsequence" title="Longest subsequence" width="620" height="399" class="size-full wp-image-3495" srcset="/wp-content/uploads/2012/12/4.-Longest-subsequence.png 620w, /wp-content/uploads/2012/12/4.-Longest-subsequence-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Another important thing to note is that we don’t search for shortest, but for longest path, since our task is to find the longest subsequence.</p>
<h2>Pseudo Code</h2>
<p>Our pseudo code for finding the shortest paths in a DAG was something like that.</p>
<pre>
1. Get the toplogically sorted list L of the DAG;
2. The starting node is s;
3. The distance to s equals to 0;
4. All other distances are initialized to &#8734;
5. For each node (v) in L\{s} do:
5.1. If dist(v) > dist(u) + w(u, v) then
5.1.1.  dist(v) := dist(u) + w(u, v)
</pre>
<p>In the above pseudo code &#8220;u&#8221; is every predecessor of &#8220;v&#8221;!</p>
<p>Now we must “reverse” the solution above in order to find the longest increasing subsequence. Note that we don&#8217;t care any more about the weight of the edges, thus we can simply substitute them with 1.</p>
<pre>
1. Get the sequence (L) as a toplogically sorted DAG;
2. For each (i) in L do:
2.1. S(i) := 1 + max(S(j), where (i, j) is an edge from the DAG);
</pre>
<h2>Application</h2>
<p>Finding the longest increasing subsequence can be very useful not only at the Google/Yahoo/Facebook interview, but also in various fields of statistics.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/" rel="bookmark" title="Computer Algorithms: Shortest Path in a Directed Acyclic Graph">Computer Algorithms: Shortest Path in a Directed Acyclic Graph </a></li>
<li><a href="/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">Computer Algorithms: Dijkstra Shortest Path in a Graph </a></li>
<li><a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Computer Algorithms: Bellman-Ford Shortest Path in a Graph </a></li>
<li><a href="/2012/12/10/computer-algorithms-topological-sort-revisited/" rel="bookmark" title="Computer Algorithms: Topological Sort Revisited">Computer Algorithms: Topological Sort Revisited </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/12/03/computer-algorithms-longest-increasing-subsequence/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Computer Algorithms: Minimum and Maximum</title>
		<link>/2012/05/21/computer-algorithms-minimum-and-maximum/</link>
		<comments>/2012/05/21/computer-algorithms-minimum-and-maximum/#comments</comments>
		<pubDate>Mon, 21 May 2012 20:14:30 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Application This algorithm]]></category>
		<category><![CDATA[Calculus]]></category>
		<category><![CDATA[comparisons solution]]></category>
		<category><![CDATA[Counting sort]]></category>
		<category><![CDATA[Mathematical analysis]]></category>
		<category><![CDATA[Mathematical optimization]]></category>
		<category><![CDATA[Maxima and minima]]></category>
		<category><![CDATA[memory solution]]></category>
		<category><![CDATA[Minima and maxima]]></category>
		<category><![CDATA[Selection algorithm]]></category>
		<category><![CDATA[sequential search]]></category>
		<category><![CDATA[Sorting algorithms]]></category>
		<category><![CDATA[The algorithm]]></category>

		<guid isPermaLink="false">/?p=3134</guid>
		<description><![CDATA[Introduction To find the minimum value into an array of items itsn&#8217;t difficult. There are not many options to do that. The most natural approach is to take the first item and to compare its value against the values of all other elements. Once we find a smaller element we continue the comparisons with its &#8230; <a href="/2012/05/21/computer-algorithms-minimum-and-maximum/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Minimum and Maximum</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/05/28/computer-algorithms-order-statistics-the-algorithm/" rel="bookmark" title="Computer Algorithms: Order Statistics">Computer Algorithms: Order Statistics </a></li>
<li><a href="/2012/11/12/computer-algorithms-kruskals-minimum-spanning-tree/" rel="bookmark" title="Computer Algorithms: Kruskal&#8217;s Minimum Spanning Tree">Computer Algorithms: Kruskal&#8217;s Minimum Spanning Tree </a></li>
<li><a href="/2012/02/13/computer-algorithms-insertion-sort/" rel="bookmark" title="Computer Algorithms: Insertion Sort">Computer Algorithms: Insertion Sort </a></li>
<li><a href="/2012/11/19/computer-algorithms-prims-minimum-spanning-tree/" rel="bookmark" title="Computer Algorithms: Prim&#8217;s Minimum Spanning Tree">Computer Algorithms: Prim&#8217;s Minimum Spanning Tree </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>To find the minimum value into an array of items itsn&#8217;t difficult. There are not many options to do that. The most natural approach is to take the first item and to compare its value against the values of all other elements. Once we find a smaller element we continue the comparisons with its value. Finally we find the minimum.</p>
<p><a href="/wp-content/uploads/2012/05/1.-Find-a-Minimum.png"><img class="size-full wp-image-3150" title="Find a Minimum" src="/wp-content/uploads/2012/05/1.-Find-a-Minimum.png" alt="Find a Minimum" width="621" height="431" srcset="/wp-content/uploads/2012/05/1.-Find-a-Minimum.png 621w, /wp-content/uploads/2012/05/1.-Find-a-Minimum-300x208.png 300w" sizes="(max-width: 621px) 100vw, 621px" /></a></p>
<p>First thing to note is that we pass through the array with <strong>n</strong> steps and we need exactly <strong>n-1</strong> comparisons. It’s clear that this is the optimal solution, because we must check all the elements. For sure we can’t be sure that we’ve found the minimum (maximum) value without checking every single value.<br />
<span id="more-3134"></span></p>
<h2>Overview</h2>
<p>The algorithm above is very simple and we’re sure that it is optimal. Obviously finding both the minimum and the maximum value is O(n) with <strong>n-1</strong> comparisons, but what about combining these tasks into one single pass.</p>
<figure id="attachment_3153" style="width: 621px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/2.-Find-a-Maximum.png"><img class="size-full wp-image-3153" title="Find a Maximum" src="/wp-content/uploads/2012/05/2.-Find-a-Maximum.png" alt="Find a Maximum" width="621" height="431" srcset="/wp-content/uploads/2012/05/2.-Find-a-Maximum.png 621w, /wp-content/uploads/2012/05/2.-Find-a-Maximum-300x208.png 300w" sizes="(max-width: 621px) 100vw, 621px" /></a><figcaption class="wp-caption-text">Finding the maximum is identical to finding the minimum and requires n-1 comparisons!</figcaption></figure>
<p>Since they both are <strong>O(n)</strong> and need <strong>n-1</strong> comparisons it’s natural to think that combining the two tasks will be O(n) and 2n &#8211; 2 comparisons. However we can reduce the number of comparisons!</p>
<p>Instead of taking only one item from the array and comparing it against the minimum and maximum we can take a pair of items at each step. Thus we can first compare them and then compare the smaller value with the currently smallest value and the greater item with the currently greatest value. This will make only 3 comparisons instead of 4.</p>
<p><a href="/wp-content/uploads/2012/05/3.-Find-both-minimum-and-maximum.png"><img class="alignnone size-full wp-image-3155" title="Find both minimum and maximum" src="/wp-content/uploads/2012/05/3.-Find-both-minimum-and-maximum.png" alt="Both minimum and maximum with less comparisons!" width="619" height="383" srcset="/wp-content/uploads/2012/05/3.-Find-both-minimum-and-maximum.png 619w, /wp-content/uploads/2012/05/3.-Find-both-minimum-and-maximum-300x185.png 300w" sizes="(max-width: 619px) 100vw, 619px" /></a></p>
<h2>Implementation</h2>
<p>It’s easy to implement the minimum (maximum) algorithms with a single loop.</p>
<p><script src="https://gist.github.com/stoimen/d2d44986bb70a19bc72c.js"></script></p>
<p>The implementation of finding the maximum is practically the same.</p>
<p><script src="https://gist.github.com/stoimen/fff5cb54c413ca332ffb.js"></script></p>
<p>Simply merging these two functions will lead us to a O(n) with 2n &#8211; 2 comparisons solution.</p>
<p><script src="https://gist.github.com/stoimen/82e563992421dc612498.js"></script></p>
<p>However we can take a pair of items on each step. First we’ll compare the items from that pair and after that we’ll compare them respectively with the minimum and the maximum value. Because on each iteration we jump by two items, in case the number of array items is even we must check for the array boundaries. This can be overcome by adding a sentinel. Thus the array items are always odd, but this will lead us to a &#8220;extra&#8221; memory solution.</p>
<h3>Sentinel</h3>
<p><script src="https://gist.github.com/stoimen/4b46f015c096630cd2b1.js"></script></p>
<h3>Without sentinel</h3>
<p><script src="https://gist.github.com/stoimen/a64ac6100e95f63812dc.js"></script></p>
<h2>Complexity</h2>
<p>The complexity of finding both minimum and maximum is O(n). Even after combining the both algorithms in one single pass the complexity remains O(n). However in the second case we can reduce the number of comparisons to 3 * ceil(n/2) instead of 2n &#8211; 2!</p>
<h2>Application</h2>
<p>This algorithm can be applied in various fields of the computer science, since its nature is so basic. However there are two reasons why this approach is so important.</p>
<p>First we can see how by combining two &#8220;algorithms&#8221; doesn’t mean that we combine their complexities or the number of operations. With a clever trick and with the observation that the two operations are related (minimum and maximum) we can reduce the number of comparisons.</p>
<p>In the other hand we see how using a sentinel can be very handy and can spare us some comparisons, just like the <a title="Computer Algorithms: Sequential Search" href="/2011/11/24/computer-algorithms-sequential-search/">sequential search</a>.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/05/28/computer-algorithms-order-statistics-the-algorithm/" rel="bookmark" title="Computer Algorithms: Order Statistics">Computer Algorithms: Order Statistics </a></li>
<li><a href="/2012/11/12/computer-algorithms-kruskals-minimum-spanning-tree/" rel="bookmark" title="Computer Algorithms: Kruskal&#8217;s Minimum Spanning Tree">Computer Algorithms: Kruskal&#8217;s Minimum Spanning Tree </a></li>
<li><a href="/2012/02/13/computer-algorithms-insertion-sort/" rel="bookmark" title="Computer Algorithms: Insertion Sort">Computer Algorithms: Insertion Sort </a></li>
<li><a href="/2012/11/19/computer-algorithms-prims-minimum-spanning-tree/" rel="bookmark" title="Computer Algorithms: Prim&#8217;s Minimum Spanning Tree">Computer Algorithms: Prim&#8217;s Minimum Spanning Tree </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/05/21/computer-algorithms-minimum-and-maximum/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
