Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Algoritmi e computabilità: Introduzione all'analisi di diagrammi di flusso, Appunti di Informatica gestionale

L'analisi di diagrammi di flusso per la definizione e la composizione di algoritmi. come usare oggetti grafici specifici, come linee di flusso e decisioni, per creare algoritmi semplificando istruzioni in linguaggio naturale. Viene presentato un esempio di algoritmo per verificare se due stringhe sono contenute in un riferimento bibliografico, e come usare diagrammi di flusso per implementarlo. Il documento conclude con una breve storia di Alan Turing e la sua macchina teorica per risolvere il problema della terminazione.

Tipologia: Appunti

2020/2021

Caricato il 24/05/2021

ludovica-caporaso
ludovica-caporaso 🇮🇹

4.4

(5)

17 documenti

1 / 12

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
16/5/2021
Algoritmi e computabilità
https://virtuale.unibo.it/mod/book/tool/print/index.php?id=510316
1/12
A
lgoritmi
e
comput
a
bilit
à
S
i
to
:
V
i
rtu
ale
C
orso
:
I
nf
or
ma
t
ica
di
B
a
s
e
(1)
(
A
-
D
)
L
ib
ro
:
A
lg
or
i
t
mi
e
c
o
m
put
abili
t
à
S
t
am
p
a
to
da
:
L
u
d
ov
ica
C
a
por
a
so
D
a
t
a
:
d
o
menica
,
16
maggi
o
2021,
1505
pf3
pf4
pf5
pf8
pf9
pfa

Anteprima parziale del testo

Scarica Algoritmi e computabilità: Introduzione all'analisi di diagrammi di flusso e più Appunti in PDF di Informatica gestionale solo su Docsity!

Algoritmi e computabilità

Sito: Virtuale Corso: Informatica di Base (1) (A-D) Libro: Algoritmi e computabilità Stampato da: Ludovica Caporaso Data: domenica, 16 maggio 2021, 15

Sommario

**1. Usi possibili della Macchina Analitica

  1. Cosʼè un algoritmo?
  2. Diagrammi di flusso
  3. Il nostro primo algoritmo
  4. Ci sono limiti alla computazione?
  5. Bibliografia**

2. Cosʼè un algoritmo?

Gli algoritmi accompagnano sistematicamente le nostre attività della vita quotidiana. Per esempio, in Figura 2 sono mostrati due esempi di procedure passo passo che dobbiamo seguire, rispettivamente, per preparare salatini e per assemblare una specifica lampada. Mentre lʼobiettivo dei due esempi è estremamente diverso, in quanto nel primo è una ricetta e nel secondo è un insieme di istruzioni per assemblare un utensile, essi sono descritti nei termini della stessa nozione astratta: istruzione per produrre qualcosa partendo da un qualche materiale iniziale a disposizione – che, di fatto, rispecchia pienamente la definizione di algoritmo. Figura 2. Due fotografie che descrivono una ricetta (sinistra) e le istruzioni per assemblare una lampada (destra). Foto di sinistra di Phil! Gold, sorgente: https://www.flickr.com/photos/phil_g/17282816/. Foto di destra di Richard Eriksson, sorgente: https://www.flickr.com/photos/sillygwailo/3183183727/. La parola algoritmo è una combinazione della parola latina algorismus (che, a sua volta, è la latinizzazione del nome Al-Khwarizmi, che era un grande matematico persiano dellʼottavo secolo) e della parola greca arithmos, che significa numero. A livello generale, possiamo definire un algoritmo come lʼastrazione di una procedura passo passo che prende qualcosa come input e produce un certo output [Wing, 2008]. Ogni algoritmo è scritto in un linguaggio specifico in modo che le istruzioni che definisce possano essere comunicate e comprese da un computer (sia esso umano o macchina) in modo da ottenere qualcosa come conseguenza dellʼelaborazione di qualche materiale di input. Un programmatore è una persona che crea algoritmi e li specifica in programmi usando uno specifico linguaggio comprensibile dal computer – ove, in questo caso, il termine computer si riferisce ai computer elettronici. Tuttavia, se ci si astrae dalla nozione di programma, un programmatore è chiunque sia in grado di creare algoritmi che possono essere interpretati da un qualunque computer (sia esso umano o macchina).

4. Il nostro primo algoritmo

In questo capitolo svilupperemo il nostro primo algoritmo, che può essere descritto informalmente come segue: prendere in input tre stringhe, ovvero due parole e un riferimento bibliografico di un articolo pubblicato, e restituire 2 se entrambe le parole sono contenute nel riferimento bibliografico, 1 se solo una delle parole è contenuta nel riferimento bibliografico, o 0 altrimenti.

Una versione incompleta

Mediante i diagrammi di flusso, un qualunque algoritmo è definito usando due oggetti terminali, che identificano lʼinizio e la fine dellʼalgoritmo. Il terminale di inizio ha una freccia che parte da esso e va verso lʼistruzione successiva (la prima dellʼalgoritmo), mentre il terminale di fine può essere raggiunto da differenti punti dellʼalgoritmo, e quindi è collegato da almeno una freccia. La prima versione incompleta dellʼalgoritmo, mostrata di seguito, semplifica un poco le istruzioni in linguaggio naturale precedentemente introdotte, in modo da mostrare come possiamo usare alcuni iniziale oggetti per creare un algoritmo, senza aggiungere ulteriore complessità, almeno per il momento. In particolare, la versione semplificata prende in input solo due stringhe, una parola e un riferimento bibliografico, e restituisce 1 se la parola è contenuta nel riferimento bibliografico, 0 altrimenti. Questa versione parziale è mostrata nel diagramma di flusso in Figura 3. Figure 3. Lʼalgoritmo incompleto descritto da un semplice diagramma di flusso. Questa versione parziale usa già molti degli oggetti grafici propri ai diagrammi di flusso. In particolare, oltre ai terminali di inizio e fine, abbiamo usato tre oggetti di input / output per acquisire i valori specificati come input e per restituire 0 o 1 dipendentemente da questo input. La decisione su quale output restituire è stata codificata grazie allʼoggetto decisionale dei diagrammi di flusso, in cui lʼinput è analizzato e, a seconda della situazione, uno specifico ramo del flusso dellʼalgoritmo viene percorso.

Lʼalgoritmo completo

Mentre nella sezione precedente è stata introdotta una prima implementazione della versione parziale dellʼalgoritmo, lʼimplementazione dellʼalgoritmo completo attraverso lo sviluppo di un diagramma di flusso è mostrata in Figura 4. In questo caso, sono stati utilizzati tutti gli oggetti grafici introdotti in Tabella 1. Tuttavia, è importante sottolineare come il diagramma di flusso presentato è soltanto un possibile modo per implementare lʼalgoritmo originale. Infatti, è possibile creare anche un diagramma di flusso diverso che, però, risolve il problema descritto dallʼalgoritmo in linguaggio naturale correttamente. Nel diagramma in Figura 4, viene utilizzato il primo oggetto di processo in cui viene inizializzato a 0, associandolo implicitamente a una variabile (ovvero, “result value” in figura), il risultato che verrà restituito alla fine dellʼesecuzione dellʼalgoritmo. Questo risultato è quello che lʼalgoritmo deve ritornare se entrambe le parole in input non sono contenute nel riferimento bibliografico specificato. Questo oggetto di processo è seguito da due oggetti decisionali messi in sequenza, che controllano le due condizioni – ovvero se la prima parola è contenuta nel riferimento bibliografico, e se la seconda parola è contenuta nello stesso riferimento – e, nel caso queste siano vere, eseguono un incremento di 1 al risultato finale da restituire, mediante lʼuso di altri oggetti di processo. Alla fine, qualunque sia il valore che è stato associato al risultato finale viene restituito da un unico oggetto di output, che conclude lʼesecuzione dellʼalgoritmo.

Figura 4. Il diagramma di flusso che implementa lʼalgoritmo completo.

non termina mai, ad esempio come mostrato in quello definito in Figura 6. Avere un modo per scoprire sistematicamente se un algoritmo termina la sua esecuzione o no sarebbe di importanza cruciale, perché permetterebbe immediatamente di identificare quegli algoritmi che non lavorano in modo appropriato. Figura 6. Un diagramma di flusso che descrive un algoritmo che non termina mai, visto che la condizione “il numero è maggiore di 0” è sempre vera per costruzione. Uno degli scienziati che di più a lavorato alla risoluzione di questo quesito è stato Alan Mathison Turing (mostrato in Figura 7). Alan Turing è stato un informatico, nonché padre dellʼinformatica teorica e dellʼintelligenza artificiale, anche se i suoi lavori hanno interessato diverse discipline tra cui la matematica (si vedano gli studi per decodificare la macchina Enigma), la logica (con lʼintroduzione della macchina di Turing [Turing, 1937]), la filosofia (si veda lo studio sulla relazione tra i calcolatori elettronici e il concetto di intelligenza [Turing, 1950]) e la biologia (si veda lo studio che identifica i processi spontanei di creazione di pattern in natura [Turing, 1952]). Figura 7. Una foto di Alan Turing fatta nel 1927. Sorgente: https://en.wikipedia.org/wiki/File:Alan_Turing_Aged 16 .jpg._ Nel 1936, Turing sviluppò la sua macchina proprio per cercare di rispondere al problema della terminazione di Hilbert. La macchina proposta da Turing era prettamente teorica, nel senso che non lʼaveva costruita fisicamente, anche se recentemente molte persone hanno provato a costruire prototipi fisici dellʼidea di Turing, come quello mostrato in Figura 8.

Figura 8. Unʼimplementazione fisica della macchina di Turing, con un nastro finito. Foto di GabrielF, sorgente: https://commons.wikimedia.org/wiki/File:Model_of_a_Turing_machine.jpg. La macchina, che è in grado di simulare lʼesecuzione di qualunque algoritmo realmente implementabile, è composta da un nastro di memoria infinito composto da celle. Ogni cella può contenere un simbolo (o 0 o 1, dove 0 è usato come default per inizializzare le celle di tutto il nastro) che può essere letto e scritto dalla testina della macchina. Lo stato in cui la macchina si trova in un certo momento è altresì annotato. Le operazioni che può fare la macchina in un certo stato sono definite in una tabella (finita) di istruzioni, dove ogni istruzione dice cosa fare (scrivere un nuovo simbolo, muovere la testina a sinistra o a destra, spostarsi in un nuovo stato) in base allo stato in cui la macchina si trova e al simbolo presente nella cella sotto la testina. Infine, sono forniti anche uno stato iniziale e zero o più stati finali, in modo da sapere dove iniziare e finire il processo. La macchina è stata usata da Turing per mostrare una soluzione per il problema della terminazione. In questo capitolo presentiamo unʼapprossimazione alla soluzione che Turing ha fornito, basata interamente sulla reductio ad absurdum, già usata per risolvere il paradosso del bibliotecario, e sui diagrammi di flusso come unʼastrazione grafica di una specifica macchina di Turing. Supponiamo sia possibile sviluppare lʼalgoritmo “termina?”, che prende in input un certo algoritmo e restituisce “vero” nel caso in cui lʼalgoritmo specificato come input termina, mentre restituisce “falso” in caso contrario. Ovviamente, questo è soltanto un algoritmo ipotetico: stiamo supponendo che possiamo svilupparlo in qualche modo, senza mostrare come farlo davvero. Ora, usiamo lʼalgoritmo “termina?” per sviluppare un nuovo algoritmo, introdotto nel diagramma di flusso in Figura 9. Questo nuovo algoritmo prende in input un algoritmo e restituisce 0 se lʼalgoritmo in input non termina, mentre non termina in caso contrario. Notate che siamo in grado di implementare davvero ogni passo di questo nuovo algoritmo, siccome scoprire se lʼalgoritmo in input termina è restituito dal nostro algoritmo (ipotetico) “termina?”, mentre la non terminazione è un processo chiaramente implementabile, visto che ne abbiamo introdotto un esempio in Figura 6. Ora la domanda è: cosa succede se cerchiamo di eseguire lʼalgoritmo descritto in Figura 9 usando se stesso come input? Abbiamo due situazioni possibili: lʼalgoritmo “termina?” afferma che il nostro algoritmo in Figura 9 termina, e conseguentemente (per come è definito) non termina lʼesecuzione; lʼalgoritmo “termina?” afferma che il nostro algoritmo in Figura 9 non termina, e conseguentemente (per come è definito) restituisce 0 e termina lʼesecuzione. Quindi, qualunque sia il comportamento del nostro algoritmo in Figura 9, la sua esecuzione passando se stesso come input genera sempre una contraddizione. Lʼunica spiegazione possibile, quindi, è che lʼalgoritmo ipotetico “termina?” che usiamo per decidere se un algoritmo termina o meno non può essere sviluppato. Di conseguenza, la risposta al problema della terminazione è che lʼalgoritmo che verifica se un altro termina non può esistere. Figura 9. Il diagramma di flusso di un algoritmo che non termina se lʼalgoritmo specificato in input termina (verificato attraverso lʼuso di dellʼalgoritmo ipotetico “termina?”), e restituisce 0 in caso contrario. Questo risultato ha avuto un effetto dirompente sulla percezione delle abilità computazionali che un computer può avere. In pratica, la macchina di Turing e le relative analisi effettuate su di essa hanno imposto dei limiti chiarissimi a quello che possiamo calcolare, e hanno permesso di dimostrare che determinati problemi computazionali interessanti, come quello della terminazione, non possono essere risolti da nessun approccio algoritmico.