300 likes | 486 Vues
Biologia Computazionale - Algoritmi. Programmi ed algoritmi. Quando si vuole risolvere un problema utilizzando un computer è necessario prima “disegnare” un algoritmo per la soluzione
E N D
Programmi ed algoritmi • Quando si vuole risolvere un problema utilizzando un computer è necessario prima “disegnare” un algoritmo per la soluzione • L’algoritmo deve essere indipendente dalla successiva implementazione (codifica) in un linguaggio di programmazione • L’algoritmo descrive un procedimento che, partendo da dati di input (l’istanza del problema), esegue un insieme di istruzioni o operazioni, in un ordine stabilito, che al termine produce come risultato (output) la soluzione del problema
Programmi ed algoritmi • I passi (istruzioni) dell’algoritmo devono essere • Finiti (l’algoritmo deve terminare) • Non ambigui • Terminare e produrre un output correttoper ogni istanza del problema • Ad esempio, una ricetta *non* è un algoritmo se scrive “aggiungere un pizzico di sale”; lo è se scrive “aggiungere 0,5 g di sale” • Ad esempio, dato il problema “Dati a, b, c risolvere l’equazione di secondo grado con coefficienti a,b,c” deve prevedere tutti i casi diversi che si possono presentare per i valori di a,b,c (equazione impossibile, di primo grado, etc.)
Programmi ed algoritmi • Per molti problemi (quelli più difficili!) possono esistere più metodi di soluzione e quindi più algoritmi • L’algoritmo migliore è quello più “efficiente”, ovvero quello che implementato richiede meno risorse di calcolo (tempo, spazio su memoria o su disco) per produrre una soluzione esatta • La “teoria degli algoritmi” si occupa di stimare - indipendentemente dall’implementazione - il numero di operazioni “atomiche” o elementari e lo spazio richiesti da un algoritmo, in modo da decidere a priori quale possa essere la soluzione migliore
Programmi ed algoritmi • Un algoritmo può essere descritto in vari modi, purché rispetti le condizioni precedenti • Ad esempio, si possono usare: • Linguaggio naturale • Diagramma di flusso • “Pseudocodice” • Il linguaggio naturale si presta a semplici algoritmi, ma già algoritmi per problemi “semplici” come l’equazione di secondo grado diventano di difficile “lettura” se descritti così “Se a è uguale a zero, allora è un equazione di primo grado, la cui soluzione, se b e c sono diversi da zero è data da meno uno per b diviso per c, altrimenti ....”
Diagramma di flusso • Un “diagramma di flusso” descrive il “flusso di calcolo” di un algoritmo • E’ suddiviso in blocchi: in ciascun blocco l’algoritmo compie un’operazione • Archi orientati (frecce) collegano un blocco all’altro, indicando la sequenza delle operazioni da compiere • Alcuni blocchi sono “condizionali” (o di “selezione”, di solito a forma di rombo), ovvero il blocco (istruzione) successivo dipenderà dalla condizione descritta dal blocco stesso: a seconda del fatto che la condizione sia soddisfatta o meno, saranno possibili due scelte per il passo successivo (e quindi ci saranno due archi uscenti)
Delta = b2-4ac Delta < 0? VERO FALSO Delta = 0? VERO FALSO Scrivi “l’equazione non ha soluzioni reali” x=-b/2a x1=(-b+Delta)/2a x2=(-b-Delta)/2a Scrivi “L’equazione ha due soluzioni coincidenti = x” Scrivi “L’equazione ha soluzioni x1 e x2”
“Pseudocodice” • “Simula” uno “pseudo” linguaggio di programmazione, e descrive l’algoritmo utilizzando le “pseudo-istruzioni” del linguaggio di programmazione • Lo pseudocodice deve comunque essere indipendente dal linguaggio in cui si scriverà il programma • Deve quindi contenere un insieme “minimale” di istruzioni che ci aspettiamo essere comuni a tutti i linguaggi (vedi dispense)
“Iterazioni” • E’ possibile fare ripetere all’algoritmo lo stesso insieme di operazioni un qualsiasi numero n di volte, senza bisogno di scriverle esplicitamente n volte • n può • essere un numero prefissato • una variabile il cui valore può variare durante l’esecuzione dell’algoritmo • dipendere dal fatto che una condizione venga soddisfatta o meno (ovvero, le istruzioni vengono ripetute finché la condizione è soddisfatta)
Esempio: calcola 2n Leggi n contatore = 0 potenza = 1 ESEGUIFINCHE’ (contatore < n) potenza = potenza * 2 contatore = contatore + 1 FINE ESEGUIFINCHE’ Scrivi “Due alla” n “è uguale a” potenza
“Pseudocodice” • Un programma per computer lavorerà su in insieme di “variabili” contenenti i dati del problema, soluzioni intermedie, soluzioni finali • Le variabili possono essere di tipo diverso, a seconda dei dati che trattiamo, ad esempio • Numeri interi • Numeri reali • Matrici • Parole costruite su un alfabeto • Vettori • .... • Anche in questo caso dobbiamo prevedere un insieme “minimale” di tipi di variabili su cui lavorare con lo pseudocodice
Variabili • I tipi di variabili disponibili e le relative operazioni dipendono dal linguaggio di programmazione • Possiamo considerare “universali” due tipi di variabile: • Variabile “numero” • Variabile “carattere” • Inoltre, possiamo prevedere la possibilità di gestire • Vettori o matrici di numeri • Sequenze di caratteri (o “stringhe”)
Variabili • La parola “ciao” è composta da quattro caratteri • In un computer è rappresentata come un array (o vettore) di quattro elementi carattere (detto stringa) • Quindi, se abbiamo una variabile di tipo stringa il cui valore è “ciao” (senza virgolette!) potremmo anche accedere a uno qualsiasi dei caratteri della parola
Variabile • Una variabile è definita da un tipo (numero, carattere, etc.) e da un nome • In un programma non si può (abbastanza logicamente) assegnare lo stesso nome a variabili diverse • Tutte le operazioni (assegnazione, confronto, etc.) devono essere effettuate su variabili dello stesso tipo • In perl le variabili (qualsiasi sia il loro tipo) sono precedute dal simbolo $, mentre i vettori dal simbolo @
Lo “pseudolinguaggio” • Possiamo assumere che il linguaggio di programmazione che usiamo conterrà operazioni: • Leggi/Scrivi (input/output) • Operazioni (e funzioni) matematiche • Assegnamento: assegnare un valore a una variabile • Selezione: SE(condizione)...ALLORA...ALTRIMENTI • Iterazione: ESEGUIFINCHE’(condizione) - esegue finché la condizione è vera • Iterazione: PEROGNI elemento IN collezione
Variabili • Mentre, intuitivamente, quando progettiamo un algoritmo una variabile può essere di qualsiasi tipo e/o assumere qualsiasi valore, nei linguaggi di programmazione ogni variabile ha un TIPO ben definito • Il tipo della variabile definisce l’insieme di valori che la variabile può assumere: • Booleano: vero/falso • Intero: un numero intero • “Floating point”: un numero con virgola (razionale!) • Carattere: uno dei 255 caratteri definiti dalla tabella ASCII associata al computer che state usando
Variabili e tipi • Linguaggi TIPIZZATI: quando si usa una variabile in un programma è necessario definire esplicitamente (la prima volta che la si usa) che tipo è associato ad essa, ad esempio: • int x = 10 • char c = ‘a’ • Linguaggi non tipizzati: quanto sopra non è necessario. E’ l’interprete del linguaggio che cerca di “indovinare” di che tipo di variabile si tratta sulla base dei valori associati ad essa (utile, ma pericoloso per chi programma!)
Variabili e tipi • In ogni caso, per qualsiasi di linguaggio di programmazione usiate, dovete abituarvi a pensare di fare fare assegnamenti/confronti/etc soltanto tra variabili dello stesso tipo ed è quindi necessario che, indipendentemente dal linguaggio, abbiate sempre chiaro quale tipo è associato a ciascuna variabile
Tipi di dati “derivati” • Abbiamo accennato all’istruzione “per ogni” PER OGNI elemento IN collezione_di_elementi ESEGUI ... • Come è possibile definire una “collezione” di elementi? • Il metodo più utilizzato è quello della “sequenza” (o “array”, vedi dispense pagine 20/21)
Stringhe • Una “stringa” (ovvero una sequenza di caratteri) è un tipo dato un po’ “particolare” • In alcuni linguaggi (es. C) è semplicemente vista come un array di caratteri • In altri (es. Perl) è invece un tipo dati a se stante, con alcune operazioni “comode” già predefinite
Stringhe • Ad esempio, in un linguaggio che contiene il tipo “stringa”, possiamo avere come operazioni associate: Date due stringhe s,t eq: (s eq t) “equal”, è vero se s è uguale a t, falso altrimenti ne: (s ne t) “not equal”, l’inverso di eq . : “concatenazione”, s.t è dato da una nuova stringa composta dai caratteri di s seguiti dai caratteri di t
Concatenazione di stringhe • s = “Ciao” • t = “come va?” • u = s.t (concatenazione) • Quale sarà il valore di u? • u = “Ciaocome va?” (non c’era uno spazio alla fine di s!)
Sottostringhe • Data una stringa di n caratteri s, una sottostringa t di s è a sua volta una stringa, composta da caratteri consecutivi di s s[i]s[i+1]s[i+2]...s[j] • Dove i >= 0 (ricordatevi che il primo elemento di una sequenza ha indice zero!), i < n, e j >=i
Sottostringhe • Quindi, se la stringa $s è “Ciao come va?”: • “Ciao” • “come” • “me v” • “ “ (uno spazio singolo) • “?” sono tutte sottostringhe di $s • Il comando sottostringa($s,i,j) restituisce la sottostringa di lunghezza j che inizia in posizione i • Quindi, nell’esempio sopra, ($s,0,4) restituirà “Ciao” • Quindi se $t = ($s,0,4) $t sarà la stringa “Ciao”
Iterazioni su array • Se abbiamo un array di n elementi, possiamo farli “scorrere” tutti utilizzando un “ciclo” PEROGNI, come avevamo visto prima • Si sfrutta il fatto che gli elementi dell’array sono “indicizzati” e quindi accessibili tramite il numero che rappresenta la loro posizione all’interno dell’array
Iterazioni su array $s = “Ciao” PER OGNI $i IN (0..3) scrivi $s[$i]; FINE PER OGNI • L’output sarà C i a o • Nota: un valore per una variabile carattere viene solitamente tra apici (‘), mentre per una stringa è tra virgolette (“) • $carattere = ‘a’ • $stringa = “stringa”
Esercizio Dati • Avete come input una sequenza di DNA (di lunghezza qualsiasi) • “Leggi” permette di leggere la sequenza di input e di memorizzarla in un array di caratteri • lunghezza(array) è un comando che permette di stabilire da quanti elementi è costituito un array • Scrivete un algoritmo che determini se e dove all’interno della sequenza sono contenuti codoni di start (ATG) • “Trattate” la sequenza di DNA come se fosse un array di caratteri
Esercizio (esempio) • Dato come input ACGACAATGACGACGT • L’output sarà Codone di start in posizione: 7 • Dato come input ATGACATTATGCAT • L’output sarà Codone di start in posizione: 1 Codone di start in posizione: 9 (notate che mentre in informatica si conta a partire da zero, in biologia una sequenza è numerata a partire da uno!)
Esercizio (complicato!) • Riuscite a scrivere in quale frame di lettura si trova ciascun codone di start trovato? • Riuscite anche a trovare se una sequenza contiene codoni di stop (qualsiasi tra TAA, TGA o TAG)? • Riuscite a fare lavorare il vostro script anche sul filamento inverso? • Riuscite a stabilire se, dato un codone di start ATG, esiste “a valle” un codone di stop “in frame”?