[Musica]
Ok. Eh,
oggi continuiamo con Space Complexity
che abbiamo iniziato ieri.
Vediamo un altro po' di classi, poi
chiudiamo su questo. Settimana prossima
faremo macchine con oracoli,
functional problems e chiudiamo. Poi
facciamo il mock exam l'ultimo giorno.
Ok.
Ah, alright.
Ok. Quindi, che abbiamo fatto ieri? Ieri
abbiamo introdotto questo concetto di
space complexity,
spaceed complexity classes
e abbiamo definito dispace, nespace e
così via. Dopodiché ci siamo focalizzati
su long space, non deterministic long
space. Abbiamo visto un paio di eh
abbiamo visto un paio di
problemi.
Questo prende
[Musica]
Abbiamo visto un paio di problemi. Ehm
l'ultimo che abbiamo visto è
Richability. abbiamo visto essere non
deterministic log space completo
e siccome c'è quel risultato che abbiamo
solamente accennato, non abbiamo
dimostrato, ma la dimostrazione non è
molto differente da quella similare su P
versus NP, abbiamo che se o è un
qualsiasi problema non deterministic log
space completo
fosse il log space deterministico,
allora L sarebbe uguale ML. Ok?
Quindi per questa ragione noi non
riteniamo che ritability sia in L, cioè
non riteniamo che sia possibile decidere
ritability in spazio logaritmico
deterministico. Ok? Però quello che
vedremo ora
è un risultato interessante riguardo la
complessità di Richanisce
fornirà il un passo intermedio per il
teorema di Sadic che vediamo vediamo più
tardi. Ok?
Allora, sebbene noi non siamo in grado
di dimostrare che richility
appartenga a L, che vi ricordo L è D
space
di log n.
Quello che siamo però in grado di
dimostrare
è che rich ability
appartiene a dispace
log square n.
Ok? Log square intendo che è questa cosa
qua, eh? log n quad.
Quello è polilogaritmico,
quindi noi siamo in grado di dimostrare
che utility sta là dentro. L'algoritmo
che dobbiamo tirar fuori è un algoritmo
un po' trucchiettoso,
e ci permette di, appunto, dimostrare
questa cosa qua. Adesso noi vediamo
com'è possibile collocare abbild
square log squared. Ehm,
e questo qua poi sarà in realtà un pezzo
di una costruzione che ci serve per
dimostrare poi un risultato abbastanza
generale sulle classi di complessità
spaziali. Ok,
allora
focalizziamoci su un esempio.
[Musica]
Ok. 1 2 3 4 e 5.
Supponiamo che vogliamo andare da S a T.
Ok? Quindi abbiamo un'istanza di
ricability in cui c'è quel grafo
orientato.
Il nodo sorgente è il nodo due, il nodo
destinazione è il nodo numero 5. Ok?
Questa qui è un'istanza sì o un'istanza
no? Del problema? È un'istanza sì. Ok?
perché ci sta un ci sta un un pass e in
particolare avremo che S poi andiamo
sul nodo 1, poi andiamo sul nodo 4, sul
nodo 3 e poi andiamo su T. Ok? Questo è
il path all'interno
di questo
di questo grafo. Allora, il trucco per
riuscire a risolverlo in spazio log
square
log square n
praticamente fare una ricerca binaria,
fare una specie di ricerca binaria.
Questo è il trucco per riuscire a
ottenere questo risultato. E allora è
sostanzialmente questo. L'osservazione
che facciamo è se esiste un pat per
andare
da S a t,
allora deve esistere un nodo intermedio,
tipo il 4 in questo esempio e ci deve
stare un path che va da s a 4 e da 4 a
t. Ok? Quindi la questione è che noi
sostanzialmente
possiamo andare a da un lato potremmo
gessarlo questo modo intermedio,
però visto che siamo in un dominio di
spazio invitato, potremmo provare a
usare lo spazio e riusarlo, no? Ci
proviamo tutti questi U, tanto noi li
scriviamo là in mezzo, li riscriviamo
sempre e quindi non stiamo abbessando,
li proviamo e manteniamo l'utilizzo
dello spazio. Ok? Quindi l'idea
sostanzialmente è questa. Se io voglio
sapere se ci sta un puff dal nodo S al
nodo T, allora io basto che basta che io
verifichi l'esistenza
di un nodo
a metà strada che possiamo chiamare U e
poi verificare che ci sia un
percorso da S verso U e poi da U verso
S. Ok? Quindi questo approccio è di tipo
ricorsivo, quindi noi ci inventiamo un
algoritmo ricorsivo che sfrutta
esattamente questo principio. Se io
voglio andare da S a tono
tre casi, sostanzialmente,
due casi base, abbastanza facile e un
caso dove applichiamo la ricorsione.
casi base sono s = t e allora
rispondiamo di sì. L'altro caso è
tcessivo di S e allora rispondiamo sì.
Se invece questo non accade, allora
proviamo sostanzialmente
tutti le U per vedere se ci sta un puff
da s a U che da U verso t. Ok? Questo è
intuitivamente
la l'approccio che utilizzeremo per
risolvere questo problema. Spazio C. Sì.
Allora, definiamo
questo algoritmo che chiamiamo
exists
pat
che prende quattro argomenti G, S, T e
K.
E questo algoritmo
risponde vero?
Se in G
es
un percorso
da S a t di lunghezza al + K. Ok? Quindi
questo è quello che noi facciamo in
questo vogliamo risolvere con questo
algoritmo. Ok? Son quattro parametri
GSTK.
È vero, no? che esiste un puff da S a T
dentro G di lunghezza K. Poi ovviamente
se noi chiamiamo exists
puff
Gst T e o A qu sono gli archi, allora
ovviamente questo algoritmo risolverebbe
il problema della rechability, ok? Se
noi gli diamo come vincolo di numero di
nodi tutti i nodi disponibili sul
grafico, ok?
Allora,
dobbiamo semplicemente trascrivere
quello che ci siamo detti prima.
Quindi caso uno, primo caso base, se K è
0,
allora
se S è T
accettiamo,
altrimenti
rifiutiamo. Ok.
[Musica]
Altro caso, se K è esattamente 1,
allora se ST
appartiene all'insieme degli archi, qui
abbiamo che G è la coppia VA,
dove V sono i vertici e A sono gli
archi.
Se ST è un arco in G, allora accettiamo,
altrimenti rifiutiamo.
Ok, finora ci siamo occupati dei casi
base della ricorsione.
Manca l'ultimo pezzo, il verificare
l'esistenza di questo U intermedio.
Allora, facciamo così. for
each you from the
if e qui facciamo le chiamate ricorsive
if exists puff
dove in g da s a u con al più k mezzi
nodi
and
exists
path
from G eh no,
from U to T con al più KZ
nodi. Allora, accettiamo.
Se nessuna di questa cosa funziona,
rifiutiamo.
Vedete tutto l'algoritmo? Yes. Qua
c'entra tutto. Ok. Allora, di nuovo
questo algoritmo che fa? Se noi abbiamo
K0 verifichiamo che sorgente e
destinazione siano lo stesso. Se sì
accettiamo, senò rifiutiamo. Se possiamo
fare al più un salto verifichiamo che T
sia un successivo di Ss. Se questo è il
caso accettiamo, senò lo rifiutiamo. Se
non siamo in nessuno di questi due casi,
quindi k è più grosso, noi verifichiamo
l'esistenza di un nodo intermedio e lo
facciamo con un for. Eh, quindi non lo
stiamo li stiamo provando tutti.
Facciamo delle chiamate ricorsive e ci
chiediamo, ma è vero che esiste un
percorso da S a U di lunghezza al + k/2
e un percorso da U verso t di lunghezza
al + k/2? Se sì accettiamo. Se per
nessuna di queste U riusciamo ad
accettare allora rifiutiamo. Percorso,
non ce ne sta. Ok? Quindi questo
algoritmo ci risolve il nostro
il nostro problema, ok?
Dobbiamo considerare, voi l'avete
trascritto perché mi serve spazio qua,
dobbiamo considerare qual è la
complessità spaziale di questo
algoritmo. Ok? Quindi vediamo quanta
memoria questo algoritmo necessiti.
Per il momento ignoriamo le chiamate
ricorsive, andiamo a guardare il resto.
Ok?
Allora,
per guardare il resto sostanzialmente
che ci serve a noi? Ci serve
dello spazio in memoria
per riuscire a
sapere chi sono S e T, perché noi
facciamo questi test, ok? Quindi sono o
dei puntatori verso il nastro di input
dove appaiono S e T nella descrizione
del grafo,
oppure, come dicevamo ieri, può essere
un ID, un ID di taglia logaritmica. Ok?
Quindi
a noi serve
due, potremmo dire registri di taglia
logaritmica, due due spazietti di taglia
logaritmica su worktape, uno per
registrare S, l'altro per registrare t,
che ci servono sia per questo test che
per questo test. Dopodiché ci serve un
altro spazio di taglia logaritmica per
tenere tracce di chi è l' corrente. Ok?
Questo qua. Quindi, se noi al momento
ignoriamo la parte delle chiamate
logaritmiche a noi servono tre
pezzettini,
le chiamate ricorsive, scusate. A noi
servono tre pezzettini di taglia
logaritmica. Ok? Quindi, a parte quello,
noi abbiamo che per memorizzare
S t e u serve spazio o di log n. Ok?
Notate che u
noi lo riscriviamo, cioè non è che noi
iniziamo a scriverlo sul nastro, è il
primo U, è il secondo U è il terzo U e
così via. Noi u lo scriviamo sul nastro
e poi lo ci riscriviamo sopra, quindi
risparmiamo spazio. Ok? Quindi se noi
ignoriamo le chiamate ricorsive
per una sola call a noi serve spazio
logaritmico. Ok? Quello che noi ci
dobbiamo chiedere adesso è siccome
questo algoritmo è ricorsivo e quindi su
stack andiamo a mettere tutte le
chiamate eccetera, lo spazio occupato
durante l'esecuzione è dato da quante
chiamate facciamo
per lo spazio di ognuna di queste
chiamate, ok? Quindi sull'altezza
massima dello ste noi lì potremo capire
quanto spazio staremo occupando in
memoria. Ok? Chiaro? Quindi ci dobbiamo
occupare di questa cosa. Andiamo a
vedere
l'albero della computazione ricorsiva
per questo per questo
algoritmo.
Supponiamo di avere exists path.
Qui abbiamo GST.
La chiamata iniziale è proprio sul
numero degli archi. Ok? In questo modo
abbiamo è la primissima chiamata GST,
numero degli archi.
Allora,
nella prima chiamata noi genereremo due
chiamate ricorsive,
ok? Per ogni U genereremo delle chiamate
ricorsive.
Adesso andiamo a guardare questa cosa
nello specifico.
Nel momento in cui andiamo a testare le
U diverse,
tutte queste chiamate ricorsive stanno
in memoria allo stesso momento
sulla primissima la primissima chiamata
di exist, no? Cioè c'è un for. Noi
questi U li consideriamo uno per volta.
Quindi, preso un u, facciamo due
chiamate ricorsive.
Allegria.
Exist path.
Andiamo da GSU
a mezzi
e l'altra è existat
Gut.
A mezzi, ok? Spazio là non ce n'è. A
mezzi c'è scritto là. Ok. Sì,
potremmoare una chiamata come per
esempio quella di sinistra prima.
Esattamente. Questa è l'osservazione che
facciamo, cioè le due chiamate parall le
due chiamate per uno mica vengono
eseguite in parallelo, facciamo prima
uno e poi l'altro. Di conseguenza, noi
esploreremmo prima questa parte qua, poi
lui genererebbe altre due chiamate
ricorsive e questo qua ne genera altre
due e così via. Ma noi di questi
chiamate ricorsive, quando si forca ne
abbiamo sempre uno in memoria. Non ne
facciamo due contemporaneamente. Quando
ritorniamo dalla chiamata ricorsiva e
quello ci ha detto sì, va bene, a quel
punto facciamo partire l'altra. Ok?
Quindi ci sarà a un certo punto qui
arriviamo all'ultimo passaggio in cui
questo è caso base
e quest'altro è un caso base e quindi
noi avremo per esempio questo path di
chiamate ricorsive in memoria oppure
questo qua. Ma non li avremo tutti
assieme, ne avremo uno per volta, come
un attraversamento in profondità. è come
un attraversamento in profondità, però
delle chiamate ricorsive. Ok? È chiaro
questo? Questo è è la parte importante
di questa di questo ragionamento, cioè
che noi questo albero di computazione di
questo algoritmo di ricorsivo non sarà
mai
tutto completo in memoria. In memoria
abbiamo un solo branch. Ok? Questa è la
parte fondamentale dell'osservazione.
Ok. Adesso la nostra domanda. Noi
sappiamo dall'analisi di prima che
ognuno di questi
luoghi di esecuzione, record di
attivazione, cioè lo spazio di lavoro di
qualsiasi di queste chiamate ricorsive,
tipo questa qua, questa qua, questa qui,
questa qui e così via, ognuno di loro
prende spazio logaritmico. Ok? Adesso
noi ci chiediamo,
ma quanto è profondo questo albero?
Perché quello ce lo dice, perché a
questo punto è chiamata ricorsiva,
chiamata ricorsiva, chiamata ricorsiva,
spazio logaritmico. Altra richiamata
chiamata ricorsiva, spazio logaritmico.
Quindi avremo spazio logaritmico per il
numero di chiamate su step. Quante sono?
sono logaritmiche perché volta
perché ogni volta dimezziamo K. Ok?
Quello è il trucco. Siccome sto K noi lo
andiamo a dimezzare ogni volta, ecco
perché c'è il principio della ricerca
binaria, noi dimezziamo ogni volta a
quel K. Di conseguenza
la profondità di questa cosa è log a.
Ok?
Quindi su step nella peggiore delle
ipotesi avremo big o di log a chiamate
ricorsive, ognuna delle quali richiede
spazio logaritmico.
Da ciò, qual è la complessità spaziale
di questo algoritmo?
è O log a
O log N. E siccome A
fa parte dell'input e quindi è lineare
nell'input, avremo che questa cosa qui è
O di log squ N.
Quindi questo algoritmo
ha
uno spazio di esecuzione
polilogaritmico, cioè al quadrato di un
logaritmo.
Ok?
Chiaro per tutti come funziona questa
cosa? Quindi noi abbiamo dimostrato che
esiste una procedura
che ci permette di
eh decidere rich ability in spazio
quadratico logaritmico. Ok? Dice "Ah,
bello sto risultato, non ce ne facciamo
niente". Sì, in effetti. Però in realtà
questo costituisce la base di un teorema
molto più importante che è un teorema
che caratterizzi
le classi di
complessità
di
le classi di complessità spaziali, ok?
Che è il teorema di Savic.
Facciamo l'altra pagina.
Allora, il teorema di Savic è un teorema
abbastanza interessante
perché ci permette di dare dei risultati
che noi sulle classi temporali non siamo
in grado di fare. sulle classi spaziali,
probabilmente perché il riuso dello
spazio ci permette di avere molta
potenza,
noi siamo in grado di dimostrare una
cosa abbastanza interessante.
Quello è definito dopo. Vabbò.
Allora, il teorema di Savic ci dice
questo: sia SN
una space function,
quindi sia Snale
che
SDN
è
big Omega di log n, cioè, quindi s n
deve essere almeno logaritmica.
Questa cosa, questo risultato non vale
per space function che crescono meno di
logaritmo. Ok?
Allora,
abbiamo che n space
di SN
è contenuto in d space
di Sn².
Ok? Allora, questo è un risultato
interessante perché sostanzialmente ci
dice che tutto quello che è possibile
fare in spazio
non deterministico
per una certa funzione lo si può fare in
spazio deterministico con quella
funzione al quadrato. Ok? Quindi
significa che riusciamo a differenza
del gap per le classi temporali in cui
per passare da non deterministico a
deterministico abbiamo un salto di tipo
esponenziale.
Quando lavoriamo su classi spaziali il
salto è solamente quadratico, ok? che è
molto poco.
Allora, diamo giusto uno sketch, una una
bozza di dimostrazione non troppo
precisa, giusto per dare un'intuizione
di come di come si dimostri questo
teorema. Allora, per dimostrare questo
teorema noi dobbiamo sfruttare
due elementi.
La riduzione verso ritability che
abbiamo visto ieri, almeno il concetto,
cioè l'idea che avevamo utilizzato e
l'algoritmo che abbiamo visto stamattina
per la risoluzione in spazio log
squarespace di ritability. Ok?
Allora,
dimostrazione
sia L un linguaggio appartenente a
Nspace SDN,
quindi esiste
una macchina
M non deterministica,
tale che il linguaggio di M è
propriamente è proprio L
e il suo
running space
è s.
Ok?
Allora, di questa macchina M non
deterministica che riconosce il
linguaggio L, noi possiamo andare ad
analizzare il suo computation graph. Che
cos'è il computation graph? È la cosa
che abbiamo visto ieri quando
ragionavamo su reachability. è
sostanzialmente
un grafo
i cui nodi sono relativi ai vari stadi
computazione della macchina e ci sta un
arco che collega due nodi se un nodo è
il successivo del precedente rispetto
alla funzione di transizione di m. Ok?
Computation graph è il concetto che
abbiamo visto ieri quando ci siamo
inventati la riduzione vernicability è
quella cosa lì. Ok?
Allora, l'idea di base
per far vedere che L possa essere,
sebbene sia riconoscibile in spazio non
deterministico Sn per riconoscerlo in
spazio deterministico
Sn²,
quello che noi facciamo è questo,
l'intuizione
proprio semplice. costruiamo il suo
computation graph e per computation
graph intendiamo quello di er. Dopodiché
lanciamo l'algoritmo di ritability che
abbiamo visto stamattina su quel grafo e
a quel punto verifichiamo se esista un
percorso dal dalla configurazione
iniziale
a quel nodo che chiamavamo ieri in
vista. Ok? Tutto qua di nuovo. Quindi
prendiamo questi due pezzi che abbiamo.
La nozione di computation graph
introdotta ieri è l'algoritmo che
abbiamo visto stamattina che dimza i
percorsi. Ok? costruiamo quello, ci
lanciamo l'algoritmo sopra da S, che è
la configurazione iniziale a Vistar, che
era quel modo particolare in cui tutte
le configurazioni accettanti
concluiscono e ci chiediamo se esista
questo percorso o meno. Ok?
Per fare questo però ci dobbiamo
chiedere quanto grosso sia questo grafo,
ok? Perché adesso questo grafo lo
dobbiamo proprio rappresentare prima di
lanciarci sopra l'algoritmo che lo
risolve che risolve il problema
della
richility.
Ok?
Allora, come dicevamo ieri,
noi abbiamo che
i nodi del computation graph possono
essere distinti, non è necessario
scrivere tutta la la configurazione come
facevamo in passato. Quei nodi possono
essere distinti guardando a quattro
elementi. il contenuto del nastro di
lavoro, perché sono le uniche cose che
realmente cambiano. Il contenuto del
nastro di lavoro, la posizione della
testina sul nastro di input, la
posizione della testina sul nastro di
lavoro e lo stato corrente di
computazione. Quindi noi avremo che una
label
avrà il work tape, una label per questi
nodi del computation graph. Avrà un
pezzo di label che è il contenuto del
work tape. Poi abbiamo la posizione
della testina sul nostro di input, la
posizione della testina sul nastro di
lavoro e
un identificativo dello stato corrente.
Ok? È la cosa che abbiamo visto ieri.
Alri,
adesso facciamo lo stesso ragionamento
di ieri.
Quanto è grande questa parte di questa
label?
Se la macchina M esegue in spazio SDN.
Attenzione, eh no, no. Lo spazio usato
da M di running space di M è SDN. Sn è
SDN, quindi questo è big o dn. Ok?
Perché lo spazio che noi diamo
disponibile alla macchina M per eseguire
è proprio SDN. Quindi su workape noi
scriviamo bigo di SDN simboli. Ok?
Quanto è grande
il puntatore alla cella corrente sul
nastro di input?
Logaritmo di
il nastro di input. Il n quanto è lungo
l'input?
N. Quindi i puntatori alle celle del
nastro di input hanno taglia log
logaritmo di n, quindi qua log n. Ok,
prego. Ma eh non potremmo scrivere H1
come una codifica
dell'alfabeto di In che senso? Nel senso
sarà capitol da N ai elementi n singoli.
H1 sarà l'elemento
uno di quei n sing simboli, quindi dovre
essere scritto come,
cioè lei vorrebbe che, se ho capito bene
che l'alfabeto di nastro abbia tanti
simboli quanto la lunghezza della
stringa input. Ho capito bene? No, forse
non ho capito bene io come fatto questo?
Allora,
semplicemente questo. Noi abbiamo il
nastro di input che ha, che ne so, 16
celle. Sì, cioè la la stringa in input
ha
16 simboli, ok? Indicizzati 0 1 2 3 bla
bla 15. Se io devo memorizzare
dove si trovi la testina, allora a me
serve indicarlo con un numero in
posizione 10. Questo numero io lo posso
scrivere in rappresentazione binaria e a
quel punto a me servono logaritmo di n
bit per dire la testina sta lì.
Ok? Ma allora non potrei direttamente
considerare la sti hola indirettamente
il simbolo letto dalla testina?
No, perché se lei ha un simbolo ripetuto
in input, come fa a sapere a quale di
quello ci stiamo riferendo?
string copi cioè ci saranno tutti string
lavoro perché il work tap sarà cambiato
se la destin ma se io ho contenuto di un
work tape che è una certa cosa e dopo
dico h simbolo stellina e input della
stellina ce ne stavano cinque o se io
come faccio a sapere dove si trova la
testina? Cioè quello è il problema,
perché io devo spostarmi, devo fare la
foto di dove cosa sta facendo la
macchina. Io posso pure dire "Ok, leggo
la stellina". Però quando poi la
funzione di transizione mi dice va a
destra, magari una stellina c'ha la
casetta, dopo un'altra stellina c'ha
l'alberello e io come faccio a sapere la
testina cosa leggerà dopo se non so dove
sta la testina? Quindi io devo
memorizzare la posizione, non solo il
contenuto. Non è sufficiente quello per
ricostruire il funzionamento della
macchina. È più chiaro così? Nulla. Ok.
Quindi in H1
memorizziamo
la posizione
che è un numero, eh, non è che chissà
che stiamo facendo. La testina sa in
posizione 27. Ok? Dobbiamo fare la
stessa cosa per H2. Quanto è grosso H2?
log di s è log s n
e q
è una costante, ok? Perché il numero dei
degli stati non dipende da
Ok? Non dipende da eh dalla lunghezza
dell'input. Ok?
Allora,
poiché
guardate qui c'è questo elemento qua
che
è l'unico che tra virgolette non dipende
da SN. Ok? Siccome, e qui c'è
l'osservazione,
siccome
S nendo
essere almeno log n,
tutta la label
Sì, label
richiede
Big o D SDN. simboli.
Sì, sì, sì, c'ha
simboli.
Ok,
quindi noi abbiamo espresso un vincolo
su Sn. Siccome Sn non è più piccolo di
log n, allora non sarà mai questo il
leading term. Da per questa ragione noi
abbiamo che tutto lo spazio che ci serve
per rappresentare
questa label che poi utilizzeremo nei
nodi del computation graph è big o ddn.
Ok?
Alright. A questo punto possiamo fare
delle considerazioni sulla sul grafo,
no? sul grafo, su questo computation
graph che stiamo andando a costruire,
perché come vi dicevo, il nostro
obiettivo è
scriviamo il computation graph in
memoria, lanciamo l'algoritmo di
ricability, diamo la risposta. Quello
che noi ci stiamo chiedendo è quanto
occupa in memoria tutta questa
procedura. Quindi il primo pezzo che ci
serve è stabilire, ma questo grafo
quanto è grosso? Ok? Quindi noi abbiamo
che questi sono gli identificativi dei
nodi. Ok?
Ci chiediamo quindi quanti sono i nodi
di questo grafico. Allora, noi abbiamo
che su work tape ci possono stare i vari
simboli di nastro. Poi qua abbiamo la
codifica binaria, binaria binaria. Però
il tutto è bounded da cosa?
dalla quantità di nodi che si possono
generare se noi usassimo tutti i simboli
di nastro in tutte le posizioni, ok?
Quello è proprio al più e quello il
numero, ok?
Siano
L I
sia L. Scriviamo meglio.
Facciamo proprio così. Sia l la
cardinalità dell'alfabeto di nastro. Ok?
Allora, il numero di nodi è big o di
cosa?
S l elevato SN. Ragazzi, qua stiamo
proprio togliendo costanti eccetera,
facciamo proprio un'analisi raff, eh,
quindi è big o d^ s n
è il numero dei nodi
di questo grafo G, di questo computation
graph. Ok, so tantini, eh.
Quando rappresentiamo il grafo, facciamo
solo la lista dei nodi.
Ci servono gli archi. Gli archi in linea
di principio sono tutte le possibili
coppie dei nodi. Posso essere proprio
tante. Ok. Quanti sono gli archi? Big O
di cosa?
Attenzione, attenzione.
Se abbiamo
eh se abbiamo V nodi, no, un numero di
S,
eh abbiamo M nodi. Ok? Se abbiamo m
nodi, quanti sono al massimo gli archi?
Qu m quato. Quindi se il numero dei nodi
è big o di l^ s n, quanti potranno mai
essere gli archi?
quadrato il quadrato di quello, quindi è
L^ S n al quadrato
che per la proprietà delle potenze è big
o di L^ 2 * S n e questo è il numero di
vertici
è numero di di di archi. Sì, sì, sì.
numero di archi.
Ok?
Fra i due, chi è quello più grande?
Il secondo. Quindi quello è leading
term. Abbiamo che la taglia di questo
computation graph è questa qui, è big o
di l^ 2 * SN. Ok?
Quindi, nel momento in cui facciamo
avanzare questa procedura, noi abbiamo
che generiamo il computation graph
e occupiamo quello spazio. Dopodiché
dobbiamo eseguire
la procedura di Richability vista
stamattina su quel grafo. Ricordo che la
complessità
spaziale
di Exist path
existia
del grafo.
Ok, allora combiniamo le cose.
Che cosa abbiamo? Abbiamo big o. Guardo
gli appunti, non voglio scrivere una
stupidaggine. Big O di
log
2 * SN
quadrato.
Questa cosa è big o
di cosa? di 2 * s n * log
al quadrato.
Questa qui che cos'è?
Una costante. È una costante, quindi la
possiamo buttare.
Costante
e anche questa è una costante e si può
togliere. Quindi il tutto è big o di
cosa? Di S n al quadrato.
Chiaro?
Vi ricordo che le costanti possono
essere tolte dalle classi asintotiche,
ok? Quindi 2 è una costante e la
togliamo. Log in base 2 di L è una
costante perché? Perché L è il numero di
simboli dell'alfabeto di nastro, ma
l'alfabeto di nastro è fissato, non è
che cambia in base a quanto è grande la
stringa, diciamo, "Ah, mi serve un
simbolo in più, la stringa è troppo
gross". Ok, quello è fissato. Quindi
questi due li possiamo ignorare e il
tutto è bigo d Sn al quadato. Ok? Qual è
la conseguenza di questa cosa qua?
Facciamo prima questo e poi
facciamo pausa.
Noto che
finiamo prestissimo oggi, quindi avremmo
il tempo di fare il questionario.
Cercavo cercavo un giorno in cui ilceste
perdere, ma non un questionario di
esame, il questionario mio. Allora,
possiamo quindi definire
possiamo quindi definire P spazio e NP
spazio, ok? Che sono l'equivalente di PD
NP, invece di essere sul tempo possono
essere sullo spazio. Ok? Secondo voi
cosa sarà My Space?
Ah, dove li ho?
Qua.
Come potremo definire la classe
polynomial space?
Me lo ricordate com'è definito P time?
è l'unione per i c maggiore uguali di 1.
Sì. E di di time e sì di space di n^
c. Bravissimo. Ok. Questo è pi spazio.
Che cos'è pi spazio? È l'insieme di
tutti i linguaggi
che possono essere decisi in spazio
polinomiale
da una macchina di Touring
deterministica. spazio è una classe
tostissima, eh, cioè mo adesso vedremo
poi la relazione con le altre con le
altre classi che abbiamo visto, ma un
problema che sia uno dei problemi tosti
di più spazio è un problema che richiede
una quantità di tempo mostruosa per
essere per essere risolto. Ok?
ed n spazio.
Esattamente l'unione su C che è maggiore
di 1 di n space
di n^ c.
È chiaro?
Ok.
Guardate queste due definizioni.
Guardate cosa possiamo dire della
relazione di contenimento di questi due
di queste due classe. Chi contiene chi?
quella la più immediata, la più
semplice.
Sì, abbiamo che sicuramente pi spazio
è contenuto in n spazio.
Ok?
Benissimo.
Guardate il teorema di Savic che cosa ci
dice?
Che sono uguali. Che sono uguali.
Il teorema di Savic sostanzialmente ci
dice che tutte le classi spaziali
da pi spazio a salire perché la cosa non
funziona sul log space perché quello
sarebbe log space al quadrato. Ok?
Quindi il teorema di Savic ci dice che
tutte le classi di complessità spaziali
da polinomial a salire la classe
deterministica eguaglia la classe non
deterministica.
P spazio
è uguale a NPA
per il teorema di Savic.
L'intuizione qual è? L'intuizione è che
siccome abbiamo vincoli sullo spazio, ma
non sul tempo, cioè il tempo una volta
che lo usiamo il tempo è andato, non è
che lo recuperiamo, lo spazio invece può
essere riutilizzato. Ecco perché
pi spazio è uguale a n spazio, perché
noi praticamente una macchina a P spazio
può simulare una macchina non
deterministica, polynomial space,
semplicemente riprovando, facendo le fa
un tentativo, non è andata bene,
riprovo, ma lo spazio chiuso è sempre lo
stesso, è quella la ragione
sostanzialmente. Ok?
Questo fa sì che tutte le classi di
complessità spaziale sopra si considera
sempre la versione deterministica perché
la versione non deterministica non ci dà
nulla di più. Ok?
Bene, con questo facciamo un po' di
pausa,
una decina di minuti.
[Musica]