E solo questione di metodo: problemi e algoritmi di matematica elementare Progetto Lauree Scientifiche Scuola Estiva di Matematica (4092015) Stefano Finzi Vita Dipartimento di Matematica - Sapienza Università di Roma Collaborano: Cecilia Andreotti, Antonio Fanelli e Andrea Minotti Per risolvere un problema matematico è opportuno analizzarlo a fondo alla ricerca del punto migliore da cui attaccarlo, riscrivendolo magari in modo diverso, scomponendolo, usando la logica delle implicazioni per trasformarlo in una sequenza di passaggi più semplici, fino a trovare una soluzione accettabile In genere non esisterà un unica strada per arrivarci, e si può sempre migliorare quella già trovata per renderla più efficiente Se poi il tutto dovrà essere eseguito da un computer, che può fare milioni di operazioni in pochi secondi ma va istruito in modo opportuno, ecco che la scelta di un metodo efficace diventa essenziale Qui ci occuperemo di problemi elementari che hanno a che fare essenzialmente coi numeri, cercando per ognuno di essi di arrivare ad un algoritmo risolutivo In qualche caso confronteremo più algoritmi per lo stesso problema, al fine di valutarne la convenienza (contando ad esempio il numero di operazioni necessarie effettuate), perché mai come in questo caso il tempo (di calcolo) è denaro Ci occuperemo inoltre di un altro aspetto cruciale che non può essere trascurato lavorando con un computer Noi siamo abituati a ragionare nell insieme dei numeri reali, sfruttandone le proprietà di continuità e illimitatezza Nella memoria di un computer di numeri ne sono rappresentabili solo un numero finito (li chiameremo i numeri macchina), e l algebra di questi numeri è molto diversa da quella abituale, così che possono diventare false alcune ovvie identità matematiche, con effetti a volte disastrosi nella risoluzione dei problemi Comprendere questi fenomeni è fondamentale per costruire algoritmi veramente efficaci 1 Somme, prodotti e potenze Le operazioni più semplici di tutte sono somme e moltiplicazioni Proprio perché le più usate, e in genere su grandi quantità di dati, è importante che siano fatte nel modo più efficiente Una situazione frequente è che ci si trovi a sommare o moltiplicare tra loro diverse quantità indicizzate: somma = n a i = a 1 + a 2 + + a n ; prodotto = i=1 n b i = b 1 b 2 b n i=1 Lo strumento ideale in entrambi i casi (pensando al computer che dovrà fare i conti per noi) è un ciclo attraverso il quale accumulare tali quantità in una variabile opportuna (che andrà inizializzata a zero nel primo caso, a uno nel secondo) Ecco gli schemi (o pseudocodici) corrispondenti: 1) somma = 0; per i = 1,, n calcola: somma = somma + a i 2) prodotto = 1; per i = 1,, n calcola: prodotto = prodotto b i In qualche caso la matematica potrà venirci incontro per risparmiare calcoli E nota la formula (attribuita al giovane Gauss): n(n + 1) 1 + 2 + + n = 2 1
che ci consente di sommare i primi n numeri interi mediante solo due operazioni, un prodotto e una divisione Questa formula ci sarà utile in seguito anche per valutare la complessità degli algoritmi A partire dall algoritmo del prodotto ricaviamo subito quello della potenza intera di un numero q Infatti q n = q q q, e rientriamo nello schema precedente: dato q, pot=1; per i=1,,n calcola: pot=pot*q Stavolta l indice i non compare nelle espressioni da calcolare, ma serve solo a contare il numero dei fattori in gioco, tutti uguali tra loro Misuriamoci con un paio di esempi dove confrontare approcci diversi Esercizio 1 Sia q un numero reale assegnato; siamo interessati alla quantità: S n (q) = 1 + q + q 2 + + q n = n q i, cioè alla somma dei primi n termini della progressione geometrica di ragione q (i) Contare quante operazioni sono necessarie per calcolare S n (q) (in funzione di n) eseguendo i calcoli così come sono scritti (ii) Sapreste trovare un altra strada per ottenere lo stesso risultato con soli n prodotti e n somme? (iii) Una nota formula matematica potrebbe ridurre ulteriormente il calcolo a n prodotti, un quoziente e due somme Qualcuno la ricorda? Esercizio 2 Supponiamo di dover valutare in un punto x = x un polinomio di grado n i=0 p n (x) = a 0 + a 1 x + a 2 x 2 + + a n x n (i) Quante operazioni (somme e prodotti) sono necessarie per calcolare p n ( x)? (ii) Provate ora a riscrivere il polinomio in un altro modo: p n (x) = a 0 + x(a 1 + x(a 2 + x(a 3 + (a n 1 + a n x))) ed eseguite il calcolo dall interno all esterno delle parentesi: dato x = x; s = a n ; per i = 1,, n calcola: s = s x + a n i E l algoritmo di Horner, molto noto in Analisi numerica e particolarmente utile quando in un problema occorrono molte valutazioni polinomiali Quanti sono ora i prodotti effettuati? (iii) Calcolate il valore di p 5 (2) mediante l algoritmo di Horner per il polinomio p 5 (x) = 3x 5 2x 4 +x 2 4x+1 2 Pari e dispari, divisori, multipli Sappiamo tutti riconoscere istantaneamente se un numero intero n è pari o dispari Ma come può farlo un computer? Possiamo ricorrere al valore del resto della divisione (intera) di n per 2 Se tale resto varrà 0 il numero sarà pari, altrimenti dispari Con variabili intere, il quoziente di due interi sarà un intero, e quindi: se (n/2)*2=n --> n pari; altrimenti n dispari; Ad esempio, per n = 6 avremo n/2 = 3 e 3 2 = 6 = n Invece per n = 7 si avrà n/2 = 3 (!) e quindi 3 2 = 6 n Più in generale un numero intero a sarà un multiplo di un altro numero b (o, il che è lo stesso, b sarà un divisore di a) se la divisione di a per b dà resto zero Il resto della divisione tra interi è anche alla base della suddivisione dei numeri interi in classi resto modulo n mediante la seguente relazione di equivalenza: a b mod n (a congruo b modulo n) (a b) è multiplo di n 2
Se a e b sono entrambi positivi, la definizione precedente equivale ad affermare che i due numeri divisi per n danno lo stesso resto Questa relazione suddivide tutto l insieme dei numeri interi in esattamente n classi di equivalenza, in base al valore del resto della divisione per n: [0], [1], [2],, [n 1] Ad esempio se n = 2 le 2 classi di equivalenza coincideranno con l insieme dei numeri pari (la classe [0]) e quello dei numeri dispari (la classe [1]) Oppure se n = 5, la classe [3] mod 5 sarà ad esempio l insieme [3] = {3, 8, 13, 18,, 2, 7, 12, } 21 Massimo comun divisore e minimo comune multiplo Le note formule apprese a scuola per il calcolo di MCD e mcm di due numeri interi a e b si basano sulla preventiva scomposizione di entrambi i numeri in fattori primi: nel primo caso si parlava di prendere tutti i fattori comuni col minimo esponente, nel secondo di prendere tutti i fattori comuni e non comuni col massimo esponente Questo approccio non è in generale conveniente perché costoso Vediamo come possiamo calcolare il MCD senza scomporre i due numeri, e come questo ci fornisca facilmente anche il mcm Algoritmo 1 per il MCD (Sottrazioni successive) Se due numeri a e b (con per esempio 0 < a < b) sono entrambi divisibili per un intero d, lo sarà anche la loro differenza b a Allora: MCD(b, a) = MCD(b a, a) e si ripete il ragionamento a partire da numeri più piccoli finché uno dei due numeri diventa zero Ad esempio: MCD(60, 18) = MCD(42, 18) = MCD(24, 18) = MCD(18, 6) = MCD(12, 6) = MCD(6, 6) = MCD(6, 0) Se assumiamo per convenzione MCD(n, 0) = n, 6 sarà il valore cercato L algoritmo è dunque: dati 0<a<b, ripeti: { r=b-a; se r=0 mcd=a; altrimenti se (r<a) poni b=a; a=r; altrimenti poni b=r } finche (r>0) Questo algoritmo potrebbe essere molto lento: se i due numeri fossero ad esempio 900 e 15, servirebbero ben 60 passaggi per concludere che 15 è proprio il loro MCD, come era subito determinabile dal fatto che si tratta di un divisore di 900 Seguiamo quindi un altra strada Algoritmo 2 per il MCD (Divisioni successive) Se due numeri a e b (sempre con 0 < a < b) sono entrambi divisibili per un intero d, lo sarà anche il resto r della divisione di b per a (b = a q + r, con 0 r < a) In particolare, se r = 0 allora MCD(b, a) = a, altrimenti MCD(b, a) = MCD(a, r) e possiamo ripetere il ragionamento a partire da numeri più piccoli finché non si perviene anche in questo caso alla situazione MCD(s, 0) = s Nell esempio precedente si avrebbe ora: Quindi l algoritmo diventa: dati 0<a<b; ripeti: {r=b-a*(b/a); se r non e 0 poni b=a; a=r; altrimenti mcd=a;} finche (r>0) MCD(60, 18) = MCD(18, 6) = MCD(6, 0) = 6 3
Algoritmo per il mcm Vale la seguente formula: ( ) mcm(a, b) = (a b)/mcd(a, b) Esercizio 3 Le classi resto mod p ci possono essere utili ad esempio per stampare una lista di numeri a gruppi di p (cioè p per riga), come nel caso di una tabella Ad esempio sapreste scrivere uno pseudocodice per stampare i numeri interi da 1 a 25 su 5 righe? Esercizio 4 Dimostrare la formula (*) Esercizio 5 Calcolare mediante gli Algoritmi 1 e 2 il MCD dei numeri 6510 e 5880 3 L algebra dei numeri macchina e le sue conseguenze 31 La rappresentazione dei numeri: il caso continuo Ogni numero reale può essere rappresentato come un numero decimale illimitato: dove n Z, a i = 0, 1,, 9 In particolare: x = na 1 a 2 a k = n + a 1 10 + a 2 10 2 + + a k 10 k + periodici razionali : 2(00000), 35(00000), 06, 702428 non periodici irrazionali : 2, 3, π, e Ogni numero reale x può essere approssimato (con precisione arbitraria) mediante un numero razionale x [densità di Q in R] e la retta reale non ha buchi [continuità dei numeri reali] Definiremo: errore assoluto: e A (x) = x x, errore relativo: e R (x) = x x x troncamento (arrotondamento per difetto) di x a k cifre: = e A x x (k) = na 1 a 2 a k arrotondamento per eccesso di x a k cifre: x (k) = na 1 a 2 (a k + 1) = x (k) + 10 k arrotondamento di x alla k-ma cifra : f l k (x) = x (k) se a k+1 < 5; f l k (x) = x (k) se a k+1 5 x (k) x < x (k), x x (k) < 10 k, x x (k) < 10 k, x f l k (x) < 05 10 k Per operare con i numeri decimali è spesso comodo rappresentarli in una forma normalizzata che ne mette in risalto l ordine di grandezza, la rappresentazione in virgola mobile: x = ±m 10 z = (±m, z), 01 m < 1, z Z con m = mantissa, z = esponente La corrispondenza x (m, z) è unica Esempi: 9 (09, 1), 12381471 ( 012381471, 3), 00000715 (0715, 4) 32 La memoria del computer e i numeri macchina I computer elaborano le informazioni (istruzioni e dati) in formato digitale L unità di informazione binaria è il bit (binary digit) che può assumere solo i valori 0 o 1 I mattoni fondamentali (le celle di memoria) sono i byte, sequenze di 8 bit scritte o lette per intero con un unica operazione Un numero verrà quindi rappresentato attraverso la sua espressione in base due, usando in genere 2, 4 o 8 byte (dipende dal tipo, intero o reale, e dalla precisione desiderata) I reali in particolare saranno memorizzati in virgola mobile, con un numero fissato di cifre rappresentative per la mantissa e l esponente, che dipendono dalla macchina utilizzata Se chiamiamo A l insieme dei numeri rappresentabili, avendo a disposizione k cifre per la mantissa e j per l esponente, allora non apparterranno ad A i numeri: 4
irrazionali (decimali illimitati non periodici) decimali periodici (periodo diverso da zero) decimali finiti con più di k cifre significative per la mantissa in modulo maggiori di M (massimo numero macchina) [overflow] in modulo minori di m (minimo numero macchina positivo, o zero macchina) [underflow] Il nostro insieme A è dunque un colabrodo, e tutti i numeri che non sono in A vanno approssimati per arrotondamento con il più vicino numero macchina Per capire come stanno le cose ragioniamo d ora in avanti su di un esempio semplificato, una sorta di computer giocattolo che però riproduce fedelmente il tipo di limitazioni del caso reale e le sue conseguenze: TOY COMPUTER Supponiamo di avere a disposizione solo TRE cifre per la mantissa e UNA per l esponente (per comodità ragioniamo in base 10 con solo numeri positivi) Allora se x A: x = 0a 1 a 2 a 3 10 ±e = (a 1 a 2 a 3, ±e), a 1 0 Esercizio 6 Indicare in questo caso chi sono M e lo zero macchina m Esercizio 7 Dire quali dei seguenti numeri appartengono all insieme A dell esempio giocattolo e quali no Per ognuno scrivere la sua rappresentazione come numero macchina (arrotondando quando necessario): 0000715, 127, 2, 1/3, 39210, 10 8, 2175, 10 9, 700000000, 10 11 Vediamo un po di conseguenze (a volte drammatiche!) del fatto di lavorare nell insieme A L insieme A non è chiuso rispetto alle operazioni elementari: x, y A non implica x + y, x y, xy, x/y A Esercizio 8 Eseguire nel computer giocattolo i seguenti calcoli Per ognuno scrivere la rappresentazione dei numeri in ingresso (appartenenti ad A) e quella del risultato rappresentabile in A, ragionando sulla sua correttezza: 823 + 195; 134 275; 4 5 10 8 ; 1000/32; Le operazioni non rispettano sempre le proprietà di cui godono tra i reali (associativa, distributiva, ecc) Esercizio 9 Controllare che per a = 1, b = 0005 e c = 0007 non vale (a + b) + c = a + (b + c); analogamente per a = 3, b = 815 e c = 521 mostrare che non vale a (b c) = a b a c In entrambi i casi qual è la sequenza che fornisce il risultato migliore? L elemento neutro della somma non è unico: x + y = x non implica y = 0 Lo zero macchina ci dice qual è il primo numero rappresentabile a destra dello zero, quindi ci dà un idea della solitudine del numero zero, e grazie alla rappresentazione in virgola mobile può davvero essere molto piccolo: le cifre significative del numero possono infatti scorrere liberamente verso destra giocando sull esponente Chiameremo invece precisione macchina il più piccolo numero positivo ε tale che 1 + ε > 1 Essa ci dà quindi la misura della solitudine del numero uno, cioè della taglia dei buchi più grandi del nostro colabrodo, indicando lo spazio vuoto che c è tra un numero intero non nullo e il successivo numero rappresentabile: poichè stavolta non possiamo perdere la prima cifra significativa relativa all unità, agire sull esponente non ci aiuterà molto In genere, se b indica la base utilizzata e k il numero di cifre a disposizione per la mantissa, vale ε = b 1 k Esercizio 10 Calcolare nel nostro esempio la precisione macchina ε e confrontarla con lo zero macchina Indicare un numero macchina y minore di ε tale che 1 + y = 1 5
Fenomeni di propagazione dell errore: quando x e y sono due numeri positivi molto vicini tra loro, anche se gli errori relativi e R (x), e R (y) sono piccoli può risultare e R (x y) molto grande In altre parole sottrarre tra loro numeri quasi uguali provoca la perdita di cifre significative del risultato, compromettendo i nostri calcoli Esercizio 11 (Due successioni o una?) Considerate le due successioni numeriche a k = k + 1 k, b k = 1 k + 1 + k (i) Dimostrate che sono matematicamente equivalenti (ii) Al crescere di k a quale valore tenderanno? (iii) Nel nostro esempio giocattolo calcolate con le cifre a disposizione i valori di a 90 e b 90 (tenendo conto che 91 = 95394 e 90 = 94868) Quale vi sembra la formula più affidabile? Esercizio 12 (Il numero di Nepero) Il numero di Nepero e = 2718281828458 viene in genere introdotto come il limite della successione monotona crescente ( a n = 1 + n) 1 n Si potrebbe pensare quindi di utilizzare questa successione per approssimarlo dal basso fino ad una precisione desiderata La cosa purtroppo non funziona affatto Infatti la crescita è molto lenta (per n = 10 milioni si troverebbero appena 6 cifre esatte del numero) Ma soprattutto per valori di n troppo grandi si osserva che la successione smette di essere monotona per poi convergere (!) al numero 1 In altre parole da un certo n in poi a n = 1 Sapete spiegare il perché? Nel nostro computer giocattolo, da quale valore di n in poi succederebbe? Le equazioni di secondo grado Tutti ricordano come si risolve un equazione di secondo grado: ax 2 + bx + c = 0 Ecco lo pseudocodice di una possibile procedura per la sua risoluzione (limitandoci al solo caso delle soluzioni reali distinte): 1 Leggi a, b, c e calcola = b 2 4ac 2 Se > 0, poni: x 1 = b, x 2 = b+ Tutto bene, se non che abbiamo scoperto nel paragrafo sui numeri macchina che certe operazioni sono potenzialmente pericolose, in particolare le sottrazioni tra quantità quasi uguali possono portare alla cancellazione di cifre significative del risultato Esercizio 13 Nel nostro giocattolo assumiamo a = 0005, b = c = 1 Calcolare in A le due soluzioni con l algoritmo precedente e il loro residuo (per residuo r(z) intendiamo il valore dell espressione az 2 + bz + c, che ci dà un idea di quanto la soluzione trovata soddisfi l equazione di partenza; ovviamente in aritmetica esatta il residuo sarebbe zero) Risolviamo ora il problema ricorrendo ad altre formule, matematicamente equivalenti Vale infatti: b ± = b ± b b = 2c b dove quando nella prima formula scegliamo il segno +, nella seconda prenderemo quello -, e viceversa Esercizio 14 Calcolare in A le due soluzioni dell esercizio precedente ma con le nuove formule Confrontare i risultati e i relativi residui Un algoritmo più affidabile per le equazioni di secondo grado dovrebbe quindi ricorrere a una formula o all altra, in base al segno di b Ecco come andrebbe modificato lo pseudocodice (per le sole radici distinte): 1 se b > 0 allora x 1 = b ; x 2 = 2c b ; 2 altrimenti x 1 = 2c b+ ; x 2 = b+ 6
E solo questione di metodo: problemi e algoritmi di matematica elementare Progetto Lauree Scientifiche Scuola Estiva di Matematica (4092015) Soluzioni degli esercizi 1 (i) 1 + 2 + + (n 1) = n(n 1)/2 prodotti per calcolare le potenze più n somme; (ii) si può fare di meglio: poiché ogni volta la nuova potenza da sommare non è altro che quella sommata al passo precedente moltiplicata per q, ci basterà un solo ciclo e una sola moltiplicazione per ogni nuovo addendo se avremo cura di memorizzare quanto già fatto, quindi in totale solo n prodotti e n somme Ecco come potrebbe funzionare: dato q; x=1, s=1; per i=1,,n calcola: x=x*q; s=s+x; Nella variabile x (inizializzata ad 1) andranno accumulandosi via via le potenze successive di q da aggiungere ad s, la variabile che alla fine conterrà la sommatoria richiesta (iii) Si prova facilmente (ad esempio per induzione) che per q 1 vale la relazione: 1 + q + q 2 + + q n = 1 qn+1 1 q, per cui per calcolare S n (q) avremmo potuto eseguire direttamente il quoziente a destra, quindi ci sarebbero serviti n prodotti per il calcolo di q n+1, un quoziente e due somme 2 (i) Per ogni valore dato di x saranno necessari n(n + 1)/2 prodotti e n somme (ii) I prodotti sono diventati solo n Se n è grande ma soprattutto se dobbiamo valutare il polinomio su tanti valori diversi di x il risparmio sarà notevole (iii) p 5 (2) = 1 + 2 ( 4 + 2 (1 + 2 (0 + 2 ( 2 + 2 3)))) = 1 + 2( 4 + 2(1 + 16)) = 1 + 60 = 61 3 per i=1,,25 stampa i ; se i-(i/5)*5=0 vai a capo; 4 Se d = MCD(a, b), allora dovrà essere a = q d, b = p d, e necessariamente p e q dovranno essere primi tra loro Allora (a b)/d = p q d, quindi otteniamo un multiplo di a e b, necessariamente minimo perché p, q sono primi tra loro 5 ALG1: (6510,5880)=(5880,630)=(5250,630)=(4620,630)=(3990,630)=(3360,630)=(2730,630)= (2100,630)=(1470,630)=(840,630)=(630,210)=(420,210)=(210,210)=(210,0) ALG2: (6510,5880)=(5880,630)=(630,210)=(210,0) 6 In questo caso avremo: M = 0999 10 9 (999 milioni), m = 10 10 = 01 10 9 7 Appartengono ad A: 0000715 = (715, 3), 127 = (127, 2), 10 8 = (100, 7), 700000000 = (700, 9); non appertengono ad A (tra parentesi il loro valore per arrotondamento): 2 = (141, 1), 1/3 = (333, 0), 39210 = (392, 5), 2175 = (218, 3), 10 9 = M, 10 11 = 0 8 823+195 = (823, 3)+(195, 3) = (101, 4) 1018 (si è usato il troncamento, (102,4) per arrotondamento); 134 275 = (134, 2) (275, 1) = (107, 2) 1065 4 5 10 8 = (400, 1) (500, 9) = 2 10 9 (over f low); 1000/32 = (100, 4)/(320, 2) = (312, 2) 31, 25 9 (a + b) + c = (1 + 0005) + 0007 = 1 + 0007 = 1; a + (b + c) = 1 + 0012 = 101 a (b c) = 3 (815 521) = 3 294 = 882; a b a c = 3 815 3 521 = 2440 1560 = 880 7
10 ε = 10 1 3 = 10 2 = 001 Infatti: 1 + 001 = 101, mentre si avrà : 1 + 0009 = 1 11 a 90 = (954, 1) (949, 1) = (500, 1) = 005; b 90 = (100, 1)/((954, 1) + (949, 1)) = (100, 1)/(190, 2) = (526, 1) = 00526, valore corretto alle prime 3 cifre significative 12 Per quanto visto sui numeri macchina il motivo è chiaro: nelle formule usate si deve sommare il numero 1 al numero via via più piccolo 1/n; appena questo diviene minore della precisione macchina la somma restituisce semplicemente 1, che elevato alla n farà sempre 1; nel toy computer succederebbe da n = 101 13 Soluzioni esatte dell equazione: x 1 = 20099504, x 2 = 099504 Con le formule tradizionali in A si ottiene: = 102, = 100995 = 101 A (per arrotondamento), x 1 = 201 001 = 201, x 2 = 001 001 = 1; quindi x 1 = 201, r(x 1 ) = 0005, x 2 = 1, r(x 2 ) = 0005 14 Con le formule alternative si ottiene x 1 = 2 001 = 200, x 2 = 2 201 = 099502 = 0995 A, quindi x 1 = 200, r(x 1 ) = 1, x 2 = 0995, r(x 2 ) = 498e 05 Notate che i risultati migliori si ottengono con le prime formule per x 1, con le seconde per x 2 8