- come fare meglio un'attività,
- come organizzare, in sequenza e/o in parallelo, delle attività (pianificazioni),
- come massimizzare ottimizzare delle risorse (tempo, memoria, spiccioli, probabilità, ricchezza, etc),
- come individuare gruppi di informazioni nascoste rispetto a determinate dimensioni (clustering),
- come individuare relazioni e reti di comportamento (organizzazioni, mercati, etc)
- come individuare gerarchi ad albero (es: parentele etc)
- etc.
I nostri algoritmi vengono "implementati" meccanicamente, intuitivamente.
Possono essere algoritmi deterministici o non deterministici. Quelli deterministici si sviluppano facilmente basandosi su delle regole esprimibili matematicamente, quelli non deterministici spesso si devono basare su probabilità e/o su euristica.
Molti sono i problemi matematici-informatici non ancora soddisfacentemente risolti. Molti di essi fanno parte del problema del millennio "P=NP?". I problemi P sono problemi che si risolvono in un tempo polinomiale, ovvero in un tempo al più potenza dell'input. I problemi NP sono, invece, quelli "non polinomiali", molto spesso NP-completi (vedi Wikipedia).
Fanno parte della famiglia NP la fattorizzazione di un numero con molte cifre (su cui si basa l'inviolabilità del RSA), il problema del logaritmo discreto, il problema del commesso viaggiatore, il problema dell'ottimizzazione del sacco, delle pesate etc.
Non crediate che solo i problemi famosi sono di questo tipo. Pensate al fastidio degli innumerevoli spiccioli che dobbiamo portarci dietro, questa estate, nel piccolo taschino dei pantaloni.
E' ovvio che chiunque che debba pagare un caffè, cercherà di levarsi quanti più spiccioli è possibile.
Ecco un problema ricreativo: "Come lavora un algoritmo per massimizzare il numero di monete in centesimi ed euro con cui pagare il bar?"
Supponiamo di avere:
S la somma da pagare
Q1 monete da taglio T1 (1 cent)
Q2 monete da taglio T2 (5 cent)
Q3 monete da taglio T3 (10 cent)
Q4 monete da taglio T4 (20 cent)
Q5 monete da taglio T5 (50 cent)
Q6 monete da taglio T6 (1 euro)
Dopo vari tentativi è sufficiente in ciclo individuare il valore dell'indice i tale che Sum(Qi*Ti) > S e in tal modo individuiamo la prima moneta di taglio Ti da usare.
A questo punto si ripete come se la somma da pagare nuova è Sn= S - Ti. Se Sn= S- Ti è positivo si ripete il ciclo per individuare un'altro taglio di moneta Ti e così via; se invece S - Ti < 0 significa che occorre ricevere resto e l'algoritmo si arresta.
In tal caso col resto ricevuto si cercherà di farsi cambiare dalla cassa le ulteriori monetine rimaste con poche altre monete di taglio maggiore.
Supponiamo S=85 centesimi, Q1=9, Q2=3, Q3=6, Q4=3, Q5=2, Q6=1. Allora se provate ad applicare più volte l'algoritmo, otterrete che ci possiamo liberare in prima battuta di 13 monetine su 28: una da 20 c, cinque da 10 c, due da 5 c, cinque da 1c.
Stesso problema, altra prospettiva: "Dobbiamo pagare una lavatrice, non abbiamo assegni ma contante e spiccioli".
Se dobbiamo pagare 400 euro con l'algoritmo di sopra ci linciano! L'algoritmo in questo caso è simile a quello di sopra ma tenta di prendere prima le monete di taglio maggiore (es: 500 euro, 100 euro, 50 euro, 10 euro) in assoluto.
I due problemi di sopra sono semplici e usano una tecnica lineare per trovare la soluzione. Se pensiamo, invece, allo stesso problema da un punto di vista ulteriore le cose si possono complicare un poco soprattutto per l'efficienza perchè si passa ad un problema esponenziale.
Problemi inutili? Pensate all'algoritmo "intelligente" che deve avere un distributore bancomat. Sa che dispone di una somma totale iniziale che varia ad ogni cliente, sa che in generale ha tagli da 10 euro, 20 e 50 con una certa quantità iniziale (anche nulla per certi tagli nel tempo), deve cercare di dare la somma richiesta dal cliente rispetto al massimo consentitogli (esempio 250 euro) cercando di dare diversi tagli e di proporre le somme che si avvicinano alla somma in denaro richiesta.
Corrispondenza esatta
Analizzate il problema: "Trovare le monete che paghino esattamente 85 centesimi". L'algoritmo in tal caso deve fare tutte le somme possibili tra 1 o più combinazioni di monete disponibili e vedere quali somme danno 85 come risultato; certamente è un algoritmo esponenziale.
Spesso il trucco, se non ci sono vincoli al problema, è di massimizzare o minimizzare una risorsa per portarsi in un problema lineare, ma in alcuni casi non è nemmeno semplice, come nel caso del problema del commesso viaggiatore: in tale problema il commesso viaggiatore deve fare in modo di fare il minimo percorso tale che si passi per una stessa strada una sola volta, partendo da casa e passando per ogni strada dove deve fare la commissione, e poi ritornare alla fine del percorso di nuovo a casa.
Purtroppo in questo caso occorre verificare tutti i percorsi, marcarli con un peso e alla fine trovare decidere il percorso migliore; esistono anche dei trucchi per ridurre tale ricerca, ma in ogni caso un algoritmo efficiente non di natura esponenziale finora non è stato individuato.
Alla prox