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 di ricerca: sequenziale e binaria, Prove d'esame di Elementi di Informatica

Le operazioni di ingresso e uscita in un agente di calcolo e descrive due algoritmi di ricerca: sequenziale e binaria. La ricerca sequenziale esegue una serie di confronti consecutivi, mentre l'algoritmo binario ristra la ricerca a metà dell'elenco. Il documento include anche un'analisi del lavoro totale svolto da entrambi gli algoritmi e una comparazione tra di essi.

Tipologia: Prove d'esame

2016/2017

Caricato il 10/01/2017

sonolollo
sonolollo 🇮🇹

4.5

(65)

18 documenti

1 / 23

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
INFORMATICA: Preparazione all'Esame
L'Informatica è lo studio degli algoritmi, che comprende:
_ le loro proprietà formali e matematiche;
_ le loro implementazioni hardware;
_ le loro implementazioni logistiche;
_ le loro applicazioni.
Esistono tre tipi di categorie che racchiudono le operazioni utili alla realizzazione degli algoritmi:
1. Operazioni sequenziali: eseguono una singola attività ben definita e sono espresse come
semplici frasi dichiarative. (Es. Aggiungi un cucchiaio di burro nella scodella)
2. Operazioni condizionali: sono istruzioni di un algoritmo che ''pongono una domanda''.
L'operazione successiva è selezionata sulla base della risposta. (Es. Se l'impasto è troppo
secco, aggiungi un bicchiere d'acqua).
3. Operazioni iterative: sono delle istruzioni ''di ciclo'' di un algoritmo. Indicano di non proseguire
con l'istruzione successiva, ma di tornare indietro e ripetere l'esecuzione di un precedente
blocco di istruzioni. (Es. Ripeti le due operazioni precedenti finché l'impasto si è ispessito)
Un algoritmo è un insieme di operazioni, per le quali deve esistere un ordinamento chiaro e non
ambiguo. Dobbiamo essere estremamente precisi nello specificare l'ordine in cui le operazioni
devono essere eseguite --> numerazione dei passi.
Gli algoritmi sono costituiti da elementi detti "operazioni". Queste "operazioni" devono soddisfare
due criteri: essere non ambigue ed essere effettivamente computabili.
Un'operazione non è ambigua (detta anche operazione primitiva) quando può essere compresa ed
eseguita direttamente dall'agente di calcolo senza necessità di ulteriori semplificazioni o
spiegazioni. L'operazione deve anche essere eseguibile dall'agente di calcolo --> deve essere
effettivamente computabile.
> Un algoritmo deve produrre un risultato e terminare in un tempo finito.
L'informatica è lo studio degli algoritmi, che comprende:
_ le loro proprietà formali e matematiche
_ le loro implementazioni hardware
_ le loro implementazioni linguistiche
_ le loro applicazioni
Cap. 2 IDEAZIONE E PROGETTO DI ALGORITMI
Una possibilità di rappresentare gli algoritmi è l'uso del linguaggio naturale, con cui abbiamo
maggiore familiarità. Il linguaggio naturale può essere estremamente prolisso, determinando
algoritmi incoerenti. Il linguaggio naturale è troppo 'ricco' in termini di interpretazioni e significato.
Poiché le lingue naturali non sono sufficientemente precise per gli algoritmi, si potrebbe cedere alla
tentazione di passare all'estremo opposto --> linguaggio di programmazione di alto livello.
Se i due estremi rappresentati dai linguaggi naturali e dai linguaggi di programmazione di alto
livello sono inadatti, cosa si dovrebbe usare?
Lo pseudo codice comprende costrutti in italiano studiati per assomigliare alle istruzioni di un
linguaggio di programmazione, ma che in realtà non si eseguono su un computer. Lo pseudo
codice rappresenta un compromesso tra i due estremi del linguaggio naturale e di quello formale; è
semplice, leggibile e privo di regole grammaticali.
OPERAZIONI SEQUENZIALI
Lo pseudo codice deve comprendere le istruzioni necessarie a eseguire le tre operazioni
sequenziali di base: calcolo, ingresso e uscita.
Una variabile è una posizione di memoria con nome, che contiene un valore.
In pseudo codice non ha importanza l'esatto modo in cui si sceglie di scrivere le istruzioni, purché
queste siano chiare, effettivamente calcolabili e non ambigue. Si tratta di una notazione elastica
che può essere adattata secondo la propria visione di come esprimere al meglio idee e algoritmi.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17

Anteprima parziale del testo

Scarica Algoritmi di ricerca: sequenziale e binaria e più Prove d'esame in PDF di Elementi di Informatica solo su Docsity!

INFORMATICA: Preparazione all'Esame L'Informatica è lo studio degli algoritmi , che comprende: _ le loro proprietà formali e matematiche; _ le loro implementazioni hardware; _ le loro implementazioni logistiche; _ le loro applicazioni. Esistono tre tipi di categorie che racchiudono le operazioni utili alla realizzazione degli algoritmi:

  1. Operazioni sequenziali : eseguono una singola attività ben definita e sono espresse come semplici frasi dichiarative. (Es. Aggiungi un cucchiaio di burro nella scodella)
  2. Operazioni condizionali : sono istruzioni di un algoritmo che ''pongono una domanda''. L'operazione successiva è selezionata sulla base della risposta. (Es. Se l'impasto è troppo secco, aggiungi un bicchiere d'acqua).
  3. Operazioni iterative : sono delle istruzioni ''di ciclo'' di un algoritmo. Indicano di non proseguire con l'istruzione successiva, ma di tornare indietro e ripetere l'esecuzione di un precedente blocco di istruzioni. (Es. Ripeti le due operazioni precedenti finché l'impasto si è ispessito) Un algoritmo è un insieme di operazioni, per le quali deve esistere un ordinamento chiaro e non ambiguo. Dobbiamo essere estremamente precisi nello specificare l'ordine in cui le operazioni devono essere eseguite --> numerazione dei passi. Gli algoritmi sono costituiti da elementi detti "operazioni". Queste "operazioni" devono soddisfare due criteri: essere non ambigue ed essere effettivamente computabili. Un'operazione non è ambigua (detta anche operazione primitiva) quando può essere compresa ed eseguita direttamente dall'agente di calcolo senza necessità di ulteriori semplificazioni o spiegazioni. L'operazione deve anche essere eseguibile dall'agente di calcolo --> deve essere effettivamente computabile.

Un algoritmo deve produrre un risultato e terminare in un tempo finito. L'informatica è lo studio degli algoritmi, che comprende: _ le loro proprietà formali e matematiche _ le loro implementazioni hardware _ le loro implementazioni linguistiche _ le loro applicazioni Cap. 2 IDEAZIONE E PROGETTO DI ALGORITMI Una possibilità di rappresentare gli algoritmi è l'uso del linguaggio naturale, con cui abbiamo maggiore familiarità. Il linguaggio naturale può essere estremamente prolisso, determinando algoritmi incoerenti. Il linguaggio naturale è troppo 'ricco' in termini di interpretazioni e significato. Poiché le lingue naturali non sono sufficientemente precise per gli algoritmi, si potrebbe cedere alla tentazione di passare all'estremo opposto --> linguaggio di programmazione di alto livello. Se i due estremi rappresentati dai linguaggi naturali e dai linguaggi di programmazione di alto livello sono inadatti, cosa si dovrebbe usare? Lo pseudo codice comprende costrutti in italiano studiati per assomigliare alle istruzioni di un linguaggio di programmazione, ma che in realtà non si eseguono su un computer. Lo pseudo codice rappresenta un compromesso tra i due estremi del linguaggio naturale e di quello formale; è semplice, leggibile e privo di regole grammaticali. OPERAZIONI SEQUENZIALI Lo pseudo codice deve comprendere le istruzioni necessarie a eseguire le tre operazioni sequenziali di base: calcolo, ingresso e uscita. Una variabile è una posizione di memoria con nome, che contiene un valore. In pseudo codice non ha importanza l'esatto modo in cui si sceglie di scrivere le istruzioni, purché queste siano chiare, effettivamente calcolabili e non ambigue. Si tratta di una notazione elastica che può essere adattata secondo la propria visione di come esprimere al meglio idee e algoritmi.

Le operazioni di ingresso inviano valori di dati dal mondo esterno all'agente di calcolo, che può quindi utilizzarli nelle istruzioni successive. Le operazioni di uscita inviano i risultati dall'agente di calcolo al mondo esterno. Se l'agente di calcolo è un computer, le comunicazioni con il mondo esterno vengono svolte tramite i dispositivi ingresso/uscita disponibili su un sistema tipico. Le istruzioni di ingresso e uscita in pseudo codice sono espresse così: Ingresso Ottieni i valori per "variabile", "variabile", ... Uscita Stampa i valori di "variabile", "variabile", ... Quando l'algoritmo raggiunge questa operazione di ingresso, attende finché qualcuno o qualcosa fornisce un valore per la variabile. Quando ha ricevuto e memorizzato un valore per la variabile, l'algoritmo continua con l'istruzione successiva. L'istruzione "stampa" indica di visualizzare il valore al mondo esterno, mostrandolo sullo schermo. Mediante le tre operazioni sequenziali - calcolo, ingresso e uscita - è possibile scrivere degli algoritmi semplici. OPERAZIONI CONDIZIONALI E ITERATIVE L'algoritmo precedente esegue una serie di operazioni una volta sola, quindi si ferma. Un algoritmo puramente sequenziale viene talvolta definito algoritmo lineare perché esegue le istruzioni in linea retta dall'alto al basso e quindi si ferma. Per poter eseguire ramificazioni e ripetizioni, lo pseudo codice richiede istruzioni supplementari per l'implementazione di operazioni condizionali e iterative --> operazioni di controllo. Le istruzioni condizionali sono operazioni che "pongono domande". Consentono all'algoritmo di porre una domanda e di selezionare, in base alla risposta fornita, l'operazione successiva da eseguire. L'istruzione condizionale più comune è if/then/else che presenta il formato seguente: Se "una condizione vera/falsa" è vera allora prima serie di operazioni algoritmiche Altrimenti seconda serie di operazioni algoritmiche Questa istruzione ha il seguente significato:

  1. Valuta la condizione vera/falsa sulla prima riga per determinare se è vera o falsa
  2. Se la condizione è vera, allora esegui la prima serie di operazioni algoritmiche e salta completamente la seconda serie.
  3. Se la condizione è falsa, allora salta la prima serie di operazioni ed esegui la seconda serie.
  4. Una volta completata la serie appropriata di operazioni, continua a eseguire l'algoritmo con l'operazione che segue l'istruzione se/allora/altrimenti. Passo Operazione 1 Ottieni i valori per galloni usati, miglia iniziali, miglia finali 2 Imposta il valore di distanza percorsa a (miglia finali - miglia iniziali) 3 Imposta il valore di miglia medie per gallone a (distanza percorsa + galloni usati) 4 Stampa il valore di miglia medie per gallone 5 Stop

100° passaggio attraverso il ciclo, il valore di conteggio viene incrementato. Quando la condizione di continuazione risulta falsa il ciclo si conclude. Questo ciclo è chiamato ciclo a valutazione anticipata perché la condizione di continuazione viene valutata all'inizio di ciascuna iterazione attraverso il ciclo e pertanto è possibile che il corpo del ciclo non venga mai eseguito. Questo fatto può causare dei problemi. Nella tabella precedente si chiede all'utente se desidera eseguire nuovamente il calcolo, ma la domanda è posta soltanto alla fine dell'esecuzione del corpo del ciclo --> per questo bisogna fornire alla variabile risposta un valore fittizio 'sì'. Un'altra variante della struttura di ciclo è il ciclo a valutazione posticipata; anch'esso utilizza la condizione di continuazione vero/falso per il controllo dell'esecuzione, tuttavia il test viene eseguito alla fine del corpo del ciclo e non all'inizio. Il ciclo viene espresso mediante l'istruzione Ripeti/ Finché. Questa struttura esegue tutte le operazioni algoritmiche contenute nel corpo del ciclo prima della valutazione della condizione vera/falsa specificata alla fine. Se questa condizione è falsa, il ciclo termina e l'esecuzione continua con l'operazione successiva. Se invece è vera, l'intero corpo del ciclo viene eseguito nuovamente. Nella variante Ripeti/Finché, il corpo del ciclo viene sempre eseguito almeno una volta, mente il ciclo Finché può essere eseguito 0, 1 o più volte. Queste operazioni rappresentano le primitive dell'agente di calcolo. Si tratta delle istruzioni che si presume vengano comprese dall'agente di calcolo e che questo deve essere in grado di eseguire senza ulteriori spiegazioni o semplificazioni. Esempi di risoluzione dei problemi algoritmici --> vedi libro da pag.51 a pag. Passo Operazione 1 Risposta = si 2 Finché (risposta = si) ripeti i passaggi da 3 a 11 3 Ottieni i valori per galloni usati, miglia iniziali, miglia finali 4 Imposta il valore di distanza percorsa a (miglia finali - miglia iniziali) 5 Imposta il valore di miglia medie per gallone a (distanza percorsa + galloni usati) 6 Stampa il valore di miglia medie per gallone 7 Se miglia medie per gallone è maggiore di 25.0 allora 8 Stampa il messaggio 'Stai viaggiando con un consumo accettabile' ALTRIMENTI 9 Stampa il messaggio 'Stai viaggiando con un consumo NON accettabile' 10 Stampa il messaggio 'Vuoi fare un altro calcolo? Inserisci Sì o No' 11 Ottieni un nuovo valore per risposta dall'utente 12 Stop

Cap. 3 EFFICIENZA DEGLI ALGORITMI La prima e fondamentale caratteristica degli algoritmi è la correttezza. Un algoritmo creato per risolvere un problema deve, per definizione, fornire un risultato e fermarsi. Il risultato deve essere una soluzione corretta del problema. Determinare che un algoritmo fornisca risultati corretti non è facile come sembra. Da un lato, l'algoritmo potrebbe fornire risultati corretti, ma al problema errato; ciò può accadere quando si progetta un algoritmo senza una completa comprensione del problema che si vuole risolvere. Inoltre, una volta compreso il problema, l'algoritmo deve fornire risultati corretti per tutti i possibili valori di ingresso, non solo per i valori più comuni. Conta anche la precisione del risultato che intendiamo accettare come corretta. La manutenzione dei programmi richiede tempo e denaro. La persona che deve modificare un programma spesso non è la stessa che ha scritto il programma originale. Per facilitare la manutenzione, l'algoritmo utilizzato dal programma deve essere facile da capire. La facilità di comprensione, la chiarezza, la facilità di gestione è una caratteristica desiderabile di un algoritmo. L'eleganza per gli algoritmi corrisponde alla linea o allo stile delle automobili. Talvolta eleganza e facilità di comprensione vanno in direzioni contrarie: più elegante è la soluzione, più difficile risulta da capire. Efficienza è il termine usato per descrivere l'uso attento delle risorse da parte di un algoritmo, e insieme a correttezza, facilità di comprensione ed eleganza, è una delle caratteristiche desiderabili di un algoritmo. La valutazione del tempo di esecuzione di un algoritmo tende a riflettere maggiormente la velocità della macchina o le variazioni nei dati di ingresso, che l'efficienza dell'algoritmo stesso. Utilizzando la stessa macchina e lo stesso elenco di nomi, ma cercando nomi diversi, si ottiene un'indicazione dell'impatto che la scelta del nome ha sul tempo di esecuzione dell'algoritmo su quella particolare macchina --> benchmarking. Questi sono utili per classificare una macchina rispetto a un'altra e per determinare la sensibilità di un particolare algoritmo rispetto a variazioni nei dati di ingresso su una particolare macchina. Lo studio dell'efficienza degli algoritmi si chiama analisi degli algoritmi.

  1. Ricerca sequenziale L'unità di lavoro centrale è il confronto del NOME cercato con un nome nell'elenco. L'essenza dell'algoritmo è la ripetizione di questa operazione sui successivi nomi dell'elenco fino a trovare NOME o a esaurire l'elenco stesso. Le attività sussidiarie comprendono l'impostazione del valore iniziale dell'indice i, la scrittura delle uscite, l'impostazione di 'Trovato' e lo spostamento in avanti dell'indice nell'elenco di nomi. Possiamo farci un'idea del lavoro totale svolto dall'algoritmo semplicemente contando il numero di confronti e moltiplicando per un fattore costante che tenga conto del lavoro di spostamento dell'indice. L'unità di lavoro fondamentale in questo algoritmo è il confronto di NOME con un elemento dell'elenco. Un confronto è eseguito a ogni passaggio nel ciclo ai passi da 4 a 7, perciò dobbiamo chiederci quante volte è eseguito il ciclo. Ciò dipende da quando, o se, troviamo NOME nell'elenco. Il caso migliore avviene quando NOME è il primo dell'elenco. Il caso peggiore, che richiede il lavoro massimo, si verifica se NOME è l'ultimo nome dell'elenco, oppure è assente dall'elenco stesso. Quando NOME si trova in un punto qualsiasi all'interno dell'elenco, sono necessari da 1 (caso migliore) a n (caso peggiore) confronti. La ricerca sequenziale non è abbastanza efficiente, per valori di n grandi, da risultare utile per effettuare ricerche in un elenco telefonico. Notate che i valori per il caso peggiore è il caso medio dipendono da n , il numero di nomi presenti nell'elenco. Più grande è l'elenco, più lavoro occorre svolgere per effettuare ricerche al suo interno. L'algoritmo memorizza l'elenco dei nomi e il NOME cercato tra i dati d'ingresso. La sola memoria aggiuntiva richiesta è quella per registrare il valore indice i e l'indicatore 'Trovato'. La ricerca sequenziale in sostanza non utilizza memoria aggiuntiva rispetto a quella richiesta per memorizzare i dati in ingresso, e quindi è molto efficiente rispetto allo spazio.

Per quanto riguarda l'efficienza dell'ordinamento di selezione rispetto allo spazio, l'elenco di partenza occupa n locazioni di memoria. Serve ancora un po' di spazio per il marcatore tra le sezioni non ordinata e ordinata, e per registrare il valore massimo temporaneo e la sua posizione nell'elenco. Se i due numeri da scambiare si trovano nelle posizioni X e Y nell'elenco, potremmo pensare di scambiarli con i due passi seguenti.

  1. Copia il valore corrente alla posizione X nella posizione Y.
  2. Copia il valore corrente alla posizione Y nella posizione X. Il problema è che il valore nella posizione X coincide con quello nella posizione Y. Lo spazio in più richiesto per l'ordinamento per selezione, oltre a quello richiesto per memorizzare l'elenco di origine, è molto poco. L'ordinamento per selezione è efficiente rispetto allo spazio. _ ORDINE DI GRANDEZZA - ORDINE Il numero di confronti svolti dall'algoritmo di ordinamento per selezione non cresce alla stessa velocità della dimensione del problema n, ma è circa il quadrato della stessa. Un algoritmo che svolge un lavoro cn°2 per qualsiasi costante c si dice di ordine di grandezza n°2. Confrontando le due forme di base n e n°2 si vede che n°2 cresce molto più velocemente di n. Le due curve si intersecano nel punto (1,1) e per qualsiasi valore di n maggiore di 1, n°2 ha un valore sempre maggiore di n e se ne distanzia sempre più. Qualsiasi qualità di ordine di grandezza alla fine avrà valori maggiori di una quantità di ordine n, indipendentemente dai fattori costanti. L'ordinamento per selezione è un algoritmo (c)n°2 in tutti i casi, e la ricerca sequenziale è un algoritmo (c)n nel caso peggiore, perciò i due algoritmi hanno ordini di grandezza diversi. Supponiamo di avere due diversi algoritmi che risolvono lo stesso problema e svolgono la stessa quantità di lavoro, ma hanno ordini di grandezza diversi. Al crescere della dimensione del problema, l'inefficienza implicita dell'algoritmo A gli fa svolgere più lavoro rispetto all'algoritmo B. Quando i due algoritmi si incontrano al punto n, i due svolgono la stessa quantità di lavoro, e perciò richiedono la stessa quantità di tempo per l'esecuzione. Per valori di n superiori, l'algoritmo A di ordine n°2 procede in modo sempre più lento rispetto all'algoritmo B di ordine n. Se un algoritmo (c)n°2 è un algoritmo (c)n svolgono lo stesso compito, allora per n sufficientemente grande l'algoritmo (c)n°2 lavora di più e richiede più tempo per l'esecuzione. Questo è il motivo per cui si possono ignorare i fattori costanti e concentrarsi sull'ordine di grandezza degli algoritmi, il punto fondamentale. Dati due algoritmi per svolgere lo stesso compito, solitamente scegliamo quello del minor ordine di grandezza, perché per n abbastanza grande risulta sempre "vincente". Un programma che risulta veloce su un ingresso di dimensione limitata potrebbe essere scelto per risolvere istanze del problema con dimensione superiore, e in quel caso l'efficienza potrebbe calare vertiginosamente. L'attività di documentazione del programma deve evidenziare qualsiasi assunto o limite sulla dimensione dell'ingresso che il programma è stato progettato per gestire. Confrontare l'efficienza degli algoritmi ha senso soltanto se si hanno vari algoritmi che eseguono lo stesso compito. Un algoritmo come l'ordinamento per selezione ha il vantaggio di essere relativamente facile da comprendere.

- ORDINE DI GRANDEZZA - ORDINE log n

L'algoritmo di ricerca sequenziale cerca un elemento particolare in un elenco di n elementi; è un algoritmo (c)n. L'algoritmo di ricerca binaria è più efficiente, ma funziona soltanto quando l'elenco è già ordinato. L'algoritmo di ricerca binaria opera in modo simile su un elenco ordinato. Prima cerca NOME verso la metà dell'elenco: se il nome che trova coincide con NOME, la ricerca è finita. Se NOME precede alfabeticamente il nome che si trova a metà dell'elenco, la ricerca viene ristretta alla prima metà dell'elenco stesso e la procedura viene ripetuta su questo elenco più piccolo.

Nella tabella è riportata una versione in pseudo codice dell'algoritmo di ricerca binaria su un elenco ordinato di n elementi. Le etichette inizio e fine indicano l'inizio e la fine della sezione dell'elenco attualmente considerata. Inizialmente viene considerato l'interno elenco, perciò inizio è 1 e fine è n. Se NOME non viene trovato al punto centrale m della sezione attuale dell'elenco, allora impostare fine uguale a 1 meno il punto centrale significa che, alla successiva iterazione del ciclo, la ricerca verrà effettuata nella prima metà della sezione corrente; impostare inizio uguale a 1 più il punto centrale significa invece che alla successiva iterazione del ciclo la ricerca verrà effettuata nella seconda metà della sezione corrente. Perciò, al procedere dell'algoritmo, il marcatore inizio può spostarsi verso la fine dell'elenco, e il marcatore fine può spostarsi verso l'inizio. Se i marcatori inizio e fine si incrociano, cioè se fine diventa inferiore a inizio, allora la sezione corrente dell'elenco è vuota e la ricerca termina. Come l'algoritmo di ricerca sequenziale, quello di ricerca binaria su a sa anch'esso su confronti, perciò al fine di analizzarlo contiamo il numero di confronti come indicazione del lavoro fatto. Il caso migliore, come nella ricerca sequenziale, richiede un solo confronto: NOME viene trovato al primo tentativo. Il caso peggiore si verifica quando NOME non nel'elenco; tuttavia, nella ricerca binaria questo fatto viene rilevato molto prima, rispetto alla ricerca sequenziale. Il numero di volte per cui un numero n può essere tagliato a metà senza scendere sotto 1 si chiama logaritmo di n in base 2 e si scrive lg n. Supponiamo di eseguire una ricerca binaria su n nomi. Nel caso peggiore il numero di confronti è legato al numero di volte per cui si può dimezzare l'elenco di lunghezza n. Gli algoritmi di ricerca binaria e di ricerca sequenziale risolvono entrambi il problema della ricerca nell'elenco telefonico, ma differiscono per l'ordine di grandezza del lavoro svolto. La ricerca binaria è un algoritmo (c)lg n, mentre la ricerca sequenziale è (c)n, sia nel caso peggiore, sia nel caso medio. Per confrontare questi due algoritmi, supponiamo che vi siano 100 elementi nell'elenco. Nel caso peggiore, la ricerca sequenziale richiede 100 confronti, la ricerca binaria 7(2°7=128). Nel caso medio, la ricerca sequenziale richiede circa 50 confronti, quella binaria 6 o 7. Il miglioramento nella ricerca binaria risulta ancora più evidente al crescere della dimensione dell'elenco. La ricerca binaria funziona soltanto su un elenco già ordinato. Un elenco non ordinato può essere ordinato usando una ricerca binaria, ma l'ordinamento in sé richiede parecchio lavoro. Se si ha Ottieni i valori per NOME, n, N1.....Nn e T..... Tn 2 Imposta il valore di Inizio a 1 e il valore di Trovato a NO 3 Imposta il valore di fine a n 4 Finché Trovato=NO e inizio è minore o uguale a fine esegui i passi da 5 a 10 5 Imposta il valore di m al valore di posto centrale tra inizio e fine 6 Se NOME è uguale a Nm il nome trovato al punto centrale tra inizio e fine, allora esegui i passi 7 e 8 7 Stampa il numero telefonico della persona trovata Tm 8 Imposta il valore di Trovato a SI 9 Altrimenti se NOME precede Nm nel l'ordinamento alfabetico, allora imposta fine= m- 1 10 Altrimenti (NOME segue Nm nel l'ordinamento alfabetico) imposta inizio = m + 1 11 Se (Trovato = NO) allora stampa il messaggio 'Spiacente, il nome cercato non è nell'elenco' 12 Stop

Il valore assoluto, tuttavia, è 0000...0000. Perciò questa configurazione di bit rappresenta la quantità numerica "zero negativo", un valore che non possiede alcun significato matematico reale e non dovrebbe avere una rappresentazione distinta dall'altra rappresentazione dello zero, 0000...0000. L'esistenza di due configurazioni di bit distinte per la stessa quantità numerica determina notevoli complicazioni dal punto di vista progettuale. I progettisti di computer tendono a favorire le rappresentazioni di interi con segno che non presentino il problema dei due zeri. Una tra le più comuni è la rappresentazione in complemento a due. Nella rappresentazione in complemento a due è presente un singolo zero, il numero binario 000...0. Tuttavia, l'esistenza di una singola configurazione per lo zero porta a un'altra situazione insolita: il numero totale di valori che può essere rappresentato con n bit è 2°n. _ numeri frazionari I numeri frazionari possono anch'essi essere rappresentati in binario utilizzando le tecniche di intero con segno appena descritte. Per fare ciò, tuttavia, occorre prima convertire il numero in notazione scientifica. M è la mantissa, B è la base dell'esponente ed E è l'esponente. Sia la mantissa, sia l'esponente sono numeri interi con segno, perciò è possibile utilizzare la notazione segno e valore assoluto o quella in complemento a due appena descritte per rappresentare ciascuno di questi due campi. In binario, il valore 5 è 101. _ Informazioni testuali Per rappresentare dati testuali in binario, il sistema assegna a ciascuna lettera o simbolo stampabile dell'alfabeto un numero univoco, quindi memorizza internamente tale simbolo usando l'equivalente binario del numero. Qui sopra è indicato che la quantità numerica a 8 bit 10000001 viene interpretata come carattere "!". Tuttavia, l'unico modo con cui il computer riesce a capire che il valore a 8 bit 10000001 rappresenta il simbolo "!" e non il valore intero senza segno 129 o il valore intero con segno -1 è dato dal contesto in cui il valore è utilizzato. Per agevolare lo scambio di informazioni testuali tra sistemi informatici sarebbe utile che tutti utilizzassero la stessa mappatura dei codici. Attualmente il codice maggiormente utilizzato per rappresentare i caratteri di un sistema informatico è denominato ASCII, acronimo per American Simbolo Valore decimale Binario (usando 8 cifre binarie) A 1. B 2. C 3. D 4.

... ... Z 26. @ 128. ! 129. ... ... ...

Standard Code for Information Interchange. Questo standard internazionale utilizza 8 bit per rappresentare ciascun carattere, perciò è in grado di codificare un totale di 2°8 = 256 caratteri diversi. Oggi sta rapidamente guadagnando popolarità un nuovo set di codici denominato UNICODE che utilizza una rappresentazione a 16 bit per i caratteri, invece degli 8 del sistema ASCII. Ciò significa che l'UNICODE è in grado di rappresentare 2°16 = 65536 caratteri univoci. RAPPRESENTAZIONE BINARIA DI SUONI E IMMAGINI Il suono è un'informazione di tipo analogico. In una rappresentazione digitale, i valori di un dato oggetto sono tratti da un insieme finito come lettere o da un sottoinsieme di interi. In una rappresentazione analogica, gli oggetti possono assumere qualsiasi valore. Nel caso del suono, per esempio, una nota è una forma d'onda sinusoidale continua che varia in modo periodico regolare nel tempo. L'ampiezza dell'onda, ovvero l'intervallo compreso tra i valori massimo è minimo che essa può assumere, è una misura della sua intensità sonora: maggiore è l'ampiezza, più forte è il suono. Il periodo dell'onda, indicato come T, è il tempo necessario all'onda stessa per completare un ciclo. La frequenza f è il numero totale di cicli per unità di tempo, misurata in cicli al secondo, o hertz. La frequenza determina l'altezza del suono. Più alta è la frequenza, più alta è la nota percepita. Per memorizzare in un computer una forma d'onda, il segnale analogico deve prima essere digitalizzato, ossia convertito in rappresentazione digitale. Per fare ciò è possibile utilizzare la tecnica del campionamento. A intervalli fissi, l'entità del segnale, ovvero il valore da questo assunto rispetto al valore 0 di riferimento, viene misurata e memorizzata come valore intero. L'onda viene così rappresentata in forma digitale nel computer come sequenza di valori numerici campionati. Ciascun campione così ottenuto deve quindi essere convertito in un valore numerico, intero o reale. Per fare questo si procede con un processo chiamato quantizzazione, che consiste, in modo semplificato, nello stabilire il numero di bit che si intendono assegnare ai campioni, e il tipo di rappresentazione del dato, se intero o reale. Da questi valori digitalizzati il computer può ricreare un' approssimazione dell'onda analogica originale. La precisione con la quale il suono originale può essere riprodotto dipende da due parametri chiave: la frequenza di campionamento e la risoluzione in bit. La frequenza di campionamento misura quante volte al secondo si esegue il campionamento dell'ampiezza dell'onda sonora. Ovviamente, maggiore è la frequenza di campionamento, più precisa è la riproduzione. Maggiore è la frequenza di campionamento, maggiore è l'intervallo di frequenze sonore che può essere catturato se la frequenza di un'onda è maggiore o uguale alla frequenza di campionamento, esiste il rischio teorico di non campionare alcun punto sull'intera forma d'onda. Questa frequenza di campionamento produce un valore di ampiezza costante, deformando completamente il suono originale. La risoluzione è il numero di bit utilizzato per codificare ciascun campione. Oggigiorno sono in suo molti formati di codifica audio, tra cui WAV, AU, QuickTime e RealAudio. Il formato più famoso è MP3. Con MP3 si esegue il campionamento dei segnali audio a una frequenza di 44100 campioni al secondo, usando 16 bit per campione --> suono di alta qualità.

Queste due tecniche sono esempi di schemi di compressione senza perdita. Ciò significa che non si perde alcuna informazione nella compressione ed è possibile riprodurre i dati originali. Gli schemi di compressione con perdita, invece, comprimono i dati in un modo che non garantisce che tutte le informazioni nei dati originali possano essere ricreate completamente. AFFIDABILITÀ DELLA RAPPRESENTAZIONE BINARIA I computer utilizzano la rappresentazione binaria non per motivi teorici, ma per motivi di affidabilità. Con l'invecchiamento i dispositivi elettrici tendono a diventare inaffidabili e potrebbero manifestare devianze o cambiare il loro stato energetico. Il problema della rappresentazione in base 10 è che richiede la memorizzazione di 10 simboli univoci, rendendo perciò necessari dispositivi con 10 stati stabili. Tali dispositivi sono rari. I sistemi elettrici tendono a funzionare in un ambiente bistabile, nel quale vi sono solo due Stati stabili separati da una barriera energetica di notevoli dimensioni. Ciascun transistor contiene tre connettori: due di ingresso e uno di uscita. La prima linea di ingresso, chiamata controllo o base, viene utilizzata per aprire o chiudere l'interruttore all'interno del transistor. In questo stato la tensione proviene dalla linea Ingresso, chiamata collettore, viene trasferita direttamente alla linea Uscita, chiamata emettitore, e questa tensione può essere rilevata mediante un dispositivo di misura. Lo stato OFF può essere utilizzato per rappresentare il valore binario 0. LOGICA BOOLEANA La costruzione dei circuiti del computer si basa sul ramo della matematica e della logica simbolica denominato logica booleana. Quest'area tratta le regole di manipolazione dei due valori logici vero (true) e falso (false). È facile vedere la relazione tra la logica booleana e la progettazione di un computer: il valore vero può rappresentare il valore binario 1 e il valore falso può rappresentare il valore binario 0. Definiamo un'espressione booleana come qualsiasi espressione che dà come risultato vero o falso. Nella logica booleana, le operazioni utilizzate per costruire le espressioni booleane sono AND, OR e NOT. La regola per eseguire le operazioni AND è la seguente: se a e b sono espressioni booleane, il valore dell'espressione (a AND b), scritta anche come (a. b), è vero se e solo se a e b hanno valore vero; altrimenti, l'espressione ha il valore falso. Questa regola afferma che l'operazione AND produce il valore vero se e solo se entrambi i suoi operandi sono veri. Tabella di verità: La seconda operazione booleana è OR. La regola è la seguente: se a e b sono espressioni booleane, il valore dell'espressione booleana (a OR b), scritta anche come (a+b), è vero se a è vero, se b è vero o se entrambi sono veri. Altrimenti, (a OR b) ha il valore falso. Ingressi Uscita a b a AND b (scritto anche a. b) Falso Falso Falso Falso VERO Falso VERO FALSO Falso VERO VERO Vero

Tabella di verità: L'ultimo operatore booleano è NOT. Diversamente da AND e OR, che richiedono due operandi e sono pertanto chiamati operatori binari, NOT richiede soltanto un operando ed è un operatore unario. La regola di valutazione dell'operazione NOT è la seguente: se a è un'espressione booleana, il valore dell'espressione (NOT a), scritta anche come ä, è vero se a ha il valore falso ed è falso se a ha il valore vero. Tabella di verità: In modo informale si dice che l'operazione NOT inverte o complementa il valore di un'espressione booleana, rendendola Vera se è falsa e viceversa. Ingressi Uscita a b a OR b (scritto anche a + b) Falso Falso Falso Falso VERO Vero VERO FALSO Vero VERO VERO Vero Ingressi Uscita a NOT a (scritto anche ä) Falso VERO VERO FALSO

Per realizzare una porta OR, si inizia nuovamente con due transistor. Tuttavia, questa volta essi vengono connessi in parallelo invece che in serie. Se Controllo 1 o Controllo 2 sono impostati a 1, il transistor corrispondente si trova nello stato ON e la corrente produce un valore di uscita 0. Solo se entrambe le linee di controllo sono 0, chiudendo entrambi i transistor, la linea di uscita contiene

  1. Questo è l'esatto opposto della definizione di OR. Per ottenere una porta OR si procede come in precedenza: si aggiunge una porta NOT alla linea d'uscita. Il motivo che porta invece dei transistor è che questi ultimi sono dispositivi troppo elementari per agire come componente di progettazione fondamentale. COSTRUZIONE DI CIRCUITI PER COMPUTER Un circuito è un insieme di porte logiche che trasforma una serie di ingressi binari in una serie di uscite binarie e in cui i valori delle uscite dipendono esclusivamente dai valori di corrente degli ingressi. Dal punto di vista interno, il circuito è realizzato con porte AND, OR e NOT. Queste porte possono essere interconnesse in qualsiasi modo, purché le connessioni non violino i vincoli sul numero appropriato di ingresso e uscita per ciascuna porta. Ogni porta AND è ORMAI deve avere esattamente due ingressi e un'uscita. Ogni porta NOT deve avere esattamente un ingresso e un'uscita. Esiste una relazione diretta tra le espressioni booleane e i diagrammi circuitali di questo tipo. Ogni espressione booleana può essere rappresentata visivamente come un diagramma circuitale e ogni valore di uscita in un diagramma può essere scritto come espressione booleana. Il valore che appare su qualsiasi linea di uscita di un circuito può essere determinata se si conoscono i valori di ingresso e le trasformazioni prodotte da ciascuna porta logica. Esiste un gran numero di algoritmi per la progettazione di circuiti logici. Il circuito comparatore Il primo circuito è un circuito comparatore di uguaglianza, detto CE, che determina se due numeri binari senza segno sono uguali. Il circuito produrrà in uscita il valore 1 (vero) se i due numeri sono uguali, 0 (falso) in caso contrario. Il circuito sommatore Il secondo esempio è un circuito per la somma di tre bit, chiamato sommatore completo (o full adder) e indicato come 1-ADD. Sommare tre bit a, b, c dà luogo a un risultato che è un numero di due bit, che indicheremo con r (riporto) e s (somma). Il circuito logico è costituito dai tre ingressi a, b, c e dalle uscite somma (s) e riporto (r). Poiché il circuito possiede due uscite, l'analisi può essere svolta separatamente per ciascuna uscita. I circuiti di controllo Questi sono utilizzati per determinare l'ordine con il quale vengono eseguite le operazioni e per selezionare i valori dei dati corretti da elaborare. Questi circuiti sono essenziali per il corretto funzionamento di un computer perché, come si è visto, gli algoritmi e i programmi devono essere ben ordinati e devono sempre sapere quale operazione eseguire in seguito. I due tipi principali di circuito di controllo sono denominati multiplexer e decodificatore. Un multiplexer è un circuito che ha 2°n linee di ingresso e una linea di uscita. La sua funzione è quella di selezionare esattamente una delle 2°n linee di ingresso e copiare il valore binario corrispondente sulla singola linea di uscita. Un multiplexer sceglie un ingresso specifico mediante un set aggiuntivo di N linee dette linee di selezione. Il decodificatore funziona in modo opposto rispetto al multiplexer. Un decodificatore ha N linee di ingresso numerate 0, 1, 2, N -1 e 2°N linee di uscita numerate 0, 1, 2, 3, ..., 2°N - 1. Ciascuna delle N linee di ingresso del decodificatore può essere impostata a 0 o a 1 e quando questi N valori vengono interpretati come singolo numero binario, possono rappresentare tutti i valori interi da 0 a 2 °N -1. È compito del decodificatore determinare il valore rappresentato sulle

sue N linee di ingresso, quindi inviare un segnale (ossia 1) sulla singola linea di uscita che ha tale numero identificativo. Tutte le altre linee di uscita sono impostare a 0. Insieme, i circuiti decodificatore e multiplexer consentono di realizzare computer che eseguono le istruzioni corrette usando i valori di dati corretti. Mentre un circuito decodificatore può essere utilizzato per selezionare l'istruzione corretta, un multiplexer può aiutare ad assicurare che il computer esegua questa istruzione con i dati corretti. Cap. 8 'IL SOFTWARE' I linguaggi di programmazione di alto livello sono stati creati per superare questi problemi. Perciò, da un programma scritto in un linguaggio di alto livello ci aspettiamo che: _ il programmatore non debba occuparsi dei dettagli circa lo spostamento degli elementi di dati in memoria, o il punto esatto in cui tali elementi sono registrati; _ il programmatore possa osservare le attività da un punto di vista macroscopico, ragionando a un livello più alto di risoluzione dei problemi; _ i programmi siano portabili e non specifici della macchina; _ le istruzioni di programmazione siano più vicine al linguaggio naturale e utilizzino la notazione matematica standard. I linguaggi di programmazione di alto livello sono spesso detti linguaggi di terza generazione. Questo livello di astrazione più alto comporta un prezzo da pagare: quando siamo passati dal linguaggio macchina al linguaggio assemblativo, ci è servito un componente del software di sistema, un assemblatore, per tradurre le istruzioni del linguaggio assemblativo in linguaggio macchina. Il software di sistema corrispondente si chiama compilatore. Invece di tradurre direttamente in codice oggetto, spesso il compilatore traduce le istruzioni di alto livello in un codice di basso livello abbastanza vicino al linguaggio macchina, lasciando il passaggio finale a un altro traduttore. Un programma può richiedere una copia di tale codice oggetto, per includerla nel proprio. Un componente del software di sistema detto linker inserisce il codice oggetto richiesto dalle librerie di codice nel codice oggetto del programma richiedente. Potrebbe sembrare che, se tutti i programmi per computer fossero scritti nello stesso linguaggio di programmazione, tutto sarebbe più semplice. In realtà, esistono più linguaggi di programmazione non tanto perché alcuni compiti possono essere eseguiti da uno e non dall'altro, ma perché ogni linguaggio è progettato per soddisfare esigenze specifiche. Il principale motivo che ha portato alla moltiplicazione dei linguaggi di programmazione è la proliferazione delle attività di programmazione. LINGUAGGI PROCEDURALI Un programma scritto in un linguaggio procedurale è costituito da sequenze di istruzioni che elaborano dati, accedono alla memoria e trasferiscono informazioni da e verso i dispositivi periferici. I linguaggi procedurali derivano direttamente dall'architettura di Von Neumann, caratterizzata da cicli sequenziali prelievo-decodifica-esecuzione. Questa architettura, nella quale la memoria è punto di partenza ed arrivo del ciclo di esecuzione delle istruzioni e dei dati su cui esse operano, giustifica la progettazione di un linguaggio in cui le operazioni di base siamo la lettura e la scrittura di dati. I linguaggi procedurali possono differire nel modo in cui le istruzioni devono essere disposte su una riga e nel modo in cui si possono definire i nomi nelle variabili, oltre che nel modo in cui si assegna un nuovo valore a una variabile, nel meccanismo fornito dal linguaggio per il controllo del flusso tramite istruzioni condizionali e cicli, e nelle istruzioni di ingresso e uscita. Tutti i linguaggi procedurali indicano al computer, passo per passo, come manipolare il contenuto dislocazioni di memoria. La gestione della complessità Tra gli aspetti da gestire nella fase di sviluppo del software va considerata la scelta dell'approccio da seguire per prevenire alla soluzione del problema. Nella programmazione procedurale si adotta spesso una metodologia di suddivisione del problema in sottoproblemi.

Un'interfaccia utente grafica con finestre, icone, pulsanti, è un esempio di quanto si può ottenere con la programmazione orientata agli oggetti. LINGUAGGI PER SCOPI SPECIFICI Uno di questi linguaggi specializzati è SQL progettato per essere utilizzato nella definizione, modifica e interrogazione di basi di dati. Un'altra classe di linguaggi adibiti ad usi speciali e che tuttavia non sono linguaggi di programmazione sono i linguaggi di marcatura tra cui si annoverano XML e HTML, molto usati nella creazione di pagine ed applicazioni per il World Wide Web. Entrambi questi linguaggi si basano sul concetto di "marcatore" o tag. Un tag è una particolare stringa di testo compresa tra i caratteri < e > utilizzata per delimitare una porzione di testo e che indica ad un apposito software di interpretazione il tipo di elaborazione da svolgere sul testo delimitato. In HTML l'insieme di tag utilizzabile è fisso. Per consentire la creazione di tag personalizzati è stato sviluppato XML. Le pagine HTML scritte con i soli tag sono immodificabili o statiche. Un linguaggio di scripting è un linguaggio "leggero". JavaScript è un linguaggio di scripting orientato agli oggetti con una sintassi simile a quella di Java, ma molto meno complesso, che possiede oggetti predefiniti i cui metodi sono in grado di manipolare dinamicamente il contenuto, cioè i tag. In questo modo è possibile elaborare i dati inseriti in un modulo di registrazione a un servizio su Internet per verificarne la completezza e correttezza, e avvertire l'utente di completare il modulo nei punti errati o mancanti, impedendo che questi vada oltre nel processo di registrazione al servizio. PARADIGMI DI PROGRAMMAZIONE ALTERNATIVI Un paradigma è un modello o struttura mentale per rappresentare o ragionare su qualche cosa. Il paradigma dei linguaggi di programmazione procedurali dice che al computer è fornita una sequenza di istruzioni dettagliate. Il risultato finale di tutte le manipolazioni delle celle di memoria è la soluzione del problema. La programmazione in un linguaggio procedurale consiste in:

  • Pianificare l'algoritmo;
  • Catturare le operazioni non ambigue ed effettivamente calcolabili come istruzioni di programma. Dobbiamo prestare attenzione ai dettagli con cui il computer eseguirà l'attività desiderata. Tra i paradigmi alternativi per i linguaggi di programmazione vi sono quelli che considerano le azioni di un programma come:
  • Una combinazione di varie trasformazioni su elementi;
  • Una serie di deduzioni logiche da fatti noti;
  • Più copie della stessa sottoattività o più sottoattività dello stesso problema svolte simultaneamente da diversi processori. Un linguaggio di programmazione funzionale vede ciascun compito in termini di funzioni. Una funzione è intesa in senso matematico come una trasformazione di un insieme di valori in ingresso in un unico valore in uscita, sulla base di un algoritmo. Il linguaggio possiede già alcune funzioni primitive. La programmazione funzionale specifica un insieme di trasformazioni dei dati e loro combinazioni che eseguite conducono alla soluzione del problema. Nella programmazione logica vengono asseriti come veri un insieme di "fatti" e sulla base di essi un programma logico cerca di inferire o dedurre altri fatti. Quando si pone una richiesta al programma esso inizia con un'analisi dei fatti in suo possesso e tenta di applicare nel modo più efficiente possibile una sequenza di deduzioni logiche per produrre una risposta. Un programma logico è correlato a un dominio di interesse nell'ambito del quale le asserzioni hanno senso e le querela eseguibili devono essere correlate allo stesso dominio. La programmazione logica è stata utilizzata per la realizzazione di sistemi esperti. CICLO DI VITA DEL SOFTWARE
  1. Studio di fattibilità. Questo passaggio valuta un progetto proposto calcolando costi e benefici di un sistema informatico. Il costo complessivo relativo all'uso del computer per risolvere un

problema può essere molto più alto di quello previsto, e superare il valore delle informazioni prodotte. Al termine dello studio, un documento di fattibilità esprime i risultati, consigliando se procedere con l'acquisto di hardware e software.

  1. Specifica del problema. I progettisti software e i clienti devono risolvere ogni incoerenza, ambiguità o contraddizione. Il documento di specifica del problema riporta su carta la specifica finale e completa e guida gli sviluppatori in tutte le decisioni successive. Tale documento descrive come si composta il programma in tutte le circostanze. Una volta ottenuto l'accordo tra sviluppatore e cliente, questo documento diventa un contratto legale che descrive ciò che lo sviluppatore promette di fornire e che il Cliente accetta.
  2. Progettazione del programma. In questa fase si identificano gli oggetti appropriati, insieme ai loro dati e alle sottoattività che devono svolgere. Questo consente di progettare classi con le necessarie variabili istanza per memorizzare i dati e i metodi per eseguire le sottoattività. Il documento di progetto del programma deve riflettere la scomposizione del problema complessivo. Le classi devono essere identificate, con le variabili istanza e le sottoattività. La progettazione del programma è una delle fasi più creative e interessanti del ciclo di vita dello sviluppo di software.
  3. Selezione e sviluppo degli algoritmi e analisi. La documentazione di questa fase include una descrizione degli algoritmi scelti o sviluppati, eventualmente in pseudo codice, e dei motivi che hanno portato a utilizzarli.
  4. Codifica. La codifica è il processo con cui si traducono i progetti dettagliati di classi e algoritmi in linguaggio di programmazione.
  5. Debugging. Il debugging è il processo in cui si individuano e correggono gli errori di programma; può essere una fase lenta e costosa che richiede altrettanto impegno della scrittura del programma originale. Questi errori di sintassi sono accompagnati da messaggi del compilatore che facilitano l'individuazione del problema. Esistono anche gli errori di routine ed errori logici. Il debugging è sempre stato uno dei passaggi più frustranti, lunghi e noiosi nella programmazione.
  6. Collaudo, verifica e valutazione delle prestazioni (benchmarking). Il collaudo empirico implica la progettazione di una serie di casi di prova ed esegue il programma con tali dati. La verifica del programma può essere impiegata per dimostrare che dopo l'esecuzione del programma su questi dati, i dati di uscita soddisferanno certe altre condizioni. La specifica del problema potrebbe richiedere alcune caratteristiche prestazionali come il tempo richiesto per calcolare i risultati.
  7. Documentazione. La documentazione del programma è tutto il materiale scritto che lo rende comprensibile. Comprende la documentazione interna che si ottiene scegliendo nomi significativi per gli identificatori di programma. La documentazione esterna è costituita dai materiali raccolti per facilitare la comprensione del programma. Esiste poi anche la documentazione tecnica e quella utente.
  8. Manutenzione. I programmi di successo vengono usati a lungo. Cap.10 'MODELLI DI CALCOLO' I modelli sono uno strumento importante per studiare molti fenomeni fisici e sociali. Un modello:
  9. Cattura l'essenza, cioè le proprietà fondamentali, dell'oggetto reale;
  10. Probabilmente differisce in scala dall'oggetto reale;
  11. è privo di alcuni dettagli dell'oggetto reale;
  12. Manca di alcune funzionalità dell'oggetto reale. I modelli possono migliorare la nostra comprensione del sistema reale a cui si riferiscono. Cambiando un aspetto nel modello possiamo vedere immediatamente gli effetti della modifica. Il vantaggio è che i modelli ci offrono un ambiente sicuro e controllato per verificare delle ipotesi, per controllare quale potrebbe essere l'effetto provocato da una modifica di un fattore nel sistema reale. Le informazioni fornite da un modello sono valide soltanto se lo sono le ipotesi effettuate nella sua creazione.