Anda di halaman 1dari 89

7.

Complejidad en el tiempo
7.1 Midiendo la complejidad
7.2 La clase P

a.guzman@acm.org
Medir la complejidad en el tiempo
Voy a manejar solo problemas decidibles.
Un problema es decidible. Pero ¿cuánto
tiempo se tarda?
– La medición es relativa a la longitud de su
entrada.
– ¿Cómo se mide?
– Clasificación de los problemas de acuerdo
con su complejidad (su “tardanza”).
– ¿Cómo determinar si un problema decidible
requiere una gran cantidad de tiempo?
Ejemplo. ¿Cuánto tiempo se tarda una
máquina de Turing en decidir A={0k1k | k0}?
Analizo el algoritmo, veo cuántos pasos toma.
Cuento los pasos (bajo nivel) de la máquina
M1 =“ParaDepende de suw,
la entrada entrada. Cuántos 0s tiene,
cuántos 1’s tiene. Si es una gráfica, cuántos
1. Rechaza si hay un 0 a la derecha de un 1.
nodos tiene, cuándos lados, etc.
2. Repite mientras haya ambos 0s y 1s:
• Por simplicidad: que dependa de la
1. Barre la cinta y cruza un 0 y un 1.
longitud de la entrada.
3. Si sobran 0s y ya todos los 1s se cruzaron, ó si
• Analizo
sobran 1s y yaeltodos
peor caso posible.
los 0s 
se cruzaron,
rechaza. Si no sobran 0s ni 1s, acepta.”
• Otro análisis: el caso promedio. 
También depende del algoritmo. Uno
puede ser más rápido que otro.
Complejidad de M en el tiempo
Sea M una máquina de Turing determinista que se para en
todas sus entradas. El tiempo de procesamiento ó
complejidad en el tiempo de M es la función f : NN,
donde f(n) es el máximo número de pasos que M usa para
cualquier cadena de longitud n.
Si f(n) es el tiempo de procesamiento de M, digo
que
– M corre en tiempo f(n)
– M es una máquina de Turing de tiempo f(n).
Es costumbre usar n para la longitud de la entrada.
O grande y o pequeña
Es difícil contar exactamente los pasos
que una máquina toma.
Los estimo. Uso análisis asintótico. –El
tiempo para cadenas largas.
– Descarto coeficientes (constantes).
– Solo veo el término de mayor orden de n.
Digo
Para cadenas largas, es el término que vaque
a f es
dominar. El que más rápido crecerá. asintóticamente
cuando mucho n3.
Ejemplo: f(n) = 6n3 + 2n2 + 45.

Descarto el coeficiente 6 Término de mayor orden


R+ son los números reales no negativos.
Sean f y g funciones f,g : NR+
Digo que f(n) = O(g(n)) si existen enteros
positivos c y n0 tales que para cada entero
nn0,
f(n)  cg(n)
Cuando f(n) = O(g(n)), digo que g(n) es
una cota superior para f(n)
– o más precisamente, que g(n) es una cota
superior asintótica, para recalcar que estoy
suprimiendo factores constantes.
Intuitivamente, f(n) =O(g(n)) significa que f
es menor o igual que g si descarto diferencias
originadas por un factor constante.

En muchos casos el término de orden superior


h de f es obvio. Entonces digo que
f(n)=O(g(n)) donde g es h sin su coeficiente.
Ejemplo. Sea f1(n) = 5n3 + 2n2 + 22n + 6.
– El término de orden superior es 5n3.
– Suprimiendo su coeficiente: f1(n) = O(n3)
– Verifico que este resultado satisface la
definición formal. Sí, cuando c=6 y n0=10.
– Entonces 5n3+2n2+22n+6 6n3 para toda n10.
Además, f1(n)=O(n4)
– Porque n4 es mayor que n3, de modo que aún
es una cota asintótica superior para f1.
Sin embargo, f1(n) no es O(n2)
– Sin importar qué valores les de a n y c0, no se
satisface la definición.
O de logaritmos.
logb n = log2 n/log2 b.
Cuando uso logaritmos necesito
especificar la base. Ej: x = log2 n.
Equivale a 2x = n.
Cambiando la base b cambia el valor de logb n
por un factor constante.
Entonces, cuando escribo O(log n) no
especifico la base, porque de todas maneras
descarto factores constantes.
Ejemplo: f2(n) = 3n log2 n + 5n log2 log2 n + 2
Entonces f2(n) = O(n log n) porque log n
domina a log log n.
O(1) ¿qué representa? Un valor queSiempre
no es mayor que
se tiene:
una constante fija c.
f(n)  O(g(n))
Suma de Os. ejemplo: f(n) =O(n2)+O(n).
– En este caso cada O representa una constante distinta
suprimida. f(n) < o(g(n))
– Como el término O(n2) domina a O(n), la expresión es
equivalente a f(n)=O(n2).
f(n)= 2O(n) ¿qué representa? = 2cn para alguna
constante c. Dos modos de decir lo mismo
f(n)=2O(log n) ¿qué representa?
n=2log n entonces nc = 2c log n para alguna constante c.
f(n) = O(nc)
f(n)=nO(1) ¿qué representa? f(n) = O(nc).
f(n) = O(g(n)) indica que asintóticamente f(n) no es mayor
que g(n).
f(n)= o(g(n)) indica que asintóticamente f(n) es menor que
g(n). o minúscula (o pequeña).
Cotas polinomiales y
exponenciales
Una cota nc para c>0 se llama cota
polinomial. Ejemplos: f(n)=O(n3);
f’(n)=O(n1/3).
)
Una cota de la forma 2(n para >0 se
llama cota exponencial. Ejemplo: O(2(n2))
– Ejemplo: O(2n)
O grande y o pequeña
O grande. f(n) = O(g(n)) indica que
asintóticamente f(n) no es mayor que g(n).
Oosea, f(n)=o(g(n))
pequeña. = o(g(n))
f(n)significa que,indica
para cada
quenúmero
real c>0, existe un número
asintóticamente n0 para
f(n) es menorel que f(n)<
que c g(n)
g(n).
para toda n>n0.
– Misma diferencia que entre  y <.
Def. Sean f y g funciones f,g:NR+. Digo
que f(n)=o(g(n)) si
f(n)
lim ------- = 0.
n
g(n)
Es o minúscula
Análisis de un algoritmo
¿Cuántos pasos toma en decidir?
A = {0k1k | k0}
M1 = “Para la entrada w,
O(n) 1. Barre la entrada y rechaza si encuentro 0’s
a la derecha de 1’s. Toma 2n pasos
O(n) 2. Repite si quedan 0’s y 1’s en la cinta.
O(n) 1. Barre la cintaSetachando unveces
repite n/2 0 y un 1. Toma n pasos
3. Si sobran 0’s pero no 1’s, o sobran 1’s pero
O(n) no 0’s, rechaza. Si no sobran ni 0’s ni 1’s,
acepta.” Toma n pasos
O(n) +O(n)O(n) + O(n) = O(n2)
Análisis de un algoritmo
El tiempo
¿Cuántos pasos toma en decidir? que tarda M 1
en procesar w es O(n 2).
A = {0k1k | k0}
La complejidad en el
M1 = “Para la entrada w,
tiempo de M1 es O(n2).
O(n) 1. Barre la entrada y rechaza si encuentro 0’s
a la derecha de 1’s. El tiempo que tarda M1
O(n) 2. Repite si quedan 0’s y 1’s
crece conenellacuadrado
cinta. de la
O(n) 1. Barre la cinta tachando un 0 de
longitud y unsu1.entrada.
3. Si sobran 0’s pero no 1’s, o sobran 1’s pero
O(n) no 0’s, rechaza. Si no sobran ni 0’s ni 1’s,
acepta.”
O(n) +O(n2) + O(n2)
G = ({v1 v2 ..vk}{(v3 v2) (v1 v3)…}
B = {<G> | G es una gráfica conexa no
dirigida} El decididor para B es M2.
M2 = “Para la entrada <G>,
1. Verifica si G comienza con ({, caracteres,
O(n) después vienen }{(, caracteres, después )(, …
caracteres, después )}. Si no, rechaza.
2. Verifica que los caracteres entre los dos
O(n ) primeros { } no estén repetidos.
2 Toma 2n pasos

3. Verifica que entre cada dos ( ) vengan


Toma k2dos
pasos
O(n2) caracteres distintos que estén en el primer
conjunto. … (continúa) Toma (2k + 2k)n pasos
El número de nodos es k, es proporcional a n.
O(n) +O(n2) + O(n2) +…
G = ({v1 v2 ..vk}{(v3 v2) (v1 v3)…}
B = {<G> | G es una gráfica conexa no
dirigida}
M2 = “Para la entrada <G>,
1. .. 2. .. 3. ..
O(1) 4. MarcaRepite
el primer vértice. Toma 3 pasos
k pasos
O(n) 5. Repite hasta que ya no haya más marcados.
O(n2) 1. Si hay un lado entre un vértice marcado y uno no
marcado, marca el no marcado. Toma kn pasos
O(n) 6. Si todos los vértices están marcados, acepta.
Si no, rechaza.” Toma n pasos
O(n) +O(n2) + O(n2) +…
G = ({v1 v2 ..vk}{(v3 v2) (v1 v3)…}
…+O(1) +O(n3) + O(n) = O(n3)
B = {<G> | G es una El
gráfica conexa
tiempo no M
que tarda 2
dirigida} en procesar w es O(n3).
M2 = “Para la entradaLa<G>,
complejidad en el
1. .. 2. .. 3. .. tiempo de M1 es O(n3).
O(1) 4. Marca el primer vértice.
O(n) 5. Repite hasta que ya no haya más marcados.
O(n ) marcado, marca el no marcado.
2 1. Si hay un lado entre un vértice marcado y uno no

O(n) 6. Si todos los vértices están marcados,


acepta. Si no, rechaza.”
Clasificando lenguajes según el
tiempo que requieren
Def. La clase de complejidad en el tiempo
TIEMPO(t(n)) es la colección de todos los
lenguajes que son decidibles por una
máquina de Turing en O(t(n)).
– El lenguaje A={0k1k | k0}  TIEMPO(n2)
porque M1 decide A en O(n2).
– TIEMPO(n3) contiene a todos los lenguajes
que pueden decidirse en O(n3).
¿Podré mejorar el tiempo para decidir A =
{0k1k | k0}?
– ¿Habrá una máquina que decida asintóticamente
más rápido?
En cada barrida puedo cruzar dos 0s y dos 1s. Eso
corta el tiempo a la mitad. Pero asintóticamente es aún
O(n2).
¿Podré hallar un algoritmo de orden o(n2)?
– El siguiente algoritmo M2 decide A en O(n log n).
O(n) +O(log n)[O(n)+O(n)]
k k +O(n)
A = {0 1 | k0}
= O(n log n)
M2 = “Para la entrada w,
O(n) 1. Barre la entrada y rechaza si hay un 0
después de un 1.
O(log n)
2. Repite mientras haya algunos 0s y algunos
? 1s en la cinta:
1. Barre la cinta y fíjate si el número total de 0s y 1s
O(n) que sobran es par o impar. Si es impar, rechaza.
2. Barre la cinta y cruza un 0 sí y otro no,
O(n) comenzando con el primer 0, y un 1 sí y otro no,
comenzando con el primer 1.

O(n) 3. Si ni 0’s ni 1’s quedan en la cinta, acepta. Si


alguno sobra, rechaza.”
¿Sí decide M2 a A?
En cada iteración se ve si la suma de los 0’s sobrantes y
los 1’s sobrantes es par (continúa) o impar (rechaza).
Si siempre los sobrantes son par y al final
son 0, acepta. De lo contrario, rechaza.
Ejemplo. 19 ceros y 13 unos = 32. continúa.
9 ceros y 6 unos = 15. rechaza.

Diez y nueve ceros:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0


nueve ceros:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
cuatro ceros:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
dos ceros:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
un cero:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ningún cero:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Cada ejecución de 2.2 divide
el número de ceros a la mitad,
y descarta el residuo. Y lo
mismo con los unos.
A= k
{0 1 k | k0}
O grande.
M1 decidía A en O(n2).
Ahora mejor: M2 decide A en O(n log n).
¿Existirá un algoritmo más rápido para A?
– No para máquinas de Turing de una cinta.
– Teorema. Todo lenguaje que puede ser
decidido por una máquina de Turing de una
cinta en o(n log n) es regular (Problema 7.47).
Con otra cinta más se puede decidir A en
O(n) (también se llama tiempo lineal).
o pequeña
A = {0k1k | k0}, máquina con dos
cintas

Cinta de entrada

0 0 0 0 0 0 1 1 1 1 1 þ þ

þ þ þ þ þ þ þ þ þ þ þ þ þ

Cinta de trabajo 1

þ Espacio en blanco
A = {0k1k | k0}
El tiempo que toma M3 para decidir A es O(n).
M3 = “Para la entrada w,
1. Barre¿Habrá otro más
la entrada rápido? si hay 0’s
y rechaza
O(n) despuésEs lo de 1’s.que se puede hacer. Es lo óptimo.
mejor
2. Barre la entrada
Porque hasta nelpasos
se necesitan primer 1. Al mismo
simplemente para
O(n) tiempo, copia los ceros a la cinta 2.
leer la entrada.
3. Barre los 1’s en la entrada, hasta el final.
Por ¿Y
cadasi agrego
1 en laotra cinta? tacha un 0 en la
entrada,
O(n) cintaEs2.loSimejor
todosque
losse0s se han
puede tachado pero
hacer.
sobran 1’s, rechaza.
4. Si noPorque
sobranse0’snecesitan n pasos
ni 1’s, acepta. Si simplemente
sobran
O(n) 0’s, rechaza.”
para leer la entrada.
{0k1k | k0}
ALa=complejidad depende del algoritmo.
Hay algoritmos más rápidos que otros
La complejidad paraen el tiempo
decidir deproblema.
el mismo A.
– El tiempo requerido para decidir A.
– El problema
La complejidad no esdel
depende si modelo
se para.deSiempre
máquina.se para.
Se trata de lenguajes decidibles.
De algoritmos decididores.
No es como en teoría de la computabilidad,
– El problema es cuánto
donde todos tiemporazonables
los modelos tarda en pararse.
de
– Para A,computación
tenía M1 con complejidad O(n 2).
son equivalentes –deciden la misma
– Luego,clase
hallo
de M 2 con .complejidad O(n log n).
lenguajes
Según el problema 7.47, con máquina de una cinta
Afortunadamente, los requerimientos
es lo más rápido posible.
– Con no
de tiempo unadifieren
máquinamucho para cintas,
de dos los M3 es O(n).
modelos deterministas principales.
Relaciones de complejidad entre
modelos de máquinas
Sea t(n) una función, donde t(n)  n.
Teorema. Toda máquina multi-cinta de
Turing de tiempo t(n) tiene una máquina
de Turing de una cinta de tiempo O(t2(n)).
– En el Cap. 3 convertí una máquina multicinta
en una unicinta equivalente.
Los contenidos de las cintas se guardan
consecutivos en la única cinta.
Las posiciones de las distintas cabezas se marcan
sobre los casilleros apropiados.
Demostración. Sea M una máquina de
Turing de k cintas que corre en tiempo t(n).
– Construiré una máquina S de Turing de una
cinta que corre en O(t2(n)).
– Inicialmente, S pone su cinta en el formato
apropiado para simular a M (ya lo vi en el Cap. 3) y
empieza a simular los pasos de M.
Para simular un paso, S barre su cinta para ver la
posición de las k cabezas.
Y la vuelve a barrer para actualizar sus contenidos y
mover las k cabezas.
Si alguna cinta ya no tiene espacio, S corre una
porción del contenido de su cinta una celda a la
derecha.
– La longitud de la información en la cinta
determina cuánto tiempo se toma S en barrerla.
¿Qué tan larga es la porción activa de la
cinta de S?
Cada porción activa de una de las k cintas
de M es de longitud t(n).
– Porque ese es el número de celdas que se
pueden escribir en tiempo t(n).
Suponiendo que la cabeza siempre se mueve a la
derecha.
Y ocuparía menos celdas si a veces se mueve a la
izquierda.
– Entonces, la longitud de la porción activa de
la cinta de S es k t(n) o sea O(t(n)).
Para simular cada paso de M, S hace dos
barridas.
– Y posiblemente hasta k corrimientos a la
derecha. (cada uno de complejidad O(t(n)).
– CadaHe supuesto
paso de Mque t(n) esa Sn.
le toma
2O(t(n)) +kO(t(n))
Suposición razonable, = O(t(n))
porque en pasos.
menos tiempo
CadaMpaso
¿Cuántos ni pasos
siquiera tendría
le toma
de la máquina tiempo de le
leer susacintas.
a S simular
multicinta M?
toma a la máquina unicinta O(t(n)) pasos.
– Poner su cinta en el formato apropiado le
toma a S O(t(n)).
– Cada paso de M le toma a S O(t(n))
Y son t(n)) los pasos que toma M en decidir.

O(t(n)) + O(t(n))  O(t(n)) = O(t2(n)).


Complejidad de máquinas no
deterministas
Un lenguaje decidible en una máquina no
determinista es decidible en una determinista –
pero toma más tiempo.
– Una máquina no determinista es un decididor si en
todas sus ramas se para bajo todas sus entradas.
Con una que acepte, la máquina acepta. Si todas
las ramas rechazan, la máquina rechaza.
Def. Sea N una máquina no determinista que es
decididora. El tiempo de ejecución de N es la
función f : NN, donde f(n) es el máximo
número de pasos que N usa en cualquier rama
de su computación para cualquier cadena de
longitud n. Sea aceptora o rechazadora
Complejidad de máquinas no
deterministas
Aún cuando un clon acepta, la máquina
espera a que todos los clones terminen antes
de contabilizar su tiempo de ejecución.
Esta definición no corresponde a algún dispositivo
físico. Es una definición útil matemáticamente.

Def. Sea N una máquina no determinista que es


decididora. El tiempo de ejecución de N es la
función f : NN, donde f(n) es el máximo
número de pasos que N usa en cualquier rama
de su computación para cualquier cadena de
longitud n.
Sea t(n) una función, donde t(n)n.

Teorema. Cada máquina no determinista de


Turing de una cinta de tiempo t(n) tiene una
máquina equivalente determinista de
Turing de una cinta de tiempo 2O(t(n)).
– Demostración. Ya vi cómo transformar una
máquina de Turing no determinista N en otra
determinista equivalente D.
D busca (explora a anchura primero) un nodo aceptor
en el árbol de computación de N. Usa tres cintas.
D es ineficiente –para explorar un tataranieto
Busca una
comienza otra vez en la raíz del árbol. historia exitosa
Pero esto no altera este teorema –lo dejo(unasí.
descendiente
que acepte).
– Sea b el máximo número de transiciones de .
Cualquier rama de N tiene longitud de t(n)
cuando mucho (si es que no aceptó o rechazó
antes). Porque el tiempo que se tarda N es t(n) y
ninguno de sus clones se puede tardar más.
Cada nodo en el árbol tendrá cuando mucho
b hijos.
el número total de hojas es a lo más bt(n).
El número total de nodos es cuando mucho 2bt(n).
El número total de
nodos es cuando
mucho 2bt(n).
– Sea b el máximo número de transiciones de .
Cualquier rama de N tiene longitud de t(n)
cuando mucho (si es que no aceptó o rechazó
antes).
Cada nodo tendrá cuando mucho b hijos.
el número total de hojas es a lo más bt(n).
El número total de nodos es cuando mucho 2bt(n).
Visitar uno de estos nodos toma t(n) cuando mucho.
Visitar a todos (para ver si alguien aceptó) toma
t(n)  2bt(n) = O(t(n)b t(n))) = 2O(t(n)).
Porque el tiempo que se tarda N es t(n) y
Ese es el tiempo queninguno
se tomadelasus
máquina D.puede
clones se Perotardar
D tiene
más
tres cintas.
O(tbt) = O(blogbtbt) = O(blogbt + t) = O(bt) = O(2t)
Una máquina de una cinta se tomará cuando mucho el
cuadrado de ese tiempo.
(2O(t(n)))2 = 2O(2t(n))=2O(t(n)). Q.E.D.
Complejidad en el tiempo según
los modelos de máquinas
La complejidad de una máquina determinista de
una cinta es cuando mucho el cuadrado de
la complejidad de una máquina con varias.
– Diferencia polinomial.
La complejidad de una máquina determinista de
una cinta es exponencial con respecto a la
complejidad de una
Lasmáquina
diferenciasno
polinomiales las
determinista. considero pequeñas.
– Diferencia exponencial.
Las diferencias exponenciales las
considero grandes.
Ejemplo.
Sea n =1000. Un algoritmo toma tiempo n2 = un millón.
Otro toma tiempo n3 = mil millones.
La diferencia es grande, pero manejable.
Pero si otro algoritmo toma 2n, esto es 21000.
Es un número muy grande.
Es mayor que el número de átomos en el universo
(11080).
Los algoritmos que toman n, n2, n3,.. Son “apropiados” o
“tolerables” para efectuar computación.
Los que toman órdenes exponenciales, no lo son. Rara
vez son útiles.
Los algoritmos exponenciales a menudo ocurren
cuando quiero resolver un problema por fuerza bruta.
Ejemplo: factorizar un número en sus factores primos.
Fuerza bruta: ensaye todos los posibles factores. El
espacio de búsqueda es exponencial.

A menudo, entender mejor el problema conlleva a un


algoritmo polinomial. Una manera práctica de resolver
el problema.
Todos los modelos computacionales deterministas
razonables son polinomialmente equivalentes.
No definiré “razonable”.
Cualquiera de ellos puede simular al
La Teoría de la Computación estudia la computación
otro con solo un incremento polinomial
en elsí,tiempo
en no estedemodelo de máquina o aquel otro.
ejecución.
Voy a hacer una distinción importante. Tiempo
polinomial vs. Tiempo no polinomial.
Consideraré “rápidos” a algoritmos que se
tomen O(log n), O(n), O(n2), O(n3)…
y lentos a los otros.
¿No estoy haciendo demasiadas simplificaciones?
Al definir O(t(n)), ya descarto coeficientes:
O(t(n)) = O(15t(n)).
Ahora voy a decir que “es lo mismo”
tiempo n2 que tiempo n4.
Ciertamente, es Es más importante
importante para un diferenciar entre
programador la tiempo polinomial y
diferencia entre n2 y tiempo no polinomial.
n 4.
Pero hay otros
problemas (otras
diferencias) más
importantes que
estudiar.
Clase P, tiempo polinomial
Def. P es la clase de lenguajes decidibles
en tiempo polinomial en una máquina de
Turing determinista de una cinta.
P = TIEMPO(nk)
k

= TIEMPO(O(1))  TIEMPO(O(n)) 
...TIEMPO(O(n2))  TIEMPO(O(n3))  …
P = k
TIEMPO(n )
La clase P juega un papel central en la Teoría de la
Complejidad porque
1. P es invariante para todos los modelos de cómputo
que son polinómicamente equivalentes a una
máquina de Turing determinista de una cinta , y
Cualquieraesdeuna clase
ellos robusta.
puede simularNo
al le afectan cambios
en un
otro con solo el modelo de computación
incremento polinomial a usar.
2. Pencorresponde
el tiempo deaproximadamente
ejecución. a la
clase de problemas que son realistamente
resolubles en una computadora.
Es una clase de utilidad práctica.
Cómo proceder para resolver
un problema
Primero veo si el problema es decidible o indecidible.

Busco hacerlo decidible.

Luego, veo si el problema es de tiempo polinomial


o de tiempo exponencial.

Busco hacerlo polinomial.

Quitarle lo de fuerza bruta.

Si aún puedo, veo si puedo reducirle el exponente.

Veo qué cálculos pueden simplificarse.


Algoritmos en la clase P
Para ver la complejidad de un algoritmo, lo
divido en pasos o etapas.
– Evalúo la complejidad de cada etapa.
– Evalúo cuántas veces se repite cada etapa.
– Uso el peor de los casos.
Codificación de la entrada. Cualquier
codificación razonable.
– Pero: la codificación unaria es inaceptable –es
exponencialmente más grande que la binaria u otra
de base k2.
Al codificar gráficas, la longitud de la entrada es en
general proporcional al número de nodos de la gráfica.
PATH={<G,s,t>|G es una gráfica dirigida que
tiene una trayectoria dirigida de s a t}
El problema: ¿Habrá una trayectoria de s a t?
Teorema. PATH  P.
Idea. Busco todas las trayectorias posibles de
s a t.
Cada trayectoria debe tener cuando más m
nodos, donde m es el número de nodos de G
(no es necesario repetir nodos).
El número de trayectorias posibles es
m(m-1)(m-2)(m-3)…21 = O(mm).
m exponencial.
orden productos
Idea 2. Comenzando en s, buscar a lo
ancho primero.
– Los nodos que se pueden alcanzar de s en
un paso.
Hasta que llegues a
– Los que se pueden alcanzar en dos
t (o ya pasos.
no avances).
– etc. 3
2
6
5 t
1
5
s0 1 4
4

2 4
6
3 Propagando la tinta
PATH  P
Encuentro un lado (a b) Regreso a los nodos. Veo si a está marcado
Demostración. Este algoritmo:
Voy al lado (a b) a ver cómo se
Q = “Para la entrada <G,s,t>
llama el otrodonde
nodo. SeG esb
llama
una gráfica dirigida, y s y t sonRegreso
nodos a losdenodos
G, Número de nodos de G

1. Marca el nodo s. Una vez. O(n).


Veo si está marcado. Lo
marco si no está marcado.
2. Repite lo siguiente hasta que no haya nodos
adicionales marcados Repite m veces. O(n).
1. Barre todos los lados de G. Si uno conecta un
nodo marcado con otro no marcado, marca ese
otro. m+m+m+m+m+m. O(n).
3. Si t está marcado, acepta. Si no, rechaza.”
PATH  P
Demostración. Este algoritmo:
Q = “Para la entrada <G,s,t> donde G es
una gráfica dirigida, y s y t son nodos de
G,O(n) + O(n)  O(n) + O(n) = O(n2). Entonces QP.
1. Marca el nodo s. Una vez. O(n).
2. Repite lo siguiente hasta que no haya nodos
adicionales marcados Repite m veces. O(n).
1. Barre todos los lados de G. Si uno conecta un
nodo marcado con otro no marcado, marca ese
otro. m+m+m+m+m+m. O(n).
Una vez. O(n).
3. Si t está marcado, acepta. Si no, rechaza.”
RELPRIME={<x,y>|x y y son primos
relativos}
Dos números son primos relativos si el
máximo divisor común es 1.
– 10 y 21 son primos relativos.
Aunque ninguno de ellos sea primo.
– 10 y 22 no son primos relativos.
El 2 divide a ambos.
RELPRIME es el problema de determinar
si dos números son primos relativos.
RELPRIME={<x,y>|x y y son primos
relativos}
Idea 1. Busco en todos los posibles
divisores de x y y si alguno divide a
ambos. la complejidad del decididor de RELPRIME.
Determine
– Suficiente buscar los divisores del menor de
ellos.
– Pero: si n es la longitud de x entonces el valor
de x es 2n (o kn, si está representado en base k).
Habrá que probar una cantidad exponencial de
posibles divisores. Solución demasiado lenta.
RELPRIME={<x,y>|x y y son primos
relativos}
Idea 2. Use el máximo común divisor.
– El máximo divisor común de x y y, mdc(x,y),
es el mayor entero que divide a ambos.
– Ejemplo. mdc(18, 24) = 6.
– Si mdc(x,y)=1, entonces x y y son primos
relativos.
Solución. Algoritmo de Euclides para
hallar el máximo divisor común.
En cada repetición (excepto quizá la primera), x>y.
El máximo divisor común
Si x/2y, entonces x mod y < y x/2 y la nueva x es cuando mucho
la mitad de la vieja x.
Algoritmo de Euclides
Si x/2<y, entonces x mod y = para
x – y < hallar el mdc:
x/2 y la nueva x es cuando
E = la“Para
mucho lalaentrada
mitad de vieja x. <x,y> donde x y y
sondosnúmeros
Cada repeticionesnaturales en originales
de (1), los valores binario,de x y de y se
reducen cuando menos a la mitad.
1. Repite hasta que y=0 No cambia x si x<y.
1. Asigna a x  x mod y. Al terminar, x<y
2. Intercambia x y y. Al terminar, x>y
2. Produce x como salida.”
Hay que analizar este algoritmo para ver
– Si es correcto.
– Si corre en tiempo polinomial.
En cada repetición (excepto quizá la primera), x>y.
Si x/2y, entonces x mod y < y x/2 y la nueva x es cuando mucho
la mitad de la vieja x.
Si x/2<y, entonces x mod y = x – y < x/2 y la nueva x es cuando
mucho la mitad de la vieja x.
Cada dos repeticiones de (1), los valores originales de x y de y se
reducen cuando menos a la mitad.
Entonces, (1) repite cuando más el menor de 2log2x y 2log2y.
Los valores de x y y son exponenciales en su longitud, de
manera
E =que 2log2la
“Para x yentrada O(n). donde x y y son
2log2y son<x,y>
números
E corre naturales
en tiempo O(n), o sea,en binario, Entonces E  P.
polinomial.
1. Repite hasta que y=0
1. Asigna a x  x mod y.
2. Intercambia x y y.
2. Produce x como salida.”
El algoritmo R decide RELPRIME
usando E como subrutina:
R = “Para la entrada <x,y>, donde x y y son
números naturales en binario,
O(n) 1. Corre E sobre <x,y>.
O(1) 2. Si el resultado es 1, acepta. Si no, rechaza.”
Hay que ver si este algoritmo está correcto y
corre en tiempo polinomial.
Sí. O(R) =O(n)+O(1)=O(n). Entonces R  P.
Teorema. Todo lenguaje libre de
contexto  P
El cap. 4 mostró que todo lenguaje libre de
contexto es decidible.
Si un lenguaje es libre de contexto, es posible
decidir si una cadena w pertenece a él o no.

Me pregunto: ¿Decidir la pertenencia de una


cadena al lenguaje, toma tiempo polinomial?
Teorema. Todo lenguaje libre de
contexto  P
Tengo un lenguaje libre de contexto
descrito (generado) por una gramática G.
¿Genera G a w? Voy a decidir esto en tiempo P.
– Transformo la gramática G que lo genera en
otra G’ en forma normal de Chomsky.
– El decididor ensaya todas las cadenas que se
pueden derivar con G’ en 2n-1 pasos, donde
Pero:nGenerar
es la longitud
todas lasdecadenas
w. que se pueden derivar
con 2n-1 pasos puede tomar un tiempo exponencial en n.
Este algoritmo no es polinomial.
Teorema. Todo lenguaje libre de
contexto  P
Idea 2. Usar programación dinámica.
– Conforme voy resolviendo problemas, guardo
las soluciones.
Así después las puedo usar sin volverlas a
calcular.
– Uso la acumulación de soluciones a
problemas pequeños para resolver problemas
más grandes.
– Al descomponer un problema grande en
varios pequeños,
En una tabla guardo las soluciones a los
pequeños.
Para no recalcularlos si los vuelvo a necesitar.
Supongo que mi lenguaje es generado por una gramática
G (con variable inicial S) en forma normal de Chomsky.

Subproblema: Ver cuál variable en G


genera cuál subcadena de w.
La longitud de w es n.
– Uso una tabla nn.
– Para ij, la celda (i,j) contendrá todas las
variables que generan la subcadena
wiwi+1…wj.
Las celdas donde i>j no se usan.
w La celda (1 1) contiene A si A genera b
bccabb La celda (1 3) contiene E B si E
1 2 3 4 5 6 genera b c c y si B genera b c c
1 2 3 4 5 6 j
1 A EB
2
3
4
5
6

i
No se usan
w La celda (2 5) contiene B si B genera c c a b
bccabb La celda (3 5) contiene A C D si A genera
1 2 3 4 5 6 c a b y C genera c a b y D genera c a b
1 2 3 4 5 6 j
1 A EB
2 B
3 ACD
4
5 C
6

i
La celda (5 6) contiene C si C genera b b
No se usan
w Las celdas de longitud 1 corresponden a
reglas de forma A  a en la gramática.
bccabb
Porque estándirectamente
Se llenan en forma normal
de de
la Chomsky.
gramática.
1 2 3 4 5 6
1 2 3 4 5 6 j
Son las únicas reglas que 1
pueden generar una terminal.
2
3
4
5
6

i
Nótese que si una de estas celdas está vacía [digamos, la
(4,4)], entonces la gramática no genera w, porque nadie
genera la terminal a que está contenida en la cadena.
w Luego, con la información de las celdas
bccabb de long. 1, lleno las celdas que
1 2 3 4 5 6
corresponden a cadenas de longitud 2.
1 2 3 4 5 6 j
1
2
Primero lleno las celdas3que
4
generan cadenas de longitud 1.
5
6

Algunas celdas tendrán i


más de una variable.
Luego, lleno las celdas
Otras estarán vacías. de cadenas de longitud 3.
w
bccabb
1 2 3 4 5 6
1 2 3 4 5 6 j
1
2
3
4
5
6

Y así, al calcular las celdas de longitud k+1,


uso los resultados de las celdas de longitud
menor o igual que k, que ya guardé en la tabla.
w
bccabb
1 2 3 4 5 6
1 2 3 4 5 6 j
1
2
3
4
5
6

i
Al terminar de llenar, si la celda (1,n) contiene el símbolo
inicial S, entonces G genera w. Si no, no la genera.
¿Cómo saber cuáles variables generan
qué cadenas?
– Para generar cadenas de longitud 0 y de
longitud 1, miro directamente la gramática.
– Estará quizá la regla S  
Entonces sé que S genera .
– O la regla A  a. Es la única regla que puede generar .
– Entonces sé que A genera a.
Para saber qué variables generan una
cadena de longitud mayor que 1, parto la
cadena en 2 y veo (en la tabla) qué variable
I genera su mitad izquierda, y cuál otra
variable D su mitad derecha.
Y busco las variables V que digan V  I D.
w ¿Por qué en dos? Porque en la forma
bccabb normal de Chomsky (la que uso) las
1 2 3 4 5 6 reglas son de la forma C  A B.
Ejemplo. Ya calculé todas las celdas de
longitud 4 y menor.
– Ahora debo llenar las celdas que corresponden
a cadenas de longitud 5.
– En w hay dos cadenas de longitud 5: b c c a b
y c c a b b.
– Tomo una: b c c a b.
– Parto esa cadena en dos, en todas las formas
posibles: b | c c a b — b c | c a b — b c c | a b
bcca|b
w
bccabb
1 2 3 4 5 6
b|ccab—bc|cab—bcc|ab
bcca|b
Repito
Para cada una depara las otras
ellas, veo sicadenas de longitud
hay una
5. En
regla en G de la este
formacasoC hay
otra:
A Bc c a b b.
– Tal que A genere b y B genere c c a b.
– O que A genere b c y B genere c a b.
– O que A genere b c c y B genere a b.
A la celda (1,5), porque
– O que A genere b c c a y b Bc c genere b. (1,5).
a b = subcadena
– Si hay, agrego su lado izq. C a la celda de
longitud 5 que estoy llenando.
Ejemplo. Sea la gramática
S SAB A  AA BBC
Aa Bb Cc 1 2 3 4 5
¿Genera S la cadena a a b c c?
(1,1)=a la genera A. 1 2 3 4 5 j
(2,2)=a la genera A. 1 A
(3,3)=b la genera B. 2 A
(4,4)=c la genera C. 3 B
(5,5)=c la genera C. 4 C
5 C
i
Ejemplo. Sea la gramática S  e
SAB A  AA BBC
Aa Bb Cc 1 2 3 4 5
¿Genera S la cadena a a b c c?
(1,2)=aa la genera AAA 1 2 3 4 5 j
(2,3)=ab la genera SAB 1 A A
(3,4)=bc la genera BBC 2 A S
(4,5)=cc la genera nadie 3 B B
4 C X
5 C
i
Ejemplo. Sea la gramática S  e
SAB A  AA BBC
Aa Bb Cc 1 2 3 4 5
¿Genera S la cadena a a b c c?
(1,3)=aab: a | ab es AS 1 2 3 4 5 j
es nadie. aa|b es AB es 1 A A S
SAB
2 A S S
(2,4)=abc: a|bc es AB es
3 B B B
S. ab|c es SC es nadie
(3,5)=bcc: b|cc es BB es 4 C
nadie. bc|c es BC es B 5 C
i
Ejemplo. Sea la gramática S  e
SAB A  AA BBC
Aa Bb Cc 1 2 3 4 5
¿Genera S la cadena a a b c c?
(1,4)=aabc: a | abc es AS 1 2 3 4 5 j
es nadie. aa|bc es AB es 1 A A S S
S. aab|c es SC es nadie.
2 A S S S
(2,5)=abcc: a|bcc es AB
3 B B B
es S. ab|cc es Snadie.
abc|c es SC es nadie. 4 C
5 C
i
Ejemplo. Sea la gramática S  e
SAB A  AA BBC
Aa Bb Cc 1 2 3 4 5
¿Genera S la cadena a a b c c?
(1,5)=aabcc: a | abcc es 1 2 3 4 5 j
AS es nadie. aa|bcc es AB 1 A A S S S
es S. aab|cc es Snadie.
2 A S S S
aabc|c es SC es nadie.
3 B B B
Como en la casilla (1,5)
aparece S, entonces la 4 C
gramática sí genera aabcc. 5 C
i  AABCC  aABCC
S  AB  AAB  AABC
 aaBCC  aabCC  aabcC  aabcc
Todo lenguaje libre de contexto  P
Demostración. Este es el algoritmo decididor:
D= “Para la entrada w, donde w=w1w2…wn
es una cadena, Caso w=.
1. Si w= y S es una regla de G, acepta.
2. Para i=1 a n: Caso
1. Para cada variable A: cadenas de
1. Fíjate si A  b es una regla, donde b=wi. longitud 1
2. De ser así, coloca la variable A en tabla(i, i).

El decididor decide si una cadena pertenece al lenguaje.


El decididor tiene adentro “alambrada” la gramática libre de contexto.
Ahora veo qué tiempo toma D.
3. Para l = 2 a n l es la longitud de la subcadena.
1. Para i=2 a n – l +1 i es el comienzo de la subcade.
1. Haz j=i+l-1 j es la posición final de la subcadena.
2. Para k=i a j-1 k es la posición del corte.
1. Para cada regla A  B C
1. Si tabla(i,k) contiene B y tabla(k+1,j)
contiene a C, guarda A en tabla(i,j)

4. Si S está en tabla(1,n), acepta.


De otro modo, rechaza.”
v = número de variables de G

D= “Para la entrada w, donde w=w1w2…wn es


una cadena,
O(1) 1. Si w= y S es una regla de G, acepta.
2. Para i=1 a n: n veces.
1. Para cada variable A: v veces, no depende de n
O(1) 1. Fíjate si A  b es una regla, donde b=wi.
O(v) 2. De ser así, coloca la variable A en tabla(i, i).

Acá llevo O(1) +n v O(v) = O(n)


r = número de reglas en G
3. Para l = 2 a n l es la longitud de la subcadena
n veces.
1. Para i=2 a n – l +1 ni es
veces.
el comienzo de la subcade
O(1). 1. Haz j=i+l-1 j es la posición final de la subcadena
2. Para k=i a j-1 n veces. k es la posición del corte
1. Para cada regla A  B C r veces, no depende de n
1. Si tabla(i,k) contiene B y tabla(k+1,j)
O(n ).
2
contiene a A, guarda C en tabla(i,j)

O(n) 4. Si S está en tabla(1,n), acepta. Este paso recorre la


tabla, que es O(n2).
De otro modo, rechaza.”
Tenía atrás O(n)

Acá tengo n(n(O(1)+n(r(O(n2))) +O(n) = O(n5)


Otro problema. En una gráfica no dirigida, un
clique es un subconjunto de sus vértices tales
que cualesquiera dos de ellos están
conectados por un lado.
Un k-clique es un clique de orden k.
Tiene k vértices.
– Un triángulo es un 3-clique.
¿Cuánto tiempo nos tomará determinar si
una gráfica tiene un triángulo?
G

H
TRIÁNGULO = {<G>|G es una gráfica
no dirigida y G tiene un triángulo}
Teorema. TRIÁNGULO  P.
Demostración.
G = {{A B C D…}{(A B) (A C) (E F) (C D)..}}
El algoritmo que decide TRIÁNGULO es
D = “Para la entrada <G>, donde G es una
gráfica no dirigida,
1. Para cada lado (M N) de G
1. Para cada nodo P al cual M esté conectado,
1. Fíjate si N también está conectado
2. Si existe esa N, acepta. (El clique es M N P)
G = {{A B C D…}{(A B) (A C) (E F) (C D)..}}
El algoritmo que decide TRIÁNGULO es P
D = “Para la entrada <G>, donde G es una P
gráfica no dirigida, P M
O(n)1. Para cada lado (M N) de G
N
O(n)1. Para cada nodo P al cual M esté conectado,
O(n) 1. Fíjate si N también está conectado a ese nodo P
O(1) 2. Si existe esa N, acepta. (El clique es M N P)
3. Si no, toma otro nodo P al cual M esté conectado
y ve a 1.1.1
4. Si ya no hay más nodos P, ve a 1.2
G es de
2. Toma el siguiente lado de G. complejidad
3. Si ya no hay más lados, rechaza.” O(n3)
ALLDFA ={<A>|A es un DFA y
L(A)=*}
Teorema. ALLDFA  P.
Demostración. Veo el decididor de ALLDFA.
T= “Para la entrada <A>, donde A es un
DFA,
– Marca el estado inicial de A. Si no es aceptor,
rechaza.
– Repite hasta que ya no haya nuevos estados
marcados.
Marca un estado si es aceptor y tiene una transición
que le llega de un estado marcado.
– Si todos los estados marcados son
aceptores, acepta. Si algún estado marcado
no es aceptor, rechaza.”

Las marcas propagan la tinta a partir del estado inicial.


A B C D E F

F b
b
a b E
A a
a
b a D
a b
a, b B
C
T= “Para la entrada <A>, donde A es un
DFA,
O(1) – Marca el estado inicial de A. Si no es aceptor,
rechaza.
– Repite hasta que ya no haya nuevos estados
n veces
marcados.
O(n2) Marca un estado si es aceptor y tiene una transición
que le llega de un estado marcado.
– Si todos los estados marcados son
O(n) aceptores, acepta. Si algún estado marcado
no es aceptor, rechaza.”

La complejidad de T es O(1) +n (O(n2) +O(n)) = O(n3)


¿Cómo saber si un algoritmo es de
complejidad P?
Escriba el algoritmo (decida el lenguaje).
– Verifique que sea correcto.
Vea si es regular.
– Haga su autómata finito, o
– Haga su expresíón regular, o
– Vea si Vea
es si
una combinación
es una deautómatas
combinación de otros finitos +
autómatas regulares.
autómatas de pila + máquinas de Turing polinomiales.
Vea si es un lenguaje libre de contexto.
– Haga su gramática, o
– Haga su autómata de pila.
¿Cómo saber si un algoritmo es de
complejidad P? (cont.)
Escriba el algoritmo (decida el lenguaje).
– Verifique que sea correcto.
Cuente cuidadosamente los pasos que
ejecuta.
– Determine su complejidad en el tiempo.

Vea si se puede resolver usando otros


decididores polinomiales.
– Por ejemplo, usando reducciones,
– Pero deben ser reducciones polinomiales.

Anda mungkin juga menyukai