Appunti Di Informatica
Appunti Di Informatica
INFORMATIC
A
MODELLI E PYTHON
COMANDI DI PYTHON
# rappresenta un commento e non sono enunciati: servono a
fornire informazioni ai programmatori;
stringa: è una sequenza di caratteri racchiusa da una coppia di
virgolette, singole o doppie (‘ ‘ “”);
print() ci permette di visualizzare un valore;
funzione: è un insieme di istruzioni di programmazione che
servono a portare a termine un compito specifico;
pseudocodice: una descrizione informale di una sequenza di passi
che portano alla soluzione di un problema;
variabile: è una zona di memoria, dotata di un nome, in cui si
possono archiviare informazioni;
enunciato di assegnazione: memorizza un valore in una
variabile;
Numeri in Python: int, sono tutti i numeri interi sia positivi che
negativi, 0 è un numero intero;
float, sono tutti i numeri frazionari, in notazione esponenziale, con
esponente negativo o positivo;
costanti: si usano per quei valori che non sono soggetti a
modifiche durante l’esecuzione del programma (di solito si usa un
nome composto da sole lettere maiuscole);
% restituisce il resto;
// divisione intera, ignorando il resto;
** elevazione a potenza;
/ divisione;
-sottrazione;
+ addizione;
* moltiplicazione;
FUNZIONI MATEMATICHE
Per poter usare, in un programma, una funzione della libreria, è
necessario importarla: ‘from math import’:
abs(x) il valore assoluto di x;
round(x,n) il valore x in virgola mobile arrotondato in modo che sia
un numero intero o che abbia n cifre decimali
max(x1,x2,x3,…,xn) il valore maggiore tra quelli presenti come
argomenti;
min(x1,x2,x2,x3,…,xn) il valore minore tra quelli presenti come
argomenti;
sqrt(x) la radice quadrata di x (con x >=0);
trunc(x) tronca il valore x in virgola mobile, restituendo un
numero intero;
cos(x) il coseno di x, in radianti;
sin(x) il seno di x, in radianti;
tan(x) la tangente di x, in radianti;
exp(x) e^x;
degrees(x) converte x da radianti a gradi;
radians(x) converte x da gradi in radianti;
log(x) oppure log(x,base) il logaritmo naturale di x (cioè
logaritmo in base e) oppure il logaritmo di x nella base indicata;
STRINGHE
len() restituisce il numero di caratteri presenti in una stringa;
int e float convertono una stringa contenente un numero in tale
valore numerico;
stringa[n] restituisce il carattere nella posizione n della stringa;
s.lower la versione minuscola della stringa s ;
s.upper la versione maiuscola della stringa s ;
s.replace(old,new) una nuova versione della stringa s nella quale
ogni occorrenza della sottostringa old è stata sostituita con new;
input() serve per leggere dati forniti in ingresso mediante la
tastiera
chr(numero) restituisce il carattere corrispondente al numero nella
tabella UNICODE
ord(carattere) restituisce il numero corrispondente al carattere
nella tabella UNICODE
s.find(str) calcola la prima posizione di s in cui compare la
stringa str. Se la stringa str non compare in s restituisce -1
s.rfind(str) calcola la prima posizione di s in cui compare la
stringa str partendo dalla fine della stringa s. Se la stringa str non
compare in s restituisce -1
s.count(str) calcola quante volte str compare in s
OPERATORE DI FORMATO PER STRINGHE
“%d” si usa d per i numeri interi
“%5d” vengono aggiunti spazi in modo che l’ampiezza del campo sia
uguale a 5
“&05d” inserendo uno 0 prima dell’ampiezza del campo, vengono
aggiunti zeri al posto degli spazi
“Quality:%5d” i caratteri che si trovano nella stringa ma sono al di
fuori di un indicatore di formato vengono visualizzati normalmente
“%f” si usa f per i numeri in virgola mobile
“%.2f” visualizza due cifre dopo il punto decimale
“%7.2f” vengono aggiunti spazi in modo che l’ampiezza del campo
sia uguale a 7
“%s” si usa s per le stringhe
“%d %.2f” si può imporre il formato desiderato a più valori
“%9s” le stringhe vengono allineate a destra, in mancanza di
indicazione diversa
“%-9s” per allineare a sinistra si usa un carattere –
“%d%%” per visualizzare un segno di percentuale si usa %%
L’ENUNCIATO if
if consente ad un programma di compiere azioni diverse in
relazione alla natura dei dati che vengono elaborati; il carattere due
punti posto dopo una condizione identifica un enunciato composto.
OPERAZIONI RELAZIONALI
> maggiore
>= maggiore o uguale
> minore
<= minore o uguale
== uguale
!= diverso
+= alterna i caratteri di due stringhe
DIRAMAZIONI ANNIDATE
Quando un enunciato di decisione è contenuto nel ramo di un altro
enunciato di decisione, si dice che i due enunciati sono annidati ; le
decisioni annidate servono per risolvere problemi che richiedono
decisioni su più livelli.
DIAGRAMMI DI FLUSSO
I diagrammi di flusso sono costituiti da elementi che rappresentano
compiti da svolgere, acquisizioni e visualizzazione di dati e decisioni
da prendere; ogni ramo di una decisione può contenere compiti da
svolgere e altre decisioni da prendere; non far mai entrare una
freccia all’interno di una diversa diramazione.
A B A and B A
not A
True True True True
False
True False False False
True
False True False
False False False Per
invertire una condizione si usa l’operatore not.
A B A or B
True True True
True False True
False True True
False False False
ANALISI DI STRINGHE
sottostriga in s restituisce True se la stringa s contiene
sottostringa, altrimenti False
s.count(sottostringa) restituisce il numero di ricorrenze non
sovrapposte di sottostringa nella stringa s
s.endswith(sottostringa) restituisce True se la stringa s
termina con sottostringa, altrimenti False
s.find(sottostringa) restituisce il più basso valore dell’indice
nella stringa s dove inizia una occorrenza sottostringa, oppure -1 se
sottostringa non ricorre in s
s.startswith(sottostringa) restituisce True se la stringa s
inizia con sottostringa, altrimenti False
s.isalnum restituisce True se la stringa s è costituita da sole
lettere o cifre e contiene almeno un carattere, altrimenti False
s.isalpha restituisce True se la stringa s è costituita da sole
lettere e contiene almeno un carattere, altrimenti False
s.isdigit restituisce True se la stringa s è costituita da sole cifre
e contiene almeno un carattere, altrimenti False
s.islower restituisce True se la stringa s contiene almeno una
lettera e tutte le lettere della stringa sono minuscole, altrimenti
False
CICLO While
Un enunciato while esegue ripetutamente istruzioni, finché una
specifica condizione è vera.
CICLO for
Il ciclo for viene usato per eseguire iterativamente istruzioni sugli
elementi di un contenitore (stringa, liste, ecc...)
range scandisce ogni singola lettera della stringa
FUNZIONI
Una funzione è una sequenza di istruzioni a cui viene dato un nome;
quando una funzione viene invocata, le vengono forniti i suoi
argomenti; il valore restituito è il risultato che ha calcolato. Essa si
introduce con def e il suo valore con return.
LISTE
[] crea una nuova lista vuota o contenente inizialmente gli
elementi forniti
[elem1,elem2,elem3,....]
values*num crea una lista replicando num volte gli elementi della
lista values;
APRIRE UN FILE
Per aprire un file, occorre fornire il suo nome, oltre alla modalità di
apertura;
infile = open(“input.txt”, “r”) per la lettura
outfille = open(“output.txt”, “w”) per la scrittura
Per leggere le righe di testo da un file, si può usare un ciclo for che
operi sull'oggetto di tipo file
for line in infile:
print(line)
ESPRESSIONI REGOLARI
Prima di tutto bisogna importare le funzioni attraverso import re
* lunghezza qualsiasi
+ lunghezza maggiore o uguale a uno
{1,3} lunghezza da uno a tre
[0-9]{1,2}/[0-9]{1,2}/[0-9]{4,4}
[0-9]{1,2} = una o due cifre
[0-9]{4,4} = quattro cifre
{4,4} si può anche scrivere {4}
espressione regolare:
tre maiuscole
spazio
tre maiuscole
spazio
due cifre, una maiuscola, due cifre
spazio
maiuscola, tre cifre, maiuscola
[0-9]{1,2} (gennaio|febbraio|marzo|aprile|maggio|giugno|
luglio|agosto|settembre|ottobre|novembre|dicembre) [0-9]
{4} scrive una data con il nome dei mesi
{n,m} ripetizioni
…
import re
ris = re.finditer(esprReg2,testo2,re.IGNORECASE)
ris = re.finditer(esprReg4,testo2,re.IGNORECASE)
len(l6) righe
len(l6[0]) colonne
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14,
15]]
mat[2][3]= 11
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
def leggiMatriceFile(file):
f = open(file, 'r', encoding = 'UTF-8')
mat = [] inizializzo la matrice
dim = f.readline().split() leggo le dimensioni
righe = int(dim[0])
colonne = int(dim[1])
for i in range(righe):
riga = f.readline().split() leggo una riga
for j in range(colonne):
riga[j] = int(riga[j]) converto le stringhe in
numeri
mat.append(riga) inserisco la riga nella
matrice
return mat
def leggiMatriceFile1(file):
f = open(file, 'r', encoding = 'UTF-8')
dim = f.readline().split() leggo le dimensioni
['2','3']
righe = int(dim[0])
colonne = int(dim[1])
mat = [[0 for i in range(colonne)] for j in
range(righe)]
inizializzo la matrice
for i in range(righe):
riga = f.readline().split() leggo una riga
for j in range(colonne):
mat[i][j] = int(riga[j]) converto le stringhe in
numeri e li assegno alla
return mat matrice
print(open('matrice.txt',encoding='UTF-8').read())
print(leggiMatriceFile('matrice.txt'))
print(leggiMatriceFile1('matrice.txt'))
4 6
12 3 0 4 1 7
3 -2 3 7 11 0
6 8 9 11 2 -11
0 11 34 -1 9 -3
def maxMatrice1(mat):
massimo = mat[0][0]
maxi=0
maxj=0
for i in range(len(mat)):
for j in range(len(mat[0])):
if mat[i][j] > massimo:
massimo = mat[i][j]
maxi=i
maxj=j
return massimo,maxi,maxj
m = leggiMatriceFile('matrice.txt')
print(maxMatrice(m))
print(maxMatrice1(m))
34
(34, 3, 2)
Funzione che prende in input una matrice e restituisce l'indice
della riga di somma massima presente
Assume che la matrice non sia vuota
def rigaMaxMatrice(mat):
massimo = sum(mat[0]) inizializzo il massimo alla somma
della prima riga
rigamax = 0
for i in range(len(mat)):
somma = sum(mat[i])
if somma > massimo:
massimo = somma
rigamax = i
return rigamax
m = leggiMatriceFile('matrice.txt')
print(rigaMaxMatrice(m))
3
Funzione che prende in input due matrici (mxn) della stessa
dimensione e restituisce una nuova matrice che è la somma
delle due
def sommaMatrici(mat1,mat2):
ris = [] inizializzo la matrice risultato
for i in range(len(mat1)):
riga = [] inizializzo la riga della matrice risultato
for j in range(len(mat1[i])):
riga.append(mat1[i][j] + mat2[i][j]) calcolo
la riga
ris.append(riga) completata la riga la inserisco nel
risultato
return ris
def sommaMatrici1(mat1,mat2):
m=len(mat1) righe
n=len(mat1[0]) colonne
ris = [[0 for j in range(n)] for i in range(m)]
inizializzo la
matrice risultato
for i in range(len(ris)):
for j in range(len(ris[0])):
ris[i][j]=mat1[i][j] + mat2[i][j] calcolo
elemento [i][j]
return ris
m1 = leggiMatriceFile('matrice.txt')
m2 = leggiMatriceFile('matrice2.txt')
print(sommaMatrici(m1,m2))
print(sommaMatrici1(m1,m2))
[[13, 6, 0, 0, 0, 15], [5, -4, 6, 14, 22, 0], [12, 16,
14, 17, 4, -13], [0, 13, 38, -2, 18, -6]]
[[13, 6, 0, 0, 0, 15], [5, -4, 6, 14, 22, 0], [12, 16,
14, 17, 4, -13], [0, 13, 38, -2, 18, -6]]
def moltiplicaMatrici(mat1,mat2):
m1 = len(mat1) calcolo il numero di righe delle prima matrice
n1 = len(mat1[0]) calcolo il numero di colonne delle prima
matrice
if len(mat2) != n1: in questo caso non si possono
moltiplicare
return 'Errore, dimensioni non corrette'
n2 = len(mat2[0]) calcolo il numero di colonne della
seconda matrice
#print(n,m,p)
def stampaM(mat):
for i in range(len(mat)):
for j in range(len(mat[0])):
print(mat[i][j],'\t',end = ' ') stampa la riga
separando con spazio
print() vado a riga nuova prima di stampare la
nuova riga
m1 = leggiMatriceFile('matrice3.txt')
m2 = leggiMatriceFile('matrice5.txt')
stampaM(m1)
print()
stampaM(m2)
print()
stampaM(moltiplicaMatrici(m1,m2))
print()
stampaM(moltiplicaMatrici1(m1,m2))
1 3 0
3 -2 3
1 3 1 1
3 -2 1 1
1 2 1 1
10 -3 4 4
0 19 4 4
10 -3 4 4
1 19 4 4
def leggiMatrice(file):
f = open(file,'r',encoding='utf-8')
dimensioni = f.readline().split() legge la prima riga
righe = int(dimensioni[0])
colonne = int(dimensioni[1])
mat = [[0 for j in range (colonne)] for i in
range(righe)]
for i in range(righe):
r=f.readline().split()
for j in range(colonne):
mat[i][j] = int(r[j])
f.close()
return mat
def sommaLaterali(m):
count=0
righe=len(m)
colonne=len(m[0])
for i in range(righe):
for j in range(1,colonne-1):
print(i,j)
if m[i][j]==m[i][j-1]+m[i][j+1]:
count+=1
return count
m=leggiMatrice('matrice1.txt')
print(sommaLaterali(m))
0 1
0 2
1 1
1 2
2 1
2 2
2
legge una matrice di interi da un file e cerca il massimo
restituisce il massimo e i suoi indici in una tupla
3 righe 4 colonne
3 8 5 7
6 1 1 0
5 5 4 5
def leggiMatrice(file):
f = open(file,'r',encoding='utf-8')
dimensioni = f.readline().split() legge la prima riga
righe = int(dimensioni[0])
colonne = int(dimensioni[1])
mat = [[0 for j in range (colonne)] for i in
range(righe)]
for i in range(righe):
r=f.readline().split()
for j in range(colonne):
mat[i][j] = int(r[j])
f.close()
return mat
def cercaMassimo(m):
mi=mj=0
massimo=m[0][0]
righe=len(m)
colonne=len(m[0])
for i in range(righe):
for j in range(1,colonne):
if m[i][j]>massimo:
massimo=m[i][j]
mi=i
mj=j
return massimo,mi,mj
m=leggiMatrice('matrice1.txt')
print(cercaMassimo(m))
(8, 0, 1)
COSA È UN CALCOLATORE
Cosa è un calcolatore Un sistema per la rappresentazione e
l’elaborazione di informazioni può
– raccogliere impressionati quantità di dati
– elaborare i dati secondo le istruzioni fornite producendo nuovi dati
– rendere disponibili questi dati in modo istantaneo e con
prospettive diverse a utenti diversi e in parti diverse del mondo
COSA È L’INFORMATICA
L'informatica ha a che fare con lo studio di risoluzione di problemi
(“problem solving”) per la cui soluzione si scrive un programma che
viene eseguito da un computer, l'informatica si basa su una serie di
tradizioni intellettuali che comprende aspetti della matematica e
l'ingegneria
PROGRAMMA:
Un programma è una sequenza di istruzioni scritte in un linguaggio
di rpogrammazione (e comprensibili da un calcolatore) che
realizzano l’algoritmo
DATI DI INGRESSO:
di solito un problema non deve essere una sola volta ma molte
volte con dati (di ingresso) diversi.
ELABORAZIONE DELL’INFORMAZIONE
RISOLUZIONE DI UN PROBLEMA:
1.Dato un problema si trova un algoritmo di soluzione
2.Si scrive l’algoritmo di soluzione in un programma comprensibile
da un calcolatore
3.Dato un programma, un calcolatore e dei dati di ingresso,
l’esecuzione del programma con i dati di ingresso sul calcolatore
risolve il problema su quei dati.
ALGORITMI
Un algoritmo è una “ricetta”, ovvero un procedimento, composto da
una sequenza di istruzioni elementari, che consente di risolvere un
problema.
un algoritmo deve verificare:
•I passi (le istruzioni) dell’algoritmo devono essere definiti in modo
chiaro e non ambiguo
•Efficace, nel senso che i suoi passi siano eseguibili da una
macchina
•Finito, nel senso che termina dopo un numero fissato di operazioni
PROGRAMMARE :
capacità di specializzare il dispositivo per attività complesse di
elaborazione dell’informazione;
Un programma è un algoritmo scritto in un linguaggio non ambiguo
e direttamente comprensibile dal computer.
LINGUAGGI DI PROGRAMMAZIONE
Per eseguire un programma scritto in un linguaggio ad alto livello
dobbiamo tradurlo nel linguaggio macchina Due possibilità
principali
• Compilatore: programma che traduce un linguaggio ad alto livello
in un linguaggio macchina
• Interprete: il programma scritto in linguaggio ad alto livello viene
simulato senza tradurlo completamente.
IL PROCESSO DI COMPILAZIONE
BUS
⬍ ⬍ ⬍
REGISTRI
UNITÀ LOGICO
ARITMETICA
CPU
SOTTOSISTEMA MEMORIA
BUS
MAR MDR
Controllo
Lettura/Scrittura
Celle di Memoria
ARCHITETTURA CPU
La CPU contiene diversi registri
•Registro Istruzione (IR): memorizza l’istruzione da eseguire
•Contatore di Programma (PC): memorizza l’indirizzo in memoria
della prossima istruzione da eseguire •Registri Dati (in numero
variabile): contengono dati utilizzati per i calcoli I registri della CPU
sono aggiornati dall’esecuzione dell’istruzione
ESECUZIONE DI UN’ISTRUZIONE
1. Caricamento di un’istruzione (Fetch): con l’informazione presente
nel PC si reperisce la prossima istruzione da eseguire che viene
memorizzata in IR
2. L’unità di controllo decodifica l’istruzione: si determina il tipo di
operazione e i dati coinvolti
3. Esecuzione dell’istruzione: a seconda dell’operazione richiesta si
usa la memoria, i registri l’unità di calcolo, l’ingresso/uscita… Inoltre
si aggiorna il PC per eseguire la prossima istruzione
4. Se l’istruzione è HALT il programma termina altrimenti si inizia
l’esecuzione di una nuova istruzione
CONVERSIONI
Per convertire un valore da una base a un'altra, si usa sempre la
definizione del valore di un numero:
Altri esempi:
convertire 101101 da binario a decimale
1×2 5 + 0×2 4 + 1×2 3 + 1×2 2 + 0×2 1 + 1×2 0 = 32 + 0 +
8 + 4 + 0 + 1 = 45
ADDIZIONI
La normale somma in decimale si fa con il solito sistema di mettere
i due addendi in colonna e sommare cifra con cifra più l'eventuale
riporto. Per esempio, 275+1754:
275+
1754=
---------
↓
5+4=9
↓
7+5=12, ossia 2 con riporto 1
↓
2+7+1=10, ossia 0 con riporto 1
↓ 1+1=2
----------
2029
In binario, 11011+100101:
10011+
100111=
-------------
↓ 1+1=due, in binario 10, ossia 0 con riporto 1
↓ 1+1+1=tre, in binario 11, ossia 1 con riporto 1
↓ 0+1+1=due, in binario 10, ossia 0 con riporto 1
↓ 0+0+1=1 ↓ 1+0=1
↓1
-------------
111010
È come in decimale, ma la somma fra le singole cifre va fatta nella
base considerata: in ottale 5+3+1=11, in binario 1+1+1=11.
SOTTRAZIONE
La sottrazione si effettua nel solito modo: si sottraggono le singole
cifre, con eventuale riporto di -1. Il sistema sfrutta ancora due
proprietà del sistema posizionale:
le due cifre nella stessa posizione sono moltiplicate per la
stessa potenza della base, per cui si può fare cifra-cifra;
le cifre vanno da 0 a b-1, per cui cifra-cifra-1 vale al minimo 0-
(b-1)-1=-b+0, che produce appunto il riporto massimo di meno
uno.
0 - - - - - - - - - - esponente
1 2 3 4 5 6 7 8 9 1
0
1 . 0 0 1 1 0 0 1 0 0 0 mantissa
20+2-3+2-4+2-7 = = 1+0,125+0,0625+0,078125 =
0 + 0.0011010111000
Nel caso di conversione fra due basi che sono l'una potenza
dell'altra, come nel caso di 2 e 16, allora si possono raggruppare le
cifre come per la conversione fra numeri interi. Per esempio, il
numero binario 0,11011000 è uguale all'esadecimale che ha cifre
1101=D e 1000=8, ossia 0,D8.
VIRGOLA MOBILE
Nella rappresentazione in virgola fissa si decide in anticipo il
numero di bit da usare prima e dopo la virgola. In quella mobile, si
usa sempre un numero prefissato totale di bit, ma la posizione della
virgola all'interno di questi può variare. Dal momento che il numero
cambia a seconda della posizione della virgola:
1023#2
valore 1023 con virgola in posizione due, ossia 10,23
21#5
valore 21 con virgola in posizione cinque, ossia 21000,0
7214#-3 valore 7214 con virgola in posizione meno tre, ossia
0,0007214
n = m × be
ALGORITMO DI SOMMA
Le operazioni necessarie per la somma sono facili da realizzare in
pratica. Il cambio di esponente è una divisione della mantissa per
una potenza di dieci e un aumento dell'esponente di questo valore.
Per esempio:
Per esempio, per sommare 994#3 con 6169#1 con quattro cifre
mantissa e due di esponente, si procede nel modo seguente:
aumentare l'esponente minore:
in questo caso l'esponente minore è quello del secondo numero, per
cui 7169#1 si trasforma in 007169#3; uguagliare il numero di cifre
delle mantisse:
dei due numeri 994#3 e 007169#3, il secondo ha più cifre; si
aggiungono zeri al primo, trasformando 994#3 in 994000#3
somma fra interi:
è una normale somma:
994000 +
007169 =
----------
1001169
Normalizzare:
è venuta una cifra in più, per cui occorre normalizzare; l'esponente
maggiore dei due numeri, cioò tre, va aumentato di uno:
l'esponente del risultato è quindi 3+1=4;
limitare le cifre:
il risultato della somma ha troppe cifre (sette invece di quattro); se
ne prendono solo quattro, per cui la mantissa del risultato è 1001;
Altro esempio: somma dei numeri 6002#-1 e 12#2 con quattro cifre
di mantissa e una di esponente:
esponente minore: 6002#-1=0006001#2
stesso numero di cifre: 12#2=1200000#2
somma:
0006001 +
1200000 =
-----------
1206001
non è aumentato il numero di cifre, non si diminuisce
l'esponente
risultato: 1206#2
In questo caso alla mantissa del primo numero sono stati aggiunti
tre zeri a sinistra. Se gli zeri fossero stati maggiori del numero di
cifre disponibili per la mantissa, si poteva concludere subito la
somma: il risultato era uguale all'altro numero.
0006001 + 0006 +
1200000 = 1200 =
----------- → --------
1206001 1206
In questo caso, 12#2 ha due cifre di mantissa, ma al massimo
potevano essere quattro. Quelle dopo sarebbero state zeri.
Sommate all'altro numero non avrebbero comunque prodotto un
riporto. Il risultato è quindi uguale a sommare i numeri con le cifre
in più e poi troncare il risultato.
LOGICA PROPOSIZIONALE
valori: falso, vero (oppure: 0 e 1)
SODDISFACIBILITÀ
formula F
verificare se ha un modello o
ppure: trovare un modello (se esiste)
modello = valori di ingresso che producono 1 in uscita
a ∧ b ∧ ¬a
Esempio:
¬b ∧ (a ∨ b) c
on a=1 e b=0
la formula è vera soddisfacibile
(a ∨ ¬b) ∧ ¬a ∧ (b ∨ a)
METODI AUTOMATICI
(a ∨ ¬b) ∧ ¬a ∧ (b ∨ a) =
applicando la regola (F∨c)∧(F∨¬c) = F:
(a ∨ ¬b) ∧ ¬a ∧ (b ∨ a) ∧ a = 0
infatti: a∧¬a=0
formula insoddisfacibile
SEMPLIFICAZIONE
(a E (NON b) E (NON c)) OPPURE (a E (NON b) E c)
a parole, due possibilità:
a E (NON b) E (NON c)
a E (NON b) E c
ossia a E (NON b), e poi o c oppure NON c
FATTOR COMUNE
(a E (NON b) E (NON c)) OPPURE (a E (NON b) E c) =
(a E (NON b)) E (c OPPURE (NON c)) =
a E (NON b)
lo stesso per l'altra sottoformula
FORMULA SEMPLIFICATA
((NON a) E b E (NON c)) OPPURE ((NON a) E b E c)
OPPURE (a E (NON b) E (NON c)) OPPURE
(a E (NON b) E c) = ((NON a) E b) OPPURE (a E (NON b))
circuito più piccolo
problema: semplificazione "a occhio"
con 100000 variabili invece di tre?
serve:
regole per semplificare
e un metodo automatico
IMPLICAZIONE
altra applicazione della logica proposizionale:
effettuare ragionamenti logici
Esempio:
Gino o sta a casa o sta al bar
Gino non sta a casa
conseguenza: Gino sta al bar
si esprime in logica proposizionale
IN LOGICA
Variabili:
casa=1 Gino sta a casa
bar=1 Gino sta al bar
IMPLICAZIONE
forma generale:
se formula, formula, … formula allora formula
per ogni valore delle variabili:
se le formule prima di "allora" valgono tutte uno
allora la formula dopo vale uno
A, B, C ⊧ Z
IMPLICAZIONE: SEMANTICA
COMPLESSITÀ
O-GRANDE
O-Grande esprime il costo (in termini di tempo) di un programma, e
serve per avere una stima di tempo sull'esecuzione del programma,
la notazione O non dà un tempo specifico misurato in secondi, ma
bensì una stima generale che varia a seconda dell'input così che
possiamo determinare quale tra due algoritmi sia il più efficiente.
Esempi di costi:
20×n efficiente
1000×n efficiente
4×n2 un po' meno efficiente
2n non efficiente
NOTAZIONE O: PRINCIPIO
considerare il tempo in funzione della grandezza dell'ingresso
prendere la parte che cresce di più
ignorare costanti moltiplicative
45×n2+1000×n+500 ⇒
45×n2 ⇒ n2
è O(n2)
NOTAZIONE O: DEFINIZIONE
un programma ha costo (in termini di tempo) O(f(n)) se:
il suo tempo di esecuzione è t(n) dove n è la grandezza
dell'input
esistono due costanti a e b tali che:
t(n) < a×f(n)+b
CASO PEGGIORE
La valutazione del costo di esecuzione di un programma fa
riferimento al caso peggiore, perché ci permette di fare una stima
nel caso in cui noi fornissimo dati molto grandi.;
COSTO MEDIO
il costo medio dipende dalle probabilità esempio, x in a:
x e gli elementi di a sono 0 o 1 probabilità indipendenti caso
medio: due passi valori interi qualsiasi sempre probabilità
indipendenti
caso medio = caso peggiore