<?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; algoritmi</title>
	<atom:link href="http://davideaversa.it/slashcode/tag/algoritmi/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>Metodi di Integrazione Numerica</title>
		<link>http://davideaversa.it/slashcode/2011/05/metodi-di-integrazione-numerica/</link>
		<comments>http://davideaversa.it/slashcode/2011/05/metodi-di-integrazione-numerica/#comments</comments>
		<pubDate>Wed, 18 May 2011 12:30:59 +0000</pubDate>
		<dc:creator>THeK3nger</dc:creator>
				<category><![CDATA[Algoritmica]]></category>
		<category><![CDATA[Guide]]></category>
		<category><![CDATA[algoritmi]]></category>
		<category><![CDATA[matematica]]></category>

		<guid isPermaLink="false">http://davideaversa.it/slashcode/?p=719</guid>
		<description><![CDATA[<div><a href="http://davideaversa.it/slashcode/2011/05/metodi-di-integrazione-numerica/"><img title="Metodi di Integrazione Numerica" src="http://davideaversa.it/slashcode/wp-content/uploads/2011/05/cereali-integrali-300x224.jpg" alt="Metodi di Integrazione Numerica"  width="200" height="149" /></a></div><br/>In parecchie applicazioni informatiche, specie in quelle simulative, saper integrare una funzione ricopre un ruolo fondamentale. Purtroppo però le tecniche di integrazione che ci hanno insegnato a scuola o nei corsi di Analisi I sono del tutto inutili. Raramente, infatti, ci troveremo a che fare con funzioni integrabili, anzi, spesso dovremo integrare funzioni non esprimibili <a href='http://davideaversa.it/slashcode/2011/05/metodi-di-integrazione-numerica/' 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%2F2011%2F05%2Fmetodi-di-integrazione-numerica%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/2011/05/metodi-di-integrazione-numerica/" ></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="Metodi di Integrazione Numerica" data-url="http://davideaversa.it/slashcode/2011/05/metodi-di-integrazione-numerica/" 
						data-via=""  ></a></div></div>
		<div style="clear:both;"></div><p><a href="http://davideaversa.it/slashcode/wp-content/uploads/2011/05/cereali-integrali.jpg"><img class="alignleft size-medium wp-image-720" title="cereali-integrali" src="http://davideaversa.it/slashcode/wp-content/uploads/2011/05/cereali-integrali-300x224.jpg" alt="" width="300" height="224" /></a></p>
<p>In parecchie applicazioni informatiche, specie in quelle simulative, saper integrare una funzione ricopre un ruolo <strong>fondamentale</strong>. Purtroppo però le tecniche di integrazione che ci hanno insegnato a scuola o nei corsi di Analisi I sono del tutto inutili. Raramente, infatti, ci troveremo a che fare con funzioni integrabili, anzi, spesso dovremo integrare funzioni non esprimibili tramite funzioni analitiche.</p>
<p>Supponete ad esempio di voler implementare un piccolo gioco di guida. La prima cosa da fare è progettare il nostro sistema di guida. Ovviamente, dato che siamo dei tipi tosti, vogliamo che sia il più realistico possibile e non c&#8217;è nulla di più realistico che usare le leggi della fisica.</p>
<p><span id="more-719"></span></p>
<p>Supponiamo che il giocatore controlli direttamente l&#8217;accelerazione della macchina (una supposizione molto ragionevole) e che tale accelerazione sia descritta da una funzione <em>a(t)</em>. A meno che il vostro giocatore non sia un androide o una specie di divinità è plausibile pensare che l&#8217;accelerazione imposta alla macchina non sia una precisa funzione analitica bensì un guazzabuglio di accelerate e frenate e, anche se il pilota è talmente bravo da accelerare seguendo una funzione analitica, voi non potreste sapere in anticipo quale funzione sia. Nonostante ciò dovete derivare lo stesso questa funzione sconosciuta per ricavare la velocità (e integrare di nuovo per ottenere la posizione della macchinina): non avete altra scelta che usare dei metodi di <strong>integrazione numerica</strong>.</p>
<p>I metodi di integrazione numerica permettono di stimare l&#8217;integrale di una funzione conoscendo solamente il suo valore in un insieme finito di punti. Ho selezionato tre metodi elencati in ordine di complessità. Esistono anche alcuni metodi più precisi (come, ad esempio, i metodi di integrazione gaussiana) ma necessitano di molti più calcoli e non sono quindi adatti all&#8217;uso &#8220;informatico&#8221; se non in alcuni campi specifici.</p>
<p><strong>Metodo dei Rettangoli</strong></p>
<p>Questo metodo è sicuramente il più semplice e, di contro, il meno preciso. Supponiamo di voler integrare una funzione <em>f(x)</em> nell&#8217;intervallo [a,b]. Per fare ciò dividiamo l&#8217;intervallo in <em>n</em> intervalli di dimensione <em>delta</em>.</p>
<p style="text-align: left;"><a href="http://davideaversa.it/slashcode/wp-content/uploads/2011/05/rettangoli.jpg"><img class="aligncenter size-full wp-image-721" title="rettangoli" src="http://davideaversa.it/slashcode/wp-content/uploads/2011/05/rettangoli.jpg" alt="" width="523" height="245" /></a>Ogni rettangolo avrà un area di <em>f(x1)*delta</em>. Per stimare il nostro integrale ci basta sommare i contributi di ogni rettangolo. Ovviamente, più il numero di intervalli è alto più il nostro integrale sarà ben approssimato.</p>
<p style="text-align: left;">Una versione delmetodo dei rettangoli in python è data dal seguente codice:</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> rectangular_min<span style="color: black;">&#40;</span>delta<span style="color: black;">&#41;</span> :<br />
&nbsp; total <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
&nbsp; i <span style="color: #66cc66;">=</span> a<br />
&nbsp; <span style="color: #ff7700;font-weight:bold;">while</span> i <span style="color: #66cc66;">&lt;=</span> b :<br />
&nbsp; &nbsp; total +<span style="color: #66cc66;">=</span> function2<span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; i +<span style="color: #66cc66;">=</span> delta<br />
&nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> total*delta</div></div>
<p>Total è l&#8217;accumulatore del risultato. Il puntatore <em>i </em>va da <em>a</em> a <em>b</em> con passo<em> delta </em>scandendo quindi intervallo per intervallo la funzione da integrare (rappresentata da <em>function2</em>).</p>
<p style="text-align: left;"><strong>Metodo dei Trapezi</strong></p>
<p style="text-align: left;">Il metodo dei trapezi è la logica estensione del metodo dei rettangoli. Invece di calcolare l&#8217;area del rettangolo di base <em>delta</em> e altezza <em>f(x_n) </em>calcoliamo l&#8217;area del trapezio il cui lato ubiquo unisce <em>f(a+n*delta) </em>con <em>f(a+(n+1)*delta).</em></p>
<p style="text-align: left;">Il metodo è molto più preciso e può essere scritto in python con una sola riga</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> trapezoidal_rule<span style="color: black;">&#40;</span>f<span style="color: #66cc66;">,</span> a<span style="color: #66cc66;">,</span> b<span style="color: #66cc66;">,</span> N<span style="color: black;">&#41;</span>:<br />
&nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span>b-a<span style="color: black;">&#41;</span> * <span style="color: black;">&#40;</span> f<span style="color: black;">&#40;</span>a<span style="color: black;">&#41;</span>/<span style="color: #ff4500;">2</span> + f<span style="color: black;">&#40;</span>b<span style="color: black;">&#41;</span>/<span style="color: #ff4500;">2</span> + <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>f<span style="color: black;">&#40;</span>a + <span style="color: black;">&#40;</span>b-a<span style="color: black;">&#41;</span>*k/N<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span>N<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span> / N</div></div>
<p><strong>Metodo di Cavalieri-Simpson</strong></p>
<p>Il metodo migliore è però il metodo di Cavalieri-Simpson. Il metodo approssima due intervalli con una parabola passante per il punto in comune fra i due.</p>
<p style="text-align: left;"><a href="http://davideaversa.it/slashcode/wp-content/uploads/2011/05/Simpsons_method_illustration.png"><img class="aligncenter size-medium wp-image-722" title="Simpsons_method_illustration" src="http://davideaversa.it/slashcode/wp-content/uploads/2011/05/Simpsons_method_illustration-300x271.png" alt="" width="300" height="271" /></a></p>
<p style="text-align: left;">Ogni coppia di intervalli ha come integrale</p>
<p style="text-align: left;"><a href="http://davideaversa.it/slashcode/wp-content/uploads/2011/05/simpson.png"><img class="aligncenter size-full wp-image-723" title="simpson" src="http://davideaversa.it/slashcode/wp-content/uploads/2011/05/simpson.png" alt="" width="330" height="47" /></a>Dove <em>h</em> è la dimensione di un intervallo, y0 è il valore della funzione nel primo estremo del primo intervallo, y2 è il valore della funzione nel secondo estremo e y1 è il valore della funzione nell&#8217;estremo in comune.</p>
<p style="text-align: left;">L&#8217;algoritmo in python è il seguente</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> simpson<span style="color: black;">&#40;</span>delta<span style="color: black;">&#41;</span> :<br />
&nbsp; total <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
&nbsp; i <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
&nbsp; <span style="color: #ff7700;font-weight:bold;">while</span> i+<span style="color: #ff4500;">2</span>*delta <span style="color: #66cc66;">&lt;=</span> <span style="color: #ff4500;">10</span> :<br />
&nbsp; &nbsp; value1 <span style="color: #66cc66;">=</span> function2<span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; value2 <span style="color: #66cc66;">=</span> function2<span style="color: black;">&#40;</span>i+delta<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; value3 <span style="color: #66cc66;">=</span> function2<span style="color: black;">&#40;</span>i+<span style="color: #ff4500;">2</span>*delta<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; value <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span>value1 + <span style="color: #ff4500;">4</span>*value2 + value3<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; total +<span style="color: #66cc66;">=</span> value<br />
&nbsp; &nbsp; i +<span style="color: #66cc66;">=</span> <span style="color: #ff4500;">2</span>*delta<br />
&nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span>total * delta<span style="color: black;">&#41;</span> / <span style="color: #ff4500;">3</span></div></div>
<p><strong>Confronti</strong></p>
<p>Ho eseguito un breve test sui tre metodi eseguendo il seguente integrale:</p>
<p><a href="http://davideaversa.it/slashcode/wp-content/uploads/2011/05/wolframalpha-20110518071559259.gif"><img class="aligncenter size-full wp-image-724" title="sinx/x from 0 to 10" src="http://davideaversa.it/slashcode/wp-content/uploads/2011/05/wolframalpha-20110518071559259.gif" alt="" width="590" height="163" /></a><strong>Test con 10 intervalli</strong></p>
<ul>
<li><strong>Rettangoli : </strong>2.124518813379953</li>
<li><strong>Trapezi: </strong>1.6517198689244215</li>
<li><strong>Simpson: </strong>1.658728115119567</li>
</ul>
<p>Già con soli 10 intervalli notiamo che il metodo di Simpson ha un errore inferiore al millesimo.</p>
<p><strong>Test con 100 intervalli</strong></p>
<ul>
<li><strong>Rettangoli : </strong>1.7055620908116773</li>
<li><strong>Trapezi: </strong>1.6582821963661236</li>
<li><strong>Simpson: </strong>1.6583476291805812</li>
</ul>
<p><strong>Test con 1000 intervalli</strong></p>
<ul>
<li><strong>Rettangoli : </strong>1.6630749297713836</li>
<li><strong>Trapezi: </strong>1.6583469403268327</li>
<li><strong>Simpson: </strong>1.6583475942223707</li>
</ul>
<p>Per un test più preciso bisognerebe eseguire il test anche per molti altri tipi di funzione. In ogni caso, se vi trovate a dover integrare una funzione in un vostro programma<strong>, </strong>ora, sapete come fare.<strong><br />
</strong></p>
 <p><a href="http://davideaversa.it/slashcode/?flattrss_redirect&amp;id=719&amp;md5=978339687732592f45393655981c3249" 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/2011/05/metodi-di-integrazione-numerica/feed/</wfw:commentRss>
		<slash:comments>8</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%2F2011%2F05%2Fmetodi-di-integrazione-numerica%2F&amp;language=it_IT&amp;category=text&amp;title=Metodi+di+Integrazione+Numerica&amp;description=In+parecchie+applicazioni+informatiche%2C+specie+in+quelle+simulative%2C+saper+integrare+una+funzione+ricopre+un+ruolo+fondamentale.+Purtroppo+per%C3%B2+le+tecniche+di+integrazione+che+ci+hanno+insegnato+a+scuola+o+nei...&amp;tags=algoritmi%2Cmatematica%2Cblog" type="text/html" />
	</item>
		<item>
		<title>La Ricerca Informata &#8211; A*</title>
		<link>http://davideaversa.it/slashcode/2010/10/la-ricerca-informata-a/</link>
		<comments>http://davideaversa.it/slashcode/2010/10/la-ricerca-informata-a/#comments</comments>
		<pubDate>Sat, 16 Oct 2010 21:17:37 +0000</pubDate>
		<dc:creator>THeK3nger</dc:creator>
				<category><![CDATA[AI e Neuroscienze]]></category>
		<category><![CDATA[Algoritmica]]></category>
		<category><![CDATA[a*]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[algoritmi]]></category>
		<category><![CDATA[grafi]]></category>

		<guid isPermaLink="false">http://davideaversa.it/slashcode/?p=701</guid>
		<description><![CDATA[<div><a href="http://davideaversa.it/slashcode/2010/10/la-ricerca-informata-a/"><img title="La Ricerca Informata &#8211; A*" src="http://davideaversa.it/slashcode/wp-content/uploads/2010/10/web-manhattan-sky-view-01-150x150.jpg" alt="La Ricerca Informata &#8211; A*"  width="200" height="200" /></a></div><br/>Supponiamo di trovarci in una città a noi sconosciuta e di avere un appuntamento importante con una stupenda ragazza (o ragazzo a seconda dei casi). La cosa più semplice da fare è chiedere indicazioni ai passanti. Purtroppo però siamo sfortunati e quel giorno diluvia che dio la manda e non c’è anima viva in giro. <a href='http://davideaversa.it/slashcode/2010/10/la-ricerca-informata-a/' 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%2F2010%2F10%2Fla-ricerca-informata-a%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/2010/10/la-ricerca-informata-a/" ></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="La Ricerca Informata &#8211; A*" data-url="http://davideaversa.it/slashcode/2010/10/la-ricerca-informata-a/" 
						data-via=""  ></a></div></div>
		<div style="clear:both;"></div><p id="internal-source-marker_0.778890807862262"><a href="http://davideaversa.it/slashcode/wp-content/uploads/2010/10/web-manhattan-sky-view-01.jpg"><img class="alignleft size-thumbnail wp-image-703" title="streets" src="http://davideaversa.it/slashcode/wp-content/uploads/2010/10/web-manhattan-sky-view-01-150x150.jpg" alt="" width="150" height="150" /></a>Supponiamo  di trovarci in una città a noi sconosciuta e di avere un appuntamento  importante con una stupenda ragazza (o ragazzo a seconda dei casi). La  cosa più semplice da fare è chiedere indicazioni ai passanti. Purtroppo  però siamo sfortunati e quel giorno diluvia che dio la manda e non c’è  anima viva in giro. Non c’è speranza.</p>
<p><strong>LA RICERCA IN AMPIEZZA</strong></p>
<p>In  questo caso l’unica soluzione che avete è di tentare tutte le strade.  Partite dal punto A e verificate tutti gli incroci a cui si arriva  direttamente da A, se non siete arrivati tornate ad A e verificate tutti  gli incroci a cui si arriva partendo da A e attraversando un solo  incrocio, e così via, aumentanto ad ogni passo la profondità della ricerca. Questo tipo di ricerca prende il nome di <strong>ricerca in ampiezza</strong>. Funziona? Sicuro, prima o poi arriverete a destinazione. Tuttavia la domanda sorge spontanea: quanto poi?</p>
<p>Supponendo,  come avviene spesso in realtà, che ad ogni incrocio si dipanino 3  strade (oltre a quella da cui siete venuti) se disgraziatamente la  ragazza si trova a solo 10 incroci di distanza dovrete testare circa  59.049 incroci e un numero maggiore di strade. Un compito decisamente  eccessivo anche per il più motivato.</p>
<p><a href="http://davideaversa.it/slashcode/wp-content/uploads/2010/10/Animated_BFS.gif"><img class="aligncenter size-full wp-image-704" title="Animated_BFS" src="http://davideaversa.it/slashcode/wp-content/uploads/2010/10/Animated_BFS.gif" alt="" width="187" height="175" /></a></p>
<p>Dobbiamo trovare un alternativa. Appare evidente che abbiamo bisogno di un <strong>informazione</strong> che ci permetta di scartare le strade che sicuramente non ci portano a  destinazione. Chiamiamo quindi la ragazza e scopriamo che è una nerd  d’alta categoria. Ella infatti vole metterci alla prova. Invece di dirci  la strada ci promette solo di dirci<strong> la distanza in linea retta che separa ogni incrocio che vogliamo da lei</strong>. È sufficiente? Si, e non solo troviamo una strada che ci conduce da lei ma troviamo <strong>la migliore.</strong></p>
<p><strong>LA RICERCA GOLOSA<br />
</strong></p>
<p>La  prima soluzione che ci viene in mente è semplice: fra tutti gli incroci  che posso raggiungere da A scelgo quello che è più vicino alla ragazza e  così via per ogni incrocio su cui vado a finire. Questo tipo di ricerca  (che prende il nome di <strong>ricerca golosa</strong>) è sicuramente migliore della ricerca in ampiezza tuttavia ha due grossi problemi: non trova la strada più breve e, nel caso di grafo con cicli, può finire per ciclare all&#8217;infinito.</p>
<p><strong>LA RICERCA A*</strong></p>
<p><a href="http://davideaversa.it/slashcode/wp-content/uploads/2010/10/AstarExample.gif"><img class="aligncenter size-full wp-image-705" title="AstarExample" src="http://davideaversa.it/slashcode/wp-content/uploads/2010/10/AstarExample.gif" alt="" width="400" height="283" /></a></p>
<p>Scegliamo  questa strategia: assegno a tutti gli incroci che posso raggiungere  dall’incrocio in cui sono un numero <strong>N</strong> corrispondente alla <strong>somma della  strada percorsa fino a quel punto più la distanza in linea retta che  separa quell’incrocio dalla ragazza</strong>. A questo punto scelgo l’incrocio  che ha il numero N <strong>più basso</strong> fra quelli che ho assegnato fin’ora. Questa  ricerca prende il nome di<strong> A*</strong> ed è l’algoritmo di ricerca più efficiente  su un grafo pesato (come ad esempio una mappa stradale).</p>
<p>I punti a favore di A* sono fondamentalmente due: l’<strong>efficienza computazionale</strong> e il fatto che, in alcune condizioni, <strong>il percorso trovato è ottimo</strong>.</p>
<p><strong>EURISTICHE AMMISSIBILI</strong></p>
<p>Ma  quali sono queste condizioni? Torniamo all’informazione che ci forniva  la ragazza: la distanza in linea retta di ogni incrocio da lei. Questa  prende il nome di <strong>funzione euristica</strong>.  In parole povere è una funzione che esprime una stima della “distanza”  dall’obiettivo. Bene, affinché la ricerca di A* sia ottima è necessario  che la funzione euristica non sovrastimi mai la distanza reale dall’obiettivo! Quando questa condizione è soddisfatti si dice che la funzione euristica è <strong>ammissibile</strong>.</p>
<p>Nel  nostro caso la funzione euristica soddisfa questa condizione in quanto  la distanza in linea retta fra un incrocio e la ragazza non può mai  essere maggiore della distanza reale (per definizione la retta è la  distanza più breve fra due punti). La funzione è quindi ammissibile soluzione che troveremo sarà  quindi ottima.</p>
<p>La non ammissibilità di una funzione non è però un limite stringente, spesso infatti trovare una funzione euristica ammissibile necessita di un quantitativo di calcoli troppo elevato che vanificherebbe i vantaggi di A*. In questi casi si può scegliere di usare una funzione non ammissibile ma di facile calcolo a patto di accontentarsi di una soluzione che <strong>potrebbe</strong> non essere ottimale.</p>
<p>Abbiamo imparato tanto in questa uscita. La ragazza al nostro arrivo sarà sicuramente soddisfatta.</p>
 <p><a href="http://davideaversa.it/slashcode/?flattrss_redirect&amp;id=701&amp;md5=ceb454a6e03db0f18153a148d8d3533e" 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/2010/10/la-ricerca-informata-a/feed/</wfw:commentRss>
		<slash:comments>6</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%2F2010%2F10%2Fla-ricerca-informata-a%2F&amp;language=it_IT&amp;category=text&amp;title=La+Ricerca+Informata+%26%238211%3B+A%2A&amp;description=Supponiamo+di+trovarci+in+una+citt%C3%A0+a+noi+sconosciuta+e+di+avere+un+appuntamento+importante+con+una+stupenda+ragazza+%28o+ragazzo+a+seconda+dei+casi%29.+La+cosa+pi%C3%B9+semplice+da...&amp;tags=a%2A%2Cai%2Calgoritmi%2Cgrafi%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Alberi decisionali in 20q</title>
		<link>http://davideaversa.it/slashcode/2010/04/alberi-decisionali-in-20q/</link>
		<comments>http://davideaversa.it/slashcode/2010/04/alberi-decisionali-in-20q/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 13:42:15 +0000</pubDate>
		<dc:creator>THeK3nger</dc:creator>
				<category><![CDATA[AI e Neuroscienze]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[alberi decisionali]]></category>
		<category><![CDATA[algoritmi]]></category>
		<category><![CDATA[reti neurali]]></category>

		<guid isPermaLink="false">http://davideaversa.it/slashcode/?p=541</guid>
		<description><![CDATA[<div><a href="http://davideaversa.it/slashcode/2010/04/alberi-decisionali-in-20q/"><img title="Alberi decisionali in 20q" src="http://davideaversa.it/slashcode/wp-content/uploads/2010/04/20q-150x150.jpg" alt="Alberi decisionali in 20q"  width="200" height="200" /></a></div><br/>Probabilmente fra tutti gli esempi di applicazioni dell&#8217;Intelligenza Artificiale la più semplice e famosa consiste sicuramente nel gioco 20q. Il gioco in questione funziona così: il giocatore pensa ad un oggetto o ad un animale e il marchingegno tenta di indovinare di cosa si tratta in meno di 20 domande a cui il giocatore può <a href='http://davideaversa.it/slashcode/2010/04/alberi-decisionali-in-20q/' 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%2F2010%2F04%2Falberi-decisionali-in-20q%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/2010/04/alberi-decisionali-in-20q/" ></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="Alberi decisionali in 20q" data-url="http://davideaversa.it/slashcode/2010/04/alberi-decisionali-in-20q/" 
						data-via=""  ></a></div></div>
		<div style="clear:both;"></div><p><a href="http://davideaversa.it/slashcode/wp-content/uploads/2010/04/20q.jpg"><img class="alignleft size-thumbnail wp-image-542" title="20q" src="http://davideaversa.it/slashcode/wp-content/uploads/2010/04/20q-150x150.jpg" alt="" width="150" height="150" /></a>Probabilmente fra tutti gli esempi di applicazioni dell&#8217;Intelligenza Artificiale la più semplice e famosa consiste sicuramente nel gioco <strong>20q</strong>. Il gioco in questione funziona così: il giocatore pensa ad un oggetto o ad un animale e il marchingegno tenta di indovinare di cosa si tratta in meno di 20 domande a cui il giocatore può rispondere <strong>si </strong>o <strong>no</strong>. Potete trovare una versione online del gioco all&#8217;indirizzo <a href="http://www.20q.net/">http://www.20q.net/</a>. Potrete constatare che in alcuni casi il programma sembra proprio leggervi nella mente con risultati quasi spaventosi.</p>
<p>La versione usata dal sito è piuttosto avanzata ed utilizza le <strong>reti neurali </strong>e permette quindi una gamma di riposte più vasto (c&#8217;è anche <em>forse, probabilmente, a volte</em>, ecc&#8230;). Il programma è inoltre in grado di apprendere mentre si gioca: ogni qual volta si gioca, o il programma si arrende richiedendo di inserire l&#8217;oggetto a cui si pensava, l&#8217;insieme di risposte appena date plasma la struttura dati interna del programma in modo tale che la prossima volta l&#8217;oggetto venga riconosciuto più velocemente. È un modello di apprendimento molto basilare ma che è analogo a quello umano <em>percezione-previsione-modifica: </em>il programma riceve dati percettivi (le risposte alle domande), formula un ipotesi (i tentativi di indovinare) e modifica la struttura dati in base all&#8217;esito della previsione.</p>
<p>Sarei curioso di sapere se il programma del sito ha qualche contromisura contro il problema del <strong>sovra-adattamento</strong>: questo tipo di problema affligge gran parte dei modelli decisionali, comprese le reti neurali, ed è causato da un eccessivo adattamento della rete a certi tipi di dati piuttosto che ad altri. Facciamo un esempio. Nel gioco 20q è molto più probabile che il giocatore pensi a cose &#8220;banali&#8221; come &#8220;gatto&#8221;, &#8220;cane&#8221;, &#8220;fiore&#8221; e simili piuttosto che a &#8220;antilope&#8221;, &#8220;spinterogeno&#8221; e &#8220;neutrino&#8221;. Questo significa che nel corso dell&#8217;esistenza del gioco il programma verrà addestrato alla perfezione a riconoscere cani e gatti mentre riceverà poche informazioni riguardo antilopi e neutrini. Possiamo quindi dire che &#8220;gatto&#8221; e &#8220;fiore&#8221; e le parole comuni facciano parte dell&#8217;<strong>insieme di addestramento</strong> di una rete. Bene, è possibile dimostrare che una rete sovra-adattata al suo insieme di addestramento indovina, in media, molto meno volte oggetti che non appartengono a tale insieme rispetto ad una rete che è solo parzialmente adattata.</p>
<p>Rimandiamo però questi approfondimenti sulle reti neurali. Il motivo per cui ho scritto questo articolo era di mostrare come sia possibile in una manciata di righe scrivere un programma che emuli in modo semplice il gioco di 20q. Per questa approssimazione consideriamo che sia possibile dare alle domande soltanto le risposte si o no.</p>
<p>Il metodo che vi mostrerò non utilizza nessuna tecnica propria dell&#8217;IA bensì dei semplicissimi <strong>alberi binari</strong>. Questi alberi binari li indicheremo come <strong>alberi decisionali binari</strong>. Nel nostro albero decisionale definaiamo:</p>
<ul>
<li>I nodi interni dell&#8217;albero sono <strong>domande</strong>.</li>
<li>I nodi foglia dell&#8217;albero sono <strong>gli oggetti da indovinare.</strong></li>
<li>Il sotto-albero destro di un nodo corrisponde al caso in cui la risposta alla domanda sia <strong>si.</strong></li>
<li>Il sotto-albero sinistro di un nodo corrisponde al caso in cui la risposta alla domanda sia <strong>no</strong>.</li>
</ul>
<p>L&#8217;algoritmo del gioco consiste in una cosa del tipo:</p>
<ul>
<li>Il programma formula la prima domanda che trova (cominciando con il nodo radice).</li>
<li>Se non c&#8217;è più nessuna domanda il programma si arrende e chiede al giocatore di inserire 1) l&#8217;oggetto a cui stava pensando. 2) una domanda che rappresenta l&#8217;oggetto 3) la risposta a questa domanda.</li>
<li>Il programma aggiunge questa domanda e la relativa risposta al sotto albero in cui si era fermato (oppure come nodo radice se l&#8217;albero era vuoto).</li>
<li>Se invece la domanda c&#8217;è il programma formula la domanda e scende nel sotto-albero relativo alla risposta.</li>
<li>Il programma ricomincia dal punto 1.</li>
</ul>
<p>Tutto qui. Tale algoritmo è effettivamente molto grezzo e sono possibili un gran numero di migliorie (ad esempio usare dei modelli di albero più &#8220;elastici&#8221; per evitare alberi troppo sbilanciati) ma svolge decentemente il proprio lavoro. Dopo che l&#8217;avete fatto girare per qualche tempo vedrete che inizierà ad imparare e ad indovinare un discreto numero di parole. Ovviamente potete partire da un albero vuoto oppure pre-costruire un albero di base con alcune domande comuni.</p>
<p>Un altra cosa che può farci capire questo semplice programma è una considerazione che mi ha fatto notare un gentile commentatore: la capacità degli algoritmi di AI non dipende dalla dimensione del programma ovvero dal suo numero di righe di codice allo stesso modo di come le capacità celebrali umane non dipendono dalla dimensione del cervello (una balena ha il cervello molto più voluminoso di un essere umano eppure fa molte meno cose). Le capacità cognitive di un programma dipendono solamente dalle relazioni che si auto-generano fra le strutture dati del programma (nel nostro caso tali relazioni sono i collegamenti ad albero fra i nodi).</p>
<p>Se qualcuno avesse voglia di creare questo programmino usando il minor numero di righe possibili sarei felice di pubblicarlo. Inoltre potreste anche usarlo per sbalordire amici, parenti e vicini di casa! XD</p>
<p>Alla prossima!</p>
 <p><a href="http://davideaversa.it/slashcode/?flattrss_redirect&amp;id=541&amp;md5=1e6ac3f64f4de3f2c5bc83b0fb6534ef" 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/2010/04/alberi-decisionali-in-20q/feed/</wfw:commentRss>
		<slash:comments>7</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%2F2010%2F04%2Falberi-decisionali-in-20q%2F&amp;language=it_IT&amp;category=text&amp;title=Alberi+decisionali+in+20q&amp;description=Probabilmente+fra+tutti+gli+esempi+di+applicazioni+dell%26%238217%3BIntelligenza+Artificiale+la+pi%C3%B9+semplice+e+famosa+consiste+sicuramente+nel+gioco+20q.+Il+gioco+in+questione+funziona+cos%C3%AC%3A+il+giocatore+pensa+ad+un...&amp;tags=ai%2Calberi+decisionali%2Calgoritmi%2Creti+neurali%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>C -Analisi con GProf</title>
		<link>http://davideaversa.it/slashcode/2008/12/c-analisi-con-gprof/</link>
		<comments>http://davideaversa.it/slashcode/2008/12/c-analisi-con-gprof/#comments</comments>
		<pubDate>Sun, 07 Dec 2008 13:23:58 +0000</pubDate>
		<dc:creator>THeK3nger</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[algoritmi]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[profiling]]></category>

		<guid isPermaLink="false">http://slashcode.wordpress.com/?p=156</guid>
		<description><![CDATA[<div><a href="http://davideaversa.it/slashcode/2008/12/c-analisi-con-gprof/"><img title="C -Analisi con GProf" src="http://www.twistedtheorysoftware.com/timer/images/timer-icon.png" alt="C -Analisi con GProf"  width="" /></a></div><br/>L&#8217;efficenza di un algoritmo e di un programma va affrotata in due passi: un analisi teorica dell&#8217;algoritmo e una analisi &#8220;on the road&#8221; in cui l&#8217;algoritmo va implementato e testato sulle varie architetture reali. Ovviamente, come abbiamo avuto modo di vedere, non c&#8217;è linguaggio che possa vantare le capacità prestazionali del C, anche senza contare <a href='http://davideaversa.it/slashcode/2008/12/c-analisi-con-gprof/' 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%2Fc-analisi-con-gprof%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/c-analisi-con-gprof/" ></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="C -Analisi con GProf" data-url="http://davideaversa.it/slashcode/2008/12/c-analisi-con-gprof/" 
						data-via=""  ></a></div></div>
		<div style="clear:both;"></div><div class="wp-caption alignleft" style="width: 160px"><img title="Timer" src="http://www.twistedtheorysoftware.com/timer/images/timer-icon.png" alt="Effettuare il tuning di un modulo C." width="150" height="150" /><p class="wp-caption-text">Effettuare il tuning di un modulo C.</p></div>
<p>L&#8217;efficenza di un algoritmo e di un programma va affrotata in due passi: un analisi teorica dell&#8217;algoritmo e una analisi <em>&#8220;on the road&#8221; </em>in cui l&#8217;algoritmo va implementato e testato sulle varie architetture reali.</p>
<p>Ovviamente, come abbiamo avuto modo di vedere, non c&#8217;è linguaggio che possa vantare le capacità prestazionali del <strong>C</strong>, anche senza contare le capacità di interfacciarsi direttamente a basso livello con innesti di codice <strong>assembly</strong> grazie al costrutto <em>_asm_</em>.</p>
<p>Ma come tutti gli strumenti potenti vanno saputi utilizzare, molto spesso differenze impercettibili e che pensiamo irrilevanti si ripercuotono in maniera catastrofica sul nostro software. Ad esempio ho avuto modo di vedere algoritmi in cui la sola variazione di due parametri strutturali faceva passare il tempo di esecuzione <strong>da 2 minuti a 11 giorni</strong>.</p>
<p>E&#8217; quindi importante identificare, in un software, quali sono le funzioni e le procedure che occupano più tempo, e quale è il loro peso nel tempo complessivo di esecuzione.</p>
<p>A venirci incontro è proprio <strong>GProf</strong>.</p>
<p><span id="more-156"></span><strong>GProf</strong> è un tool che permette di interpretare con statistiche avanzate sui tempi di esecuzioni delle singole funzioni il file di <strong>profiling</strong> generato dagli eseguibili compilati con il parametro <strong>-pg</strong>.</p>
<p>Ma andiamo con ordine. Per utilizzare GProf per prima cosa prendiamo il nostro codice C e compiliamolo come consueto ma aggiungendo il parametro <strong>-pg</strong>.</p>
<pre>gcc prova.c -o prova -pg</pre>
<p>Dopo aver compilato correttamente il file non ci resta che eseguirlo. Una volta terminato ci accorgeremo che nella cartella dell&#8217;eseguibile è stato creato un file chiamato <em>gmon.out</em>.</p>
<p>Ora per leggere il report dettagliato non ci resta che dare il comando:</p>
<pre>gprof prova | less</pre>
<p>I primi dati ce potremo consultare sono i tempi di esecuzioni delle singole funzioni del programma ordinate in ordine decrescente in base alla percentuale di tempo di esecuzione. Ma non solo, possiamo vedere anche quante volte una data funzione viene chiamata. Come ad esempio:</p>
<pre>% cumulative  self              self     total
 time seconds  seconds  calls s/call s/call name
43.32   46.03  46.03 339952989  0.00  0.00 CompareNodes(Node *,Node *)
25.06   72.66  26.63    55000   0.00  0.00 getNode(char *,NodeListNode *&amp;)
16.80   90.51  17.85 339433374  0.00  0.00 CompareEdges(Edge *,AnnotatedEdge *)
12.70  104.01  13.50    51987   0.00  0.00 addAnnotatedEdge(AnnotatedGraph *,Edge *)
 1.98  106.11   2.10    51987   0.00  0.00 addEdge(Graph *,Node *,Node *)
 0.07  106.18   0.07        1   0.07  0.07 FindTreshold(AnnotatedEdge *,int)
 0.06  106.24   0.06        1   0.06 28.79 getGraphFromFile(char *,NodeListNode *&amp;,Config *)
 0.02  106.26   0.02        1   0.02 77.40 summarize(GraphListNode *,Config *)
 0.00  106.26   0.00    55000   0.00  0.00 FixName(char *)</pre>
<p>Un altro modo che abbiamo per consultare il file di profiling è usando alcuni tool grafici, fra i quali vi cito <a href="http://kprof.sourceforge.net/">KProf</a> per KDE, con il quale potrete accedere alle stesse informazioni grazie all&#8217;interfaccia grafica spartana ma completa.</p>
<p>Una volta che abbiamo a disposizione questi dati non ci resta che individuare le funzioni <em>anomale</em>, apportare modifiche, ricompilare e vedere le eventuali variazioni in termini di tempo di esecuzione&#8230; sperando siano positive! <img src='http://davideaversa.it/slashcode/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Fate alcuni esperimenti e vedrete che GProf sarà il vostro migliore amico nel debellare il <em>virus</em> dell&#8217;inefficenza! <img src='http://davideaversa.it/slashcode/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><strong>LINK UTILI:</strong></p>
<ul>
<li><a href="http://kprof.sourceforge.net/">Optimizing C/C++ programs using the GProf profiler</a> [ENG]</li>
<li><a href="http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html">GNU prof Homepage</a> [ENG]</li>
</ul>
 <p><a href="http://davideaversa.it/slashcode/?flattrss_redirect&amp;id=156&amp;md5=9b647dad04af2781e0242004f24604cb" 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/c-analisi-con-gprof/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%2Fc-analisi-con-gprof%2F&amp;language=it_IT&amp;category=text&amp;title=C+-Analisi+con+GProf&amp;description=L%26%238217%3Befficenza+di+un+algoritmo+e+di+un+programma+va+affrotata+in+due+passi%3A+un+analisi+teorica+dell%26%238217%3Balgoritmo+e+una+analisi+%26%238220%3Bon+the+road%26%238221%3B+in+cui+l%26%238217%3Balgoritmo+va+implementato+e+testato...&amp;tags=algoritmi%2CC%2Cprofiling%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>
		<item>
		<title>Programmazione #10: Funzioni &#8211; Iterazione e Ricorsione</title>
		<link>http://davideaversa.it/slashcode/2008/09/programmazione-10-funzioni-iterazione-e-ricorsione/</link>
		<comments>http://davideaversa.it/slashcode/2008/09/programmazione-10-funzioni-iterazione-e-ricorsione/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 13:20:55 +0000</pubDate>
		<dc:creator>THeK3nger</dc:creator>
				<category><![CDATA[Generale]]></category>
		<category><![CDATA[algoritmi]]></category>
		<category><![CDATA[Guide]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[ricorsione]]></category>

		<guid isPermaLink="false">http://slashcode.wordpress.com/?p=103</guid>
		<description><![CDATA[<div><a href="http://davideaversa.it/slashcode/2008/09/programmazione-10-funzioni-iterazione-e-ricorsione/"><img title="Programmazione #10: Funzioni &#8211; Iterazione e Ricorsione" src="http://slashcode.files.wordpress.com/2008/09/frattale.jpg" alt="Programmazione #10: Funzioni &#8211; Iterazione e Ricorsione"  width="" /></a></div><br/>Ora conosciamo sufficientemente la struttura della memoria e i principi del suo funzionamento. Per spiegare lo stack, in particolare, ho dovuto fare richiamo alle funzioni. Le funzioni sono un argomento fondamentale della programmazione e alcuni processori le implementano addirittura a livello di assembly. Il concetto di funzione è molto semplice. Una funzione può essere vista <a href='http://davideaversa.it/slashcode/2008/09/programmazione-10-funzioni-iterazione-e-ricorsione/' 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%2F09%2Fprogrammazione-10-funzioni-iterazione-e-ricorsione%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/09/programmazione-10-funzioni-iterazione-e-ricorsione/" ></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="Programmazione #10: Funzioni &#8211; Iterazione e Ricorsione" data-url="http://davideaversa.it/slashcode/2008/09/programmazione-10-funzioni-iterazione-e-ricorsione/" 
						data-via=""  ></a></div></div>
		<div style="clear:both;"></div><div id="attachment_104" class="wp-caption alignleft" style="width: 160px"><img class="size-full wp-image-104" src="http://slashcode.files.wordpress.com/2008/09/frattale.jpg" alt="Per capire la ricorsione bisogna innanzitutto capire la ricorsione..." width="150" height="150" /><p class="wp-caption-text">Per capire la ricorsione bisogna innanzitutto capire la ricorsione...</p></div>
<p>Ora conosciamo sufficientemente la struttura della memoria e i principi del suo funzionamento. Per spiegare lo <strong>stack</strong>, in particolare, ho dovuto fare richiamo alle <strong>funzioni</strong>.</p>
<p>Le funzioni sono un argomento fondamentale della programmazione e alcuni processori le implementano addirittura a livello di assembly.</p>
<p>Il concetto di funzione è molto semplice. Una funzione può essere vista come una &#8220;macchina&#8221; che riceve in pasto dei dati, li elabora e a volte restituisce un risultato.</p>
<p><span id="more-103"></span></p>
<p>La funzione &#8220;+&#8221; è una funzione che prende come dati due numeri (<strong>parametri</strong>), gli somma (<strong>corpo della funzione</strong>) e restituisce il risultato (<strong>valore di ritorno</strong>). La funzione <strong>print</strong> (presente in molti linguaggi) prende come dati una stringa e gli elabora stampandoli sullo schermo.</p>
<p>Le funzioni sono definibili dall&#8217;utente e tutti i linguaggi permettono di definire funzioni.</p>
<p>Ma come funziona una funzione ( <img src='http://davideaversa.it/slashcode/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  )?</p>
<p>Con lo stack. Quando chiamiamo una funzione il computer crea un nuovo elemento in cima allo stack chiamato <strong>record di attivazione</strong> che contiene la <strong>copia dei dati passati per parametro</strong>, <strong>il puntatore all&#8217;ultima istruzione eseguita nella funzione &#8220;madre&#8221; e lo spazio per il valore di ritorno.</strong></p>
<p>Quasi tutte le funzioni tradizionali sono <strong>funzioni iterative</strong> ovvero che ricavano la loro soluzione solo mediante i dati e altre funzioni.</p>
<p>Questo meccanismo dello stack però permette di implementare un altro strumento molto potente: <strong>la ricorsione.</strong></p>
<p>La ricorsione consiste nell&#8217;usare una funzione (con parametri più piccoli) all&#8217;interno della stessa funzione. Consiste cioè nel risolvere un problema risolvendone uno di taglia minore.</p>
<p>Per esempio potremo pensare ad una versione ricorsiva della moltiplicazione:</p>
<pre>def moltiplicazione(x,y) :
    if y == 1 : return x
    return x + moltiplicazione(y-1) :</pre>
<p>Come si vede si risolve x*y risolvendo x*(y-1) + x &#8230; e cosi via.</p>
<p>Dall&#8217;esempio vediamo che una funzione ricorsiva si divide in:</p>
<ul>
<li><strong>Uno o più CASI BASE:</strong> ovvero le condizioni immediate, la cui soluzione non necessita di usare la ricorsione. (nell&#8217;esempio è il caso x*1 = x)</li>
<li><strong>Uno o più CASI RICORSIVI: </strong>ovvero i casi in cui si usa la ricorsione.</li>
</ul>
<p>Ovviamente i casi base sono <strong>necessari</strong> per far terminare la ricorsione. (Una ricorsione infinita causa uno <strong>stack overflow</strong> ovvero lo stack si mangia tutta la memoria a disposizione).</p>
<p>Le soluzioni ricorsive sono molto eleganti ma hanno lo svantaggio che la pila dei record di attivazione e la loro creazione &#8220;mangia&#8221; risorse non necessarie esclusivamente alla risoluzione del problema. Quindi nei casi di programmi che necessitano di alte prestazioni tutti gli algoritmi ricorsivi vengono convertiti in iterativi.</p>
<p>Ma è sempre possibile?</p>
<p>Si. <strong>Dato un algoritmo ricorsivo è SEMPRE possibile scrivere il suo corrispettivo iterativo.</strong></p>
<p>Il caso più semplice è quello in cui la ricorsione è l&#8217;ultima operazione della funzione. Questi casi vengono chiamati <strong>tail recursion</strong> e molti compilatori sono in grado di individuarli e convertirli in automatico nella loro versione iterativa.</p>
<p>Casi più complessi invece vengono convertiti usando una <strong>pila artificiale</strong> creata dal programmatore che essendo fatta ad-hoc per l&#8217;algoritmo contiene solo le informazioni necessarie e quindi è molto più efficente!</p>
 <p><a href="http://davideaversa.it/slashcode/?flattrss_redirect&amp;id=103&amp;md5=fff2f86d490497acf11899a51d20ccd7" 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/09/programmazione-10-funzioni-iterazione-e-ricorsione/feed/</wfw:commentRss>
		<slash:comments>5</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%2F09%2Fprogrammazione-10-funzioni-iterazione-e-ricorsione%2F&amp;language=it_IT&amp;category=text&amp;title=Programmazione+%2310%3A+Funzioni+%26%238211%3B+Iterazione+e+Ricorsione&amp;description=Ora+conosciamo+sufficientemente+la+struttura+della+memoria+e+i+principi+del+suo+funzionamento.+Per+spiegare+lo+stack%2C+in+particolare%2C+ho+dovuto+fare+richiamo+alle+funzioni.+Le+funzioni+sono+un+argomento...&amp;tags=algoritmi%2CGuide%2Cprogrammazione%2Cricorsione%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Programmi #3: Progetto e Complessità</title>
		<link>http://davideaversa.it/slashcode/2008/08/programmi-3-progetto-e-complessita/</link>
		<comments>http://davideaversa.it/slashcode/2008/08/programmi-3-progetto-e-complessita/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 16:53:42 +0000</pubDate>
		<dc:creator>THeK3nger</dc:creator>
				<category><![CDATA[Generale]]></category>
		<category><![CDATA[algoritmi]]></category>
		<category><![CDATA[Guide]]></category>
		<category><![CDATA[programmazione]]></category>

		<guid isPermaLink="false">http://slashcode.wordpress.com/?p=64</guid>
		<description><![CDATA[<div><a href="http://davideaversa.it/slashcode/2008/08/programmi-3-progetto-e-complessita/"><img title="Programmi #3: Progetto e Complessità" src="http://slashcode.files.wordpress.com/2008/08/catorcio.jpg" alt="Programmi #3: Progetto e Complessità"  width="" /></a></div><br/>Abbiamo visto cos&#8217;è un algoritmo, come è suddiviso e come lo si rappresenta astrattamente in fase di &#8220;progetto&#8221;. Ora affronteremo il come progettarlo e in particolare il metodo del Dividi et Impera. La progettazione di un algoritmo è la fase più delicata del processo di programmazione. Spesso scelte che sembrano ininfluenti nella nostra mente si <a href='http://davideaversa.it/slashcode/2008/08/programmi-3-progetto-e-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%2F2008%2F08%2Fprogrammi-3-progetto-e-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/2008/08/programmi-3-progetto-e-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="Programmi #3: Progetto e Complessità" data-url="http://davideaversa.it/slashcode/2008/08/programmi-3-progetto-e-complessita/" 
						data-via=""  ></a></div></div>
		<div style="clear:both;"></div><div id="attachment_65" class="wp-caption alignleft" style="width: 160px"><img class="size-full wp-image-65" src="http://slashcode.files.wordpress.com/2008/08/catorcio.jpg" alt="Foto di un programma che usa algoritmi scadenti." width="150" height="150" /><p class="wp-caption-text">Foto di un programma che usa algoritmi scadenti.</p></div>
<p>Abbiamo visto cos&#8217;è un algoritmo, come è suddiviso e come lo si rappresenta astrattamente in fase di &#8220;progetto&#8221;.</p>
<p>Ora affronteremo il <strong>come</strong> progettarlo e in particolare il metodo del <strong>Dividi et Impera.</strong></p>
<p>La progettazione di un algoritmo è la fase più delicata del processo di programmazione. Spesso scelte che sembrano ininfluenti nella nostra mente si tramutano in barriere computazionali invalicabili (cosa che appare manifesta se si combatte con il <a href="http://projecteuler.net/">Progetto Eulero</a>).</p>
<p><span id="more-64"></span></p>
<p>Possiamo distinguere 3 fasi:</p>
<p><strong>1) SCOMPOSIZIONE IN SOTTO PROBLEMI<br />
</strong></p>
<p>In questa fase abbiamo nella nostra testa solamente l&#8217;obbiettivo che ci prefiggiamo (<strong>risultato</strong>) e i punti di partenza (<strong>dati in ingresso</strong>). Per esempio abbiamo l&#8217;obbiettivo di fare la spesa nel minor tempo possibile avendo come dati in ingresso la posizione dei supermercati della città.</p>
<p>La prima cosa da fare a questo punto è trovare a grandi linee i passi che ci portano dalla partenza all&#8217;obbiettivo. Nel nostro esempio sappiamo che la soluzione consiste nel:</p>
<ol>
<li>Trovare la strada più breve per arrivare ad un supermercato.</li>
<li>Andare a fare la spesa.</li>
<li>Trovare la strada più breve per tornare a casa.</li>
</ol>
<p><strong>2)</strong> <strong>RISOLUZIONE DEI SOTTO-PROBLEMI</strong></p>
<p>Trovati i sotto problemi del nostro problema principale dobbiamo risolvere i sotto-problemi (i quali di solito sono più semplici del problema di partenza) tenendo conto che abbiamo a disposizione solo tre elementi:</p>
<ol>
<li>Istruzioni (le istruzioni da eseguire).</li>
<li>Controlli su condizioni (corrisponde all&#8217;italiano <em>se&#8230;)</em>.</li>
<li>Salti (per <em>saltare</em> ad un istruzione specifica).</li>
</ol>
<p>Qui non c&#8217;è un metodo universale. Bisogna lavorare di intuito suddividendo, se necesarrio, il sotto-problema in <em>sotto-sotto-problemi</em>, se necessario fino al punto in cui i <em>sotto-sotto-sotto-&#8230;..-sotto-problemi</em> non diventino le istruzioni base di cui disponiamo.</p>
<p><strong>3) UNIONE DEI RISULTATI</strong></p>
<p>Questa fase non è banale come sembra. Per ricostruire il problema principale sembra ovvio che vadano messi in fila i risultati dei sotto-problemi. Invece no. Qui è il punto (non l&#8217;unico ma uno dei principali) in cui entra in gioco <strong>l&#8217;efficienza.</strong></p>
<p>Per tornare all&#8217;esempio della spesa ci rendiamo conto. Che i sotto-problemi (1) e (2) in realtà fanno la stessa cosa: la strada più breve all&#8217;andata, con buona possibilità, sarà anche la più breve al ritorno.</p>
<p>Quindi perchè calcolarla due volte? Basta salvare da qualche parte il risultato del problema (1) e riutilizzarlo in (3) senza pagare due volte il costo (in termini di calcolo) dell&#8217;elaborazione del percorso.</p>
<p>In questo esempio sembra ovvio ma vi assicuro che non è cosi. Spesso quando si programma si tende a andare <em>a risparmio</em> sulle variabili (forse per non sforzarsi a trovare un nome) e quindi a volte per usare un valore si applica più volte la funzione che lo genera. <strong>Ma spesso questo appesantisce enormemente il lavoro e l&#8217;efficienza.</strong></p>
<p>Sul costo e la complessità di un algoritmo torneremo in seguito perchè è un argomento interessante e utile.</p>
<p>Abbiamo quindi definito queste fasi: <strong>SCOMPOSIZIONE-RISOLUZIONE-UNIONE. </strong>Questo principio prende il nome di <strong>Dividi et Impera</strong> ed oltre ad avere il vantaggio di aiutare nella &#8220;creazione&#8221; rende il software <strong>modulare</strong> il che comporta:</p>
<ol>
<li>Maggiore capacità di manutenzione e individuazione degli errori.</li>
<li>Possibilità di riutilizzare la stessa soluzione di un sotto-problema di un algoritmo in un altro algoritmo (Per esempio il problema di trovare la strada più breve per fare la spesa lo si può riutilizzare nel trovare la strada più breve per un viaggio).</li>
</ol>
<p>Bene. Poichè per approfondire maggiormente alcuni concetti non posso trascendere dall&#8217;informatica, dobbiamo abbandonare per un po gli algoritmi per introdurre concetti di <strong>programmazione dei calcolatori vera e propria</strong>.</p>
 <p><a href="http://davideaversa.it/slashcode/?flattrss_redirect&amp;id=64&amp;md5=a323d01646315b4939a6e0288dd3a6f3" 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/08/programmi-3-progetto-e-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%2F2008%2F08%2Fprogrammi-3-progetto-e-complessita%2F&amp;language=it_IT&amp;category=text&amp;title=Programmi+%233%3A+Progetto+e+Complessit%C3%A0&amp;description=Abbiamo+visto+cos%26%238217%3B%C3%A8+un+algoritmo%2C+come+%C3%A8+suddiviso+e+come+lo+si+rappresenta+astrattamente+in+fase+di+%26%238220%3Bprogetto%26%238221%3B.+Ora+affronteremo+il+come+progettarlo+e+in+particolare+il+metodo+del+Dividi...&amp;tags=algoritmi%2CGuide%2Cprogrammazione%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Programmazione #2: Algoritmi</title>
		<link>http://davideaversa.it/slashcode/2008/08/programmazione-2-algoritmi/</link>
		<comments>http://davideaversa.it/slashcode/2008/08/programmazione-2-algoritmi/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 23:16:33 +0000</pubDate>
		<dc:creator>THeK3nger</dc:creator>
				<category><![CDATA[Generale]]></category>
		<category><![CDATA[algoritmi]]></category>
		<category><![CDATA[Guide]]></category>
		<category><![CDATA[programmazione]]></category>

		<guid isPermaLink="false">http://slashcode.wordpress.com/?p=52</guid>
		<description><![CDATA[<div><a href="http://davideaversa.it/slashcode/2008/08/programmazione-2-algoritmi/"><img title="Programmazione #2: Algoritmi" src="http://slashcode.files.wordpress.com/2008/08/algoritmo.jpg" alt="Programmazione #2: Algoritmi"  width="" /></a></div><br/>Nella scorsa lezione abbiamo visto che cosa è la programmazione e abbiamo notato che si può semplificare nella creazione di algoritmi. L&#8217;astrazione da ogni linguaggio ci permette di dimenticarci per il momento le difficoltà implementative di ogni algoritmo e concentrarci solo sulla sua essenza. Partiamo quindi dalla struttura di algoritmi veramente semplici. Il più semplice <a href='http://davideaversa.it/slashcode/2008/08/programmazione-2-algoritmi/' 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%2F08%2Fprogrammazione-2-algoritmi%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/08/programmazione-2-algoritmi/" ></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="Programmazione #2: Algoritmi" data-url="http://davideaversa.it/slashcode/2008/08/programmazione-2-algoritmi/" 
						data-via=""  ></a></div></div>
		<div style="clear:both;"></div><div id="attachment_53" class="wp-caption alignleft" style="width: 160px"><img class="size-full wp-image-53" src="http://slashcode.files.wordpress.com/2008/08/algoritmo.jpg" alt="No... forse non è questo l'algo-ritmo..." width="150" height="150" /><p class="wp-caption-text">No... forse non è questo un algo-ritmo...</p></div>
<p>Nella scorsa lezione abbiamo visto <strong>che cosa è</strong> la programmazione e abbiamo notato che si può semplificare nella <strong>creazione di algoritmi</strong>.</p>
<p>L&#8217;astrazione da ogni linguaggio ci permette di dimenticarci per il momento le difficoltà implementative di ogni algoritmo e concentrarci solo sulla sua essenza.</p>
<p>Partiamo quindi dalla struttura di algoritmi veramente semplici.</p>
<p><span id="more-52"></span></p>
<p>Il più semplice tipo di algoritmo consiste in una semplice lista di istruzioni. Se per esempio vogliamo scrivere l&#8217;algoritmo per fare la pasta potremo scrivere:</p>
<ol>
<li>Metti l&#8217;acqua a bollire.</li>
<li>Aspetta che l&#8217;acqua bolla.</li>
<li>Mettere la pasta.</li>
<li>Aspetta che sia cotta.</li>
<li>Scola la pasta.</li>
</ol>
<p>Questo è un algoritmo <strong>aciclico </strong>(ovvero privo di salti all&#8217;indietro, in poche parole di istruzioni ripetute più volte) e a <strong>flusso unico</strong> (ovvero tutte le istruzioni sono eseguite almeno una volta). E&#8217; il modello di algoritmo più semplice.</p>
<p>Al lettore attento non sarà sfuggito però che ogni istruzione potrebbe considerarsi a sua volta come un algoritmo. Per esempio la (1) potrebbe diventare:</p>
<ol>
<li>Prendi la pentola.</li>
<li>Riempila d&#8217;acqua.</li>
<li>Accendi il fornello.</li>
<li>Metti la pentola sul fornello.</li>
</ol>
<p>E via dicendo. A sua volta anche &#8220;prendi la pentola&#8221; potrebbe essere scomposto.</p>
<p><strong>Ma fino a che punto dobbiamo <em>espandere</em> le operazioni di un algoritmo?</strong></p>
<p>La risposta in verità dipende dal linguaggio che si userà per realizzare l&#8217;algoritmo. Se vogliamo eseguirlo in assembly dovremmo espanderlo ai massimi livelli mentre se vogliamo farlo in Java avremo bisogno di un minore dettaglio.</p>
<p>E&#8217; buona norma però, quando si scrivono algoritmi, partire sempre da un livello di dettaglio basso e scomporre via via i <strong>sotto-problemi</strong> risultanti in altri <strong>sotto-algoritmi.</strong> Un po come abbiamo fatto per l&#8217;esempio della pasta. Questa segnatela perché all&#8217;atto pratico è una delle cose più potenti che un programmatore possa fare: la <strong>modularizzazione</strong> (di cui parleremo in seguito)</p>
<p>L&#8217;istruzione (2) &#8220;Aspetta che l&#8217;acqua bolla.&#8221; scomposta rivela proprietà che non avevamo visto nell&#8217;algoritmo generale. Scomposto infatti assume questa forma:</p>
<ol>
<li>Guarda l&#8217;acqua nella pentola.</li>
<li>Se bolle termina, altrimenti torna a (1).</li>
</ol>
<p>Come si nota questo è un algoritmo <strong>ciclico</strong> (dei più semplici pergiunta) in quanto presenta una condizione che ci fa tornare <strong>indietro</strong> ad un istruzione precedente. Questo è quindi un ciclo.</p>
<p>Quindi il nostro algoritmo aciclico di partenza in realtà nasconde un sotto-algorimto ciclico.</p>
<p>Ora ci chiediamo qual&#8217;è il metodo più efficace per rappresentare un algoritmo? Il metodo forse più conosciuto è quello dei <strong>diagrammi di flusso</strong> (per approfondire vai <a href="http://it.wikipedia.org/w/index.php?title=Diagramma_a_blocchi">qui</a>)</p>
<div class="wp-caption aligncenter" style="width: 310px"><img src="http://upload.wikimedia.org/wikipedia/it/thumb/0/0e/Flusso_fatt_ricor.png/300px-Flusso_fatt_ricor.png" alt="Il diagramma di flusso del calcolo del fattoriale." width="300" height="358" /><p class="wp-caption-text">Il diagramma di flusso del calcolo del fattoriale. Il calcolo del fattoriale è un algoritmo ciclico e a flusso multiplo.</p></div>
<p>Il diagramma di flusso è quindi una rappresentazione per via grafica molto evidente di quello che fa l&#8217;algoritmo. Lo svantaggio che lo rende inapplicabile in quasi tutti i casi pratici è che è <strong>inadatto per algoritmi vasti e complessi </strong>in quanto stare dietro a frecce e blocchi sparse per una superficie troppo vasta più che aiutare disorienta.</p>
<p>A questo punto ci viene in aiuto <strong>lo pseudo-codice.</strong></p>
<p>Lo pseudo-codice in realtà non è molto dissimile dalla lista di istruzioni che ho usato per rappresentare l&#8217;algoritmo della pasta. In poche parole è <strong>un algoritmo espresso in linguaggio naturale impostato in modo tale da somigliare a un listato di codice.</strong></p>
<p>Non c&#8217;è una tecnica universale per lo pseudo-codice, ognuno è libero di trovare il suo stile a patto che il risultato sia comprensibile e chiaro ai più. Per esempio (2) &#8220;Aspetta che l&#8217;acqua bolla.&#8221; diventerebbe una cosa del tipo:</p>
<p style="padding-left:30px;"><em>algoritmo AspettaAcquaBolle() :<br />
Finchè &lt;l&#8217;acqua NON bolle&gt; :<br />
&lt;Guarda L&#8217;acqua&gt;</em></p>
<p>Mentre l&#8217;algoritmo del fattoriale diventerebbe:</p>
<p style="padding-left:30px;"><em>algoritmo Fattoriale(Numero Intero N) :<br />
Se N=0 :<br />
restituisci 1<br />
altrimenti :<br />
restituisci N * Fattoriale(N-1)</em></p>
<p>Come vedete il risultato è facilmente interpretabile e la struttura permette una conversione piuttosto semplice in un linguaggio di programmazione vero e proprio. Si tratta cioè di <em>tradurre </em>riga per riga lo pseudo-codice in codice.</p>
<p>Nella prossima lezione parleremo ancora degli algoritmi introducendo concetti un po più complessi che per ora vedremo solo in modo superficiale ma che, volendo approfondirò più avanti.</p>
 <p><a href="http://davideaversa.it/slashcode/?flattrss_redirect&amp;id=52&amp;md5=485a81b7105b327462ceef28ea5828d0" 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/08/programmazione-2-algoritmi/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%2F08%2Fprogrammazione-2-algoritmi%2F&amp;language=it_IT&amp;category=text&amp;title=Programmazione+%232%3A+Algoritmi&amp;description=Nella+scorsa+lezione+abbiamo+visto+che+cosa+%C3%A8+la+programmazione+e+abbiamo+notato+che+si+pu%C3%B2+semplificare+nella+creazione+di+algoritmi.+L%26%238217%3Bastrazione+da+ogni+linguaggio+ci+permette+di+dimenticarci+per...&amp;tags=algoritmi%2CGuide%2Cprogrammazione%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>

