Considerazioni sugli algoritmi di calcolo

Esaminiamo cinque situazioni che inducono i programmatori a compiere errori loro malgrado.

 

1) Una prima possibilità di errore interviene quando si hanno valori dello stesso ordine di grandezza, cioè tutti molto piccoli oppure molto grandi, i quali subiscono somme e sottrazioni successive. In questi casi può succedere che le cifre più significative si elmininino a vicenda mentre il risultato si restringe sulle cifre di destra.
Per chiarire il meccanismo prendiamo la seguente espressione algebrica:

E = (A + B + C) * D

e supponiamo che i numeri siano:
 
CASO I°
A = + 324,18962
B = + 534,71093
C = – 858,90056

Il termine (A + B + C) è –0,00001. Assumiamo che D sia pari a 955.417.300.231 ed il valore finale è:

E = –9554173,00231

L'esempio mostra che successive somme e sottrazioni fanno sì che il risultato dipenda in maniera esclusiva dall'ultimo decimale. Le cifre di destra assumono una importanza fondamentale ed un arrotondamento produce un risultato del tutto inattendibile. Infatti supponiamo che i valori esatti abbiano sei cifre decimali e non cinque come nel caso precedente cioè siano:
 
CASO 2°
A = + 324,189625
B = + 534,710937
C = – 858,900561

Si ottiene il risultato parziale +0,000002 ed il risultato finale è:

E = +19108346,00462

E' evidente che il valore di E ricavato nel primo calcolo seppure ottenuto con ben cinque cifre decimali è completamente sbagliato. In pratica è fondamentale che il programmatore eviti somme e sottrazioni alternate, e, se non può evitarle, ne consideri adeguatamente le conseguenze.

2) Un'altro tipo di errore algoritmico interviene a causa dei decimali illimitati. Qualsiasi numero ha una precisione che si può ampliare ma che comunque ha un limite fisico a causa del fatto che è contenuto in un campo di memoria il quale è finito. Il numero decimale periodico o aperiodico non produce un risultato esatto. Ad esempio in qualsiasi macchina si provi a calcolare:

(1/3) * 3

non si avrà mai l'unità come dovrebbe essere:

(1/3) * 3 =1

bensì il valore:

(1/3) * 3 = 0,999999 

Semplicemente perché la macchina calcola 1/3 pari a 0,333333 e poi compie la moltiplicazione.

 

3) Un punto critico nasce dai troncamenti dei decimali che producono arrotondamenti accettabili se il calcolo è limitato, cioè compie un solo passo. Quando invece il calcolo è esteso, cioè compie più passi, questi comportano successive ripercussioni le quali producono risultati talora del tutto errati. Oltre al caso delle somme e sottrazioni successive sopra visto facciamo il caso delle divisioni. Prendiamo come esempio i due algoritmi:
 
(A/D + B/D + C/D)
(A + B + C) / D 
 
i quali da un punto di vista matematico sono identici, mentre
per la programmazione il secondo è senza dubbio il migliore.
Le tre divisioni producono approssimazioni che sommate alterano il risultato più di quanto possa fare l'unico arrotondamento del secondo algoritmo.
 
4) In talune situazioni l'imprecisione sembrerebbe dettata dalle condizioni stesse di calcolo come a proposito della serie armonica:

S(N) = 1 + 1/2 + 1/3 + .. + 1/N
 
L'algoritmo che segue pedissequamente la formula perde i valori più piccoli:
 
INIZIO - SERIE ARMONICA 1° ALGORITMO
Leggi N
Serie = 0
K = K + 1
RIPETI FINCHE' K = N
    Elemento = 1/K
    Serie = Serie + Elemento
    K = K + 1
FINE-RIPETI
...
FINE
 
Il seguente algoritmo invece comincia la somma dai valori più piccoli e risulta più accurato:


INIZIO - SERIE ARMONICA 2° ALGORITMO
Leggi N
Serie = 0
K = N
RIPETI FINCHE' K <= 1
    Elemento = 1/K
    Serie = Serie + Elemento
    K = K – 1
FINE-RIPETI
...
FINE


Per avere una misura del fenomeno, diamo il risultato S ottenuto con diversi valori di N. L'ultima colonna riporta le differenze dei risultati tra i due algoritmi
 
 N S (Algoritmo 1°) S (Algoritmo 2°)  Differenza
100 5,1873775174 5,1873775176 0,0000000002
200 5,8780309475 5,8780309480 0,0000000005
300 6,2826638794 6,2826638802 0,0000000008
400 6,5699296899 6,5699296910 0,0000000011


L'ultima colonna mostra che le differenze non sono grandi in valore assoluto, tuttavia presentano una incidenza non trascurabile e soprattutto non lineare. L'approssimazione cresce via via che l'algoritmo gestisce cifre più piccole, infatti proprio questo è il limite della iterazione nel primo algoritmo che volevo mostrare.


5) Succede che un programma venga sviluppato anche se non
si possiedono tutti i parametri per la sua stesura perché taluni mancano, oppure perché ci sono ma provengono da statistiche affette da fluttuazioni. Si pone allora il problema di giudicare la bontà dell'algoritmo, nel senso di valutare come una piccola variazione rispetto a quello che in teoria è del tutto preciso, pregiudichi o meno l'attendibilità del programma. Per lo scopo si esamina la risposta r che muta
al variare d dei parametri dell'algoritmo. Il rapporto:
 
c = r/ d 
 
chiamato numero di condizionamento esprime l'instabilità dell'algoritmo. Come esempio consideriamo il seguente sistema di equazioni lineari:
 
X + Y = 2
1001
·X + 1000·Y = 2001 
 
che prevede come soluzioni esatte:

X=1  ed  Y=1

 

Alterando dell'1% soltanto il primo coefficente si ha:
 
1,01·X + Y = 2
1001
· X + 1000 ·Y = 2001 
 
Le soluzioni di questo sistema sono:

 X=1/9  ed  Y=1901/900

 

le quali presentano una variazione superiore al 100% rispetto a quella corretta, ed offrono un esempio di notevole instabilità.

 

 


  Indietro

anno 2008





=