Quaderni di Informatica Problem Solving Luigino Calvi I.I.S. Negrelli-Forcellini - Feltre 2014 ii L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 Indice 1 Problemi 1.1 PROBLEMI . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 LA RISOLUZIONE DEI PROBLEMI . . . . . . . . . . . 1.3 IL PROBLEMA DELLE 8 REGINE . . . . . . . . . . . . 1.4 IL PROBLEMA DEI 4 COLORI . . . . . . . . . . . . . . 1.5 IL PROBLEMA DELLA TORRE DI HANOI . . . . . . 1.6 PROBLEMA DEL COMMESSO VIAGGIATORE . . . . 1.7 PROBLEMA DEI PONTI DI KÖNISBERG . . . . . . . 1.8 IL PROBLEMA DELLE EQUAZIONI . . . . . . . . . . . 1.9 IL DECIMO PROBLEMA DI HILBERT . . . . . . . . . √ 1.10 IL PROBLEMA DELLA 2 . . . . . . . . . . . . . . . . . 1.11 IL PROBLEMA DEL MASSIMO COMUNE DIVISORE 1.12 IL PROBLEMA DEL SISTEMA MU . . . . . . . . . . . 1.13 IL PROBLEMA DELLA SCACCHIERA MUTILATA . 1.14 ESERCIZI . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Tipologie dei Problemi 2.1 PROBLEMI BEN FORMULATI . . . . . 2.2 ISTANZE E CLASSI DI PROBLEMI . . 2.3 GENERALIZZAZIONE DEI PROBLEMI 2.4 RISOLVIBILITÀ DEI PROBLEMI . . . . 2.5 FORMA DEI PROBLEMI . . . . . . . . . 2.6 FORMALIZZAZIONE DEI PROBLEMI 2.7 IL PROBLEMA DELL’ORDINAMENTO 2.8 I PROBLEMI DI RICERCA . . . . . . . . 2.9 I PROBLEMI DI DECISIONE . . . . . . 2.10 ESERCIZI . . . . . . . . . . . . . . . . . . . iii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 2 4 5 7 8 9 9 11 12 13 13 15 15 . . . . . . . . . . 17 18 19 21 22 24 25 26 27 28 28 iv 3 Risolvere 3.1 LA METODOLOGIA TOP-DOWN . . . 3.2 LA METODOLOGIA BOTTOM-UP . . . 3.3 EFFICACIA DELLE SCOMPOSIZIONI 3.4 TRASFORMAZIONE DEI PROBLEMI . 3.5 ESERCIZI . . . . . . . . . . . . . . . . . . . INDICE . . . . . . . . . . . . . . . . . . . . 4 Algoritmi 4.1 FORMULE RISOLUTIVE . . . . . . . . . . . . . 4.2 ALGORITMI . . . . . . . . . . . . . . . . . . . . . 4.3 ALGORITMI COME FUNZIONI . . . . . . . . . 4.4 SCHEMI FONDAMENTALI DI ALGORITMI . 4.5 ESEMPI DI ALGORITMI . . . . . . . . . . . . . 4.6 TAVOLA DI TRACCIA DI UN ALGORITMO 4.7 LIVELLI DESCRITTIVI DEGLI ALGORITMI 4.8 NOTAZIONI DI ALTO E BASSO LIVELLO . . 4.9 IL PRINCIPIO DI COMPLESSITÀ . . . . . . . 4.10 ESERCIZI . . . . . . . . . . . . . . . . . . . . . . . 5 Problemi risolti 5.1 UN PROBLEMA GEOMETRICO . . . . . 5.2 UN PROBLEMA DI DECISIONE . . . . . 5.3 UN ALTRO PROBLEMA DI DECISIONE 5.4 UN PROBLEMA NUMERICO . . . . . . . 5.5 UN PROBLEMA SUI BLOCCHETTI . . . 5.6 UN PROBLEMA SULLE STRINGHE . . . 5.7 ESERCIZI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Soluzioni dei problemi 6.1 UN PERCORSO SUI PONTI √ DI KÖNISBERG 6.2 ALLA RICERCA DELLA 2 . . . . . . . . . . . 6.3 IL PROBLEMA DELLE 8 REGINE . . . . . . . 6.4 IL MASSIMO COMUNE DIVISORE . . . . . . . 6.5 LA SCACCHIERA MUTILATA . . . . . . . . . . 6.6 NESSUNA STRADA PORTA A MU . . . . . . . . 6.7 ESERCIZI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 36 39 40 43 44 . . . . . . . . . . 47 48 49 50 52 53 55 56 57 59 62 . . . . . . . 69 70 72 73 75 77 79 81 . . . . . . . 87 88 89 93 96 99 100 100 L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 Capitolo 1 Problemi Sentiamo in noi l’eterno richiamo: ecco il problema, cercane la soluzione. D. Hilbert Il matematico David Hilbert, al Congresso Internazionale di Matematica tenutosi a Parigi nell’agosto del 1900, si espresse con le parole riportate nella citazione sopra per sottolineare che nell’uomo è connaturata la propensione a risolvere le questioni ed i problemi che gli si presentano. In quell’occasione Hilbert presentò una lista di 23 problemi all’epoca non ancora risolti, proponendoli come sfida per i matematici e con la speranza che potessero essere risolti nel secolo che stava per iniziare. I problemi di quella lista hanno resistito per molti decenni ed alcuni attualmente non sono stati ancora risolti. In questo capitolo verrà presentata una variegata gamma di problemi, con l’obiettivo di incuriosire e stimolare a seguire tutto quello che verrà presentato più avanti, quando questi problemi saranno ripresi in considerazione e, per quelli risolvibili, ne verrà presentata una soluzione. Si tratta di problemi che riguardano argomenti molto elementari che non richiedono conoscenze avanzate; la loro formulazione è molto semplice ma la loro risoluzione non è mai immediata e banale e risulta interessante in quanto tocca alcuni importanti aspetti delle tecniche di risoluzione algoritmica dei problemi. 1 2 1.1 CAPITOLO 1. PROBLEMI PROBLEMI Per quanto sarà detto nel seguito, fra le tante possibili, assumiamo la seguente come definizione di problema: Un problema è un quesito a cui si vuole dare risposta o un obiettivo che si intende perseguire. Da questa definizione risulta implicitamente che ogni problema sottintende uno sforzo volontario per il raggiungimento del risultato finale; pertanto non considereremo come problemi quelli che ammettono palesemente la risposta o quelli ai quali non siamo interessati. Coerentemente con queste ipotesi, un problema è tale relativamente ad un dato soggetto che lo considera. Ad esempio, possiamo considerare come problema il seguente: Determinare le intensità delle correnti in un dato circuito. Al contrario, per noi non sarà un problema il seguente (essendo evidente la risposta): Decidere se un dato numero naturale è pari o dispari. Analogamente, possiamo non considerare come problema il seguente (in quanto non ci interessa): Determinare un numero naturale primo composto da cento cifre decimali. Nonostante l’apparente stravaganza, questioni di questo ultimo tipo rappresentano degli effettivi problemi pratici che si incontrano in applicazioni di codifica/decodifica di informazioni cifrate nella cosiddetta crittografia a chiave pubblica. 1.2 LA RISOLUZIONE DEI PROBLEMI Risolvere un problema significa ricercare e descrivere un procedimento che, eseguito, consenta, a partire da delle informazioni iniziali (dati), di ottenere delle informazioni finali (risultati) soddisfacenti ad un criterio di verifica, secondo lo schema descritto nella figura 1.1. dati - risultati 6 criterio di verifica Figura 1.1: Schema del processo risolutivo di un problema. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 1.2. LA RISOLUZIONE DEI PROBLEMI 3 Il solutore è il soggetto (in genere l’uomo) che descrive le azioni da eseguire per risolvere un problema. L’esecutore è l’entità (in genere una macchina) che esegue le azioni descritte dal solutore. La soluzione di un problema è la descrizione delle azioni (istruzioni), da parte del solutore e rivolte all’esecutore, che, eseguite, forniscono i risultati del problema. I dati sono le informazioni iniziali in base alle quali ricavare i risultati, che rappresentano gli oggetti o l’effetto che si ottiene mediante l’esecuzione delle istruzioni che costituiscono la soluzione. Qui i termini dati e risultati sono da intendersi in senso lato: possono essere un numero, un insieme di numeri, la risposta ad un quesito, un disegno o qualcos’altro di più generale ancora. Notiamo che la ricerca e la descrizione della soluzione di un problema è un’attività del solutore (e non dell’esecutore, il quale esegue il procedimento risolutivo ma non lo costruisce). Esempio 1. Consideriamo il problema della risoluzione di un’equazione di secondo grado ax2 + bx + c = 0. Un procedimento risolutivo di questo problema è fornito dalla ben nota formula risolutiva delle equazioni di secondo grado: √ −b ± b2 − 4ac x1 , x 2 = 2a Con riferimento a questo problema, il solutore è colui che ha ideato la formula risolutiva delle equazioni di secondo grado, mentre chi la applica per trovare, con carta e penna, le radici di una particolare equazione assume il ruolo di esecutore. Nel caso venga utilizzato un programma su calcolatore per trovare le radici di un’equazione, l’esecutore è rappresentato dal calcolatore (e chi utilizza il programma assume il ruolo di semplice utente). Un criterio di verifica consiste nella sostituzione diretta dei valori trovati delle radici e nella verifica dell’identità. Osservazione. L’impostazione basata sui termini chiave problema, solutore, soluzione, esecutore, risultato è tipica del cosidetto paradigma imperativo, secondo il quale il solutore specifica all’esecutore delle direttive di come deve agire per ottenere il risultato finale. Un’impostazione alternativa, tipica del cosidetto paradigma dichiarativo, consiste nel descrivere, con informazioni e vincoli stringenti, da parte del solutore all’esecutore, in cosa consiste il risultato, delegando all’esecutore il compito di trovare i passi da eseguire per determinarlo. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 4 CAPITOLO 1. PROBLEMI 1.3 IL PROBLEMA DELLE 8 REGINE Il problema delle 8 regine consiste nel determinare le configurazioni di 8 regine disposte su un’usuale scacchiera in modo tale che nessuna regina sia attaccata da qualche altra; in altri termini, le 8 regine devono trovarsi su righe, su colonne e su diagonali distinte. Questo problema fu studiato da Carl Friedrich Gauss che, nel 1850, riuscì a determinare inizialmente 76 configurazioni e successivamente, con altri tentativi, riuscì a determinare tutte le 92 possibili configurazioni. Questa soluzione in più tempi fa intuire che all’epoca Gauss non disponesse di un procedimento sistematico di ricerca che conosciamo noi oggi. Nella figura 1.2 è riportata una non-soluzione in quanto sono presenti solo 7 regine e non è possibile disporne un’altra senza entrare in conflitto con quelle già presenti. Q Q Q Q Q Q Q Figura 1.2: Una non-soluzione del problema delle 8 regine. Nel 1874 J. W. Glaisher propose una generalizzazione di questo problema, considerando una generica scacchiera quadrata di lato n sulla quale disporre n regine; egli giunse ad ipotizzare che su una tale scacchiera fosse sempre possibile disporre n regine. Tale ipotesi venne dimostrata solo nel 1969 1 . Problemi di questo tipo sono diventati di particolare interesse in quanto, pur non ammettendo delle soluzioni analitiche, si prestano ad essere risolti efficacemente mediante l’uso degli elaboratori. Il problema delle 8 regine è divenuto un classico della programmazione in quanto coinvolge tipici ed interessanti aspetti dell’informatica e della programmazione, quali la ricorsività e le strategie di backtracking. 1 E. J. Hoffman, J. C. Loessi, R. C. Moore, Construction for the solution of the n-queens problem, Mathematical Magazine 42 (1969), 66-72. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 1.4. IL PROBLEMA DEI 4 COLORI 1.4 5 IL PROBLEMA DEI 4 COLORI Il problema dei quattro colori può essere formulato nei seguenti termini: È possibile, mediante al più quattro colori, colorare una generica carta geografica piana in modo che regioni contigue abbiano colori differenti? In questo problema si ipotizza che ogni regione sia connessa, ossia sia costituita da un unico pezzo. Si pensa che questo problema fosse noto a Möbius già nel 1840. Si è comunque soliti far risalire l’origine di questo problema all’ottobre 1852 quando Francis Guthrie, giovane matematico studente di De Morgan, riuscendo a colorare una cartina delle contee dell’Inghilterra con soli 4 colori, ipotizzò che 4 colori fossero sempre sufficienti per colorare qualsiasi cartina, imponendo l’ovvio vincolo che due regioni contigue abbiano colori diversi. Talvolta, dato il successo della colorazione di tutte le mappe considerate, ci si riferisce a questo quesito con il termine di Teorema dei 4 colori. De Morgan propose la congettura alla London Mathematical Society, invitando a cercarne una dimostrazione o una refutazione. È davvero sorprendente che un tale problema, all’apparenza così semplice, sia rimasto irrisolto per più di un secolo, nonostante, da subito, moltissimi matematici si siano impegnati nella sua soluzione ed abbiano dedicato anni di lavoro nel tentativo di dimostrare il teorema. Nel 1879 Alfred Bray Kempe, avvocato londinese che studiò matematica a Cambridge, pubblicò una dimostrazione della congettura. Tale dimostrazione venne ritenuta valida per undici anni, fino al 1890 quando Percy John Heawood vi trovò un errore. Nonostante l’errore insito nella sua dimostrazione, Kempe ebbe il merito di introdurre le cosidette catene di Kempe che vennero utilizzate un secolo dopo per la dimostrazione definitiva del teorema. Tale risultato conclusivo venne raggiunto nel 1977 da Kenneth Appel e Wolfang Haken, due matematici dell’Università dell’Illinois. La loro dimostrazione si basa sulla riduzione del numero infinito delle mappe possibili a soli 1476 configurazioni per le quali la validità del teorema venne verificata caso per caso, usando un complesso algoritmo informatico la cui esecuzione richiese 1200 ore di elaborazione su diversi computer ad alta velocità. La dimostrazione di Appel ed Haken richiese oltre 500 pagine per essere trascritta, rimanendo comunque impossibile una verifica diretta. Ciò alimentò molte polemiche e molti matematici rifiutarono di accettarla come dimostrazione 2 . Successivi miglioramenti della dimostrazione hanno ridotto il numero di configurazioni 2 Vennero all’epoca sollevate profonde discussioni sul cosa sia effettivamente una dimostrazione; ma questa questione si insinua nel campo dei fondamenti della matematica e della logica, e non tentiamo degli approfondimenti qui. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 6 CAPITOLO 1. PROBLEMI a 633. Sono state successivamente proposte nuove dimostrazioni alternative, basate sull’uso della teoria dei gruppi, un’importante branca dell’algebra astratta. Un divertente anneddoto riguardante questo problema risale al 1975, quando Martin Gardner, un famoso esperto e divulgatore di giochi matematici, pubblicò un articolo su un numero di una rivista uscita il 1 aprile, riportando una mappa per colorare la quale non sarebbero stati sufficienti 4 colori. Ad alcuni lettori sorse il sospetto, visto anche il giorno dell’uscita dell’articolo, che si trattasse di uno scherzo, come in effetti era. La mappa dello scherzo è riportata nella figura 1.3. Figura 1.3: Mappa dello scherzo di Martin Gardner. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 1.5. IL PROBLEMA DELLA TORRE DI HANOI 1.5 7 IL PROBLEMA DELLA TORRE DI HANOI Il problema della torre di Hanoi è un gioco ideato nel 1883 dal matematico francese Edouard Lucas. Il gioco prende spunto dalla leggenda secondo la quale nel tempio di Benares in India i monaci avevano il compito di spostare una piramide di 64 dischi in oro, disposti uno sopra l’altro, dal più grande posto in basso, da un piolo di diamante ad un altro, spostando un solo disco alla volta, utilizzando un terzo piolo come appoggio, con il vincolo che ogni disco debba poggiare sopra uno di dimensioni più grandi. Secondo la leggenda il mondo avrà fine quando i monaci avranno finito il proprio lavoro. Sintetizzando quanto tramandato dalla leggenda, il problema è generalmente noto nella seguente formulazione. Sono dati tre pioli e n dischi di diversi diametri. Inizialmente tutti gli n dischi sono impilati su un piolo in modo tale che nessun disco sia disposto sopra di un disco più piccolo. Il problema consiste nello spostare la pila degli n dischi da un piolo ad un altro, muovendo un solo disco alla volta, potendo utilizzare il terzo piolo come supporto ausiliario e rispettando il vincolo che nessun disco sia disposto sopra uno più piccolo. Figura 1.4: Problema della torre di Hanoi con 4 dischi. Il problema suggerisce le seguenti questioni: • È possibile risolvere il problema per qualsiasi numero n di dischi? • Determinare il numero di spostamenti necessari per spostare una pila di n dischi. • Determinare e descrivere un procedimento per spostare gli n dischi. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 8 1.6 CAPITOLO 1. PROBLEMI PROBLEMA DEL COMMESSO VIAGGIATORE Il problema del commesso viaggiatore fu considerato per la prima volta agli inizi degli anni ’30 del secolo scorso, anche se, sotto altra veste, comparve all’interno della teoria dei grafi già nel diciannovesimo secolo. Nella sua formulazione più caratteristica il problema si enuncia come segue: Un commesso viaggiatore deve visitare un dato numero di città. Ogni città è collegata a tutte le altre da una strada di cui si conosce la lunghezza. Determinare il percorso più breve che passa per ogni città una sola volta e ritorna alla città di partenza. Il problema richiede la formulazione di un procedimento risolutivo generale che non dipenda da una particolare disposizione delle città, né dal numero delle città. Una istanza di questo problema corrispondente a 532 punti è presentata nella figura 1.5. Figura 1.5: Il cammino ottimale sulle 532 centraline della società AT&T negli USA, calcolato nel 1987 da Padberg e Rinaldi. Al di là della sua formulazione in termini di città da visitare, il problema ha un’importanza pratica in vari settori dell’industria, ad esempio nella stampa dei circuiti elettronici. Un ovvio metodo di soluzione consiste nel determinare tutti i percorsi possibili e poi determinarne il più breve fra questi. La scarsa utilità di questo approccio discende dal fatto che il numero di possibili percorsi che passano attraverso n città è (n − 1)!/2 e questo è un numero al di fuori della portata di calcolo anche dei più potenti elaboratori attuali e futuri, anche per modesti valori di n. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 1.7. PROBLEMA DEI PONTI DI KÖNISBERG 1.7 9 PROBLEMA DEI PONTI DI KÖNISBERG Königsberg, città della Prussia orientale attualmente situata in territorio russo e nota come Kaliningrad, è attraversata dal fiume Pregel al cui interno sorge un’isola oltre la quale il fiume si spezza nuovamente in due rami. I suoi quartieri sono collegati da sette ponti. La mappa è riportata nella figura 1.6. Agli inizi del XVIII secolo gli abitanti di Könisberg si chiedevano se fosse possibile fare una passeggiata attraversando una sola volta i sette ponti della cittadina e ritornare al punto di partenza. Figura 1.6: Mappa della cittadina di Könisberg. Il problema divenne famoso come il problema dei ponti di Königsberg, quando il grande matematico svizzero Leonhard Euler, all’inizio di un suo celebre scritto pubblicato nel 1736, lo espose nei seguenti termini: È possibile uscire di casa e farvi ritorno dopo avere percorso tutti e sette i ponti non più di una volta? Il problema venne approfondito e risolto dallo stesso Euler e le sue disquisizioni sull’argomento diedero avvio alla teoria dei grafi, uno degli ambiti più fecondi della matematica moderna. 1.8 IL PROBLEMA DELLE EQUAZIONI Moltissimi problemi, di diversa natura, opportunamente trasformati, si riconducono alla soluzione di un’equazione algebrica o ad un sistema di equazioni L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 10 CAPITOLO 1. PROBLEMI algebriche. Anche per questo motivo, uno dei problemi più importanti dell’Algebra riguarda la risolubilità delle equazioni polinomiali di grado n in una sola incognita, mediante delle formule risolutive costituite da un’espressione contenente solo le quattro operazioni elementari e l’estrazione di radice. Ci limiteremo qui a considerare il caso particolare delle equazioni polinomiali di grado n, per le quali il problema può essere formulato come segue: Determinare una formula risolutiva per risolvere un’equazione polinomiale di grado n, in una sola incognita x: a0 xn + a1 xn−1 + ⋯ + an−1 x + an = 0 Le equazioni di primo grado (a x+b = 0) e quelle di secondo grado (a x2 +b x+c = 0) sono state risolte sin dall’antichità, individuando delle formule che forniscono direttamente le radici. Le equazioni di terzo grado furono risolte solo nei primi anni del Cinquecento, all’epoca del Rinascimento, ad opera dell’italiano Scipione Dal Ferro (1465 circa - 1526), professore di matematica a Bologna; egli non pubblicò la sua scoperta ma la comunicò ad uno dei suoi allievi. In quegli stessi anni anche il matematico Nicolò Tartaglia (1500 circa - 1557), forse senza conoscere le scoperte di Dal Ferro, scoprì la formula e la comunicò a Gerolamo Cardano (1501-1576) il quale, senza esserne l’ideatore, la pubblicò nella sua opera Ars Magna. Pochi anni dopo il matematico italiano Ludovico Ferrari (1522-1565) risolse anche l’equazione generica di quarto grado, trovando un modo per trasformare una generica equazione di quarto grado ad una di terzo grado e potersi quindi avvalere della formula per l’equazione di terzo grado. Al di là della diatriba su chi debba essere considerato il primo scopritore della formula risolutiva per le equazioni di terzo grado, gli splendidi risultati ottenuti in quegli anni stimolarono molti lavori sulla ricerca di formule risolutive per equazioni di grado superiore al quarto. Al noto algebrista Ehrenfried Walter von Tschirnhaus (1651-1708) sembrò persino di aver scoperto un metodo generale per risolvere una generica equazione polinomiale di grado n, riconducendosi ad equazioni di grado inferiore. Ma era solo un’illusione: già per ricondurre un’equazione di quinto grado ad una di quarto grado si richiedeva di risolvere un’equazione ausiliaria di sesto grado, che non si era in grado di risolvere. Nel 1824 il giovane matematico norvegese Niels Henrik Abel (1802-1829) fornì una dimostrazione che non esiste alcuna formula risolvente una generica equazione di grado superiore al quarto. In seguito il matematico francese Evariste Galois (1811-1832), pur nella sua breve vita, basandosi su profondi concetti algebrici, fornì dei criteri per ridurre un’equazione polinomiale al prodotto di polinomi di grado inferiore fornendo così, indirettamente, dei metodi per la sua soluzione. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 1.9. IL DECIMO PROBLEMA DI HILBERT 1.9 11 IL DECIMO PROBLEMA DI HILBERT Il decimo problema di Hilbert rappresenta uno dei più famosi problemi della matematica. Tale nome deriva dal fatto che questo problema apparve come decimo in una lista di 23 problemi proposti da David Hilbert al secondo congresso dei matematici tenutosi a Parigi nell’agosto dell’anno 1900. Alcuni di questi problemi hanno resistito ai tentativi di molti matematici e risultano a tutt’oggi ancora insoluti. Famoso è il decimo problema di quella lista. Esso riguarda le equazioni polinomiali a coefficienti interi, ossia equazioni a più incognite legate tra loro da un’espressione polinomiale; ad esempio 3xy−4y 2 +y = 0. Il problema proposto da Hilbert può essere formulato nei seguenti termini: Data un’equazione polinomiale a coefficienti interi con un qualunque numero di incognite, descrivere un procedimento per decidere se essa ammetta radici intere. Il problema non richiede un procedimento per trovare le soluzioni ma solamente per stabilire se l’equazione ne possegga. Nella formulazione del problema è essenziale il fatto che si cerchino solo radici intere. Un’equazione di questo tipo viene detta diofantea, in onore del matematico Diofanto di Alessandria che si occupò di questi argomenti nel terzo secolo d.C.. Per le equazioni di primo grado, ad esempio 3x − 7y + 2z − 14 = 0, l’esistenza di soluzioni può essere determinata mediante un procedimento ideato ancora da Euclide. Per le equazioni di secondo grado a due incognite, ad esempio 7x2 − 4y 2 + xy − 13 = 0, è possibile stabilire se esistono soluzioni basandosi su una teoria e su dei procedimenti sviluppati all’inizio del XIX secolo dal grande matematico Carl Friedrich Gauss. Per le equazioni di grado superiore al secondo sono stati escogitati alcuni metodi applicabili solo ad alcuni casi particolari. Nel 1970 il giovane matematico russo Yuri Matijasevic poneva fine alla questione dimostrando che non esiste alcun procedimento generale per stabilire se un’equazione diofantea ammetta radici. Una famiglia molto nota di equazioni diofantee ha la forma xn + y n = z n , n = 2, 3, 4, . . . Per n = 2 l’equazione risulta soddisfatta dalle lunghezze dei lati di ogni triangolo rettangolo e corrisponde al teorema di Pitagora; ad esempio l’equazione è soddisfatta per x = 3, y = 4, z = 5. Per n ≥ 3 l’equazione è nota come equazione di Fermat. Il matematico francese Pierre de Fermat nel diciasettesimo secolo sul margine della sua copia del libro di Diofanto scrisse di aver trovato una dimostrazione veramente mirabile che l’equazione non è soddisfatta per L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 12 CAPITOLO 1. PROBLEMI alcuna terna x, y, z) e n ≥ 3, ma che era troppo lunga per poter essere riportata su quel margine. La dimostrazione di Fermat non venne mai trovata (ammesso che l’avesse effettivamente trovata) e da allora il problema divenne famoso con il nome di l’ultimo teorema di Fermat. Nonostante l’appellativo di teorema, tale risultato è stato dimostrato solamente nel 1993 da Andrew Wiles: a contrasto con l’estrema semplicità della formulazione della questione, la dimostrazione è lunga 200 pagine ed ha richiesto nove anni di lavoro. 1.10 IL PROBLEMA DELLA √ 2 √ La 2 è un personaggio matematico, non altrettanto noto come i suoi colleghi famosi i, e, φ e π (che hanno avuto un nome proprio), ma è sicuramente un individuo interessante in quanto stimola interessanti considerazioni sia dal punto di vista matematico che da quello informatico. √ Si definisce: La 2 è quel numero che moltiplicato per se stesso dà 2 come risultato. Questa definizione, apparentemente innocua, sembra autosufficiente, conclusiva e non lascia presagire alcuna problematica. Sfruttando delle proprietà che discendono direttamente dalla sua definizione, questo oggetto può essere manipolato in modo formale; ad esempio si possono eseguire dei calcoli quali: √ √ 2→2 √ 1 2⋅ √ →1 2 √ √ 1 2 2 √ → √ √ → 2 2 2⋅ 2 2⋅ I problemi iniziano√ a sorgere quando si considera l’obiettivo Determinare √ la 2. Ovviamente 2 non è la soluzione del problema, è semplicemente una notazione, un simbolo proprio per denotare quel numero che moltiplicato per se stesso da 2, in modo analogo a come possiamo usare 3/4 per denotare quel numero che moltiplicato per 3 da 4. Determinare un oggetto significa esibirlo, in un contesto ben precisato, in un formato ed in una notazione specifica del contesto considerato. Questo quesito richiede implicitamente di √ definire l’insieme nel quale la 2 viene cercata. I greci pensavano che tutti i numeri fossero√ esprimibili come numeri razionali, come rapporto di due numeri naturali. La 2 non è invece esprimibile come numero razionale. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 1.11. IL PROBLEMA DEL MASSIMO COMUNE DIVISORE 13 √ Con le premesse date, il problema della 2 solleva le seguenti questioni: √ 1. dimostrare che 2 non è esprimibile mediante un numero razionale √ 2. determinare in quale insieme si trova 2 √ 3. determinare una frazione che approssima bene il valore 2 4. determinare e descrivere un procedimento che, basandosi solo sulle quattro √ operazioni aritmetiche fondamentali, fornisca le varie cifre decimali di 2 5. dato un segmento di lunghezza unitaria √ nel piano, costruire con riga e compasso un segmento di lunghezza 2 1.11 IL PROBLEMA DEL MASSIMO COMUNE DIVISORE Consideriamo il problema del calcolo del massimo comune divisore di due numeri naturali. Il problema può essere formulato come segue: Dati due numeri naturali positivi, determinare il loro massimo comune divisore, ossia il più grande numero intero che li divide entrambi. Tale problema, oltre ad essere un’interessante palestra per lo studio degli algoritmi, riveste una particolare importanza pratica in quanto si presenta in svariati ambiti della matematica. Il problema sorge in molte questioni riguardanti l’aritmetica elementare, in particolare nell’elaborazione delle frazioni, ad esempio quando si deve ridurre una frazione ai minimi termini oppure quando si debbano addizionare due frazioni. Sorge inoltre in questioni più avanzate quale l’aritmetica modulare e nella soluzione di alcuni tipi di equazioni diofantee. 1.12 IL PROBLEMA DEL SISTEMA MU Il sistema formale M U venne originariamente proposto da Hofstadter 3 . Il sistema è costituito da stringhe sull’alfabeto {M, I, U}. A partire dalla stringa MI si possono generare altre stringhe usando le seguenti quattro regole di generazione: 3 D. R. Hofstadter, Godel, Escher, Bach, 1979. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 14 CAPITOLO 1. PROBLEMI (a) Se una stringa termina con I, si può accodare U alla fine. (b) Se una stringa inizia con M, si può accodare la sottostringa che segue tale M. (c) Se in una stringa è presente la sottostringa III, si può sostituirla con una U. (d) Se in una stringa è presente la sottostringa UU, si può eliminarla. La porzione di albero riportata nella figura 1.7 illustra la generazione di alcune stringhe. MI Q Q Q + QQ s MIU MII QQ k @ Q MIUIU MIUIUIUIU Q Q @ R @ MIIII J J ^ J MUI MIIIIIIII MIIU J J ^ J MIIUIIU Figura 1.7: Generazione di alcune stringhe nel sistema MU. Il problema consiste nel decidere se MU è generabile a partire dalla stringa MI applicando le regole ammesse. È evidente che un ragionamento interno al sistema, ossia l’applicazione diretta delle regole, può condurre alla soluzione (ossia alla generazione della stringa MU); nel caso in cui l’applicazione diretta non ci porti alla stringa cercata, rimane vivo il dubbio che la stringa MU possa non essere generabile applicando le regole del sistema; in questo caso qualsiasi applicazione meccanica delle regole (ossia rimanendo all’interno del sistema) non può darci alcuna informazione e non ci rimane altro che uscire dal sistema. Si invita a ragionare a risolvere il problema proposto. Come suggerimento per la soluzione del problema notiamo che ci sono regole che allungano e regole che accorciano. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 1.13. IL PROBLEMA DELLA SCACCHIERA MUTILATA 1.13 15 IL PROBLEMA DELLA SCACCHIERA MUTILATA Il seguente problema viene generalmente proposto nei libri di giochi matematici. Ad una scacchiera di 8 caselle per lato vengono tolti i due quadretti di due angoli appartenenti ad una stessa diagonale. Ricoprire la scacchiera mediante 31 tessere del domino, ciascuna composta da due quadretti unitari. Una soluzione potrebbe essere trovata cercando delle possibili disposizioni dei tasselli oppure rispondendo negativamente al quesito posto dal problema qualora nessuno di tutti i possibili tappezzamenti conduca al successo. Il problema può essere generalizzato considerando un quadrato reticolato avente un numero n di quadretti su ciascun lato. 1.14 ESERCIZI 1. Spiegare la differenza fra i termini soluzione e risultato. 2. Spiegare il significato dei termini solutore ed esecutore. 3. Spiegare perché non ha senso considerare un procedimento risolutivo senza fare riferimento alle capacità dell’esecutore. 4. Determinare qualche configurazione soluzione del problema delle 8 regine. 5. Usando solo 4 colori, colorare la mappa riportata nella figura 1.3. 6. Determinare la sequenza di mosse che risolve il problema della torre di Hanoi con 4 dischi, illustrato nella figura 1.4. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 16 CAPITOLO 1. PROBLEMI 7. Determinare il tempo necessario ad un elaboratore per risolvere il problema del commesso viaggiatore, esaminando tutti i possibili percorsi fra 100 città, nell’ipotesi che impieghi un miliardesimo di secondo per calcolare ed esaminare ciascun singolo percorso. 8. Dimostrare che nel sistema MU la stringa IU non è generabile. 9. Dimostrare che il problema della scacchiera mutilata non è risolvibile se il numero delle caselle per lato è dispari (7 × 7, 7 × 9, . . . ). L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 Capitolo 2 Tipologie dei Problemi Da dove dovrei partire? Parti dalla formulazione del problema. G. Polya, How to solve it Una attenta ed approfondita analisi del testo del problema permette di fare il primo passo nella giusta direzione che porta alla soluzione. I problemi presentano delle analogie rispetto ad alcune caratteristiche quali la forma del problema, la sua risolvibilità, la tipologia dei dati e dei risultati, l’ambiente di operatività (aritmetico, geometrico, grafico, . . . ). La variegata gamma dei problemi che si incontrano può essere pertanto classificata in categorie rispetto ad una di queste caratteristiche. Classificare un problema costituisce un primo passo verso la sua comprensione e, quindi, verso la sua soluzione. 17 18 CAPITOLO 2. TIPOLOGIE DEI PROBLEMI 2.1 PROBLEMI BEN FORMULATI Nel seguito considereremo solo problemi che sono definibili in modo preciso, univoco e non ambiguo, e che si prestano, quindi, ad essere risolti in modo automatico. Con questa ipotesi si potrà ambientare i problemi in appositi contesti formali, all’interno dei quali la soluzione può essere descritta in modo rigoroso. Ai fini della sua risolvibilità un problema deve soddisfare ad ulteriori vincoli espressi dalla seguente definizione. Si afferma che un problema è ben formulato o formalmente definito se soddisfa alle seguenti specifiche: 1. Il problema è formulato in una forma comprensibile dal solutore 2. I dati sui quali si deve cercare la soluzione sono completi e coerenti 3. È univoco il criterio di verifica della soluzione Con queste premesse abbiamo definito una prima classificazione dei problemi, come descritto nella figura 2.1. ' $ problemi problemi risolvibili in modo automatico & % Figura 2.1: Una classificazione dei problemi. Esempio 2. Consideriamo il seguente problema: Determinare il barimetro di un poliangolo. Questo è un chiaro esempio di problema mal formulato poichè non viene rispettata la condizione a) in quanto nella formulazione del problema compaiono dei termini che non hanno alcun significato. Esempio 3. Consideriamo il seguente problema: Trovare una soluzione al seguente gioco: L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 2.2. ISTANZE E CLASSI DI PROBLEMI 1 1 0 3 1 19 2 2 Questo è un altro esempio di problema mal formulato poichè non viene rispettata la condizione a) in quanto non è precisato qual è il gioco, quali sono le possibili mosse e qual è il criterio per determinare se una data posizione finale è vincente. Sono invece ben formulati gli usuali problemi di scacchi che si trovano sui giornali di enigmistica, in quanto le regole del gioco sono ben precisate ed è univoco il criterio per valutare se una data posizione finale sia vincente, in base alle regole del gioco degli scacchi, anche se tali ipotesi sono assunte implicitamente e non direttamente riportate nella formulazione del problema. Esempio 4. Un altro problema mal formulato è il seguente: Determinare l’area di un trapezio rettangolo sapendo che le basi maggiore e minore misurano rispettivamente 18 e 12 unità. In questo caso non è soddisfatta la condizione b). Esempio 5. Consideriamo un altro caso di problema mal formulato: Calcolare il valore dell’espressione 1 + 1. Nonostante la banalità del quesito, si può osservare che si possono accettare più risposte a seconda del contesto che si considera: 0 se il quesito è formulato nel contesto dell’addizione fra numeri interi modulo 2; 1 in un contesto di algebra booleana; 2 nell’usuale contesto dei numeri naturali. In questo caso viene a cadere la condizione c); infatti non sapremo in alcun caso verificare se la risposta è corretta o no. 2.2 ISTANZE E CLASSI DI PROBLEMI In generale, i dati che compaiono nella formulazione dei problemi sono dei valori generici, denotati solitamente mediante dei nomi. In questo modo si evidenzia una classe di problemi i cui elementi (problemi), detti istanze di problemi, si ottengono per particolari valori assunti dai dati. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 20 CAPITOLO 2. TIPOLOGIE DEI PROBLEMI Esempio 6. Consideriamo il problema di determinare l’area di un rettangolo, note le misure dei suoi lati. In questo caso rimane individuata la seguente classe di problemi: Determinare l’area di un rettangolo di lati a e b. A questa classe appartiene, ad esempio, la seguente istanza di problema: Determinare l’area di un rettangolo di lati 3 cm e 4 cm. Nel seguito, quando si parla di problema si intenderà solitamente una classe di problemi, che risulta caratterizzata da dei parametri che costituiscono i dati. Una classe di problemi è strettamente associata alla classe delle entità coinvolte nel problema. Pertanto, come si vedrà nelle prossime pagine, le considerazioni relative ai problemi si possono trasporre e formulare in termini delle entità coinvolte nei problemi stessi. Ad esempio, generalizzare una classe di problemi sarà spesso equivalente a generalizzare le classi delle entità coinvolte nel problema. Le classi di problemi ammettono un procedimento risolutivo generale indipendente dalle particolari istanziazioni dei dati. Ad esempio, un metodo di soluzione per la ricerca del massimo comune divisore di due numeri naturali m e n deve essere valido per qualsiasi coppia di valori assunti da m e n. Risulta dunque evidente che un metodo risolutivo di un problema deve essere applicabile ad un’intera classe di problemi le cui istanze differiscono soltanto per i particolari valori assunti dai dati iniziali. Con queste premesse, quando nel seguito si userà il termine soluzione di un problema ci si riferirà ad un procedimento risolutivo generale, valido per un’intera classe di problemi alla quale appartiene il problema considerato. Lo schema attraverso il quale si ricava il risultato di una particolare istanza di problema si sviluppa attraverso le seguenti fasi successive: 1. considerazione dell’istanza P del problema 2. individuazione di una classe C alla quale appartiene il problema P 3. ricerca e descrizione di un procedimento risolutivo A per la classe C 4. applicazione del procedimento risolutivo A all’istanza P Graficamente, queste fasi possono essere evidenziate mediante lo schema riportato in figura 2.2. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 21 2.3. GENERALIZZAZIONE DEI PROBLEMI generalizzazione del problema istanza P di problema - classe C di problemi soluzione della classe C di problemi soluzione istanza P particolarizzazione del procedimento risolutivo ? procedimento per C Figura 2.2: Schema delle fasi per la soluzione di un’istanza di problema. 2.3 GENERALIZZAZIONE DEI PROBLEMI Come è stato sopra suggerito, quando ci si imbatte in un problema particolare (ad esempio, trovare le radici dell’equazione x2 +3x−5 = 0) prima di impostare la soluzione è conveniente, per fare un buon investimento dello sforzo che ci si appresta a compiere, trovare una opportuna generalizzazione del problema. La generalizzazione di un problema specifico individua una classe di problemi della quale il problema originale costituisce una particolare istanza. Il punto centrale del procedimento di generalizzazione riguarda le seguenti questioni: • Come generalizzare? • Fino a che punto generalizzare? Un po’ di buon senso (all’inizio) ed un po’ di esperienza (quando sarà stata maturata) saranno sufficienti come guida per individuare una buona generalizzazione. Graficamente, il procedimento di generalizzazione di un’istanza di problema e delle successive generalizzazioni può essere descritto come in figura 2.3. Esempio 7. Consideriamo la seguente istanza di problema: Determinare la distanza fra i due punti del piano cartesiano P (1, 2), Q(4, 3). Una prima generalizzazione consiste nel prendere dei valori generici per i dati delle coordinate dei punti: L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 22 CAPITOLO 2. TIPOLOGIE DEI PROBLEMI ' ● istanza - classe C1 ● classe C2 classe C1 ● $ & % Figura 2.3: Procedimento di generalizzazione di un’istanza di problema. Determinare la distanza fra i due punti del piano cartesiano P (x1 , y1 ), Q(x2 , y2 ). Per individuare delle successive generalizzazioni è sufficiente considerare i termini del problema che si prestano ad essere generalizzati: 2 punti Ð→ n punti piano Ð→ spazio n-dimensionale distanza Ð→ distanza d generica Adottando queste generalizzazioni si ottiene la seguente formulazione molto generale del problema: Determinare il diametro della più piccola sfera k-dimensionale contenente un dato insieme {a1 , ..., an } di n elementi di uno spazio metrico (E, d). Per il momento questa formulazione potrà risultare alquanto oscura, ma siamo sicuri che, una volta risolta questa classe di problemi, avremo trovato una soluzione per moltissime sottoclassi, appartenenti magari a contesti molto disparati. 2.4 RISOLVIBILITÀ DEI PROBLEMI Un procedimento risolutivo di un problema può essere efficacemente raffigurato come un cammino che congiunge i dati iniziali ai risultati finali. È stato osservato precedentemente che per alcuni problemi non si conosce oppure non esiste alcun cammino risolutivo. A seconda che questo cammino esista o no, si possono classificare i corrispondenti problemi come segue: L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 23 2.4. RISOLVIBILITÀ DEI PROBLEMI 1. problemi risolvibili: sono quei problemi che ammettono un procedimento risolutivo. Questi problemi possono essere descritti dal seguente schema: dati - risultati Appartengono a questa classe i seguenti problemi: • problema del commesso viaggiatore • problema dei 4 colori • problema della torre di Hanoi • risoluzione delle equazioni polinomiali ad una incognita di grado n≤4 2. problemi risolvibili? : sono quei problemi per i quali non è noto se esista un procedimento risolutivo. Possono essere descritti dal seguente schema: dati ? - risultati Un esempio di problema di questa classe è costituito dalla congettura che esistano infinite coppie di numeri primi gemelli. 3. problemi irrisolvibili: sono quei problemi per i quali è noto che non esiste alcun procedimento risolutivo. Possono essere descritti dal seguente schema: dati // - risultati L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 24 CAPITOLO 2. TIPOLOGIE DEI PROBLEMI Esempi di questo tipo di problemi sono i seguenti: • risoluzione delle equazioni polinomiali ad una incognita di grado n>4 • decimo problema di Hilbert 2.5 FORMA DEI PROBLEMI Molto spesso i problemi rappresentano delle analogie con riferimento alle informazioni iniziali che si dispongono ed all’obiettivo finale che si intende raggiungere. Come si vedrà più avanti, queste tre classi di problemi verranno risolte mediante delle corrispondenti classi di algoritmi (funzioni, predicati, procedure). In base a questo criterio i problemi che più frequentemente si incontrano nella programmazione possono essere partizionati nelle seguenti classi: 1. problemi di tipo computazionale: i problemi di questa classe si formulano come segue: A partire da dei dati iniziali noti, mediante dei calcoli, determinare dei risultati. dati calcolo - risultati Appartengono a questa classe i seguenti problemi: • risolvere un’equazione di secondo grado • determinare la lunghezza della diagonale di un parallelepipedo 2. problemi di tipo decisionale: i problemi di questa classe si formulano come segue: Fissate delle ipotesi iniziali, attraverso delle deduzioni logiche, stabilire se una data proposizione è vera. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 25 2.6. FORMALIZZAZIONE DEI PROBLEMI dati decisione - vero/falso Appartengono a questa classe i seguenti problemi: • decidere se un dato elemento è presente in un dato insieme di elementi • stabilire se un dato numero naturale è primo 3. problemi di tipo esecutivo: i problemi di questa classe si formulano come segue: Fissata una situazione iniziale di partenza, eseguire una sequenza di trasformazioni in modo da ottenere una situazione finale obiettivo. situazione iniziale trasformazione - situazione finale Appartengono a questa classe i seguenti problemi: • problema della torre di Hanoi • problema del traghettamento del lupo, capra e cavoli 2.6 FORMALIZZAZIONE DEI PROBLEMI Il processo di formalizzazione o modellizzazione di un problema consiste nel tradurre un problema reale in una sua formulazione alternativa, alquanto semplificata ma equivalente per quanto riguarda la tematica di interesse, in modo tale che esso possa essere risolto automaticamente. Applicando l’inverso di questa trasformazione si tradurranno poi immediatamente i risultati nell’ambito originale del problema. Questi artifici sono spesso utilizzati in Matematica (risoluzione delle equazioni differenziali mediante le trasformate di Laplace, analisi di un segnale in frequenza, calcoli nell’ambito della geometria analitica ed in molte altre situazioni). Vengono qui di seguito presentati degli esempi che illustrano questo artificio. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 26 CAPITOLO 2. TIPOLOGIE DEI PROBLEMI Esempio 8. Consideriamo il seguente problema: Si ha un bersaglio delimitato da 3 cerchi concentrici. Il cerchio più interno vale 19 punti, mentre le due corone esterne valgono rispettivamente 13 e 7 punti. Il raggio del cerchio interno e lo spessore delle corone sono di 5 cm. Decidere se, ed eventualmente come, è possibile totalizzare 100 punti, in più tiri. Filtrando i dettagli superflui, tale problema può essere formalizzato come segue: Risolvere l’equazione diofantea 19x + 13y + 7z = 100. 2.7 IL PROBLEMA DELL’ORDINAMENTO L’ordinamento di elementi (numeri o altre tipologie di dati) costituisce una delle forme di elaborazione più frequenti: si stima che oltre il 25 per cento del tempo di elaborazione impiegato dai computer sia impegnato per ordinare. Il problema dell’ordinamento può essere formulato come segue: Dato un insieme di elementi sui quali sia definito un qualche criterio d’ordine, disporli in sequenza, uno dopo l’altro, in modo che ogni elemento preceda gli elementi uguali o più grandi. Esempio 9. Il giocatore di carte affronta un problema di ordinamento quando deve disporre inizialmente le carte che gli sono state distribuite, al fine di essere agevolato nelle successive fasi del gioco. Esempio 10. Ordinare la seguente sequenza di numeri 27 32 15 11 54 78 15 23 significa operare una permutazione degli elementi in modo da ottenere la seguente sequenza: 11 15 15 23 27 32 54 78 Esistono moltissimi procedimenti adatti per ordinare una sequenza di elementi; questi procedimenti costituiscono uno dei capitoli più importanti della teoria dell’elaborazione delle informazioni. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 2.8. I PROBLEMI DI RICERCA 2.8 27 I PROBLEMI DI RICERCA Moltissimi problemi rientrano nella categoria dei problemi di ricerca che, in generale, si possono formulare come segue: Dato un insieme A ed una proprietà P , determinare gli elementi x ∈ A che soddisfano alla proprietà P , ossia gli elementi x ∈ A per i quali P (x). Esempio 11. Con la formulazione generale data sopra, i seguenti due problemi rientrano nella categoria dei problemi di ricerca: P1 : Determinare le radici di un’equazione ax2 + bx + c = 0. P2 : Determinare la scomposizione in fattori primi di un dato numero naturale n. Nella ricerca del risultato di un problema si possono attivare diversi gradi di affinamento della ricerca all’interno di un dato spazio di ricerca: • decidere se il risultato esiste • determinare un risultato • determinare tutti i risultati • determinare il risultato migliore • determinare un buon risultato Qui i temini migliore e buon vanno adeguatamente precisati, a seconda del contesto nel quale si colloca il particolare problema di ricerca che si considera. Esempio 12. Consideriamo il seguente problema: Determinare un numero positivo x in modo che si abbia x2 = 2. √ Il risultato è x = 2 se si ammette che il numero x possa essere un numero reale, mentre il problema non ammette soluzione se si impone che il numero x debba essere razionale. In tali casi nella definizione del problema deve essere precisato lo spazio di ricerca, ossia l’insieme in cui ricercare gli eventuali possibili risultati del problema. Lo spazio di ricerca è un parametro fondamentale per caratterizzare il problema. Nella maggior parte dei casi lo spazio di ricerca risulta definito implicitamente dal contesto in cui è formulato il problema. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 28 CAPITOLO 2. TIPOLOGIE DEI PROBLEMI 2.9 I PROBLEMI DI DECISIONE Una vasta classe di problemi rientra nell’insieme dei problemi di decisione che hanno il caratteristico incipit Decidere se . . . ed hanno come risultato vero o falso. Questi problemi spaziano dall’ambito della logica, alla matematica ed includono molte questioni tipiche dell’informatica. Esempio 13. I seguenti esempi sono tratti dalla matematica: P1 : Decidere se un dato numero naturale n è primo. P2 : Decidere se esistono infinite coppie di numeri primi gemelli, cioè numeri primi che differiscono di 2; ad esempio 11 e 13 costituiscono una coppia di numeri primi gemelli. Si ipotizza che esistano infinite coppie siffatte, ma ancora non è stata fornita alcuna dimostrazione definitiva. P3 : Decidere se esistono numeri naturali x, y, z, n, con n > 2, tali che xn +y n = z n È questo il famoso Ultimo teorema di Fermat che, dopo molti sforzi, è stato risolto solamente nel 1994, ad opera di Andrew Wiles il quale ha dimostrato che non esistono numeri soddisfacenti al teorema. P4 : Decidere se una data equazione algebrica polinomiale a coefficienti interi ammette soluzioni intere (si tratta del Decimo problema di Hilbert). 2.10 ESERCIZI 1. Spiegare se i problemi risolvibili? possono essere classificati con il termine irrisolvibili?. 2. Fissato un dato problema P, si considerino i seguenti due problemi: P1 : Il problema P ammette soluzione ? P2 : Risolvere il problema P . Classificare i problemi P1 e P2 in base alla loro forma. Stabilire, in funzione della risolvibilità di P , la risolvibilità dei problemi P1 e P2 . 3. Descrivere una classe di problemi che includa le seguenti tre classi di problemi: (a) Numerare per n da p a q. (b) Determinare tutti i numeri compresi fra due dati valori. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 2.10. ESERCIZI 29 (c) Determinare tutti i multipli di un dato valore, compresi fra due numeri assegnati. 4. Si considerino le seguenti due istanze di problemi: P1 : Valutare log2 9871 P2 : Valutare log8 24364 Definire una classe C di problemi alla quale appartengano le due istanze P1 e P2 riportate sopra. 5. Individuare i dati ed i risultati della seguente classe di problemi: Convertire un numero naturale fra due generiche basi. Si faccia attenzione al significato di numero e rappresentazione di un numero. 6. Individuare i dati ed i risultati della seguente classe di problemi: Determinare la somma dei reciproci dei primi n numeri naturali. 7. Individuare i dati ed i risultati delle seguenti classi di problemi nel contesto della geometria del piano cartesiano: P1 : Determinare la circonferenza circoscritta ad un triangolo. P2 : Determinare la retta passante per due punti. P3 : Determinare il punto di intersezione fra due rette. 8. Determinare per quali valori di n il seguente problema ammette un unico risultato: Fissati sul piano un insieme di n punti distinti A1 , . . . , An , disegnare un poligono di n lati non intrecciati, aventi A1 , . . . , An come vertici. 9. Descrivere un problema che sia modellizzabile mediante un’equazione diofantea. 10. Definire delle ipotesi in modo che il seguente problema risulti ben formulato: Ordinare una sequenza di triangoli. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 30 CAPITOLO 2. TIPOLOGIE DEI PROBLEMI 11. Spiegare perché, senza assumere tacite ipotesi, il seguente problema è mal formulato: Risolvere l’equazione di secondo grado ax2 + bx + c = 0. 12. Spiegare perché il seguente problema è mal formulato: Determinare la somma delle cifre di un numero naturale n. Spiegare perché, ad essere estremamente pignoli, il seguente problema è ancora mal formulato: Determinare la somma delle cifre di un numero naturale n considerato in base 10. 13. Spiegare perché il seguente problema è mal formulato: Determinare i più piccoli dieci numeri naturali che si leggono indifferentemente da sinistra a destra e da destra a sinistra. Riformulare il problema in modo da renderlo ben formulato. 14. Spiegare perchè il seguente problema è mal formulato: Dato un triangolo acutangolo avente i lati di misure a, b, c, determinare il più piccolo rettangolo che lo ricopre. Riformulare il problema in modo da renderlo ben formulato. 15. Stabilire se il seguente problema è ben formulato: Determinare il numero delle cifre di un numero naturale. Nel caso sia mal formulato, riformularlo in modo corretto. 16. Stabilire se il seguente problema è ben formulato: Determinare l’area ed il perimetro di un rettangolo di cui sono note le misure di un lato e della diagonale. Nel caso sia mal formulato, riformularlo in modo corretto. 17. Stabilire se il seguente problema è ben formulato: L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 2.10. ESERCIZI 31 Date le misure dei lati di un quadrilatero, decidere se il quadrilatero è convesso. 18. Stabilire se il seguente problema è ben formulato: Date le misure dei 6 segmenti congiungenti in tutti i modi possibili i vertici di un quadrilatero, determinare il perimetro del quadrilatero. 19. Stabilire se il seguente problema è ben formulato: Fissati sul piano 4 punti distinti e non allineati, disegnare il quadrilatero non intrecciato avente per vertici i 4 prefissati punti. 20. Determinare per quali valori di n il seguente problema è ben formulato: Determinare l’area di un poligono di n lati conoscendone la misura dei lati, in ordine in base alla consecutività dei lati. 21. È assegnato un insieme A = {P1 , P2 , ..., Pn } di n punti del piano. Stabilire se i seguenti due problemi sono ben formulati; in caso affermativo dire in cosa consistono i dati, i risultati ed il criterio di verifica. (a) Determinare l’area del poligono di vertici A. (b) Determinare l’involucro convesso dell’insieme dei punti A, ossia il più piccolo poligono convesso contenente i punti dati. 22. Generalizzare la seguente istanza di problema: Risolvere, nell’insieme dei numeri naturali, l’equazione 2x−8 = 0. Suggerimento: si possono ottenere delle generalizzazioni sia ampliando l’insieme dove si cercano le soluzioni, sia generalizzando la forma dell’equazione. 23. Generalizzare la seguente istanza di problema: Decidere se ci sono domeniche comprese nel periodo dal 30 ottobre 2013 al 2 novembre 2013. Classificare, in base alla forma ed alla risolvibilità, la classe di problemi ottenuta nella precedente generalizzazione. 24. Generalizzare le seguenti istanze di problemi: L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 32 CAPITOLO 2. TIPOLOGIE DEI PROBLEMI (a) Determinare l’area di un quadrato di lato 2 cm. (b) Trovare il lato del triangolo equilatero inscritto in un cerchio di raggio 8 cm. (c) Ordinare i tre numeri 5, 4, 6. (d) Nel piano cartesiano, determinare la distanza fra i due punti P = (1, 2), Q = (3, 4). (e) Disegnare un quadrato rosso di lato 1 cm. (f) Determinare la distanza del punto di coordinate (1, 2) dall’origine degli assi cartesiani. Per ciascuna classe di problemi che si è individuata, si precisino quali sono i dati e quali i risultati. 25. Si consideri il seguente problema: Dire se il punto del piano cartesiano avente per coordinate le radici dell’equazione 6x2 − 5x + 1 = 0 è vicino all’origine degli assi. (a) Motivando le affermazioni, dire se il problema proposto è ben formulato. (b) Nel caso il problema sia mal formulato, riformularlo adeguatamente in modo che risulti ben formulato. (c) Con riferimento al problema ben formulato, specificare in cosa consistono i dati ed i risultati. (d) Classificare il problema in base alla sua forma (computazionale, decisionale, trasformazionale). (e) Generalizzare il problema, proponendo più generalizzazioni successive. 26. I seguenti tre problemi sono apparentemente simili ma, ad una attenta analisi, si capisce che sono di differenti complessità: P1 : Determinare un numero primo di k cifre decimali. P2 : Decidere se un dato numero naturale n è primo. P3 : Scomporre in fattori primi un dato numero naturale n. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 2.10. ESERCIZI 33 Assumendo in modo intuitivo il concetto di complessità di un problema, intesa come una misura del tempo di esecuzione della miglior soluzione del problema, discutere questi problemi in riferimento alla loro complessità, ordinandoli dal più semplice al più difficile. 27. In questo capitolo i problemi di ordinamento e di ricerca sono stati presentati separatamente, senza evidenziare particolari collegamenti; le due classi di problemi sono però fortemente connesse. Discutere ed evidenziare, avvalendosi anche di opportuni esempi, di alcuni nessi logici ed operativi fra queste due classi di problemi. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 34 CAPITOLO 2. TIPOLOGIE DEI PROBLEMI L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 Capitolo 3 Risolvere Risolvere problemi è il compito specifico dell’intelligenza e l’intelligenza è la dote specifica dell’uomo. La capacità di aggirare un ostacolo, di prendere una via indiretta quando non si presenta nessuna via diretta, innalza l’animale intelligente al di sopra di quello ottuso, eleva l’uomo enormemente al di sopra degli animali più intelligenti e gli uomini di talento al di sopra dei loro simili. G. Polya, La scoperta matematica Non domandarci la formula che il mondo possa aprirti sí qualche storta sillaba e secca come un ramo. E. Montale, dagli Ossi di seppia In questo capitolo vengono presentate alcune metodologie per risolvere i problemi mediante degli algoritmi. Vengono forniti dei suggerimenti alla seguente domanda: Come si sviluppa una soluzione algoritmica di un dato problema? Verranno analizzate delle situazioni problemiche per la soluzione delle quali non è sufficiente una semplice applicazione di varie conoscenze e regole, ma si richiede di elaborare delle strategie risolutive in base alle conoscenze acquisite, all’esperienza accumulata ed ad una buona dose d’intuito e fantasia. Nel seguito verrà utilizzato il termine risolvere per indicare l’attività della ricerca di una soluzione. 35 36 3.1 CAPITOLO 3. RISOLVERE LA METODOLOGIA TOP-DOWN La maggior parte dei problemi che si incontrano presenta notevoli difficoltà ed una prima analisi non consente di individuare subito un percorso risolutivo. Una valida strategia risolutiva che si applica alla soluzione di generici problemi è nota con il nome di metodologia top-down o dei raffinamenti successivi; consiste nella risoluzione dei problemi affrontandoli, dall’alto verso il basso, scomponendoli in sottoproblemi più semplici che vengono via-via risolti per approfondimenti successivi. Tale approccio risulta particolarmente indicato quando i problemi non sono di immediata soluzione. La metodologia top-down per la soluzione di un problema (classe di problemi) P può essere descritta come segue. Indicheremo con α la struttura di una scomposizione in sottoproblemi, ossia un algoritmo in cui compaiono delle istruzioni non direttamente comprensibili dall’esecutore. Queste istruzioni costituiranno i sottoproblemi da raffinare e dettagliare in fasi successive. Con Q(α) = {P1 , ..., Pn } indicheremo l’insieme dei sottoproblemi individuati dall’algoritmo α e non ancora espressi nel linguaggio dell’esecutore che si considera. Con S(Pi ) indicheremo la soluzione (algoritmo) di un generico problema Pi . Adottando queste notazioni, la soluzione di un problema mediante la metodologia top-down può essere espressa come una sorta di meta-algoritmo rivolto ad un solutore e può essere formulata come descritto nell’algoritmo 1. Algoritmo 1 - Meta-algoritmo di risoluzione di problemi Input: problema P da risolvere Output: procedimento per la soluzione di P 1: if la soluzione del problema P è direttamente esprimibile then 2: esprimi la soluzione S del problema P 3: else 4: scomponi il problema P secondo una struttura α 5: risolvi i sottoproblemi Q(α) mediante la metodologia top-down 6: ricomponi secondo la struttura α le soluzioni S(Pi ) 7: end if Nello sviluppo degli algoritmi mediante la metodologia top-down dobbiamo porci nella convinzione di poter disporre di un esecutore sufficientemente potente ad eseguire delle azioni complesse (e sperare di poter esprimere tali azioni in termini delle azioni elementari effettivamente eseguibili da un esecutore reale). L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 3.1. LA METODOLOGIA TOP-DOWN 37 I vantaggi più evidenti indotti dall’applicazione della metodologia topdown per la soluzione dei problemi possono essere riassunti nei seguenti punti: • Un problema viene scomposto in sottoproblemi più piccoli e quindi più facilmente risolvibili • In ogni istante si ha una visione complessiva dell’intero problema e della struttura dell’algoritmo risolutivo • Aumenta la leggibilità dell’algoritmo • La soluzione di un problema può essere affidata a più persone diverse • La soluzione può essere ripresa in tempi successivi e sviluppata a blocchi • Se nella scomposizione vengono evidenziate delle parti di problema simili fra loro, esse possono essere risolte da uno stesso algoritmo • Le varie fasi di sviluppo dell’algoritmo fungono da documentazione per le successive fasi di maggior dettaglio • Viene semplificata la localizzazione e la correzione di eventuali errori Osservazione. Sopra si è preferito usare il termine metodologia anziché il termine più deterministico metodo in quanto quest’ultimo dà l’idea che si possa cercare la soluzione a colpo sicuro. La ricerca di una soluzione richiede, invece, dei tentativi, delle prove di avvicinamento, dei ritorni sui propri passi e pertanto il termine metodologia meglio si adatta ad esprimere questa ricerca della soluzione che si realizza circuendo il problema fino a vincerlo. Usando un linguaggio figurato, si tratta di catturare una preda che tenta di fuggire, piuttosto che un tiro al bersaglio. In altri termini potremmo esprimerci affermando che non esiste un algoritmo (generale) per sviluppare gli algoritmi ma un algoritmo viene esplicitato seguendo una sorta di fiuto felino che porta alla preda. E neanche il fiuto felino può essere sufficiente a raggiungere la meta ma deve essere unito ad una buona dose d’inventiva, guidato da intelligenza e sorretto da costanza. Il problema di base consiste nel riuscire ad individuare una buona scomposizione. A questo proposito risultano appropriate le seguenti parole di Hofstadter. Non vi è alcuna garanzia che il metodo della riduzione a sottoproblemi funzionerà. Vi sono molte situazioni nelle quali fallisce. Si consideri, per esempio, questo problema. Sei un cane e un amico uomo ti ha appena gettato il tuo osso preferito in un altro giardino al di là di una L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 38 CAPITOLO 3. RISOLVERE rete metallica. Tu vedi l’osso attraverso la rete: eccolo là sull’erba, che sembra dire “mangiami, mangiami!”. Lungo la rete, a circa venti metri dall’osso, c’è un cancello aperto. Che cosa fai? Alcuni cani corrono semplicemente fino alla rete e restano lí ad abbaiare. Altri si lanciano verso il cancello aperto e poi tornano indietro verso l’osso ambito. Si può dire che entrambi i cani hanno applicato la tecnica della riduzione a sottoproblemi. Essi, però, rappresentano il problema nella loro mente in modi diversi, e in ciò sta tutta la differenza. Il cane che abbaia vede come sottoproblemi 1. correre alla rete, 2. attraversarla, 3. correre all’osso; ma quel secondo sottoproblema è un osso duro: da cui l’abbaiare. L’altro cane vede come sottoproblemi 1. raggiungere il cancello; 2. attraversare il cancello; 3. correre verso l’osso. Si noti come tutto dipende dal modo in cui si rappresenta lo spazio dei problemi: cioè, da cosa si percepisce come riduzione del problema (movimento in avanti verso l’obiettivo globale) e che cosa si percepisce come ingrandimento del problema (movimento all’indietro che allontana dall’obiettivo). Alcuni cani cercano di correre direttamente verso l’osso e, quando incontrano la rete, qualcosa scatta nel loro cervello; cambiano subito direzione e corrono verso il cancello. Questi cani si rendono conto che ciò che a prima vista sembrava dover aumentare la distanza tra la situazione iniziale e quella desiderata (cioè, allontanarsi dall’osso per correre verso il cancello aperto) in realtà l’avrebbe diminuita. Inizialmente confondono la distanza fisica con la distanza nel problema. Ogni movimento che allontani dall’osso sembra per definizione una Cosa Cattiva. Ma poi, in qualche modo, si rendono conto che possono spostare la percezione di ciò che li porterà più vicini all’osso. In uno spazio astratto opportunamente scelto, il muoversi verso il cancello è una traiettoria che porta il cane più vicino all’osso! In ogni istante, il cane si sta avvicinando, nel nuovo senso, all’osso. Quindi l’utilità della riduzione a sottoproblemi dipende da come ci si rappresenta mentalmente il problema stesso. Ciò che in uno spazio sembra un indietreggiamento può in un altro spazio apparire un rivoluzionario passo in avanti. [Tratto da: D. R. Hofstadter: Gödel, Escher, Bach] L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 3.2. LA METODOLOGIA BOTTOM-UP 3.2 39 LA METODOLOGIA BOTTOM-UP Diversamente da quanto avviene per la metodologia top-down, l’approccio ad un problema mediante la metodologia bottom up consiste nell’iniziare dal livello dei problemi più elementari risalendo verso il livello del problema da risolvere. Si cerca di individuare e risolvere subito dei problemi che serviranno per soluzione del problema generale la quale viene ricavata ricomponendo le soluzioni dei problemi elementari già risolti. La metodologia bottom-up prevede un approccio intellettualmente diverso dalla metodologia top-down in quanto si risolvono dapprima i problemi elementari preparando i blocchi risolutivi che, assemblati, forniranno la soluzione del problema complessivo. Ma anche qui si vede che la metodologia top-down interviene (almeno in modo latente) in quanto ci si deve preventivamente porre la domanda: Quali sono i problemi elementari da risolvere? La metodologia top-down offre il vantaggio di delineare subito la scomposizione del problema; ciò può comportare lo svantaggio che delle scelte errate ad un livello elevato compromettano tutte le fasi successive dei livelli più elementari. La metodologia bottom-up, invece, incentiva il riutilizzo di soluzioni di (sotto)problemi già affrontati e risolti in precedenza. Le metodologie top-down e bottom-up non devono essere considerate alternative: l’atteggiamento più proficuo consiste nel considerarle come degli strumenti che si integrano. Ad esempio, quando si evidenzia un sottoproblema si deve generalizzarlo opportunamente affinché possa risultare utile per situazioni future. È questo un atteggiamento bottom-up. Esempio 14. Il seguente problema illustra in modo schematico un confronto fra la metodologia top-down e la metodologia bottom-up nella soluzione di un problema; nel caso specifico si tratta evidenziare una suddivisione in quadrati di una data figura piana. Nel primo caso (soluzione top-down) si può pensare di scomporre la figura in quadrati usando delle forbici, nel secondo (soluzione bottom-up) si può pensare di ricostruire la figura incollando assieme dei tasselli quadrati. Dalle due soluzioni riportate nella figura 3.1 si può notare, pur dalla banalità dell’esempio proposto, che le metodologie top-down e bottom-up possono portare a dei diversi procedimenti risolutivi. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 40 CAPITOLO 3. RISOLVERE A AAU + Q Q s Q @ @ R @ @ @ R @ @ R @ @ R @ Scomposizione top-down Composizione bottom-up Figura 3.1: Illustrazione della scomposizione top-down e della composizione bottom-up. 3.3 EFFICACIA DELLE SCOMPOSIZIONI L’aspetto più caratterizzante della metodologia top-down consiste nel trovare delle buone ed utili scomposizioni dei problemi. Le maggiori difficoltà per la soluzione di un problema risiedono, infatti, non tanto nell’esplicitazione della soluzione dei singoli sottoproblemi elementari, quanto nella capacità di trovare delle adeguate scomposizioni in sottoproblemi. La fase di scomposizione deve tendere a ridurre (in un qualche senso) la complessità del problema originale. A questo proposito possono risultare significativi i problemi proposti nei seguenti esempi. Esempio 15. Trovare l’area della figura delimitata dalla circonferenza e dal quadrato interno nota la lunghezza del lato del quadrato esterno: '$ @ @ @ @ &% Una prima scomposizione potrebbe essere: area = 4 ⋅ segc L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 41 3.3. EFFICACIA DELLE SCOMPOSIZIONI dove con segc si denota l’area di uno dei 4 segmenti circolari individuati dal cerchio e dal quadrato più interno che compaiono nella figura precedente. Evidentemente questa scomposizione è poco utile poichè il sottoproblema di trovare l’area di un segmento circolare è della stessa difficoltà del problema originale. Adottando questa soluzione saremmo come i cani che puntano dritti all’osso ... imbattendosi poi nella rete. Una scomposizione più efficace è la seguente: '$ area = @ @ − @ &% @ in cui si evidenziano i seguenti due sottoproblemi: P1 : Trovare l’area del cerchio di dato diametro P2 : Trovare l’area del quadrato di data diagonale Entrambi questi problemi sono di immediata soluzione. Il sottoproblema P2 merita un’ulteriore osservazione. Senza scomodare il teorema di Pitagora, l’area di un quadrato di data diagonale può essere determinata seguendo il percorso risolutivo suggerito dalle seguenti uguaglianze geometrico-algebriche fondate su delle proprietà di composizione e scomposizione che valgono per l’operazione di valutazione dell’area di figure piane. @ @ @ @ @ @ = = 4 @ = 2 @ @ @ = 1 2 In definitiva si trova che l’area cercata è uguale a '$ area = − 1 2 &% A questo punto i dettagli dei calcoli risultano banali. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 42 CAPITOLO 3. RISOLVERE Esempio 16. Come altro esempio consideriamo il problema di determinare l’area della seguente figura composta da quattro petali ottenuti dall’intersezione di quattro semicerchi, nota la lunghezza del diametro della circonferenza: $ ' '$ &% % & Senza ricorrere ad alcuna formula di aree, similmente all’esempio precedente, notando che quattro semicerchi che si sovrappongono dannno luogo, come intersezione, alla figura in questione, dall’equazione # 4 # = + "! # ! " si ricava # " #! = 2 ! " '$ − &% e quindi, numericamente, l’area cercata è uguale a 2πr2 − 4r2 = 2r2 (π − 2) Osservazione. In alternativa a quanto è stato fatto nei due esempi sopra proposti, si sarebbe potuto giungere al risultato numerico finale impostando già all’inizio i calcoli numerici; è evidente che un tale approccio sarebbe stato più difficoltoso, richiedendo già all’inizio dei concetti (area) e conoscenze (pi greco) non strettamente necessarie per l’impostazione del procedimento risolutivo; anche in questo caso, comunque, i vari calcoli numerici sarebbero stati guidati da un’idea risolutiva di fondo, analoga a quella che è stata presentata sopra. Adottando un approccio bottom-up si avrebbe potuto ottenere il risultato del secondo esempio osservando che l’area di questa figura è il doppio di quella dell’esempio precedente, e da ciò si avrebbee conseguito immediatamente il risultato. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 43 3.4. TRASFORMAZIONE DEI PROBLEMI Osservazione. Dagli esempi sopra proposti e dalle considerazioni appena riportate scaturisce la conclusione che, nello sviluppo della soluzione di un dato problema, è preferibile lavorare il più a lungo possibile con un linguaggio e con un formalismo adeguato al livello del problema trattato; solo in un secondo momento il procedimento risolutivo va espresso dettagliatamente (ad esempio in un linguaggio di programmazione), in una forma pronta da essere sottoposta ad un esecutore. 3.4 TRASFORMAZIONE DEI PROBLEMI Non sempre l’ambito nel quale sorgono e vengono formulati i problemi è il contesto più idoneo nel quale ricercarne e descriverne la soluzione. Risulta spesso comodo eseguire una trasformazione in un altro ambito nel quale risulta più facile risolvere il problema. Si parla di passaggio dallo spazio dei problemi allo spazio delle soluzioni. Esempio 17. Consideriamo la seguente situazione: È data una scacchiera 3 × 3 sulla quale sono disposti tre cavalli bianchi e tre cavalli neri, posti ai lati opposti della scacchiera. Il problema consiste nello scambiare fra loro i cavalli bianchi con quelli neri, nel minor numero possibile di mosse, alternando le mosse del bianco e del nero e rispettando le modalità di movimento dei cavalli secondo le regole del gioco degli scacchi. Operando direttamente sulla scacchiera ci si convince che il problema non è di immediata soluzione. Il problema si sbroglia rappresentando la scacchiera tramite un grafo; ogni nodo del grafo rappresenta una casella della scacchiera; due nodi del grafo vengono congiunti se si può passare da uno all’altro mediante una mossa del cavallo. Convenendo di etichettare ciascuna casella con un numero naturale da 1 a 9, si ottiene la rappresentazione e successiva trasformazione, come indicato nella figura che segue. 1 2 3 4 5A H 6 nHAHn n A H 7 A AH HH A HA A 9 8 A H H A N N N 1 n 6 7 N 2 8 3 4 9 N n n N L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 44 CAPITOLO 3. RISOLVERE 3.5 ESERCIZI 1. Illustrare, mediante degli esempi, in cosa consistono le metodologia topdown e bottom-up per la soluzione dei problemi, evidenziando i vantaggi che esse offrono. 2. Si consideri il caso di un bambino che gioca con i mattoncini Lego per costruire una casetta. Si spieghi, in questo contesto, in cosa consistono le metodologie top-down e bottom-up. 3. Molti sono stati i filosofi e gli informatici che hanno suggerito delle indicazioni per la soluzione dei problemi. A seguire sono riportati alcuni stralci. Dividete ciascun problema che state esaminando in tante parti quante potete e quante ve ne occorrono per risolverlo più facilmente. [Cartesio, Discorso sul metodo] Questa regola di Cartesio serve poco finché l’arte di dividere [...] rimane inspiegata [...]. Dividendo il suo sottoproblema in parti non convenienti, il risolutore di problemi inesperto può aumentare la sua difficoltà. [Leibnitz, Scritti filosofici] Le tecniche di costruzione dei programmi si basano su un unico principio: scomporre l’azione necessaria per risolvere un problema in azioni più semplici, e suddividere (di conseguenza) il problema in sottoproblemi. [N.Wirth, Principi di programmazione strutturata] Molte sono le strade per risolvere tantissimi problemi e molte sono anche le soluzioni degli stessi. Questa situazione non rende più facile il compito di risolvere i problemi: messi dinanzi a una molteplicità di linee di attacco possibili, è normalmente difficile riuscire a capire rapidamente quale percorso è probabilmente infruttuoso e quale può essere produttivo. [R.G.Dromey, How to solve it by computer] Discutere le affermazioni sopra riportate, alla luce di quanto è stato esposto in questo capitolo. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 45 3.5. ESERCIZI 4. Dimostrare l’equivalenza delle seguenti figure costituite da cerchi. Determinarne l’area in funzione della lunghezza l del lato del quadrato che le racchiude. '$ &% 5. Determinare l’area della parte più interna delle seguenti figure (sono in ordine di difficoltà crescente). Si assuma l’ipotesi che l’esecutore sia in grado di valutare l’area c(r) di un cerchio di dato raggio r e l’area p(n, r) di un n-poligono regolare di dato raggio r del cerchio circoscritto. Si richiede di esprimere l’area delle figure come combinazione lineare a coefficienti razionali di aree di cerchi e di poligoni regolari, ossia mediante un’espressione della forma α c(r) + β p(n, r) con α, β ∈ Q. $ $ ' ' % & ' $ & & % % L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 46 CAPITOLO 3. RISOLVERE L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 Capitolo 4 Algoritmi Per troppo tempo, la gente ha tentato di formulare gli algoritmi in un linguaggio di programmazione, piuttosto che decomporre attentamente il problema in problemi più semplici e verificare le loro relazioni prima di procedere ad una specificazion più dettagliata. [...] L’esperienza ha dimostrato che [il secondo approccio] permette di sviluppare algoritmi con molti meno errori che non il vecchio metodo linea-per-linea. S.Alagic, M.A.Arbib, The design of well-structured and correct programs Nelle pagine seguenti sarà definita e precisata la nozione di procedimento risolutivo per la soluzione di un problema, in modo che sia adattabile ai calcolatori. Sarà presentato il concetto di algoritmo che rappresenta un’evoluzione in senso dinamico del concetto di formula risolutiva della matematica. I primi algoritmi furono ideati per risolvere problemi di tipo numerico: moltiplicazione e divisione fra due numeri, massimo comune divisore fra due numeri naturali. Oggigiorno gli algoritmi vengono applicati per risolvere problemi di varia natura ed operano sulle più svariate tipologie di entità. 47 48 4.1 CAPITOLO 4. ALGORITMI FORMULE RISOLUTIVE Consideriamo il seguente problema: Determinare l’area di un trapezio note le misure B e b delle basi e h dell’altezza. Per questo problema il procedimento risolutivo è immediato e può essere espresso per mezzo della semplice formula risolutiva area = (B + b)h/2 Anche qui, comunque, la formula risolutiva maschera un procedimento risolutivo, a più basso livello, che può essere esplicitato, a parole, come descritto nell’algoritmo 2. Algoritmo 2 - Calcolo dell’area di un trapezio 1: considera i valori delle misure delle basi e dell’altezza 2: somma le misure delle due basi 3: moltiplica il risultato per l’altezza 4: dividi il risultato per 2 5: il risultato ottenuto rappresenta l’area del trapezio È noto però che i procedimenti risolutivi di molti problemi, anche limitandosi ai problemi di tipo computazionale, non possono essere espressi mediante un’unica formula risolutiva né mediante un’elencazione sequenziale di passi. Servono, in generale, dei costrutti linguistici più articolati. In altre parole, non esiste più una corrispondenza biunivoca fra le frasi della descrizione delle istruzioni e l’esecuzione delle istruzioni. Per convincersi di quanto appena affermato consideriamo il seguente altro problema: Determinare il massimo comune divisore di due numeri naturali m ed n, ossia il più grande numero naturale che divide sia m che n. In questo esempio il risultato non è direttamente ricavabile mediante una singola formula risolutiva come nell’esempio precedente, ma necessita di un procedimento risolutivo più articolato detto algoritmo. Questo problema sarà ripreso e risolto in più modi nel seguito. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 4.2. ALGORITMI 4.2 49 ALGORITMI In modo informale, un algoritmo è la descrizione della soluzione di una classe di problemi, ossia la descrizione delle azioni, da eseguirsi da parte di un dato esecutore, mediante le quali si risolve una classe di problemi; inoltre, un algoritmo deve soddisfare alle seguenti condizioni: definitezza : ogni azione deve essere deterministica ed univocamente interpretabile dall’esecutore. eseguibilità : ogni azione deve essere effettivamente eseguibile da parte dell’esecutore. finitezza : le istruzioni devono essere in numero finito, ciascuna azione deve essere eseguita in un tempo finito ed ogni azione deve essere eseguita un numero finito di volte. generalità : la descrizione del procedimento risolutivo deve applicarsi a tutte le istanze della classe dei problemi. Queste condizioni differenziano quelli che genericamente sono dei procedimenti risolutivi da quei procedimenti che possono essere classificati come algoritmi. Ad esempio, una ricetta di cucina può essere classificata come un procedimento risolutivo ma non come un algoritmo. Comunque, quando nel seguito si utilizzerà il termine procedimento risolutivo, tale termine è da intendersi con significato di algoritmo, secondo la definizione data sopra. Questa definizione di algoritmo è una fra le tante possibili. Tutte le altre che si possono trovare sui testi di informatica, anche se apparentemente diverse ed espresse in modo più formale (ad esempio, macchina di Turing, sistema canonico di Post, lambda-calcolo di Church) sono equivalenti a questa. Nonostante nella definizione di algoritmo si sia posta la condizione che impone che la descrizione delle istruzioni sia finita, non si esclude il caso che le istruzioni possano essere eseguite un numero infinito di volte. Osserviamo ancora che, con le condizioni di generalità e finitezza, si viene ad imporre che un algoritmo termini per ogni istanziazione dei dati di ingresso. In molti casi la condizione di finitezza risulta troppo forte e, per poter trattare una classe più ampia di procedimenti risolutivi, risulta conveniente alleggerire la condizione di finitezza relativamente al numero di volte che viene eseguita ogni singola istruzione, ammettendo che delle istruzioni possano essere eseguite per un numero infinito di volte. In tali condizioni un procedimento risolutivo è detto metodo computazionale. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 50 CAPITOLO 4. ALGORITMI ' $ procedimenti risolutivi ' $ metodi computazionali ' $ algoritmi & & & % % % Figura 4.1: Algoritmi, metodi computazionali e procedimenti risolutivi. La nozione di algoritmo è strettamente connessa con la nozione di esecutore: basti considerare i termini univocamente interpretabile e realmente eseguibile. È evidente quindi che un algoritmo presuppone che esista un esecutore che lo interpreti ed esegua le istruzioni specificate. Più avanti, trattando delle macchine di Turing, si vedrà che la nozione di algoritmo e di esecutore coincidono. Anche se la finalità di un algoritmo è quella di essere eseguito da un calcolatore e necessita pertanto di essere tradotto in uno specifico linguaggio di programmazione, un algoritmo risulta indipendente dal linguaggio di programmazione nel quale verrà tradotto. 4.3 ALGORITMI COME FUNZIONI Risolvere un problema significa sostanzialmente definire una funzione che opera sui dati iniziali di input e produce dei risultati finali di output. Ad esempio, se il problema è Trovare l’area di un trapezio date le misure B e b delle basi e la misura h dell’altezza. la soluzione può essere espressa mediante l’espressione funzionale area = f (B, b, h) = (B + b) h/2 Anche quando l’algoritmo non sia esprimibile mediante una singola espressione funzionale, esso può sempre comunque essere considerato come una funzione che, operando sui dati di input, costruisce i risultati di output (in questo caso è solo più laboriosa la descrizione e la valutazione della funzione). Adottando L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 51 4.3. ALGORITMI COME FUNZIONI questa impostazione, ed usando la tradizionale convenzione di denotare con il termine Input l’insieme dei dati e con il termine Output l’insieme dei risultati, descriveremo un algoritmo mediante uno schema a blocchi come il seguente: algoritmo Input - Output oppure Input - algoritmo - Output Nel primo caso si vuole mettere in evidenza i dati ed i risultati, mentre nel secondo viene sottolineato il ruolo dell’algoritmo cha stabilisce l’associazione fra dati e risultati. In alternativa, un algoritmo può essere assimilato ad una funzione che opera sui dati iniziali x di input e produce dei risultati finali y di output: a ∶ Input → Output x ↦ y L’interpretazione di un algoritmo come funzione porta a delle naturali definizioni e concetti. In particolare il codominio dell’algoritmo è detto spazio di ricerca (dei risultati). Con queste premesse risulta significativa la seguente DEFINIZIONE 1. Due algoritmi A1 ed A2 si dicono funzionalmente equivalenti se hanno lo stesso dominio e calcolano lo stesso risultato y per ogni possibile istanziazione dei dati di input x, ossia A1 (x) = A2 (x) = y per ogni x ∈ Input Due algoritmi si dicono equivalenti se fanno compiere all’esecutore la stessa sequenza di azioni. È evidente che l’equivalenza implica l’equivalenza funzionale. Data la definizione di equivalenza fra algoritmi, acquista importanza pratica il seguente problema: Decidere se due dati algoritmi sono equivalenti. La soluzione di questo problema dovrebbe essere un algoritmo che, dati due algoritmi come suoi dati di input, decida se questi algoritmi sono equivalenti. È stato dimostrato che un tale algoritmo di decisione non esiste. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 52 CAPITOLO 4. ALGORITMI 4.4 SCHEMI FONDAMENTALI DI ALGORITMI Gli algoritmi possono essere descritti mediante la combinazione di alcuni schemi di base. Fra questi noi utilizzeremo nel seguito le forme previste dalla programmazione strutturata, descritte nel seguito. Sotto a ciascuna forma è riportato il significato in termini discorsivi. Algoritmo 3 - Struttura sequenziale 1: azione A1 2: azione A2 3: . . . 4: azione An Esegui in sequenza le azioni A1 , A2 , . . . , An . Algoritmo 4 - Struttura condizionale 1: if condizione C then 2: azione A 3: else 4: azione B 5: end if Se la condizione C è vera esegui l’azione A altrimenti esegui l’azione B. Algoritmo 5 - Struttura ciclica 1: while condizione C do 2: azione A 3: end while Finché la condizione C è vera continua ad eseguire l’azione A. Gli schemi di algoritmi sopra descritti vengono considerati come fondamentali in quanto, combinandoli fra loro, si riesce ad esprimere qualsiasi algoritmo. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 4.5. ESEMPI DI ALGORITMI 4.5 53 ESEMPI DI ALGORITMI A seguire sono riportati alcuni esempi di algoritmi che illustrano gli schemi fondamentali sopra descritti. Esempio 18. Consideriamo il seguente problema: Su un gocciolatoio sono disposti dei piatti piani e delle fondine in modo da occupare tutte le posizioni. Si vuole sistemare ordinatamente i piatti in modo da avere tutti i piatti piani sulla sinistra e le fondine sulla destra. Si suppone di poter eseguire uno scambio fra due piatti, prendendo un piatto alla volta in ciascuna mano e senza la possibilità di appoggiare i piatti fuori dal gocciolatoio. Questo problema può essere risolto come descritto nell’algoritmo 6. L’idea espressa in questo algoritmo viene sfruttata nell’algoritmo di ordinamento di ordinamento quicksort che sarà descritto più avanti. Algoritmo 6 - Algoritmo di ordinamento dei piatti Input: fila dei piatti da ordinare Output: fila di piatti ordinata 1: poni le mani alle estremità della fila dei piatti 2: while le mani non si sono incontrate do 3: while la mano sinistra è su un piatto piano do 4: avanza la mano verso destra 5: end while 6: while la mano destra è su un piatto fondo do 7: avanza la mano verso sinistra 8: end while 9: if i piatti che hai in mano sono fuori ordine then 10: scambiali 11: end if 12: sposta la mano sinistra di un posto a destra 13: sposta la mano destra di un posto a sinistra 14: end while 15: la fila di piatti è ordinata L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 54 CAPITOLO 4. ALGORITMI Esempio 19. Consideriamo il seguente problema: Un sacco contiene molte palline di al più due pesi diversi anche se all’apparenza uguali. Il problema consiste nel determinare quante sono le palline di ciascuno dei due pesi, utilizzando una bilancia a due piatti. Descrivere un algoritmo per risolvere il problema proposto. Si richiede di gestire anche il caso in cui le palline siano tutte di uno stesso peso. Questo problema può essere risolto come descritto nell’algoritmo 7. Algoritmo 7 - Algoritmo di conteggio di sfere Input: insieme S di sfere di due pesi Output: numeri m e n delle sfere dei due tipi 1: if ci sono sfere nell’insieme then 2: sposta una sfera dall’insieme S al piatto A 3: porta m a 1 4: else 5: porta m a 0 6: end if 7: porta n a 0 8: while ci sono sfere nell’insieme do 9: sposta una sfera dall’insieme S al piatto B 10: if piatto A = piatto B then 11: incrementa m di 1 12: else 13: incrementa n di 1 14: end if 15: svuota piatto B 16: end while 17: return [m, n] Esempio 20. Consideriamo il seguente problema: Si ha un mucchio di sfere di acciaio uguali fra loro, dei pesi di k unità ed una bilancia a due piatti. Determinare quanto pesa una sfera (si supponga che il numero delle sfere e dei pesi a disposizione sia sufficientemente grande e che il peso delle sfere sia commensurabile con k). L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 4.6. TAVOLA DI TRACCIA DI UN ALGORITMO 55 Indicando con A e B i due piatti della bilancia sui quali vengono posti, rispettivamente, i pesi e le sfere, un procedimento risolutivo può essere descritto come riportato nell’algoritmo 8; la terminazione di questo algoritmo è garantita dall’ipotesi di commensurabilità fra k ed il peso delle sfere. Algoritmo 8 - Algoritmo di pesatura di una sfera Input: sfera da pesare Output: peso della sfera 1: metti un peso sul piatto A 2: metti una sfera sul piatto B 3: while i piatti della bilancia non sono in equilibrio do 4: if il piatto A è più alto (pesa meno) del piatto B then 5: aggiungi un peso sul piatto A 6: else 7: aggiungi una sfera sul piatto B 8: end if 9: end while 10: sia m il numero dei pesi sul piatto A 11: sia n il numero delle sfere sul piatto B 12: una sfera pesa m ∗ k/n unità 4.6 TAVOLA DI TRACCIA DI UN ALGORITMO La tavola di traccia di un algoritmo applicato ad un’istanza di problema consiste nella descrizione nel tempo dei vari valori associati alle entità coinvolte nell’algoritmo. La tavola di traccia è paragonabile ad una sequenza di fotogrammi che descrive l’avanzamento del processo corrispondente all’esecuzione di un algoritmo su una specifica istanza di problema. Esempio 21. Si dispone di due recipienti A e B, senza gradazione di misura, aventi rispettivamente la capacità di 3 e 5 litri. Il problema consiste nel mettere 4 litri nel recipiente B. Sono ammesse le seguenti operazioni: • riempire un dato secchio x • svuotare un dato secchio x • travasare un secchio x in un secchio y fino a riempire y o svuotare x L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 56 CAPITOLO 4. ALGORITMI Per questa istanza di problema il procedimento può essere illustrato mediante la tavola di traccia riportata nella figura 4.2. operazione riempi A travasa A riempi A travasa A svuota B travasa A riempi A travasa A in B in B in B in B secchio A 0 3 0 3 1 1 0 3 0 secchio B 0 0 3 3 5 0 1 1 4 Figura 4.2: Tavola di traccia per un problema di travasamento di recipenti. 4.7 LIVELLI DESCRITTIVI DEGLI ALGORITMI Consideriamo il seguente problema: Note le misure x e y dei due lati di un rettangolo, determinare la misura d della diagonale. Se l’esecutore è uno studente che abbia frequentato almeno le scuole medie inferiori, un procedimento risolutivo potrebbe essere: Determina d usando il teorema di Pitagora. Se l’esecutore non conosce il teorema di Pitagora, un procedimento risolutivo, espresso in modo algebrico, potrebbe essere: √ d = x2 + y 2 Se l’esecutore non conosce nemmeno il simbolismo algebrico che compare nella formula precedente o non è in grado di eseguire le operazioni indicate, il procedimento risolutivo dovrebbe essere descritto ad un livello ancora più elementare. Questo semplice esempio evidenzia che uno stesso algoritmo, pur riferendosi allo stesso problema, può essere espresso con notazioni ed a livelli descrittivi diversi, in funzione delle capacità e delle conoscenze dell’esecutore al quale è rivolto. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 4.8. NOTAZIONI DI ALTO E BASSO LIVELLO 4.8 57 NOTAZIONI DI ALTO E BASSO LIVELLO Consideriamo il problema del calcolo del prodotto fra due numeri naturali. L’usuale metodo imparato alle scuole elementari richiede che l’esecutore abbia le seguenti abilità: • applicare le tabelline della moltiplicazione dallo 0 al 9 • eseguire l’addizione fra numeri naturali di una sola cifra Come si nota immediatamente, queste abilità sono molto più semplici ed elementari che la capacità di saper moltiplicare di colpo due numeri naturali qualunque grandi. Consideriamo ora un altro algoritmo per moltiplicare due numeri naturali. Tale procedimento è noto con il nome di algoritmo del contadino russo. L’algoritmo consiste nel raddoppiare iterativamente un fattore mentre si dimezza l’altro, notando dove il valore del primo fattore è dispari. L’ultimo passo dell’algoritmo consiste nell’addizionare i multipli del fattore che è stato raddoppiato, in corrispondenza dei punti in cui il valore del primo fattore è dispari (numeri sottolineati). Ad esempio, l’applicazione di questo algoritmo per ottenere il prodotto fra i due numeri m = 22 e n = 13 è descritto dalla tavola di traccia riportata nella figura 4.3. m 22 11 5 2 1 0 m dispari ? no si si no si n 13 26 52 104 208 prodotto: 286 Figura 4.3: Traccia del calcolo 22 × 13 mediante l’algoritmo del contadino russo. Notiamo che le fasi operative per l’applicazione di questo procedimento sono (specialmente se i fattori sono grandi) più laboriose rispetto all’usuale metodo di moltiplicazione, ma in questo caso le capacità coinvolte sono più elementari. Un esecutore deve infatti essere in grado di eseguire le seguenti operazioni: L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 58 CAPITOLO 4. ALGORITMI • duplicare un numero naturale • dimezzare un numero naturale • decidere se un numero naturale è dispari • addizionare numeri naturali Notiamo inoltre che questo procedimento di moltiplicazione non è commutativo e che, poiché l’operazione astratta di moltiplicazione è commutativa, in un prodotto è vantaggioso prendere come fattore da dimezzare quello minore, per ottimizzare l’efficienza del procedimento. In una forma algoritmica di alto livello, tipica dei linguaggi di programmazione, il procedimento di moltiplicazione mediante il metodo del contadino russo può essere descritto mediante l’algoritmo 9. Algoritmo 9 - Algoritmo del contadino russo (notazione di alto livello) Input: numeri naturali m e n Output: prodotto fra m e n 1: porta p a 0 2: while m ≠ 0 do 3: if m è dispari then 4: incrementa p di n 5: end if 6: dimezza m 7: raddoppia n 8: end while 9: return p L’algoritmo 9 può essere espresso in modo equivalente mediante la notazione di basso livello riportata nell’algoritmo 10. Le forme algoritmiche di basso livello, caratterizzate da istruzioni di salto, possono essere espresse, equivalentemente, in forme di alto livello con strutture di controllo più vicine al nostro modo di pensare. Queste argomentazioni saranno riprese più avanti. Si noti che i due precedenti algoritmi, pur espressi con notazioni di diverso livello, descrivono le stesse operazioni. Si vedrà nel seguito che le notazioni di L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 59 4.9. IL PRINCIPIO DI COMPLESSITÀ Algoritmo 10 - Algoritmo del contadino russo (notazione di basso livello) Input: numeri naturali m e n Output: prodotto fra m e n 1: porta p a 0 2: if m = 0 goto 8 3: if m è pari goto 5 4: incrementa p di n 5: dimezza m 6: raddoppia n 7: goto 3 8: return p basso livello vengono generalmente adottate per esecutori in grado di eseguire operazoni di base molto elementari. Osservazione. Il concetto di livello di un linguaggio è relativo e non ha senso parlare in termini assoluti di alto livello e basso livello quanto piuttosto in termini relativi, quali livello x più alto/basso di ..., livello x adeguato al problema y. Per inciso osserviamo che il livello più basso di linguaggio è rappresentato dal linguaggio dell’esecutore che si dispone e che il livello più alto nella soluzione di un dato problema P può essere considerato quello costituito da frasi della forma Risolvi il problema P. 4.9 IL PRINCIPIO DI COMPLESSITÀ In questo paragrafo si analizzerà la relazione che intercorre tra la potenza di un esecutore e la complessità della soluzione per risolvere un dato problema. Consideriamo il problema di trasformazione di una configurazione di blocchi, come illustrato dallo schema che segue: D C B A - A B D C Possiamo pensare che qui l’esecutore sia una persona, un robot o qualcos’altro. Per rendere il problema un po’ interessante supponiamo, per il momento, che L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 60 CAPITOLO 4. ALGORITMI l’esecutore abbia la capacità di spostare un solo blocco alla volta. Con questa ipotesi, una soluzione del problema è fornita dall’algoritmo 11. Algoritmo 11 - Algoritmo spostamento blocchi (caso a) 1: sposta il blocco D sul piano 2: sposta il blocco C sul piano 3: sposta il blocco D sopra a C 4: sposta il blocco B sopra a D 5: sposta il blocco A sopra a B In questo contesto, il solutore è colui che ha scritto la sequenza delle azioni, l’esecutore è l’entità che effettua lo spostamento dei blocchi, gli oggetti che vengono manipolati sono costituiti dai blocchi, le azioni consistono nello spostare i blocchi, i dati sono rappresentati dalla configurazione iniziale ed i risultati dalla configurazione finale che si intende ottenere. Se ammettiamo che l’esecutore abbia la capacità di spostare una qualsiasi pila di blocchi, senza capovolgerla, la soluzione del problema può essere formulata come descritto nell’algoritmo 12. Algoritmo 12 - Algoritmo spostamento blocchi (caso b) 1: sposta la pila di blocchi CD sul piano 2: sposta il blocco B sopra a D 3: sposta il blocco A sopra a B Da questa semplice variazione si intuisce che la soluzione dipende dalle capacità dell’esecutore. Se ammettiamo che l’esecutore abbia anche la capacità di spostare una qualsiasi pila di blocchi e possa, eventualmente, deporla capovolta, una soluzione può essere più semplicemente espressa come descritto nell’algoritmo 13. Algoritmo 13 - Algoritmo spostamento blocchi (caso c) 1: sposta la pila di blocchi CD sul piano (senza capovolgerla) 2: sposta la pila di blocchi AB sopra D capovolgendola Gli esempi appena presentati evidenziano che la soluzione di un problema non solo dipende dalle capacità dell’esecutore ma che la soluzione è tanto più L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 4.9. IL PRINCIPIO DI COMPLESSITÀ 61 breve e semplice quanto più potenti sono le capacità dell’esecutore. La lunghezza di una soluzione, misurata come numero delle istruzioni elementari che la compongono, rappresenta un’indicazione della complessità della soluzione. Se la soluzione viene espressa in una forma non sequenziale ma strutturata mediante delle strutture (condizionali e/o cicliche ) di controllo delle azioni, il concetto di complessità deve essere espresso in un modo più elaborato. Assumendo in modo intuitivo il concetto di complessità di una soluzione, possiamo affermare il seguente principio: PROPRIETÀ 1. (Principio di complessità della soluzione). La complessità della soluzione di un problema diminuisce all’aumentare della potenza delle azioni che l’esecutore è in grado di compiere. In base a questo principio possiamo dedurre che è molto più laborioso far eseguire una moltiplicazione fra due numeri naturali ad un esecutore che è capace solamente di addizionare un’unità alla volta che non ad un esecutore capace di addizionare due numeri qualsiansi. Il caso estremo è quando l’esecutore è capace di moltiplicare due numeri; in tale caso la soluzione del problema può essere espressa semplicemente in una forma del tipo moltiplica x per y. Il discorso può essere generalizzato come segue. Dato un problema P , l’ideale sarebbe disporre di un esecutore così potente da poter esprimere la soluzione mediante la sola istruzione Risolvi il problema P . Evidentemente, la realtà è ben diversa; inoltre, il procedimento risolutivo è tanto più lungo e complesso quanto più il linguaggio con il quale ci si rivolge all’esecutore è ”lontano” dal problema trattato. Per diminuire la distanza fra il linguaggio usato e problema trattato, i linguaggi di programmazione offrono degli strumenti appositi: definizioni di sottoprogrammi, definizioni di tipi di dato, definizioni di classi ed altro ancora. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 62 CAPITOLO 4. ALGORITMI 4.10 ESERCIZI 1. Nell’ipotesi di disporre di un esecutore in grado di eseguire le quattro operazioni fondamentali +, −, ∗, /, discutere comparativamente il concetto di formula risolutiva e procedimento risolutivo relativamente alla solu˙ + 1)/2, zione dei seguenti due problemi, tenendo conto che: ∑nk=1 k = n(n mentre non esiste un’analoga forma chiusa che fornisca il risultato di n! = ∏nk=1 k. (a) Calcolare la somma dei primi n numeri naturali (b) Calcolare il prodotto dei primi n numeri naturali 2. Per i problemi che seguono si individuino i dati ed i risultati e si dica se il problema è ben formulato o meno. Nel caso il problema sia ben formulato, descrivere un procedimento risolutivo, evidenziando quali devono essere le capacità dell’esecutore. (a) Dato il perimetro e l’area di un triangolo, determinarne le misura dei lati. (b) Data l’area ed il perimetro di un rettangolo, determinarne la diagonale. (c) Dato il perimetro di un rettangolo, determinarne l’area. (d) Data l’area e la base di un rettangolo, determinarne l’altezza. (e) Determinare i lati di un rettangolo conoscendone l’area ed il perimetro. (f) Determinare l’altezza relativa all’ipotenusa di un triangolo rettangolo del quale sono noti i due cateti. 3. Generalizzare la seguente istanza di problema, proponendo delle classi di problemi via-via più generali. Determinare la lunghezza della diagonale di un quadrato di lato 2 cm. Riformulare il problema in modo da renderlo ben formulato. Disponendo di un esecutore in grado di eseguire le usuali operazioni aritmetiche √ (+, −, ∗, /, , . . . ) descrivere un algoritmo per risolvere il problema in questione. 4. Si consideri il seguente problema: L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 4.10. ESERCIZI 63 Dire se il triangolo avente i lati di misure a, b, c è più piccolo del triangolo avente i lati di misure d, e, f . (a) Motivando le affermazioni, dire se il problema proposto è ben formulato. (b) Nel caso che il problema non sia ben formulato, riformularlo adeguatamente in modo che risulti ben formulato. (c) Classificare il problema in base alla sua forma (computazionale, ...). (d) Con riferimento al problema ben formulato, specificare in cosa consistono i dati, i risultati ed un criterio di verifica della soluzione. (e) Descrivere un procedimento risolutivo che richieda all’esecutore delle capacità il più possibile elementari. Precisare le capacità richieste all’esecutore da parte del procedimento che si è descritto. (f) Generalizzare il problema, proponendo più generalizzazioni successive. 5. Dire, motivando le affermazioni, perchè il seguente problema non è ben formulato: Determinare l’area di un quadrilatero note le misure a, b, c, d dei lati. Ridefinire il problema in modo che risulti ben formulato, con l’obiettivo di risolverlo per un esecutore capace di valutare l’area di un triangolo date le lunghezze dei tre lati del triangolo. Adottando queste ipotesi sulle capacità dell’esecutore, descrivere un algoritmo per risolvere il problema in questione. 6. Si consideri il seguente problema: Data l’area ed il perimetro di un triangolo, decidere se esso è un triangolo rettangolo. (a) Stabilire la tipologia del problema proposto (computazionale, decisionale, trasformazionale, ...) (b) Motivando adeguatamente le affermazioni, stabilire se il problema proposto è ben formulato. (c) Nel caso in cui il problema sia ben formulato, descrivere un algoritmo adeguato per un esecutore avente le conoscenze di uno studente di una terza superiore. 7. Si conoscono le misure a, b, c delle lunghezze degli spigoli di un parallelepipedo rettangolo. Determinare la misura della sua massima superficie di appoggio e l’altezza minima del suo baricentro (nella situazione L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 64 CAPITOLO 4. ALGORITMI in cui il parallelepipedo si appoggiato sulla sua massima superficie di appoggio). 8. Si consideri la seguente istanza di problema: Suddividere un segmento di 10 cm in 2 parti di cui una sia i 3/7 dell’altra. Si supponga di disporre degli usuali attrezzi da disegno: due squadrette a 45o e 30o , 60o , una matita, un compasso, con l’ipotesi che le squadrette siano sufficientemente lunghe ma non siano graduate. (a) Generalizzare il problema proposto. (b) Descrivere un procedimento, da riportare su un testo scolastico di disegno tecnico, per risolvere la classe di problemi che si è individuata. (c) Motivare perchè nella formulazione del quesito precedente si è sentita l’esigenza di precisare “da riportare su un testo scolastico di disegno tecnico”? 9. Si ha un sacco pieno di chicchi di grano ed uno pieno di chicchi di frumento. Il problema consiste nel decidere quale dei due sacchi contiene più chicchi. Con riferimento a questo problema: (a) Si precisi in cosa consistono i dati, i risultati ed un criterio di verifica della soluzione. (b) Descrivere un procedimento risolutivo che richieda all’esecutore delle capacità il più possibile elementari. Precisare le capacità richieste all’esecutore da parte del procedimento che si è descritto. Suggerimento: non serve che l’esecutore sappia contare. 10. Un sacco contiene molte palline di al più due pesi diversi anche se all’apparenza uguali. Il problema consiste nel determinare quante sono le palline di ciascuno dei due pesi, utilizzando una bilancia a due piatti. Descrivere un algoritmo per risolvere il problema proposto. Si richiede di gestire anche il caso in cui le palline siano tutte di uno stesso peso. 11. Ricercare se un dato numero è presente in una sequenza di numeri. 12. Ricercare se un dato numero è presente in una sequenza ordinata di numeri. Discutere la soluzione proposta, confrontandola con quella dell’esercizio precedente. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 4.10. ESERCIZI 65 13. Disponendo di un esecutore in grado di eseguire le usuali operazioni √ aritmetiche (+, −, ∗, /, , . . . ), risolvere il seguente problema: Dato un triangolo avente i lati di misure a, b, c, determinare il rettangolo di minima area che lo ricopre. 14. Decidere se un dato numero naturale, considerato in notazione decimale, è palindromo, ossia se si legge indifferentemente da sinistra a destra e da destra a sinistra. 15. Decidere se un dato numero naturale m è divisibile (esattamente) per un dato numero naturale n. Si supponga che l’esecutore al quale è rivolto l’algoritmo sia capace di eseguire solamente le operazioni di addizione e sottrazione e sia in grado di confrontare fra loro due numeri. 16. Nell’ipotesi di disporre di un esecutore in grado di eseguire le operazioni aritmetiche di addizione e sottrazione, scrivere un algoritmo per determinare la divisione fra due numeri naturali. 17. Una calcolatrice permette l’uso delle sole operazioni elementari sui numeri naturali: +, −, ∗, /. L’operazione di divisione fornisce il quoziente intero. Descrivere un algoritmo per determinare il resto della divisione intera fra due numeri naturali. È possibile trascrivere su un foglio i risultati intermedi. 18. Determinare il prodotto fra due dati numeri naturali m ed n. Si dispone di un esecutore in grado di eseguire le sole operazioni aritmetiche di addizione e sottrazione fra due numeri naturali e di comparare tra loro due numeri naturali. 19. Determinare il quoziente ed il resto della divisione intera fra due dati numeri naturali m ed n. Sono ammesse le sole operazioni aritmetiche di addizione, sottrazione e comparazione fra numeri naturali. 20. Determinare il resto della divisione intera fra due dati numeri m ed n. Si dispone di un esecutore in grado di eseguire le sole operazioni aritmetiche di addizione e sottrazione fra due numeri naturali e di comparare tra loro due numeri naturali. 21. Determinare la potenza mn fra due dati numeri naturali m ed n. Sono ammesse le quattro operazioni aritmetiche di addizione, sottrazione, prodotto e divisione e la comparazione fra numeri naturali. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 66 CAPITOLO 4. ALGORITMI 22. Determinare la potenza di un numero con base reale ed esponente intero. 23. Determinare la somma delle cifre in base 10 di un numero naturale. Si supponga che l’esecutore al quale è rivolto l’algoritmo sia capace di eseguire le quattro operazioni aritmetiche +, −, ∗, /. 24. Determinare la cifra più significativa di un dato numero naturale, considerato in base 10. Sono ammesse le quattro operazioni aritmetiche fondamentali ed i confronti fra numeri. 25. Determinare il numero di cifre di un dato numero naturale, considerato in base 10. 26. Determinare la cifra più grande di un dato numero naturale, considerato in base 10. 27. Supponendo di disporre di un esecutore capace di applicare il teorema di Pitagora, descrivere un procedimento risolutivo per determinare la diagonale di un parallelepipedo rettangolo di cui si conoscono le lunghezza degli spigoli. 28. Definire in modo preciso e non ambiguo le operazioni lecite nelle costruzioni con riga e compasso. Con le operazioni definite, determinare un segmento avente per misura la radice quadrata della misura di un dato segmento. Suggerimento: utilizzare il secondo teorema di Euclide. 29. Sono dati due punti distinti A e B del piano. Descrivere un procedimento per disegnare due circonferenze di uguale raggio, fra loro tangenti esternamente nel punto medio M del segmento AB ed aventi rispettivamente i segmenti AM e M B come diametri. Si assuma l’ipotesi che l’esecutore possa usare solamente riga (non graduata), compasso e matita. 30. Sono dati due punti distinti A e B del piano. Descrivere un procedimento per determinare il quadrato avente il segmento AB come diagonale. Si assuma l’ipotesi che l’esecutore possa usare solamente riga (non graduata), compasso e matita. 31. Adattare il procedimento di pesatura delle sfere, presentato in questo capitolo, per determinare il minimo comune multiplo fra due numeri naturali. 32. Si è in un deserto e si dispone di un lungo spago lungo 47 metri e delle forbici. Costruire un recinto di forma quadrata. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 67 4.10. ESERCIZI 33. Un foglio rettangolare di dimensioni m ed n è suddiviso in un reticolo di rettangoli aventi per dimensioni p e q. Scrivere un algoritmo per determinare la dimensione dei più piccoli e dei più grandi quadrati formati da questi rettangoli. Discutere se il problema ammette sempre soluzione nei casi in cui m, n, p, q ∈ Q e m, n, p, q ∈ R. 34. Decidere se un numero naturale è primo. Descrivere la tavola di traccia dell’esecuzione dell’algoritmo applicato al numero 161. 35. Nell’ipotesi di disporre di un esecutore in grado di eseguire le operazioni aritmetiche elementari addizione e sottrazione, risolvere la seguente istanza di problema: Calcolare 7!. 36. Oltre ai russi, anche gli arabi, da buoni algebristi, hanno ideato nei secoli scorsi un loro metodo per moltiplicare fra loro due numeri naturali. Il metodo è descritto dallo schema che segue, dove è descritto il processo di moltiplicazione 726 × 43 = 31218. Lungo le linee oblique evidenziate mediante una freccia vengono addizionati (a partire dalla destra e considerando i riporti) i numeri che vi si incontrano. 7 2 6 2 0 2 4 8 8 4 2 0 1 3 1 6 8 3 1 2 1 8 L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 68 CAPITOLO 4. ALGORITMI Si lascia per esercizio la decifrazione del metodo (basandosi sullo schema sopra riportato), l’individuazione delle capacità richieste all’esecutore e la dimostrazione (o semplicemente la motivazione) che il metodo funziona. Descrivere il metodo mediante un algoritmo. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 Capitolo 5 Problemi risolti Il risolvere i problemi è un’arte pratica, come il nuotare, o lo sciare o il suonare il piano: potete impararlo solo con l’imitazione e la pratica. Questo libro non può offrirvi la chiave magica che apre tutte le porte e risolve tutti i problemi, ma vi offre dei buoni esempi da imitare e molte opportunità per fare pratica: se desiderate imparare a nuotare dovete gettarvi in acqua e, se desiderate diventare un risolutore di problemi, dovete risolvere problemi. G. Polya, La scoperta matematica In questo capitolo saranno affrontati e risolti alcuni problemi elementari. Saranno applicate le metodologie descritte nei capitoli precedenti. Le soluzioni saranno descritte mediante le forme fondamentali di algoritmi presentate precedentemente. 69 70 CAPITOLO 5. PROBLEMI RISOLTI 5.1 UN PROBLEMA GEOMETRICO La soluzione del seguente problema illustra una tipica applicazione della metodologia top-down ed evidenzia come una cattiva scomposizione di un problema renda difficile la soluzione dei sottoproblemi. Consideriamo il problema di calcolare l’area della figura geometrica riportata in figura 5.1, note le lunghezze dei cinque lati, assumendo l’ipotesi che la figura sia convessa e che i due lati alla base siano retti. e L L Ld L L a L c b Figura 5.1: Il problema: Determinare l’area del pentagono. Una scomposizione della figura in due trapezi come descritto nella figura 5.2 risulterebbe poco utile in quanto ciò comporterebbe il calcolo dell’area di due trapezi rettangoli dei quali sono noti pochi ed insufficienti elementi. L L L L L L Figura 5.2: Una scomposizione non efficace. Una scomposizione più efficace è descritta nella seguente figura 5.3. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 71 5.1. UN PROBLEMA GEOMETRICO eL A2 LLd HH HH L h HH L f a HL A1 c b Figura 5.3: Una scomposizione efficace. Questa scomposizione suggerisce il seguente procedimento risolutivo per il calcolo dell’area A del pentagono: A ← A1 + A2 Adottando la metodologia top-down, i due sottoproblemi corrispondenti al calcolo delle due aree A1 e A2 si esplicitano come segue: calcolo di A1 : A1 ← (a + c) ∗ b/2 calcolo di A2 : h f p A2 ← ← ← ← ∣a √− c∣ b2 + h2 (d √ + e + f )/2 p ∗ (p − d) ∗ (p − e) ∗ (p − f ) La ricomposizione delle soluzioni parziali sopra riportate conduce all’algoritmo 14. Algoritmo 14 - Calcolo dell’area del pentagono riportato nella figura 5.1 Input: misure a, b, c, d, e del pentagono Output: area del pentagono 1: A1 ← (a + c) ∗ b/2 2: h ← ∣a √− c∣ 3: f ← b2 + h2 4: p ← (d√ + e + f )/2 5: A2 ← p ∗ (p − d) ∗ (p − e) ∗ (p − f ) 6: A ← A1 + A2 7: return A L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 72 5.2 CAPITOLO 5. PROBLEMI RISOLTI UN PROBLEMA DI DECISIONE Gli alberi di decisione costituiscono un utile formalismo grafico di supporto per impostare la soluzione di molti problemi di tipo decisionale. Esempio 22. L’albero di decisione riportato nella figura 5.4 descrive il procedimento per la determinazione del valore massimo fra 3 elementi. x>y v ZZ f Z = ~ Z x>z y>z v S f v S f / x S w S z y / S w S z Figura 5.4: Albero di decisione per la determinazione del massimo fra 3 elementi x, y, z. L’albero di decisione riportato nella figura 5.4. può essere espresso in modo algoritmico come descritto nell’algoritmo 15. Algoritmo 15 - Determinazione del massimo fra x, y, z Input: numeri x, y, z Output: massimo fra x, y, z 1: if x > y then 2: if x > z then 3: return x 4: else 5: return z 6: end if 7: else 8: if y > z then 9: return y 10: else 11: return z 12: end if 13: end if L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 73 5.3. UN ALTRO PROBLEMA DI DECISIONE 5.3 UN ALTRO PROBLEMA DI DECISIONE Il seguente esempio descrive un tipico caso di applicazione della metodologia top-down. Supponiamo di disporre di una bilancia a due piatti che permetta di decidere se due oggetti abbiano lo stesso peso, ma non consenta di decidere quale dei due oggetti, se di peso diverso, pesi più dell’altro. Il problema consiste nel determinare la moneta (falsa) di peso diverso, fra 12 monete all’apparenza uguali. Indicando con m1 , m2 , . . . , m12 le 12 monete, con A?B il confronto di pesatura fra i due insiemi A e B di monete e con F A la soluzione del problema di determinare la moneta falsa dell’insieme A, un primo abbozzo di un procedimento risolutivo può essere descritto mediante l’albero di decisione riportato in figura 5.5. Con questa soluzione parziale ci si è ricondotti ai tre sottoproblemi P1 , P2 , P3 evidenziati con un riquadro a linea tratteggiata nella figura 5.5; questi tre sottoproblemi sono fra loro simili: per ciascuno di essi si tratta di individuare la moneta falsa fra quattro monete. {m1 , m2 , m3 , m4 }?{m5 , m6 , m7 , m8 } = P1 F{m9 , m10 , m11 , m12 } @ ≠@ @ R @ F{m1 , m2 , m3 , . . . , m8 } {m1 , m2 , m3 , m4 }?{m9 , m10 , m11 , m12 } = P2 F{m5 , m6 , m7 , m8 } @ ≠@ @ R @ P3 F{m1 , m2 , m3 , m4 } Figura 5.5: Albero di decisione per il problema delle 12 monete. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 74 CAPITOLO 5. PROBLEMI RISOLTI L’albero di figura 5.5 può essere descritto mediante l’algoritmo 16. Algoritmo 16 - Algoritmo per determinare la moneta falsa fra 12 Input: pesi m1 , m2 , . . . , m12 di 12 monete Output: moneta falsa 1: if {m1 , m2 , m3 , m4 } = {m5 , m6 , m7 , m8 } then 2: F (m9 , m10 , m11 , m12 ) 3: else if {m1 , m2 , m3 , m4 } = {m9 , m10 , m11 , m12 } then 4: F (m5 , m6 , m7 , m8 ) 5: else 6: F (m1 , m2 , m3 , m4 ) 7: end if Indicando con a, b, c, d i pesi delle quattro monete che compaiono nei tre sottoproblemi P1 , P2 , P3 , la soluzione del sottoproblema F {a, b, c, d} può essere ottenuta mediante l’albero di decisione riportato in figura 5.6 dove, nell’ultima riga della figura, sono evidenziate le monete false nei diversi casi. a?b a?c HH = ≠H Q Q = ≠Q + s Q d c HH j = + b a?c Q ≠Q s Q Q a Figura 5.6: Albero di decisione per il problema delle 4 monete. In notazione algoritmica l’albero di decisione descritto nella figura 5.6 può essere espresso come riportato nell’algoritmo 17. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 5.4. UN PROBLEMA NUMERICO 75 Algoritmo 17 - Determinazione della moneta falsa fra 4 Input: pesi a, b, c, d di quattro monete Output: moneta falsa 1: if a = b then 2: if a = c then 3: la moneta falsa è d 4: else 5: la moneta falsa è c 6: end if 7: else 8: if a = c then 9: la moneta falsa è b 10: else 11: la moneta falsa è a 12: end if 13: end if L’albero di decisione completo, corrispondente all’albero riportato nella figura 5.5, si ottiene sostituendo l’albero di decisione della figura 5.6 nei tre punti corrispondenti ai tre sottoproblemi P1 , P2 , P3 evidenziati nella figura 5.5, istanziando i parametri a, b, c, d con i valori effettivi di ciascun sottoproblema viene ricostruita la soluzione complessiva del problema originale (algoritmo 16). Il massimo numero di pesate necessarie per arrivare alla decisione è dato dall’altezza dell’albero. 5.4 UN PROBLEMA NUMERICO Consideriamo il problema di determinare il numero r definito dalla rappresentazione decimale inversa di un numero naturale n (esempio: n = 4372, r = 2734). Supponiamo, per il momento, che il numero n non sia divisibile per 10, ossia che il numero, nella sua rappresentazione decimale, non termini con 0. Nell’ipotesi di disporre di un esecutore in grado di eseguire le 4 operazioni aritmetiche di base +, −, ∗, /, un possibile procedimento risolutivo per questo problema può essere espresso mediante l’algoritmo 18. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 76 CAPITOLO 5. PROBLEMI RISOLTI Algoritmo 18 - Rovesciamento di un numero naturale in base 10 - ver. A Input: numero naturale n da rovesciare Output: numero r rovesciato 1: considera il numero r uguale a 0 2: while ci sono cifre in n do 3: trasporta la cifra delle unità di n alla fine di r 4: end while 5: return numero r Nella formulazione dell’algoritmo 18 si nota che le varie istruzioni informali sono direttamente traducibili in un generico linguaggio di programmazione, ad eccezione del sottoproblema trasporta la cifra delle unità di n alla fine di r. Tale sottoproblema può essere ulteriormente scomposto nei seguenti due: P1 : togli la cifra delle unità dal numero n P2 : accoda tale cifra alla destra del numero r A questo punto si arriva alla forma quasi definitiva riportata nell’algoritmo 19. Algoritmo 19 - Rovesciamento di un numero naturale in base 10 - ver. B Input: numero naturale n da rovesciare Output: numero r rovesciato 1: r ← 0 2: while ci sono cifre in n do 3: c ← cifra delle unità di n 4: n ← n privato della cifra delle unità 5: r ← r con aggiunta la cifra sulla destra 6: end while 7: return numero r Raffinando ulteriormente l’algoritmo 19, si perviene alla formulazione definitiva (algoritmo 20) in cui tutte le operazioni indicate sono direttamente eseguibili dall’esecutore. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 5.5. UN PROBLEMA SUI BLOCCHETTI 77 Algoritmo 20 - Rovesciamento di un numero naturale in base 10 - ver. C Input: numero naturale n da rovesciare Output: numero r rovesciato 1: r ← 0 2: while n > 0 do 3: q ← n/10 4: p ← q ∗ 10 5: c←n−p 6: n ← n/10 7: r ← r ∗ 10 8: r ←r+c 9: end while 10: return numero r In una forma più compatta, le istruzioni di assegnazione interne al ciclo potrebbero essere scritte come segue: r ← (r ∗ 10) + (n − (n/10) ∗ 10) n ← n/10 Si lascia per esercizio l’analisi del comportamento dell’algoritmo precedente nei casi in cui il numero da invertire termini con delle cifre 0. 5.5 UN PROBLEMA SUI BLOCCHETTI Si hanno due pile di blocchetti sui quali è impresso un numero naturale. Le due pile sono poste inizialmente nelle posizioni A e B. Nelle due pile i blocchetti sono disposti in modo tale che ogni blocchetto (esclusi quelli direttamente appoggiati sul piano) sia appoggiato sopra uno avente un numero maggiore o uguale del suo. Il problema consiste nel fondere 1 le due pile di blocchetti, costruendone una composta dai blocchetti delle due pile originali, in ordine inverso. È ammesso di utilizzare una terza posizione C per parcheggiare temporaneamente i blocchetti. Alla fine della trasformazione i blocchetti devono trovarsi sulla posizione A, ordinati dal più grande (appoggiato in basso) al più piccolo (in alto). Sviluppiamo, mediante la metodologia top-down, un algoritmo per risolvere il problema in questione, assumendo l’ipotesi di disporre di un esecutore in grado di spostare un solo blocchetto per volta (uno di quelli posti in testa alle pile) ed in grado di confrontare i numeri impressi sui 1 Fondere: unione di due sequenze ordinate in un’unica sequenza ordinata. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 78 CAPITOLO 5. PROBLEMI RISOLTI blocchetti. Si tratta di un problema di trasformazione descrivibile mediante lo schema grafico illustrato nella figura 5.7. 6 5 3 A 7 5 4 4 B C 3 4 4 5 5 6 7 A situazione iniziale B C situazione finale Figura 5.7: Situazione iniziale (a sinistra) e finale (a destra) per un problema di fusione di due pile di blocchetti. Adottando la metodologia top-down, una prima scomposizione può essere: F : fondi le due pile A, B mettendo il risultato in C T : trasla la pila C in A (senza rovesciarla) Il sottoproblema F può essere risolto come riportato nell’algoritmo 21. Il sottoproblema T può essere scomposto nei seguenti due sottoproblemi: R3 : rovescia la pila da C in B R4 : rovescia la pila da B in A Si può notare che i sottoproblemi R1 , R2 , R3 ed R4 hanno la stessa struttura e, pertanto, appartengono ad una stessa classe di problemi descrivibile come segue: Rovescia la pila da Xa Y Una soluzione di questo problema è riportata nell’algoritmo 22. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 5.6. UN PROBLEMA SULLE STRINGHE 79 Algoritmo 21 - Fusione di due pile di blocchetti Input: pile A e B ordinate crescentemente Output: pila C ordinata decrescentemente 1: while ci sono blocchetti in A ed in B do 2: if la testa di A > testa di B then 3: sposta blocchetto da A a C 4: else 5: sposta blocchetto da B a C 6: end if 7: end while 8: if è finita la pila A then 9: R1 : rovescia la pila da B a C 10: else 11: R2 : rovescia la pila da A a C 12: end if 13: return pila C decrescente Algoritmo 22 - Rovesciamento della pila X in Y 1: while ci sono blocchetti in X do 2: sposta blocchetto da X a Y 3: end while 5.6 UN PROBLEMA SULLE STRINGHE Le stringhe sono delle sequenze di caratteri; costituiscono una classe di oggetti importante in quanto emergono in molteplici forme di elaborazione; tanto per citarne alcune: controlli di correttezza di una password, correzione ortografica in un programma di elaborazione testi, ricerca di parole e testi in un motore di ricerca di un browser, test del DNA. Consideriamo il seguente problema sulle stringhe: Decidere se una stringa è un anagramma di un’altra. La semplice e spontanea idea della soluzione di seguito proposta (anche se non è ottimale) si basa sulle seguenti osservazioni: L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 80 CAPITOLO 5. PROBLEMI RISOLTI Se le stringhe hanno lunghezze diverse, non possono essere una anagramma dell’altra. Altrimenti il controllo viene svolto analizzando, per ciascun carattere della prima stringa, se la sua frequenza è uguale nelle due stringhe. Se durante questa fase di analisi si riscontra nelle due stringhe una frequenza diversa di qualche carattere, allora le due stringhe non sono una anagramma dell’altra. Se si analizzano tutti i caratteri della prima stringa senza trovare diversità di frequenza, allora le due stringhe sono anagrammi una dell’altra. Il procedimento sopra descritto si basa sulle seguenti due operazioni elementari sulle stringhe: • ∣s∣ : lunghezza della stringa s • si : i-esimo carattere della stringa s L’algoritmo 23 risolve il problema sopra proposto. In questo algoritmo, con f [c, r] si denota la frequenza con la quale compare il carattere c all’interno della stringa r; con a si denota la variabile logica che esprime lo stato attuale del processo di analisi: il valore di verità vero esprime il fatto che ancora non si sono ancora riscontrate situazioni che determinano la conclusione che r non è anagramma di s. Algoritmo 23 - Decidere se una stringa è anagramma di un’altra Input: stringhe r e s Output: vero se e solo se r è anagramma di s 1: a ← ∣r∣ = ∣s∣ 2: i ← 1 3: while a ∨ (i ≤ r) do 4: c ← ri 5: a ← f [c, r] = f [c, s] 6: i←i+1 7: end while 8: return a L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 5.7. ESERCIZI 5.7 81 ESERCIZI 1. Una piramide a base esagonale, avente il lato di base di lunghezza k e l’altezza h è appoggiata interamente sopra un cubo di lato l. Determinare la superficie totale del solido composto così ottenuto. 2. Descrivere, mediante un albero di decisione, un procedimento per risolvere i seguenti problemi. Tradurre l’albero di decisione in un algoritmo. (a) Determinare il massimo fra tre numeri. (b) Stabilire se tre dati elementi sono uguali fra loro. (c) Stabilire se tre dati elementi sono tutti diversi fra loro. 3. Con riferimento al problema delle 12 monete presentato in questo capitolo, disponendo di una bilancia a due piatti che permette di distinguere se due oggetti pesano uguale o, altrimenti, quale dei due pesa di più, scrivere un algoritmo per determinare la moneta falsa, nel minor numero possibile di pesate. 4. Nelle stesse ipotesi dell’esercizio precedente, scrivere un algoritmo per determinare la moneta falsa e per stabilire se pesa di più o di meno delle altre. 5. Si hanno 4 monete di pesi diversi. Descrivere un albero di decisione per decidere se le monete hanno tutte lo stesso peso, disponendo di una bilancia non tarata, dotata di due braccia. Tradurre l’albero di decisione in un algoritmo. 6. Sono date 5 palline, all’apparenza uguali, di cui 2 di un peso e 3 di un altro peso. Usando una bilancia a due piatti, ripartire in base al loro peso le palline in due gruppi ciascuno composto da palline di uguale peso. 7. Si dispone di una bilancia a due bracci che permette di distinguere se due oggetti pesano uguale oppure quale dei due pesa di più. Si hanno quattro monete a, b, c, d, apparentemente uguali, a due a due di peso uguale. Descrivere, mediante un albero di decisione, un procedimento per individuare le due coppie di monete uguali. Tradurre l’albero di decisione in una notazione algoritmica. 8. Si hanno 5 monete apparentemente uguali; una di queste, falsa, è di rame mentre le altre 4, autentiche, sono di bronzo. Si vuole individuare la L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 82 CAPITOLO 5. PROBLEMI RISOLTI moneta falsa disponendo di una bilancia a due piatti. Descrivere un procedimento risolutivo, mediante un albero di decisione (a 3 alternative). Successivamente, descrivere il procedimento in una forma algoritmica, a parole. Si tenga presente che il bronzo è una lega di rame e stagno e che il peso specifico del rame è maggiore del peso specifico dello stagno. 9. Stabilire quanti confronti binari sono necessari per determinare il massimo fra n elementi di un insieme ordinato. Stabilire, in funzione di n, la minima e la massima altezza di un albero di decisione binario per determinare il massimo di n elementi. 10. Si ha una pila di blocchetti di tre colori: arancione, blu, ciclamino. La pila si trova inizialmente sulla posizione A. Descrivere un procedimento per separare i blocchetti, secondo il colore, costruendo sulle posizioni A, B e C tre pile con blocchetti di colore, rispettivamente, arancione, blu, ciclamino. È ammesso di spostare un solo blocchetto alla volta e di utilizzare, come appoggio, solo le tre posizioni A, B e C. 11. Si hanno due pile di blocchetti: una di colore arancione posta nella posizione A ed una di colore blu posta nella posizione B. Descrivere un procedimento per scambiare di posto le due pile di blocchetti, utilizzando come appoggio ausiliario una terza posizione C, facendo in modo che i blocchetti, in ciascuna pila, mantengano la loro reciproca posizione che avevano originariamente, prima dello spostamento. L’esecutore al quale deve essere rivolto il procedimento ha la capacità di spostare un solo blocchetto alla volta ed è in grado di riconoscere i colori dei blocchetti, ma non sa contare. Dimostrare che il problema non sarebbe risolvibile se l’esecutore non avesse la capacità di distinguere i colori. 12. Si ha un mucchio di dischi di tre dimensioni diverse. Descrivere un procedimento per disporre i dischi su una pila in modo che ogni disco poggi su uno di dimensione maggiore o uguale, nell’ipotesi che l’esecutore possa prendere e spostare un solo disco alla volta e che abbia spazio a piacere per appoggiare temporaneamente i dischi. 13. Nell’ipotesi di disporre un esecutore che può spostare un solo oggetto alla volta, descrivere dei procedimenti risolutivi per i seguenti problemi di trasformazione di configurazioni di blocchetti. (a) Spostare una pila di oggetti rovesciandola. (b) Spostare una pila di oggetti senza rovesciarla. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 5.7. ESERCIZI 83 (c) Spostare sul posto una pila di oggetti rovesciandola. (d) Estrarre da una pila il blocchetto appoggiato in basso e metterlo sopra 14. Si ha una pila di libri su un tavolo e si dispone di un esecutore capace di spostare un solo libro alla volta. La pila di libri si trova inizialmente sulla posizione A. Il problema consiste nel rovesciare sul posto la pila di libri, usando altre due posizioni ausiliarie di appoggio B e C. Descrivere un algoritmo per risolvere il problema. 15. Si hanno tre pioli A, B, C sui quali disporre dei dischi. Si hanno inizialmente n dischi disposti sulla postazione A; i dischi sono tutti uguali e sono in numero multiplo di 3. Descrivere un algoritmo per suddividere i dischi in numero uguale nelle tre pile, nell’ipotesi di disporre di un esecutore in grado di eseguire le seguenti operazioni: spostare un solo disco alla volta, decidere se una pila è vuota, comparare l’altezza di due pile. Determinare, in funzione di n, il numero di movimenti di singoli dischi che vengono eseguiti in un processo. 16. Si hanno tre pioli A, B, C sui quali disporre dei dischi. Inizialmente tutti i dischi sono disposti sul piolo A; i dischi sono di spessori diversi e sono in numero multiplo di 3. nelle stesse ipotesi sull’esecutore come indicate nell’esercizio precedente, descrivere un algoritmo per spostare sul piolo B un terzo dei dischi presenti inizialmente in A, usando il piolo C come postazione ausiliaria per gli spostamenti (alla fine il piolo A dovrà contenere il doppio dei dischi presenti in B e il piolo C dovrà risultare vuoto). Si supponga di disporre di un esecutore in grado di spostare un solo disco alla volta ed in grado di decidere se un piolo è vuoto. 17. Si ha una pila di blocchetti su ciascuno dei quali è segnato un numero. Si hanno a disposizione tre posizioni A, B e C e sono ammesse le seguenti operazioni di base: spostare da una pila ad un’altra un solo blocchetto alla volta (quello posto in cima ad una pila), comparare i valori dei blocchetti posti in cima a due pile, controllare se una pila è vuota. Descrivere un algoritmo per determinare uno dei blocchetti con valore minimo. Nella situazione iniziale tutti i blocchetti sono disposti nella posizione A; alla fine del processo uno dei blocchetti con valore minimo deve trovarsi nella posizione B e tutti gli altri blocchetti devono essere riportati nella posizione A, disposti nell’ordine in cui erano all’inizio. Usando il precedente algoritmo, scrivere un algoritmo per ordinare una L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 84 CAPITOLO 5. PROBLEMI RISOLTI pila di blocchetti, dal valore più grande (in basso) al valore più piccolo (in alto). 18. Sono date tre posizioni A, B e C; nella posizione A è posto un numero n, multiplo di 3, di monete di tipo e di spessore diversi. Descrivere un algoritmo per ripartire equamente le monete fra le posizioni A e B in modo che in entrambe queste due posizioni ci siano monete in un numero uguale o al più diverso di un’unità. È indifferente l’ordine con il quale si troveranno le monete alla fine del processo. È concesso utilizzare la posizione C come appoggio ausiliario. L’esecutore al quale è rivolto l’algoritmo è in grado di spostare una sola moneta alla volta, ma non è in grado di contare né di eseguire calcoli aritmetici. Determinare, in funzione di n, il numero di movimenti di singole monete che vengono eseguiti in un processo. 19. Si ha una sequenza di n piatti piani e fondi disposti su uno sgocciolatoio con n + 1 posizioni, di cui una è libera. Descrivere un algoritmo per ordinare i piatti, mettendo all’inizio i piatti piani ed alla fine i fondi. È consentito spostare un piatto nella posizione libera; è possibile inoltre mettere e spostare dei segnalini colorati come segnaposto in corrispondenza di una posizione. Spiegare come è possibile codificare l’algoritmo in linguaggio Java. 20. Stabilire le capacità che deve avere un esecutore per decidere se una data parola (sequenza di caratteri) precede alfabeticamente un’altra. Scrivere un algoritmo per stabilire la relazione di ordinamento lessicografico fra due stringhe; ad esempio albero precede album mentre quadro segue quaderno. 21. Decidere se all’interno di una stringa è presente un dato carattere. 22. Decidere se all’interno di una stringa è presente una data sottostringa. 23. Stabilire se una stringa di parentesi tonde aperte e chiuse è bilanciata, secondo le usuali regole dell’algebra; ad esempio la stringa ()(()()) è bilanciata mentre non lo è la stringa ())((). 24. Eliminare da una stringa un dato carattere; ad esempio, eliminando dalla stringa montagna il carattere n si ottiene la stringa motaga. Eliminare da una stringa le vocali; ad esempio, eliminando dalla stringa montagna le vocali si ottiene la stringa mntgn. 25. Valutare la potenza xn , con x numero reale ed n numero naturale. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 5.7. ESERCIZI 85 26. Valutare la somma dei primi n numeri naturali. 27. Valutare il minimo numero intero maggiore o uguale a logb a. 28. Decidere se due numeri naturali sono coprimi, ossia se non hanno fattori comuni (suggerimento: calcolare il loro minimo comune multiplo e ...). 29. Decidere se un numero naturale è una potenza di 2. 30. Decidere se un dato numero naturale è il fattoriale di un qualche numero. 31. Decidere se un dato numero naturale appartiene alla successione di Fibonacci. 32. Nell’ipotesi di disporre di un esecutore in grado di eseguire le operazioni aritmetiche di addizione e sottrazione, determinare il prodotto fra due numeri naturali. 33. Calcolare la parte intera della radice quadrata di un dato numero naturale; ad esempio, la parte intera della radice quadrata di 15 vale 3; la parte intera della radice quadrata di 16 vale 4. È concesso di operare solo sui numeri naturali, mediante le quattro operazioni aritmetiche fondamentali ed i confronti. 34. Determinare il numero dei divisori di un dato numero naturale positivo. Ad esempio, il numero 40 è divisibile per 1, 2, 4, 5, 8, 10, 20, 40 e pertanto il numero dei suoi divisori è 8. 35. Determinare il numero di divisori propri di un dato numero naturale. Ad esempio il numero dei divisori propri del numero 20 è 5 (1, 2, 4, 5, 10). 36. Decidere se due dati numeri naturali sono coprimi, ossia se non hanno alcun fattore primo in comune. 37. Decidere se un dato numero naturale, considerato in notazione decimale, è palindromo, ossia se si legge indifferentemente da sinistra a destra e da destra a sinistra. Ad esempio, i numeri rappresentati dalle seguenti notazioni decimali sono palindromi: 121, 7337, 39293. Si ipotizzi di disporre di un esecutore in grado di eseguire le quattro operazioni aritmetiche +, −, ∗, /. 38. Si considerino i seguenti due problemi: P1 : Decidere se un punto è interno ad una circonferenza. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 86 CAPITOLO 5. PROBLEMI RISOLTI P2 : Decidere se un segmento è interno ad una circonferenza. Discutere se la soluzione di uno dei due problemi può risultare utile alla soluzione dell’altro. Definire un coerente insieme di operazioni elementari adeguate a risolvere i problemi. Coerentemente con queste ipotesi, risolvere i due problemi. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 Capitolo 6 Soluzioni dei problemi Una grande scoperta risolve un grande problema ma c’è un granello di scoperta nella soluzione di ogni problema. Il tuo problema può essere modesto; ma se esso sfida la tua curiosità e mette in gioco le tue facoltà inventive, e lo risolvi con i tuoi mezzi, puoi sperimentare la tensione e godere del trionfo della scoperta. Questa esperienza ad una età suscettibile può creare un gusto per il lavoro mentale e lasciare un’impronta nella mente e un carattere per tutta la vita. G. Polya, How to solve it In questo capitolo verranno presentate le soluzioni dei problemi proposti al primo capitolo. 87 88 6.1 CAPITOLO 6. SOLUZIONI DEI PROBLEMI UN PERCORSO SUI PONTI DI KÖNISBERG Il problema dei ponti di Könisberg venne preso in considerazione dal famoso matematico Leonhard Euler (Basilea 1707-San Pietrobutgo 1783). Nei suoi scritti Euler affermò che un possibile approccio al problema consiste nell’adottare un procedimento di forza-bruta che consiste nell’elencare tutti i possibili percorsi, determinando così i cammini che soddisfano al problema oppure constatando che non esiste alcun cammino soddisfacente. Lo stesso Euler scartò subito questo approccio per vari motivi: il numero di possibili percorsi è enorme e difficilmente trattabile; inoltre, tale approccio crea delle difficoltà indotte che non sono strettamente connesse con la natura del problema; altro aspetto importante è che sarebbe desiderabile un procedimento generale, non adatto solamente al caso specifico in questione, ma valido per una generica configurazioni di ponti. È evidente che certi aspetti quali la larghezza e la lunghezza dei ponti, la grandezza dell’isola, la distanza fra i ponti sono ininfluenti. Detta in un linguaggio matematico non sono importanti le caratteristiche metriche ma le caratteristiche topologiche. Sulla base di questa osservazione semplificativa, per descrivere la sua soluzione Euler denominò le varie regioni di terra connesse dai ponti con delle lettere A, B, C, D. In questo modo il problema può essere schematizzato con il grafo riportato in figura 6.1, costituito da 4 nodi (le regioni) e 7 archi (i ponti) Figura 6.1: Grafo del problema relativo ai ponti di Könisberg. Ragionando sulla figura 6.1, risulta immediato riconoscere che il numero degli archi collegati ad un dato nodo di passaggio del percorso deve essere un numero pari in quanto il numero di percorsi entranti nel nodo deve essere uguale al numero di percorsi uscenti dal nodo; pertanto si può concludere che un percorso che passi per tutti i ponti e ritorni al punto di partenza non può esistere. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 6.2. ALLA RICERCA DELLA 6.2 √ 2 ALLA RICERCA DELLA √ 89 2 Nell’indagine scientifica, in generale, ci sono due momenti cruciali e strettamente connessi: la definizione dell’oggetto di indagine e la determinazione dello stesso. La fase di definizione viene realizzata specificando delle proprietà caratterizzanti univocamente l’oggetto di indagine, mentre la fase di determinazione consiste nell’attività di ricerca o di costruzione basata su una strategia operativa. In alcuni casi la fase di determinazione viene preceduta dalla dimostrazione di esistenza (in un prefissato insieme) dell’oggetto cercato. In informatica il termine determinare ha una valenza molto specifica: Fissato un contesto ed un insieme di operazioni utilizzabili, descrivere un procedimento risolutivo per generare l’oggetto richiesto. Può trattarsi di un contesto logico popolato da proposizioni e da delle regole per generare delle conclusioni (si tratta del classico meccanismo della dimostrazione matematica); può trattarsi dell’ambiente costituito dal piano geometrico euclideo con le operazioni di costruzioni geometriche con riga e compasso; può trattarsi dell’ambiente aritmetico dei numeri dove sono possibili le quattro operazioni aritmetiche di addizione, sottrazione, moltiplicazione e divisione. Spesso il processo di generazione del risultato viene descritto mediante un algoritmo. √ In questo paragrafo considereremo come oggetto di indagine la 2. Il professore e matematico francese Benoit Rittaud nel capitolo introduttivo del suo libro La favolosa storia della radice quadrata di due dice: La radice quadrata di 2, che vale approssimativamente 1, 414213562, è, secondo la definizione attualmente più in voga, Il numero che, moltiplicato per se stesso, dà 2. È anche La radice del quadrato di dimensioni pari a 2, ovvero la lunghezza del lato di un quadrato di area 2. È questo carattere geometrico che fa di questa radice un punto di partenza, un’origine. Entrambe le definizioni potrebbero farci pensare di avere a che fare con un numero buono solamente a esprimere la soluzione di un problema di geometria per degli studenti cui si chieda di imparare che l’area A di un quadrato di lato a è data dalla formula A = a2 . In realtà, non solo i due aspetti (quello algebrico e quello geometrico) hanno numerosissime conseguenze in direzioni spesso inattese, ma la radice quadrata di 2 ammette ulteriori definizioni, e anche queste danno vita a ramificazioni che si estendono ben oltre il semplice calcolo dell’area di un quadrato. È così che i campi in cui interviene questo numero almeno quattro volte millenario nella storia del pensiero sono di una varietà pressoché infinita. [...] Una prima caratteristica interessante della radice di 2 è che essa rappresenta una porta aperta su interi settori della matematica, sia antica che moderna: la geometria e la teoria dei numeri, ma anche la logica, l’algebra, l’aritmetica, l’analisi e, più recentemente, l’algoritmica, le strutture di dati, i numeri gadici e la dinamica simbolica. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 90 CAPITOLO 6. SOLUZIONI DEI PROBLEMI √ È facile mostrare che una tale 2 non è esprimibile come frazione: un risultato che risale alla scuola pitagorica ed era ben noto a Euclide. Una dimostrazione del risultato pitagorico, citata da Paul Erdös come una delle più belle di tutta la matematica, è riportata a seguire. Dimostrazione. Supponiamo per assurdo che esistano due numeri naturali p e q tali che p 2 p2 2=( ) = 2 q q Possiamo supporre che la frazione sia ridotta, ovvero che p e q siano primi fra di loro. Dalla precedente relazione si ottiene p2 = 2 ⋅ q 2 Ne segue che 2 divide p2 , e quindi p è pari. Quindi p = 2 ⋅ k per qualche k ∈ N. Di conseguenza otteniamo: 2 ⋅ k2 = q2 Allora anche q è pari, in contraddizione con il √ fatto che p e q siano coprimi. Dunque deve essere falsa l’ipotesi iniziale, cioè 2 non può essere razionale. √ Dimostrato che 2 non può essere un numero razionale, si tratta ora di accertarsi che tale numero esiste fra i numeri reali. Ciò è garantito dal seguente √ TEOREMA 1 (Esistenza di 2). Nell’insieme dei numeri reali R esiste la radice quadrata di 2, cioè un numero positivo il cui quadrato è esattamente 2. La dimostrazione di questo teorema, che qui non viene riportata, può essere basata usando soltanto le quattro operazioni e i principi fondamentali dell’ordinamento di R. √ La 2 ha anche una semplice definizione geometrica: è la lunghezza della diagonale del quadrato di lato unitario. Questa lineare definizione ed il corrispondente metodo di costruzione con riga e compasso fa intuire che questo numero si trova più a suo agio in ambito geometrico. I greci traducevano i numeri in ambito geometrico, mediante segmenti la cui lunghezza rappresentava il numero stesso; in particolare determinare un numero significava costruire√ un segmento la cui lunghezza era il numero. In tale contesto, determinare 2 significava costruire con riga e compasso un √ segmento di lunghezza 2 a partire da un segmento di lunghezza unitaria. La figura 6.2 descrive una costruzione L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 6.2. ALLA RICERCA DELLA √ 2 Figura 6.2: La costruzione di un segmento di lunghezza segmento di lunghezza unitaria AB. 91 √ 2 a partire dal I babilonesi, usando √ un sistema di numerazione in base 60 diedero una approssimazione di 2, tramite 24 51 10 1+ + 2 + 3 ≈ 1, 414213562373095... 60 60 60 Un’altra approssimazione di questo numero è quella data da un antico testo matematico indiano, il Sulbasutras, che cita: Aumenta la lunghezza [del lato] della sua terza parte, poi aggiungi la sua dodicesima parte, infine sottrai un trentaquattresimo della sua dodicesima parte. Tradotta numericamente, questa approssimazione diventa 1 1 1 577 1+ + − = ≈ 1.414215686 3 12 12 ⋅ 34 408 √ Esiste una gran quantità di algoritmi atti a calcolare le cifre di 2. Uno dei più usati dai calcolatori è un antico metodo babilonese descritto di seguito. Adottando la definizione stessa, si tratta di trovare la soluzione dell’equazione x2 = 2. Tale equazione può essere scritta nella forma x = 2/x. Se x0 non è la soluzione esatta di questa equazione ma una sua approssimazione, allora i due valori x0 e 2/x0 saranno delle approssimazioni, una per difetto e l’altra per eccesso. La soluzione effettiva sarà quindi compresa fra questi due valori. La media fra questi due valori vale 1 2 x1 = (x0 + ) 2 x0 e costituirà quindi un’approssimazione migliore. Generalizzando, si può generare una successione di numeri x0 , x1 , . . . , xn , . . . mediante le relazioni x0 = valore 2 1 xn+1 = (xn + ) 2 xn L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 92 CAPITOLO 6. SOLUZIONI DEI PROBLEMI dove valore è una generica approssimazione iniziale, ad esempio 1. Tale √ successione converge a 2. Notiamo che, se x0 è un numero razionale, tutti i valori della successione {xi } sono numeri razionali. La tabella 6.1 riporta il processo di generazione di alcuni termini della successione. La successione converge con velocità quadratica, ossia il numero di decimali corretti raddoppia ad ogni iterazione. Il suo valore approssimato a quaranta cifre decimali è: 1, 4142135623730950488016887242096980785696... n 0 1 2 3 4 xn 1 1.5 1.4166666666666 1.41421568627451 1.41421356237469 √ Tabella 6.1: Valori della successione per il calcolo di 2 mediante il metodo babilonese; in grassetto sono evidenziate le cifre corrette. Maggiore è il numero di iterazioni, migliore sarà la precisione del risultato. Nel febbraio 2006 utilizzando questo metodo sono state calcolati 200 miliardi di cifre in 13 giorni e 14 ore. Tra le costanti matematiche irrazionali non periodiche, √ solo π è stata calcolata con maggior precisione. La 2 può essere calcolata anche mediante strumenti e metodi dell’Algebra e dell’Analisi. Ad esempio può essere espressa tramite frazione continua è √ 2=1+ 1 1 2+ 2+ 1 2+ . 1 ⋱ Rappresentazioni tramite prodotti infiniti delle funzioni seno e coseno consentono di ricavare formule quali le seguenti: √ ∞ (4k + 2)2 2 ⋅ 2 6 ⋅ 6 10 ⋅ 10 14 ⋅ 14 =( )( )( )( )⋯ 1⋅3 5⋅7 9 ⋅ 11 13 ⋅ 15 k=0 (4k + 1)(4k + 3) 2=∏ ∞ √ 2 = ∏ (1 + k=0 1 1 1 1 1 1 ) (1 − ) = (1 + ) (1 − ) (1 + ) (1 − ) ⋯ 4k + 1 4k + 3 1 3 5 7 L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 6.3. IL PROBLEMA DELLE 8 REGINE 6.3 93 IL PROBLEMA DELLE 8 REGINE Il problema delle 8 regine consiste nel determinare le configurazioni di 8 regine disposte su un’usuale scacchiera in modo tale che nessuna regina sia attaccata da qualche altra; in altri termini, le 8 regine devono trovarsi su righe, su colonne e su diagonali distinte. Una configurazione che contenga 8 regine si dirà completa, altrimenti incompleta; una configurazione (completa o incompleta) sarà detta ammissibile se le regine soddisfano ai vincoli sopra esposti; una configurazione completa ed ammissibile sarà chiamata soluzione 1 ; è ovvio che una configurazione ammissibile incompleta è potenzialmente estendibile in una soluzione. Una soluzione del problema delle 8 regine è descritta nella figura 6.3. Q Q Q Q Q Q Q Q Figura 6.3: Una soluzione del problema delle 8 regine. In generale il problema delle 8 regine può essere risolto adottando diverse strategie: • strategia analitica: consiste nel generare direttamente tutte e sole le configurazioni complete ammissibili; purtroppo per il problema delle 8 regine non si è (ancora?) riusciti ad individuare un procedimento risolutivo analitico. • strategia enumerativa: consiste nel generare direttamente tutte le configurazioni complete e valutare se ciascuna di esse sia ammissibile; relativamente al problema proposto, tale strategia risulta teoricamente applicabile ma in pratica intrattabile in quanto le possibili disposizioni 1 Qui il termine soluzione viene usato con significato diverso dal solito: viene inteso come risultato e non come procedimento risolutivo. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 94 CAPITOLO 6. SOLUZIONI DEI PROBLEMI di 8 regine su una scacchiera di 64 caselle sono pari al binomiale di 64 su 8, che è un numero intrattabile. • strategia di backtracking: consiste nel generare dinamicamente, disponendo sulla scacchiera una regina alla volta, le varie configurazioni, abbandonando subito una strada quando ci si accorge che essa non può portare ad una soluzione. Nelle figure che seguono (figura 6.4) è descritto il procedimento di ricerca della prima soluzione nel caso di una scacchiera di dimensione 4, adottando una strategia di backtracking. Q ○ ○ ○ ○ Q ○ ○ Q (a) Q ○ ○ Q ○ ○ ○ Q (e) Q (i) Q × Q (b) (c) × × Q (f ) (l) (d) × Q ○ Q ○ ○ Q Q Q (g) (h) Q ○ ○ Q Q Q Q Q (m) Q (n) Figura 6.4: Procedimento risolutivo per una scacchiera 4 × 4; con Q viene indicata una regina posizionata, con × viene indicata una regina da rimuovere perchè si è giunti ad una configurazione non più estendibile e con ○ viene indicato un tentativo di posizionamento su una casella minacciata. Dal punto di vista della programmazione, il procedimento risolutivo suggerito nella figura 6.4, può essere impostato mediante una procedura ricorsiva L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 6.3. IL PROBLEMA DELLE 8 REGINE 95 che assume che un certo numero di regine siano già state collocate correttamente; senza perdere in generalità si può assumere che le regine siano state disposte nelle prime colonne; tale procedura dovrà generare tutte le soluzioni ottenibili come estensione della configurazione ammissibile incompleta attuale; indicando con j il numero della prossima regina che dovrà essere posta sulla scacchiera, alla riga i (da determinarsi) ed alla colonna j (stabilita), indicheremo tale procedura con genera(j). Il procedimento completo che genera tutte le possibili soluzioni viene innescato dalla chiamata genera(1) che partirà dalla situazione iniziale di scacchiera vuota. configurazione incompleta ammissibile ⋆ i j Figura 6.5: Schema del procedimento risolutivo per il problema delle 8 regine. Algoritmo 24 - Genera(j) 1: # generazione delle configurazioni complete ed ammissibili, 2: # assumendo che j − 1 regine siano già state collocate 3: # nelle prime j − 1 colonne 4: for tutte le righe i da 1 a N do 5: if la posizione (i, j) è sicura then 6: posiziona la regina in (i, j) 7: if la scacchiera è completa then 8: si è ottenuta una soluzione 9: else 10: genera(j + 1) 11: end if 12: togli la regina dalla posizione (i, j) 13: end if 14: end for L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 96 CAPITOLO 6. SOLUZIONI DEI PROBLEMI 6.4 IL MASSIMO COMUNE DIVISORE Direttamente dalla definizione di massimo comune divisore può essere ricavato un algoritmo per la determinazione del massimo comune divisore fra due numeri naturali m e n (algoritmo 25). Algoritmo 25 - Calcolo del massimo comune divisore fra due numeri naturali Input: numeri naturali m e n Output: massimo comune divisore fra m ed n 1: costruisci l’insieme M dei divisori di m 2: costruisci l’insieme N dei divisori di n 3: costruisci l’insieme intersezione P = M ∩ N 4: determina il massimo p dell’insieme P 5: return p Per questo algoritmo le capacità richieste all’esecutore consistono nel • determinare l’insieme dei divisori di un numero naturale • determinare l’insieme intersezione di due insiemi dati • determinare il massimo di un insieme di numeri Questo algoritmo risulta di scarsa utilità per essere eseguito su un calcolatore in quanto richiede delle operazioni molto onerose dal punto di vista dell’esecuzione, in particolare il calcolo degli insiemi dei divisori dei due numeri. Un altro algoritmo risolutivo, funzionalmente equivalente al precedente, solitamente riportato sui testi elementari di aritmetica, può essere descritto come riportato nell’algoritmo 26. Algoritmo 26 - Calcolo del massimo comune divisore fra due numeri naturali Input: numeri naturali m e n Output: massimo comune divisore fra m ed n 1: scomponi m in fattori primi 2: scomponi n in fattori primi 3: considera solo i fattori comuni 4: fra i fattori comuni scegli quelli con esponente minore 5: determina il prodotto p fra questi fattori 6: return p Tale algoritmo richiede che l’esecutore possieda le capacità di L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 6.4. IL MASSIMO COMUNE DIVISORE 97 • scomporre un numero in fattori primi • selezionare i fattori desiderati • eseguire il prodotto di più fattori L’aspetto più penalizzante consiste nel fatto che questo algoritmo richiede la scomposizione di m ed n in fattori primi; poiché attualmente non si conoscono degli efficienti metodi per la scomposizione in fattori primi, anche tale algoritmo risulta di scarsa utilità. Nei due precedenti gli algoritmi le capacità richieste all’esecutore sono abbastanza complesse e mal si adattano all’uso di un calcolatore. Un algoritmo alternativo che richiede all’esecutore delle semplici capacità di calcolo, e che, pertanto, si presta ad essere facilmente eseguito da un calcolatore è stato ideato da Euclide ancora nel IV sec. a.C. e descritto per la prima volta nel Libro VII, Proposizione 2 degli Elementi di Euclide. Da degli studi storici si è propensi comunque a ritenere che questo metodo fosse noto almeno due secoli prima di Euclide e certamente era noto ad Eudosso attorno al 375 a.C.. Si è accertato inoltre che tale metodo era noto indipendentemente anche dagli antichi cinesi. Tale algoritmo evita il ricorso alla scomposizione in fattori e richiede all’esecutore delle capacità più elementari di quelle richieste dai due algoritmi presentati precedentemente. Nel testo di Euclide l’algoritmo è formulato in modo diverso da come compare usualmente sui testi attuali in quanto i greci non consideravano l’unità come un divisore di un numero, ed inoltre, al tempo, lo zero non era ancora noto. Tale algoritmo si fonda sulle seguenti proprietà del massimo comune divisore: mcd[m, 0] = m mcd[m, n] = mcd[n, m%n] L’algoritmo derivato da queste proprietà, anche se con qualche variazione rispetto all’originale, è descritto mediante la tavola di traccia riportata nella figura 6.6, relativa al caso m = 16, n = 42. L’algoritmo sotteso da questa tavola di traccia può essere espresso mediante l’algoritmo 27. Il procedimento appena descritto costituisce un algoritmo effettivo se l’esecutore al quale è rivolto possiede le capacità indicate nel testo del procedimento stesso. Per rendere più istruttivo l’esempio, supponiamo che l’esecutore non sappia valutare il resto della divisione intera, bensì sappia applicare solo le quattro operazioni (addizione, sottrazione, moltiplicazione, divisione). In tale ipotesi, per rendere effettivo l’algoritmo è sufficiente tradurre ed esprimere le azioni non eseguibili dall’esecutore in termini delle azioni effettivamente L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 98 CAPITOLO 6. SOLUZIONI DEI PROBLEMI m 16 42 16 10 6 4 2 n 42 16 10 6 4 2 0 m%n 16 10 6 4 2 0 Figura 6.6: Tavola di traccia dell’algoritmo di Euclide. Algoritmo 27 - Algoritmo di Euclide per il calcolo del mcd[m, n] Input: numeri naturali m e n Output: massimo comune divisore fra m e n 1: while n ≠ 0 do 2: r ← m%n 3: m←n 4: n←r 5: end while 6: return m eseguibili. L’istruzione r ← m%n può essere espressa mediante le istruzioni (effettivamente eseguibili) riportate nell’algoritmo 28. Algoritmo 28 - Calcolo del resto r della divisione m/n Input: numeri naturali m e n Output: resto r della divisione intera fra m e n 1: d ← m/n 2: p ← d ∗ n 3: r ← m − p Nel caso l’esecutore abbia le capacità di eseguire solo l’addizione e la sottrazione, l’algoritmo effettivo sarebbe ancora più lungo. Viene lasciato per esercizio. L’algoritmo di Euclide evidenzia che è possibile organizzare fra loro in modo complesso delle azioni molto elementari per eseguire delle azioni equivalenti che richiederebbero delle capacità più elevate. È proprio quello che si intende fare con i programmi per i calcolatori. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 6.5. LA SCACCHIERA MUTILATA 6.5 99 LA SCACCHIERA MUTILATA Il problema della scacchiera mutilata può essere risolto dimostrando che non è possibile le 31 tessere del domino in modo tale che ricoprano la scacchiera mutilata. Tale risultato viene ottenuto mediante un tipico esempio di ragionamento esterno al contesto. La dimostrazione che segue è generalizzata al caso di una scacchiera quadrata di n caselle per lato. Dimostrazione. Se n è dispari la risposta è negativa e facilmente motivabile in quanto n2 − 2 è un numero dispari. Nel caso di n pari, ragionando internamente al sistema una soluzione potrebbe essere trovata cercando delle possibili disposizioni dei tasselli oppure rispondendo negativamente al quesito posto dal problema qualora nessuno di tutti i possibili tappezzamenti conduca al successo. Ovviamente, tale strategia risulta difficilmente applicabile ed inoltre mal si presta ad individuare un metodo generale valido per ogni valore n del numero di quadretti su ogni lato del reticolo. Risulta dunque spontaneo tentare di trovare delle soluzioni al problema ragionando fuori del sistema. L’idea base, che costituirà la linea di appoggio per la soluzione, consiste nel considerare il quadrato reticolato come fosse una scacchiera avente i quadretti alternativamente bianchi e neri. È evidente allora, con quest’artificio, che i quadretti angolari tolti dal reticolo hanno uno stesso colore in quanto appartengono ad una stessa diagonale. La conclusione immediata che ne deriva è: la scacchiera privata di due caselle agli angoli opposti non può essere ricoperta con delle tessere da domino poiché tali tessere ricoprono sempre un numero uguale di caselle bianche e nere, in quanto ogni tessera, comunque disposta sulla scacchiera, ricopre sempre un quadrato bianco ed uno nero. Il problema posto si può naturalmente generalizzare ammettendo delle tessere da domino che coprono un numero pari di quadrati bianchi e neri, come ad esempio i seguenti: Anche ammettendo delle combinazioni e la possibilità di ribaltamenti di queste forme, il problema sopra proposto non ammette soluzione. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 100 CAPITOLO 6. SOLUZIONI DEI PROBLEMI 6.6 NESSUNA STRADA PORTA A MU A seguire è riportata la soluzione, in negativo, del problema del sistema MU proposto alla fine del primo capitolo. Anche in questo caso viene applicato un tipico ragionamento esterno al sistema. La dimostrazione può essere sviluppata come segue. La configurazione MU non contiene I. Quindi, nella generazione delle configurazioni, si devono applicare delle regole che eliminano la I di MI. Le regole che modificano il numero di I sono la (b) e la (c). La (b) raddoppia il numero delle I, mentre la (c) permette di eliminare le I di un multiplo di 3. Poichè queste due regole non modificano la divisibilità per 3 del numero di I, partendo da una I, si conclude che nessuna combinazione delle regole (b) e (c) può eliminare la I della configurazione iniziale MI. 6.7 ESERCIZI 1. Scrivere un algoritmo per il calcolo di nese descritto nel paragrafo 6.2. √ 2 basandosi sul metodo babilo- 2. Scrivere un algoritmo corrispondente alla seguente espressione della mediante una frazione continua: √ √ 2 1 2=1+ 1 2+ 2+ 1 2+ 1 ⋱ . √ 3. Scrivere degli algoritmi per il calcolo di 2 basati sulle rappresentazioni mediante prodotti descritti alla fine del paragrafo 6.2. 4. Discutere se la seguente affermazione è vera: Data una soluzione del problema delle regine per un dato n, eliminando la riga e la colonna contenente una data regina si ottiene una soluzione del problema per n − 1 regine. 5. Dimostrare che l’algoritmo 24 per la soluzione del problema delle n regine, fornisce tutte le soluzioni. Determinare la massima profondità di ricorsione dell’algoritmo. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014 6.7. ESERCIZI 101 6. Il Problema del giro del cavallo degli scacchi consiste nel passare su tutte le caselle di una scacchiera muovendo un cavallo secondo le regole degli scacchi, senza passare su una casella visitata precedentemente. Scrivere un algoritmo che risolva il Problema del giro del cavallo degli scacchi. 7. Dimostrare che una scacchiera quadrata alla quale vengono tolte 2 caselle (ovunque poste) non può essere ricoperta con tessere di area uguale a 3 unità. Quelle che seguono sono le uniche forme distinte (a meno di rotazioni e di ribaltamenti). Suggerimento: è sufficiente dimostrare che n2 − 2 non è divisibile per 3. Qui il ragionamento fuori del sistema porta ad una conclusione più forte di quanto sarebbe stato necessario. Non vale il viceversa, ossia se un numero è divisibile per 3 non è detto che sia ricopribile con domini di 3 quadrati. 8. Dimostrare che una scacchiera quadrata avente n = 2k caselle per lato (n = 4, 8, 16, . . . ) alla quale viene tolta una casella d’angolo, è sempre ricopribile con tessere di 3 caselle ciascuna, disposte a forma di L. 9. Stabilire se le seguenti figure sono disegnabili con un unico percorso, senza alzare la penna dal foglio e senza ripassare su un tratto già disegnato. In caso affermativo, descrivere il percorso. Corrispondentemente a ciascuna delle scomposizioni individuate, descrivere un algoritmo per disegnare la figura. L. Calvi - Quaderni di Informatica - Problem Solving - Feltre - 2014