Sull'infinito in informatica (source at http://guide.supereva.it with Google translation)

Un breve excursus sul concetto di infinito nella informatica teorica in genere, nella teoria della computabilità e nel calcolo discreto.

Iniziamo col dire che il concetto di infinito non è affatto amichevole nella branca della matematica che ci riguarda più da vicino, ovvero l'informatica teorica. Tale concetto, per noi, si presenta sempre a braccetto con quello di impossibile, ovvero non computabile, che è l'espressione più sgradita in assoluto per qualsiasi informatico, in relazione ad un particolare problema.

E' facile rendersi conto di quanto sopra considerando l'oggetto centrale di tutti gli sforzi di teorici, analisti e programmatori, ovvero la definizione fondamentale di algoritmo:

Si definisce algoritmo una sequenza finita di passi eseguiti secondo un numero finito di regole e di operazioni esplicite, che da un insieme di dati in entrata X produce un insieme di dati in uscita Y (in termini funzionali, si tratta di una applicazione che va da X in Y).

Questa funzione, per essere utile, deve essere computabile: deve esistere un metodo tramite il quale sia possibile descriverne tutti i singoli valori. Appare dunque chiaro che la computazione non può richiedere un numero di passi infinito (in tal caso si avrebbe un algoritmo che non termina mai), e neppure, considerazione forse più sottile, può richiedere un numero infinito di regole e/o di operazioni per il suo svolgimento. Seguendo l'intuizione fornita da quest'ultima affermazione, Böhm e Jacopini hanno dimostrato un importantissimo teorema, secondo il quale qualsiasi algoritmo può essere implementato tramite un linguaggio semplificato che supporti solamente sequenze e cicli con precondizione di tipo "While" (Teorema di Böhm-Jacopini sull'espressività dei linguaggi di programmazione).
Ecco quindi che risorse significativamente importanti dell'informatica teorica sono dedicate alla trasformazione di successioni e procedure di calcolo infinite in serie finite di steps discreti, che possano fornire risultati parziali e/o approssimazioni. Esempi divertenti e facilmente fruibili, in questo senso, sono gli algoritmi per il calcolo del'n-esima cifra di pigreco, per l'i-esimo termine di successioni come quella di Fibonacci senza approssimazione, o anche il semplice algoritmo non ricorsivo per il calcolo del fattoriale di numeri giganti... quest'ultimo banale esempio ci conduce ad una ulteriore considerazione: problemi apparentemente banali e notoriamente nel dominio del finito possono produrre, in modo pressochè inaspettato per i profani, tempi di computazione non infiniti, ma pericolosamente superiori all'aspettativa di vita media di un essere umano (o dell'intero sistema solare, a volte...).

Naturalmente, se l'infinito è messo alla porta, i suoi parenti più stretti - gli infinitesimi - sono sicuramente in grado di rientrare dalla simbolica finestra (ogni riferimento a sistemi operativi esistenti e prodotti a Redmond è assolutamente casuale :-)): l'optimum algoritmico, infatti, sarebbe l'esecuzione in tempi nulli, o realisticamente tendenti a zero. Anche qui, però, i tempi (finiti) di esecuzione delle singole istruzioni sugli elaboratori fisici costituiscono un limite teoricamente invalicabile verso la più spinta compressione dei tempi di elaborazione. Esistono tuttavia anche ulteriori vincoli, di natura teorica, che limitano ulteriormente la possibilità di trovare l'algoritmo in assoluto più veloce per un dato problema, o per una intera categoria di problemi.
Cionondimeno, la ricerca dell'algoritmo più veloce in assoluto, o quantomeno della relativa efficienza all'interno di un pool di soluzioni finito e ben noto, per un determinato problema, rimane uno dei compiti fondamentali, nonché più ardui, dell'informatica, e costituisce il nucleo primitivo della scienza dell'ottimizzazione.

Si parte dalla intuitiva considerazione che, di norma, un algoritmo deve poter elaborare i propri dati fornendo i risultati in tempi ragionevoli: un algoritmo che impiegasse un miliardo di anni per calcolare l'ammontare della vostra pensione sociale non sarebbe affatto efficiente, se si esclude l'ovvio vantaggio apportato alle casse dell'INAIL :-).
A livello teoretico, non siamo però interessati a dover scrivere un algoritmo specifico per ogni problema (come invece avviene nella pratica operativa e nell'approccio classico): è molto più interessante e produttivo operare ad un metalivello, che ci consenta di trattare ampie classi di problemi, da cui eventualmente derivare forme algoritmiche ad hoc. Orbene, è dimostrato (da Blum, nel noto teorema dello Speed-up) che esistono moltissimi problemi per i quali non esiste l'algoritmo più veloce.
Consolatevi: per problemi del genere esiste sempre una sequenza non computabile di algoritmi impossibili, di dimensioni e di complessità crescenti.

In ogni caso, è ben noto in informatica che una vasta classe di problemi può essere descritta in termini di specifiche formali (un ampio ed interessante territorio, che prevede anche specifici linguaggi come Z, Scheme, MZ, RZ) nel modo seguente:

Data la specifica formale f (logica, matematica, simbolica in genere, ma non necessariamente algoritmica) di un problema dipendente da più parametri in X, si cerca l'algoritmo più veloce che ne calcoli la soluzione in Y, cioè si vuole costruire l'algoritmo che calcoli la funzione f: X --> Y.

L'approccio teoretico più moderno tende a considerare solamente algoritmi che risolvono un dato problema con tempo limite basso (constrained algorithms), il che costituisce già un problema di ottimizzazione, ovviamente traslato al metalivello computazionale di generazione degli algoritmi stessi.
Prendendo in considerazione solo algoritmi rapidamente computabili, e lavorando in classe asintotica, M. Hutter è riuscito a proporre l'algoritmo asintotico più veloce per risolvere ogni problema f ben definito. Il che sposta i termini del problema sulla corretta definizione della specifica f, ovviamente, anche se questo rappresenta un problema più trattabile, e soprattutto non modifica gli attributi dei problemi NP-ardui ed NP-completi ben noti, rappresentando tuttavia un ottimo progresso in campo teorico (ed ovviamente applicativo) nella teoria della computabilità.

Volendo chiudere con una (facile) battuta, si potrebbe dire che un passo infinitesimale è stato compiuto per allontanarsi dallo spettro della computazione infinita...



 I link correlati all'argomento

Fine intervento