Dato un problema, la progettazione dell’algoritmo risolutivo fino alla sua traduzione in un programma software, non è un compito semplice, soprattutto se non viene supportato da un metodo. Vediamo allora di fissarne uno!
Questo metodo parte sempre da un’attenta analisi del problema e segue ricorsivamente alcuni passi che possono essere cosi sintetizzati:
- Interpretare correttamente e comprendere pienamente l’enunciato del problema.
- Individuare con chiarezza quali sono gli obiettivi da raggiungere in modo da identificare gli aspetti fondamentali che caratterizzano il problema e che necessariamente devono essere considerati perché indispensabili per la sua soluzione.
- Riflettere su una strategia risolutiva che permetta di raggiungere tali obiettivi.
- Nel contempo, individuare quali sono i dati iniziali, finali e gli eventuali dati di lavoro (intermedi) coinvolti in tale strategia.
- Individuare le (oper)azioni o elaborazioni da eseguire secondo un ordine definito, che ci permettono di risolvere il problema e che sono necessarie per ottenere i risultati cercati. Questo punto si concretizza con la descrizione delle operazioni con cui attuare la strategia risolutiva fissata e, come spiegheremo più avanti, con la loro scomposizione nella sequenza dei passi elementari dell’algoritmo risolutivo.
- Fatto ciò, non resta che tradurre l’algoritmo utilizzando un linguaggio di programmazione.
I passi di questa procedura possono essere organizzati nelle tre fasi schematizzate nella figura seguente.
Prima fase – Analisi del problema
Prima di tutto si deve studiare ed interpretare attentamente il problema, che sarà descritto utilizzando il linguaggio naturale (ovvero, quello parlato, ndr). Durante questa fase preliminare di analisi si consiglia di schematizzare il problema il più possibile, ricorrendo a qualunque risorsa o stratagemma (schemi, disegni, tabelle, ecc) che possano essere di aiuto per la sua interpretazione. Un primo scoglio da superare, infatti, consiste proprio nella corretta interpretazione e completa comprensione del problema. Questo è un passo fondamentale della progettazione di un algoritmo, perché un’errata o anche parziale comprensione delle richieste del problema, inevitabilmente porta a delle scelte progettuali sbagliate.
In questo modo si riuscirà a comprendere meglio quali sono gli obiettivi da raggiungere – i risultati attesi – e a rendere più semplice l’individuazione di una strategia risolutiva da adottare. Durante questa fase ci si concentra essenzialmente su quali sono le cose da fare (cosa fare) e, quindi, anche sugli obiettivi intermedi da raggiungere. Nel far questo conviene anche iniziare ad organizzare i dati che man mano vengono coinvolti, definendo:
- Quali sono i risultati attesi (che cosa si deve calcolare o, più in generale, determinare? I dati di output).
- Quali sono i dati indispensabili per ottenere i risultati attesi.
- Fra i dati indispensabili, inoltre, quali sono già disponibili nella descrizione del problema, quali dovranno essere richiesti (dati di input) e quali, infine, servono all’esecutore come risultati intermedi indispensabili per ulteriori elaborazioni (dati di lavoro o intermedi).
Sempre per quanto riguarda l’organizzazione dei dati, durante quest’analisi si troverà che:
- Alcuni dati sono impliciti, cioè che pur essendo essenziali per determinare i risultati finali, non sono espressi nell’enunciato del problema, ma sono sottintesi. Ad esempio, nell’enunciato “Calcolare l’area di un rettangolo”, sono dati impliciti la base e l’altezza, in quanto senza di essi è impossibile calcolare l’area di un rettangolo; nell’enunciato “Convertire in lire un importo espresso in euro”, la costante di conversione da euro a lire, 1936,27, è un altro esempio di dato implicito. Altri dati, invece, sono espliciti, ossia dati chiaramente evidenziati nell’enunciato del problema. Ad esempio, nell’enunciato “Calcolare lo sconto del 10% su un importo dato”, il tasso di sconto, 10%, è un esempio di dato esplicito.
- Alcuni dati sono costanti, ossia non modificabili nel corso di una esecuzione e tanto meno passando da una esecuzione all’altra dello stesso algoritmo. Ad esempio, è questo il caso del dato 1936,27 dell’esempio di prima. Atri dati sono variabili, cioè suscettibili di variazioni nel corso di una esecuzione o passando da una esecuzione all’altra dello stesso algoritmo. Ad esempio, è questo il caso per la base ed l’altezza dell’esempio di prima.
A ciascun dato, inoltre, bisognerà assegnare un tipo di dato in funzione dei valori che potrà assumere e delle operazioni che potranno essere eseguite con esso.
Seconda fase – Progettazione e descrizione (scrittura) dell’algoritmo
Dopo la fase di analisi del problema, si può procedere con l’individuazione delle operazioni e delle elaborazioni da compiere sui dati, per ottenere i risultati attesi. Durante questa fase dal pensare a cosa fare si passa al come fare. Nel far questo spesso sarà necessario scomporre le operazioni individuate in elaborazioni più semplici, perché non bisogna dimenticare che, affinché l’algoritmo possa essere eseguito dall’esecutore, è indispensabile coinvolgere solo operazioni ed elaborazioni che per l’esecutore siano elementari e che, cioè, rientrino tra quelle discusse nel seguente post: I passi elementari di un algoritmo.
Durante questa fase potrà essere utile prendere in esame un numero ristretto di casi particolari del problema, che siano il più possibile rappresentativi delle diverse situazioni che potranno verificarsi al variare dell’input. Il che vuol dire simulare quello che accade in corrispondenza di particolari valori di input. Questo lavoro sarà utilissimo nella fase successiva di generalizzazione della soluzione. Si ricorda, infatti, che è indispensabile che all’elaboratore venga indicato non solo come risolvere un singolo caso o un ristretto numero di casi del problema, ma tutta la classe di problemi che differiscono per i dati iniziali e di input. In altri termini l’algoritmo che si progetta deve fornire all’esecutore una ben definita procedura da eseguire, qualunque sia l’input fra quelli ammissibili per il problema (per tutti gli input appartenenti al dominio del problema).
Durante questa fase la descrizione (ovvero la scrittura) dell’algoritmo potrà avvenire indifferentemente tramite flow-chart e/o il linguaggio di progetto (pseudolinguaggio). Va da se che le diverse fasi della procedura sin qui descritta, non necessariamente devono essere condotte in maniera rigorosamente sequenziale e che potranno essere ripetute ciclicamente, cioè si procederà per raffinamenti successivi.
Nel far tutto ciò si fisseranno le varie risorse che saranno utilizzate per le elaborazioni dei dati, per esempio le variabili da utilizzare, le procedure di calcolo che si hanno a disposizione e che si intende utilizzare, ecc.
Per un esempio di progettazione di un algoritmo si rimanda al seguente post: Esempio – Tariffa telefonica.
Ultima fase – Coding, scrittura del programma
Dopo aver progettato l’algoritmo (o gli algoritmi, nel caso di problemi più complessi) si potrà finalmente pensare di utilizzare un linguaggio di programmazione per tradurre l’algoritmo in righe di codice sorgente, che potranno così essere compilate in codice eseguibile o direttamente interpretate da un elaboratore elettronico. (Per approfondimenti si rimanda al seguente post: La programmazione informatica fino al programma).