<?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>SlashCode &#187; complessità</title>
	<atom:link href="http://davideaversa.it/slashcode/tag/complessita/feed/" rel="self" type="application/rss+xml" />
	<link>http://davideaversa.it/slashcode</link>
	<description></description>
	<lastBuildDate>Thu, 03 May 2012 14:28:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Scheme &#8211; Lezione 6 &#8211; Complessita&#8217;</title>
		<link>http://davideaversa.it/slashcode/2009/10/scheme-lezione-6-complessita/</link>
		<comments>http://davideaversa.it/slashcode/2009/10/scheme-lezione-6-complessita/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 17:53:11 +0000</pubDate>
		<dc:creator>THeK3nger</dc:creator>
				<category><![CDATA[Lisp/Scheme]]></category>
		<category><![CDATA[complessità]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[scheme]]></category>

		<guid isPermaLink="false">http://davideaversa.it/slashcode/?p=448</guid>
		<description><![CDATA[<div><a href="http://davideaversa.it/slashcode/2009/10/scheme-lezione-6-complessita/"><img title="Scheme &#8211; Lezione 6 &#8211; Complessita&#8217;" src="http://davideaversa.it/slashcode/wp-content/uploads/2009/10/frattale-150x150.jpg" alt="Scheme &#8211; Lezione 6 &#8211; Complessita&#8217;"  width="200" height="200" /></a></div><br/>Dopo aver visto come funziona la ricorsione in Scheme dobbiamo valutare un altro aspetto molto rilevante: il costo. Non tutto ciò che logicamente funziona funziona poi all&#8217;atto pratico. Ad esempio, se ripescate la funzione ricorsiva della Funzione di Fibonacci e provate a farla partire noterete che già con numeri relativamente bassi (come 100) il sistema <a href='http://davideaversa.it/slashcode/2009/10/scheme-lezione-6-complessita/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<div style="height:33px;" class="really_simple_share robots-nocontent snap_nopreview"><div class="really_simple_share_facebook_like" style="width:100px;"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavideaversa.it%2Fslashcode%2F2009%2F10%2Fscheme-lezione-6-complessita%2F&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;send=false&amp;height=27" 
						scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe></div><div class="really_simple_share_google1" style="width:90px;"><div class="g-plusone" data-size="medium" data-href="http://davideaversa.it/slashcode/2009/10/scheme-lezione-6-complessita/" ></div></div><div class="really_simple_share_twitter" style="width:110px;"><a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" 
						data-text="Scheme &#8211; Lezione 6 &#8211; Complessita&#8217;" data-url="http://davideaversa.it/slashcode/2009/10/scheme-lezione-6-complessita/" 
						data-via=""  ></a></div></div>
		<div style="clear:both;"></div><p><img class="alignleft size-thumbnail wp-image-460" title="frattale" src="http://davideaversa.it/slashcode/wp-content/uploads/2009/10/frattale-150x150.jpg" alt="frattale" width="150" height="150" />Dopo aver visto come funziona la ricorsione in Scheme dobbiamo valutare un altro aspetto molto rilevante: <strong>il costo</strong>. Non tutto ciò che logicamente funziona funziona poi all&#8217;atto pratico. Ad esempio, se ripescate la funzione ricorsiva della <strong><em>Funzione di Fibonacci</em></strong> e provate a farla partire noterete che già con numeri relativamente bassi (come 100) il sistema inizierà a intasarsi e non darà alcun risultato se non quello di dover killare il processo.</p>
<p>Perché questo? Perché l&#8217;implementazione dell&#8217;algoritmo, sebbene sia vera e matematicamente corretta, necessita un numero troppo elevato di calcoli o di memoria.</p>
<p>Iniziamo col dare dei cenni sulla complessità di un algoritmo. La complessità di un algoritmo è definita asintoticamente con un infinito di ordine superiore a una funzione f(x). In questo caso si dice che l&#8217;algoritmo ha complessità dell&#8217;ordine di f(x).</p>
<p>Cosa significa? E&#8217; semplice. Supponete di far valere 1 il costo di ogni operazione base come somma, prodotto, cdr, car e via dicendo (ovviamente è un approssimazione). Supponete di stabilire un contatore che sommi il costo di ogni operazione eseguita. Supponete poi di eseguire questa funzione (con relativo contatore) per un imput di dimensione 1, poi per un input di dimensione 2, poi per un input di dimensione 3 e così via. La serie di numeri che otterrete non sarà altro che i valori di una funzione f(x)al variare di x. La complessità si riduce quindi all&#8217;ordine di infinito di questa funzione.</p>
<p>Data l&#8217;asintoticità della definizione, solitamente si trascurano i valori per x piccolo e si approssima molto per x che tende a infinito.</p>
<p>Senza addentrarci nei particolari sappiate che in ogni algoritmo esiste un operazione, detta <strong>operazione dominante</strong>, la quale complessità è uguale alla complessità dell&#8217;algoritmo nella sua interezza.</p>
<p>Negli algoritmi ricorsivi l&#8217;operazione dominante è <strong>la ricorsione</strong>. Per trovare la complessità di una funzione in scheme (che sono per definizione tutte ricorsive) ci basta quindi sapere quante volte una funzione chiama la ricorsione.</p>
<p>Questo può essere molto complicato, ma è giusto che impariate a identificare almento i casi semplici. Questo può essere fatto molto semplicemente.</p>
<p>Supponiamo di voler calcolare la complessità dell&#8217;algoritmo <strong>fattoriale</strong> visto qualche lezione fa. L&#8217;espressione ricorsiva del fattoriale è la seguente:</p>
<p><img class="aligncenter size-full wp-image-457" title="Fattoriale" src="http://davideaversa.it/slashcode/wp-content/uploads/2009/10/CodeCogsEqn.gif" alt="Fattoriale" width="168" height="57" />Per trovare il costo basta seguire la formula:</p>
<p><img class="aligncenter size-full wp-image-458" title="CodeCogsEqn(2)" src="http://davideaversa.it/slashcode/wp-content/uploads/2009/10/CodeCogsEqn2.gif" alt="CodeCogsEqn(2)" width="392" height="57" />Questo perché il costo di f(0) è chiaramente unitario. Il costo di f(n), per il principio dell&#8217;operazione è solamente il costo della ricorsione e il costo della ricorsione non è altro che 1 più il costo di tutte le altre funzioni invocate.</p>
<p>Ma siamo arrivati ad una suluzione? Ancora no. Dobbiamo esplicitare il costo ovvero toglierlo dalla sua forma ricorsiva. Per fare ciò possiamo semplicemente espandere la seconda equazione.</p>
<ul>
<li>C[f(n)]</li>
<li>1 + C[f(n-1)]</li>
<li>2 + C[f(n-2)</li>
<li> ...</li>
<li> n + C[f(0)]</li>
<li> n+1</li>
<li>che è asintoticamente O(n)</li>
</ul>
<p>Il costo è quindi lineare. (Non esattamente&#8230; ma per non mettere troppa carne al fuoco farò alcune precisazioni al riguardio nella prossima appendice).</p>
<p>Una funzione con complessità lineare è solitamente una funzione discretamente veloce e potente.</p>
<p>Vediamo ora la stessa cosa con la Funzione di Fibonacci.</p>
<p><img class="aligncenter size-full wp-image-459" title="Costo Fibonacci" src="http://davideaversa.it/slashcode/wp-content/uploads/2009/10/CodeCogsEqn3.gif" alt="Costo Fibonacci" width="331" height="79" /></p>
<p>La situazione è leggermente più complessa. Per esplicitare la funzione possiamo comunque espandere C[f(n)] ma non conviene in questo caso. Facciamo un ragionamento più sottile. Cerchiamo di calcolare direttamente il costo totale. Sappiamo che ogni ricorsione chiama due ricorsioni. Alla prima ricorsione avremo costo totale<strong> 1</strong>, alla seconda avremo il costo totale di prima più il costo delle due nuove ricorsioni ovvero<strong> 1 + 2</strong>. Alla terza avremo il costo di prima  più le due ricorsioni nuove lanciate da ognuna delle due ricorsione precedenti ovvero <strong>1 + 2 + 4</strong> (il costo di prima più le due ricorsioni nuove lanciate da ognuna delle due ricorsione precedenti).</p>
<p>Notiamo che abbiamo una serie geometrica che possiamo riassumere in <strong>2^n+1 &#8211; 1</strong> che asintoticamente è <strong>O(2^n)</strong>.</p>
<p>Il costo è <strong>esponenziale</strong>. Un algoritmo esponenziale può solitamente calcolare solo input molto piccoli. Ecco perché il nostro algoritmo di Fibonacci si bloccava anche con numeri piccoli come 100.</p>
<p>Come possiamo allora migliorare questo algoritmo? Esistono tecniche un po&#8217; più elaborate che permettono di eseguire algoritmi simili lanciando solo una ricorsione al posto delle due &#8220;canoniche&#8221;. Queste tecniche le esploreremo più in là in quanto necessitano di un po&#8217; di esperienza.</p>
<p>Per il momento vi basti intuire che algoritmi che eseguono troppe ricorsioni contemporaneamente sono spesso troppo costosi per essere utili. Infatti abbiamo visto che basta lanciare due ricorsioni in vece di una per fare esplodere il costo da lineare ad esponenziale.</p>
<p>Non vi serve saper calcolare la complessità di tutto ma vi basta intuire quando un algoritmo sta diventando troppo costoso. Questo è basilare per ogni programmatore, anche al di là di Scheme.</p>
<p>Provate a calcolare il costo di altre funzioni di esempio che ho dato in precedenza. Postate il costo che avete ottenuto nei commenti e vedrò di verificare se avete indovinato.</p>
 <p><a href="http://davideaversa.it/slashcode/?flattrss_redirect&amp;id=448&amp;md5=0b78f9e9fc9cb2c030c7606fcc1c72e6" title="Flattr" target="_blank"><img src="http://davideaversa.it/slashcode/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://davideaversa.it/slashcode/2009/10/scheme-lezione-6-complessita/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=thek3nger&amp;popout=1&amp;url=http%3A%2F%2Fdavideaversa.it%2Fslashcode%2F2009%2F10%2Fscheme-lezione-6-complessita%2F&amp;language=it_IT&amp;category=text&amp;title=Scheme+%26%238211%3B+Lezione+6+%26%238211%3B+Complessita%26%238217%3B&amp;description=Dopo+aver+visto+come+funziona+la+ricorsione+in+Scheme+dobbiamo+valutare+un+altro+aspetto+molto+rilevante%3A+il+costo.+Non+tutto+ci%C3%B2+che+logicamente+funziona+funziona+poi+all%26%238217%3Batto+pratico.+Ad+esempio%2C...&amp;tags=complessit%C3%A0%2Clisp%2Cscheme%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Algoritmica &#8211; Ordinamento &#8211; Bubble Sort</title>
		<link>http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-bubble-sort/</link>
		<comments>http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-bubble-sort/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 00:14:30 +0000</pubDate>
		<dc:creator>THeK3nger</dc:creator>
				<category><![CDATA[Algoritmica]]></category>
		<category><![CDATA[algoritmi]]></category>
		<category><![CDATA[complessità]]></category>
		<category><![CDATA[ordinamento]]></category>

		<guid isPermaLink="false">http://slashcode.wordpress.com/?p=165</guid>
		<description><![CDATA[<div><a href="http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-bubble-sort/"><img title="Algoritmica &#8211; Ordinamento &#8211; Bubble Sort" src="http://upload.wikimedia.org/wikipedia/commons/3/37/Bubble_sort_animation.gif" alt="Algoritmica &#8211; Ordinamento &#8211; Bubble Sort"  width="" /></a></div><br/>Insertion Sort e Selection Sort non si sono rivelati all&#8217;altezza delle nostre aspettative e noi ci ritroviamo ancora senza un algoritmo efficente per ordinare, o meglio: sappiamo ordinare le tracce di un album, oppure i CD di un apiccola collezione domestica, ma avremo molte difficoltà nell&#8217;ordinare in ordine di età gli abitanti di Roma o <a href='http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-bubble-sort/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<div style="height:33px;" class="really_simple_share robots-nocontent snap_nopreview"><div class="really_simple_share_facebook_like" style="width:100px;"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavideaversa.it%2Fslashcode%2F2008%2F12%2Falgoritmica-ordinamento-bubble-sort%2F&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;send=false&amp;height=27" 
						scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe></div><div class="really_simple_share_google1" style="width:90px;"><div class="g-plusone" data-size="medium" data-href="http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-bubble-sort/" ></div></div><div class="really_simple_share_twitter" style="width:110px;"><a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" 
						data-text="Algoritmica &#8211; Ordinamento &#8211; Bubble Sort" data-url="http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-bubble-sort/" 
						data-via=""  ></a></div></div>
		<div style="clear:both;"></div><div class="wp-caption alignleft" style="width: 178px"><img title="Bubble Sort" src="http://upload.wikimedia.org/wikipedia/commons/3/37/Bubble_sort_animation.gif" alt="Lalgoritmo di Bubble Sorting in azione." width="168" height="142" /><p class="wp-caption-text">L&#39;algoritmo di Bubble Sorting in azione.</p></div>
<p>Insertion Sort e Selection Sort non si sono rivelati all&#8217;altezza delle nostre aspettative e noi ci ritroviamo ancora senza un algoritmo efficente per ordinare, o meglio: sappiamo ordinare le tracce di un album, oppure i CD di un apiccola collezione domestica, ma avremo molte difficoltà nell&#8217;ordinare in ordine di età gli abitanti di Roma o i volumi di un agrande biblioteca.</p>
<p>Dobbiamo proseguire la nostra ricerca, cambiamo approccio, questa volta il nostro tentativo cade sul <strong>Bubble Sort</strong>.</p>
<p><span id="more-165"></span>Il <strong>Bubble Sort</strong> deriva il suo nome dal comportamento degli elementi da ordinare sotto l&#8217;effetto di questo algoritm: essi infatti sembrano &#8220;risalire&#8221; l&#8217;array come bollicine nell&#8217;acqua minerale (si nota bene nell&#8217;animazione a lato).</p>
<pre>BubbleSort(array[], elemN)
  alto = elemN
  changed = True
  while (alto &gt; 0 and changed = True) :
    change = False
    for i = 0 to alto - 1 :
      if (array[i] &gt; array[i + 1]) :
        tmp = array[i]
        array[i] = array[i + 1]
        array[i+1] = tmp
        changed = True
    alto = alto - 1</pre>
<p>Il meccanismo di fondo è molto semplice: finchè <em>alto</em> (che l&#8217;indice che indica la &#8220;sommità&#8221; dell&#8217;array) rimane maggiore di zero ed è stato effettuato almento uno scambio (indicato dalla variabile <em>changed</em>) inizio una scansione dall&#8217;inizio fino ad <em>alto</em> dell&#8217;array e ogni volta che trovo un elemento maggiore del successivo, scambio i due elementi di posto.</p>
<p>E&#8217; chiaro quindi che il <strong>Bubble Sort</strong> ha la capacità di accorgersi se un array è già ordinato (infatti se un array è ordinato non entra mai nel if per resettare la variabile <em>changed</em> e questo provoca l&#8217;uscita dal while) nel qual caso effettuerà soltanto la scansione di <em>controllo</em> con consto O(n).</p>
<p>Il caso peggiore è ovviamente <strong>un array ordinato al contrario</strong>. In questo caso infatti ogni scansione serve a posizionare con scambi successivi un solo elemento. Quindi avremo che in totale l&#8217;algoritmo ha costo O(n²).</p>
<p>Esatto anche lui. Anche il Bubble Sort si comporta come l&#8217;Insertion e il Selection Sort. Nessun vantaggio allora?</p>
<p>In realtà no. Un piccolo passo l&#8217;abbiamo fatto. Il Bubble Sort ci permette, con la sua capacità di fermarsi quando un array è ordinato, di eseguire <strong>inserimenti ordinati</strong> (ovvero inserimenti che mantengono l&#8217;ordine) con costo costante nel caso peggiore di O(n). Infatti non dobbiamo fare altro che sfruttare lo stesso meccanismo per scambiare elemento dopo elemento l&#8217;elemento da inserire (inizialmente in testa) fino alla sua posizione naturale.</p>
<p>Quindi ora, dato un array ordinato, sappiamo fare inserimenti ordinati, ma dobbiamo trovare ancora un metodo per ordinare l&#8217;array di partenza.</p>
<p>La nostra ricerca non è finita qui. Possiamo fare di meglio. Proveremo con il <strong>Quick Sort</strong>. Sperando che sia Quick.</p>
 <p><a href="http://davideaversa.it/slashcode/?flattrss_redirect&amp;id=165&amp;md5=60b46ef2376dae7d16b788a01cbf827c" title="Flattr" target="_blank"><img src="http://davideaversa.it/slashcode/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-bubble-sort/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=thek3nger&amp;popout=1&amp;url=http%3A%2F%2Fdavideaversa.it%2Fslashcode%2F2008%2F12%2Falgoritmica-ordinamento-bubble-sort%2F&amp;language=it_IT&amp;category=text&amp;title=Algoritmica+%26%238211%3B+Ordinamento+%26%238211%3B+Bubble+Sort&amp;description=Insertion+Sort+e+Selection+Sort+non+si+sono+rivelati+all%26%238217%3Baltezza+delle+nostre+aspettative+e+noi+ci+ritroviamo+ancora+senza+un+algoritmo+efficente+per+ordinare%2C+o+meglio%3A+sappiamo+ordinare+le+tracce...&amp;tags=algoritmi%2Ccomplessit%C3%A0%2Cordinamento%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Algoritmica &#8211; Ordinamento &#8211; Selection Sort</title>
		<link>http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-selection-sort/</link>
		<comments>http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-selection-sort/#comments</comments>
		<pubDate>Mon, 08 Dec 2008 12:15:23 +0000</pubDate>
		<dc:creator>THeK3nger</dc:creator>
				<category><![CDATA[Algoritmica]]></category>
		<category><![CDATA[algoritmi]]></category>
		<category><![CDATA[complessità]]></category>
		<category><![CDATA[ordinamento]]></category>

		<guid isPermaLink="false">http://slashcode.wordpress.com/?p=161</guid>
		<description><![CDATA[<div><a href="http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-selection-sort/"><img title="Algoritmica &#8211; Ordinamento &#8211; Selection Sort" src="http://upload.wikimedia.org/wikipedia/en/b/b0/Selection_sort_animation.gif" alt="Algoritmica &#8211; Ordinamento &#8211; Selection Sort"  width="" /></a></div><br/>Nell&#8217;ultimo appuntamento abbiamo visto e analizzato gli aspetti generali dell&#8217;Insertion Sort e notato che esso non è affatto un algoritmo usabile in pratica per istanze (ovvero input) molto grandi. Ovviamente l&#8217;Insertion Sort non è l&#8217;unico algoritmo di sorting esistente. Nella nostra ricerca dell&#8217;algoritmo ottimo di sorting oggi guarderemo il Selection Sort. for i = 0 <a href='http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-selection-sort/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<div style="height:33px;" class="really_simple_share robots-nocontent snap_nopreview"><div class="really_simple_share_facebook_like" style="width:100px;"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavideaversa.it%2Fslashcode%2F2008%2F12%2Falgoritmica-ordinamento-selection-sort%2F&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;send=false&amp;height=27" 
						scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe></div><div class="really_simple_share_google1" style="width:90px;"><div class="g-plusone" data-size="medium" data-href="http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-selection-sort/" ></div></div><div class="really_simple_share_twitter" style="width:110px;"><a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" 
						data-text="Algoritmica &#8211; Ordinamento &#8211; Selection Sort" data-url="http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-selection-sort/" 
						data-via=""  ></a></div></div>
		<div style="clear:both;"></div><div class="wp-caption alignleft" style="width: 183px"><img title="Selection Sort" src="http://upload.wikimedia.org/wikipedia/en/b/b0/Selection_sort_animation.gif" alt="Rappresentazione grafica di un ordinamento con Selection Sort" width="173" height="173" /><p class="wp-caption-text">Rappresentazione grafica di un ordinamento con Selection Sort</p></div>
<p>Nell&#8217;ultimo appuntamento abbiamo visto e analizzato gli aspetti generali dell&#8217;<em>Insertion Sort</em> e notato che esso non è affatto un algoritmo usabile in pratica per istanze (ovvero input) molto grandi.</p>
<p>Ovviamente l&#8217;Insertion Sort non è l&#8217;unico algoritmo di sorting esistente. Nella nostra ricerca dell&#8217;algoritmo ottimo di sorting oggi guarderemo il <strong>Selection Sort</strong>.<br />
<span id="more-161"></span></p>
<pre>
<span class="kw1">for</span> i = <span class="nu0">0</span> <span class="kw1">to</span> n<span class="nu0">-2</span> <span class="kw1">:</span>
    min = i
    <span class="kw1">for</span> j = <span class="br0">(</span>i + <span class="nu0">1</span><span class="br0">)</span> <span class="kw1">to</span> n<span class="nu0">-1</span> <span class="kw1">:</span>
        <span class="kw1">if</span> A<span class="br0">[</span>j<span class="br0">]</span> &lt; A<span class="br0">[</span>min<span class="br0">]</span> :
            min = j
    swap A<span class="br0">[</span>i<span class="br0">]</span> <span class="kw3">and</span> A<span class="br0">[</span>min<span class="br0">]</span></pre>
<p>Il principio su cui si basa il Selection Sort è veramente molto semplice. In pratica dato un array A, seleziona il minimo e lo mette in testa, poi, nel sotto-array di dimensione n-1 seleziona il minimo e lo mette in seconda posizione&#8230; e cosi via. Vediamolo con un esempio.</p>
<pre>8i 4 5 6 2 3 min=2
2 4i 5 6 8 3 min=3
2 3 5i 6 8 4 min=4
2 3 4 6i 8 5 min=5
2 3 4 5 8i 6 min=6
2 3 4 5 6 8 (finito)</pre>
<p>Il problema di questo algoritmo è che la ricerca del minimo in un passo non da alcuna informazione su quale sia il minimo nel passo successivo. Per questo motivo ad ogni passo, indipendentemente dall&#8217;ordinamento dell&#8217;input, dobbiamo effettuare la suddetta ricerca. Quindi, poiché la ricerca del minimo ha costo lineare, al primoi passo dovremo pagare n, poi n-1, poi n-2, finché non avremo ordinato tutto l&#8217;array.</p>
<p>Ovvero n  + (n-1) + (n -2) + &#8230; + 1 e quindi, parimenti all&#8217;Insertion Sort, la complessità sarà di O(n²)! Con la differenza che il Selection Sort rimane quadratico anche per un input già ordinato.</p>
<p>Data la quadraticità dell&#8217;algoritmo possiamo effettuare integralmente le stesse considerazioni di &#8220;tempo di calcolo&#8221; che facevamo con l&#8217;Insertion Sort.</p>
<p>Anche il selection sort quindi è un algoritmo molto sconveniente. La nostra ricerca deve quindi proseguire.</p>
 <p><a href="http://davideaversa.it/slashcode/?flattrss_redirect&amp;id=161&amp;md5=d6a448780cc449f66f39a628816e2f30" title="Flattr" target="_blank"><img src="http://davideaversa.it/slashcode/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-selection-sort/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=thek3nger&amp;popout=1&amp;url=http%3A%2F%2Fdavideaversa.it%2Fslashcode%2F2008%2F12%2Falgoritmica-ordinamento-selection-sort%2F&amp;language=it_IT&amp;category=text&amp;title=Algoritmica+%26%238211%3B+Ordinamento+%26%238211%3B+Selection+Sort&amp;description=Nell%26%238217%3Bultimo+appuntamento+abbiamo+visto+e+analizzato+gli+aspetti+generali+dell%26%238217%3BInsertion+Sort+e+notato+che+esso+non+%C3%A8+affatto+un+algoritmo+usabile+in+pratica+per+istanze+%28ovvero+input%29+molto+grandi.+Ovviamente...&amp;tags=algoritmi%2Ccomplessit%C3%A0%2Cordinamento%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Algoritmica &#8211; Ordinamento &#8211; Insertion Sort</title>
		<link>http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-insertion-sort/</link>
		<comments>http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-insertion-sort/#comments</comments>
		<pubDate>Thu, 04 Dec 2008 09:14:31 +0000</pubDate>
		<dc:creator>THeK3nger</dc:creator>
				<category><![CDATA[Algoritmica]]></category>
		<category><![CDATA[algoritmi]]></category>
		<category><![CDATA[complessità]]></category>
		<category><![CDATA[ordinamento]]></category>

		<guid isPermaLink="false">http://slashcode.wordpress.com/?p=153</guid>
		<description><![CDATA[<div><a href="http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-insertion-sort/"><img title="Algoritmica &#8211; Ordinamento &#8211; Insertion Sort" src="http://upload.wikimedia.org/wikipedia/commons/2/25/Insertion_sort_animation.gif" alt="Algoritmica &#8211; Ordinamento &#8211; Insertion Sort"  width="" /></a></div><br/>Volevo discutere in qualche articolo alcuni problemi di algoritmica presentando alcuni algoritmi che li risolvono e analizzandone la complessità. Cominciamo questa vetrina di algoritmi con quelli che risolvono il più classico dei problemi: l&#8217;ordinamento. In particolare cominceremo vedendo uno dei più semplici: insertion sort.Insertion Sort : def insertion_sort(x[], n) : for i = 1 to <a href='http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-insertion-sort/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<div style="height:33px;" class="really_simple_share robots-nocontent snap_nopreview"><div class="really_simple_share_facebook_like" style="width:100px;"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavideaversa.it%2Fslashcode%2F2008%2F12%2Falgoritmica-ordinamento-insertion-sort%2F&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;send=false&amp;height=27" 
						scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe></div><div class="really_simple_share_google1" style="width:90px;"><div class="g-plusone" data-size="medium" data-href="http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-insertion-sort/" ></div></div><div class="really_simple_share_twitter" style="width:110px;"><a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" 
						data-text="Algoritmica &#8211; Ordinamento &#8211; Insertion Sort" data-url="http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-insertion-sort/" 
						data-via=""  ></a></div></div>
		<div style="clear:both;"></div><div class="wp-caption alignleft" style="width: 144px"><img title="Insertion Sort" src="http://upload.wikimedia.org/wikipedia/commons/2/25/Insertion_sort_animation.gif" alt="Come ordina linsertion sort." width="134" height="114" /><p class="wp-caption-text">Come ordina l&#39;insertion sort.</p></div>
<p>Volevo discutere in qualche articolo alcuni problemi di algoritmica presentando alcuni algoritmi che li risolvono e analizzandone la complessità.</p>
<p>Cominciamo questa vetrina di algoritmi con quelli che risolvono il più classico dei problemi: <strong>l&#8217;ordinamento</strong>.</p>
<p>In particolare cominceremo vedendo uno dei più semplici: <strong>insertion sort.</strong><span id="more-153"></span><strong>Insertion Sort</strong> :</p>
<pre>def insertion_sort(x[], n) :
    for i = 1 to n - 1 :
        app = x[i]
        j = i - 1
        while (j &gt;= 0) and (x[j] &gt; app) :
            x[j + 1] = x[j]
            j = j - 1
        x[j + 1] = app</pre>
<p>L&#8217;algoritmo segue un procedimento molto semplice. <em>Insertion Sort </em>utilizza due indici: uno che punta all&#8217;elemento da ordinare (i) mentre l&#8217;altro comincia dall&#8217;elemento che precede il primo indice e va decrescendo (j). All&#8217;inizio viene messo in <em>app</em> il valore puntato dal primo indice. Se l&#8217;elemento puntato dal secondo indice è maggiore di <em>app</em> i due elementi vengono scambiati di posto e decrementato j, altrimenti il valore di app viene copiato in j, il primo indice viene incrementato di uno e infine j resettato.</p>
<p>Vediamo un esempio, supponiamo un array di prova:</p>
<pre>5 3 7 2 8 4</pre>
<p>All&#8217;inizio avremo i due indici  cosi inizializzati:</p>
<pre>j5 i3 2 8 4 app=3</pre>
<p>ed eseguiremo i seguenti passi:</p>
<pre>j3 i5 2 8 4 app=3
3 j5 i2 8 4 app=2
3j 2 i5 8 4 app=2
2 3 j5 i8 4 app=8
2 3 5 j8 i4 app=4
2 3 j5 4 i8 app=4
2 j3 4 5 i8 app=4

2 3 4 5 8</pre>
<p>In pretica il meccanismo alla base dell&#8217;insertion sort è quello di selezionare un elemento con <em>i </em>ed andarlo ad <em>inserire</em> nel suo posto facendolo spostare piano piano verso sinistra.</p>
<p>Ma quanto è oneroso computazionalmente questo algoritmo? Nel caso migliore <em>app </em>è sempre minore dell&#8217;elemento puntato da <em>j</em> e quindi banalmente l&#8217;algorimto termina dopo aver scandito ogni casella dell&#8217;array.</p>
<p>Ma l&#8217;analisi dei costi va fatta analizzando caso peggiore (e spesso il caso medio). Nell&#8217;insertion sort il caso peggiore equivale a quando j deve scandire tutto il sotto-array dall&#8217;inizio alla fine, ovvero <strong>quando l&#8217;array è ordinato al contrario.</strong> In questo caso al primo ciclo avremo che j farà 1 passo, al secondo ciclo ne farà 2 e così via.</p>
<p>Questo ci dice che in un array di dimensione n avremo che j farà in totale:</p>
<pre>1 + 2 + ... (n-1)</pre>
<p>Che in forma chiusa equivale a:</p>
<pre>n(n-1) / 2</pre>
<p>Ovvero, per n che tende a infinito, j fa un numero di iterazione che cresce come una funzione quadratica: ovvero l&#8217;algoritmo ha complessità <strong>O(N²)</strong>.</p>
<p>Ma quantifichiamo questa cosa in termini pratici. Prendiamo il nostro calcolatore ideale di esempio e supponiamo di aver un calcolatore che esegua (molto ottimisticamente) ogni iterazione in 1 nanosecondo e supponiamo di voler ordinare un array X di 40MB di interi. 40MB di interi, poichè ogni intero è composto da 4 byte, equivale ad un array con 40.000.000 / 4 elementi. Ovvero n = 10.000.000.</p>
<p>Poichè insertion sort ha complessità quadratica per ordinare X eseguirà 10^14 iterazioni (sono centomila miliardi di iterazioni). Poichè ogni operazione è eseguita in un nanosecondo il nostro calcolatore è in grado di fare 10^9 operazioni al secondo (un miliardo di operazioni al secondo). Quindi per ordinare l&#8217;array impiegherà 10^5 secondi = 100.000 secondi = 27.7 ore che è circa un giorno.</p>
<p>Poichè, invece, nel caso migliore abbiamo che il costo è lineare, nel caso migliore il nostro calcolatore impiegherà 10^-2 secondi ovvero un centesimo di secondo.</p>
<p><strong>Quindi un applicazione che utilizza insertion sort, su grandi moli di dati ha un <em>gap</em></strong><em> <strong>di complessità</strong> </em><strong>di 10^5/10^-2 = 10^7!! Ovvero il tempo che impiega la vostra applicazione può variare da pochi centesimi di secondo ad un giorno solo a causa di un input!!!</strong></p>
<p>Decisamente inaccettabile per qualunque applicazione rispettabile. L&#8217;insertion sort è quindi grosso modo bocciato: è da tener presente però che può trovare validità per ordinare quantità piccole di dati soprattutto grazie alla sua capacità di essere <strong>in place</strong>, ovvero di non richiedere più memoria di quella dell&#8217;array dato in input.</p>
<p>Nel prossimo articolo continueremo la ricerca del miglior algoritmo di ordinamento, proveremo con il <strong>Selection Sort.</strong></p>
 <p><a href="http://davideaversa.it/slashcode/?flattrss_redirect&amp;id=153&amp;md5=00ca59500f7b5a1aea1bec9c65654516" title="Flattr" target="_blank"><img src="http://davideaversa.it/slashcode/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://davideaversa.it/slashcode/2008/12/algoritmica-ordinamento-insertion-sort/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=thek3nger&amp;popout=1&amp;url=http%3A%2F%2Fdavideaversa.it%2Fslashcode%2F2008%2F12%2Falgoritmica-ordinamento-insertion-sort%2F&amp;language=it_IT&amp;category=text&amp;title=Algoritmica+%26%238211%3B+Ordinamento+%26%238211%3B+Insertion+Sort&amp;description=Volevo+discutere+in+qualche+articolo+alcuni+problemi+di+algoritmica+presentando+alcuni+algoritmi+che+li+risolvono+e+analizzandone+la+complessit%C3%A0.+Cominciamo+questa+vetrina+di+algoritmi+con+quelli+che+risolvono+il+pi%C3%B9...&amp;tags=algoritmi%2Ccomplessit%C3%A0%2Cordinamento%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>

