Está en la página 1de 37

rboles y grafos

Vladimir Tmara Patio.


2004. Dominio pblico. Sin garantas.
Agradecemos que como fuente se cite:
http://structio.sourceforge.net/guias/arbgraf/
Este escrito se dedican a nuestro Padre Creador, a su santo Espritu y a Jess su
Hijo y maestro nuestro.
Captulo 1 Introduccin y definiciones
- logro: Define grafo, bosque y rbol
- logro: Emplea rboles binarios
1.1 Definiciones
Indicadores de logro:
- indicador: Define diversos tipos de grafo
- indicador: Define rbol
- indicador: Implementa y emplea un TAD para rboles binarios
En este contexto rboles y grafos se refiere a estructuras de datos que permiten
organizar y mantener informacin en un computador. Esta forma se inspira una
forma de organizar informacin con lpiz y papel usando nodos y flechas entre
los nodos (a esas flechas tambin se les llama arcos, a los nodos tambin se les
llama vrtices). Los grafos y rboles en papel son apropiados por ejemplo para
capturar slo una parte de la informacin de objetos, situaciones y otros tipos de
informacin (i.e son apropiados para abstraer).

En un computador adems de permitir organizar informacin, resultan estructuras
tiles para resolver ciertos tipos de problema (por ejemplo pueden emplearse
rboles AVL para mantener informacin ordenada de forma eficiente).

Para jugar, entender y emplear mejor grafos (y rboles) varias personas (e.g
Euler) han propuesto definiciones; a partir de estas definiciones y con ayuda de
razonamientos lgicos han demostrado propiedades. Un mnimo de definiciones
y de propiedades de grafos y rboles (con estilo inspirado en [6]) se presenta a
continuacin.

Note que para ver mejor esta pgina puede requerir configurar su navegador para
que presente smbolos especiales, que se esperan con el tipo de letra de symbol.
En el caso del navegador Mozilla, y suponiendo que en su sistema ya est
instalado y configurado para Mozilla el tipo de letra para smbolos marque el
botn de chequeo que permite que el documento use otras fuentes, en el men
apariencia del dilogo de preferencias (elemento del men editar).
1.1.1 Teora
Grafos
Un grafo G es una pareja G=(V,A), donde V es un conjunto finito (i.e vrtices)
y A es un subconjunto del conjunto de parejas no ordenadas de V (i.e arcos). Por
ejemplo G=({a,b,c},{{a,c},{c,b}}), que se representa grficamente en la
figura 1.1.


Figure 1.1: Ejemplo de grafo



Dado un grafo G con V(G) denotamos el conjunto de vrtices y con A(G)
denotamos el conjunto de arcos. Decimos que un arco {x,y}e A(G) une los
vrtices x e y; as que x,y denota el mismo arco que {y,x}. Si {x,y} es un arco,
decimos que x e y son extremos del arco, tambin decimos que x es adyacente o
vecino de y.

Un grafo G'=(V',A') es subgrafo de G=(V,A) si V'c V y Ac A'. En tal caso
escribimos G'c G.

Si G' contiene todos los arcos de G que unen dos vrtices de V' decimos que G' es
un subgrafo inducido por V' y se denota por G[V'].

El orden de un grafo G es el nmero de vrtices, tambin se denota por G
1
. El
tamao de G es el nmero de arcos, y se denota por a(G).

Decimos que dos grafos son isomorfos si hay una correspondencia entre sus
conjuntos de vrtices que preserva la adyacencia. As que G=(V,E) es isomorfo
a G'=(V',E') si hay una biyeccin : V V' tal que x,ye E si y solo si (x)(y)e E'.
Entonces dos grafos isomorfos tienen el mismo orden y el mismo tamao.

El tamao de un grafo de orden n es al menos 0 y a lo sumo (
2
n
). Un grafo de
orden n y tamao (
2
n
) se llama un n-grafo completo
2
y se denota por K
n
; un n-
grafo vaci E
n
tiene orden n y ningn vrtice. En todo K
n
todo par de vrtices son
adyacentes, mientras que en E
n
ningn par de vrtices son adyacentes.

El conjunto de vrtices adyacentes a un vrtice xe G, se denota por I(x).
El grado de x es g(x)= I(x). El grado mnimo de los vrtices de un grafo se
denota por o(G), mientras que el grado mximo se denota porA(G). Un vrtice de
grado 0 se dice que es un vrtice aislado. Si o(G)=A(G)=k, es decir todo vrtice
es de grado k entonces se dice que G es k-regular o regular de grado k. Un grafo
es regular si es k-regular para algn k.

Dado que V(G)={x
1
,x
2
x
n
}, como todo arco tiene dos vrtices extremos, la suma
de los grados es exactamente dos veces el nmero de vrtices:
n

i=1
g(x
i
)=2e(G)

Esta observacin se llama tambin el lema de los apretones de manos, pues
expresa que en una fiesta el nmero total de manos apretadas es par. Esto
tambin establece que el nmero de vrtices de grado impar es par.

Un camino W en un grafo G es una secuencia de los vrtices de G, (x
0
,x
1
, ,x
l
) tal
que {x
i
,x
i+1
}e A(G) para 0s i<l. A x
0
y a x
l
los llamamos vrtices extremos del
camino. Un camino en el que todos los vrtices son diferentes se
denomina sendero. Un sendero en el que los vrtices extremos son iguales se
denomina un circuito o si l>2 tambin se denomina un ciclo, y puede denotarse
por x
1
x
2
x
l
.

Con C
l
denotamos un ciclo de longitud l. Llamamos a C
3
un tringulo, a C
4
un
cuadriltero, a C
5
un pentgono, etc.

Dados vrtices x, y su distancia d(x,y) es la longitud mnima de un camino
de x a y.

Un grafo es conexo si para todo par x, y de vrtices diferentes hay un camino
de x a y. Note que un grafo conexo de orden al menos 2 no puede tener vrtices
aislados.

Con la definicin que empleamos un grafo no contiene lazos, es decir un arco
que una vrtice consigo mismo; ni contiene arcos mltiples es decir que varios
arcos unan los mismos dos vrtices. En un multigrafo se permiten lazos, arcos
mltiples y lazos mltiples.

Si los arcos son parejas ordenadas de vrtices entonces tenemos la nocin
de grafo dirigido o multigrafo dirigido. Un pareja ordenada (a,b) se llama
un arco dirigido de a hacia b, o decimos que el arco comienza en ay termina
en b. En un grafo dirigido dado un vrtice x, llamamos grado de entrada
de x ge(x) a la cantidad de arcos dirigidos que comienzan en x, mientras que
el grado de salida de x gs(x) es la cantidad de arcos dirigidos que terminan en x.
En un grafo dirigido una secuencia de vrtices (x
0
,x
1
, ,x
l
) es un camino si existen
arcos dirigidos (x
i
,x
i+1
) para 0s i<l.

Llamamos vista no dirigida de un grafo dirigido G=(V,A) al grafo no
dirigido G'=(V,A') en el que tomamos los arcos dirigidos de G como arcos no
dirigidos, i.e: A'={{x,y}:(x,y)e A}.

Un grafo dirigido decorado G=(V,A,d) consta de un grafo (V,A) y una
funcin d:A E que decora los arcos con elementos de cierto conjunto E de
etiquetas (e.g E podra ser conjunto de nmeros, en el caso de grafos cuyos arcos
se decoran con cantidades --por ejemplo para representar distancia).
rboles
Un grafo sin ciclos es un bosque o un grafo acclico; mientras que un rbol es un
bosque conexo.
TAD rbol Binario
Llamamos rbol binario a un grafo dirigido decorado con
etiquetas E={ Derecho, Izquierdo} que cumple:
- su vista no dirigida es un rbol
- todo vrtice tiene grado de salida a lo sumo 2 y grado de entrada a lo sumo
1.
- todo vrtice adyacente a un vrtice inicial x, est marcado bien como hijo
izquierdo o bien como hijo derecho.
Un rbol binario tiene un vrtice con grado de entrada 0 al que llamamos raz. A
los vrtices con grado de salida 0 los llamamos hojas.

Para representar rboles binarios en un programa puede emplearse un TAD
3

- para un rbol vaco ABvacio y
- para un rbol con un posible hijo derecho y/o un posible hijo
izquierdo ABcons
y con selectoras:
- izq que retorna el hijo izquierdo de un vrtice,
- der que retorna el hijo derecho,
- raiz que retorna la identificacin del vrtice raz del rbol.
- esVacio que decide si un rbol es vaco.
1.1.2 Lecturas recomendadas
Las definiciones de grafos son adaptadas de [6], mientras que el TAD rbol
Binario es adaptado de [11].
1.1.3 Ejercicios para afianzar teora
1. De un ejemplo de un grafo de orden 4 y tamao 3 y dibuje una
representacin grfica.
2. En el grafo presentado al comienzo de esta gua cules son los vrtices
adyacentes a c y cuales a b ?
3. Cual es el subgrafo inducido por V'={a} en el grafo de ejemplo?
4. Los grafos G=({a,b,c},{{a,b},{a,c}}) y G'=({1,2,3},{{2,3},{3,1}}) son
isomorfos, Cual es la biyeccin (o correspondencia) entre sus vrtices
que preserva adyacencia?
5. Presente dos grafos isomorfos de orden 4 y tamao 3, junto con la
biyeccin explicita.
6. De un ejemplo de un grafo de orden 4, conexo, con al menos un ciclo de
orden 3.
7. De un ejemplo de un grafo 3-regular. Es su ejemplo un grafo regular?
1.1.4 Ejercicios de programacin
1. Implemente un TAD rbol Binario y pruebe cada funcin con casos de
diversa complejidad.
2. Emplee el TAD que implement en las siguientes funciones:
o orden que retorna el orden de un rbol
o tamao que retorna el tamao
o distancia que retorne la distancia entre dos vrtices del rbol
o haySendero que decide si hay o no sendero entre dos vrtices.

3. Proponga un TAD grafo e implemntelo.
4. Usando su TAD escriba la funcin distancia que determine la distancia
entre dos vrtices de un grafo.
5. Proponga un TAD grafo dirigido.

1
Note que la cardinalidad de un conjunto X, se denota por X, as
que G= V(G).
2
Note que para determinar el tamao de un grafo completo puede pensarse
como formar todas las posibles parejas no ordenadas de vrtices (hay (
2
n
)
posibles) o pueden tratarse de contar sin repetir: del primer vrtice salen n-
1 arcos, del segundo sin repetir seran n-2, del tercero sin repetir n-3 y as
sucesivamente, del ltimo vrtice seran 0, de forma que el total de arcos
sera 1+2+ +n+(n-1)=
i=1
n-1
i que a su vez es (n-1)(n) /2 que es igual a (
2
n
).
3
TAD es abreviatura de Tipo Abstracto de Datos. Un tipo abstracto de
datos encapsula un tipo con funciones al menos para construir elementos
del tipo (i.e constructoras) y funciones para analizar o extraer informacin
(i.e selectoras).
Captulo 2 rboles
- logro: Calcula complejidad de funciones
- logro: Emplea rboles binarios y n-arios para representar informacin y
realizar operaciones eficientes
- logro: Emplea herramientas y TADs eficientes
2.1 rboles de bsqueda
Indicadores de logro:
- indicador: Emplea un rbol binario para realizar bsquedas
- indicador: Emplea un rbol binario balanceado
- indicador: Emplea graphviz para visualizar grafos
2.1.1 Teora
Un problema importante en informtica es determinar si un elemento e pertenece
a una secuencia (e
1
, e
2
, e
n
) o a un conjunto {e
1
, e
n
}. Aunque la solucin ms
simple (examinar uno a uno los elementos de la secuencia o del conjunto) puede
ser suficiente para algunos propsitos, cuando se requiere eficiencia deben
emplearse estructuras de datos apropiadas.

En esta seccin se estudian estructuras basadas en rboles que permiten efectuar
bsquedas eficientemente.

Para medir eficiencia suelen emplearse dos mtricas: espacio y tiempo. Ambas
suelen medirse de forma asinttica para el peor de los casos. Por ejemplo con el
algoritmo de bsqueda recin mencionado en el peor de los casos (si el elemento
no est), se requieren n comparaciones cuando el tamao del problema es n, se
dice entonces que la complejidad temporal de ese algoritmo es O(n) (orden de n),
como no se requiere espacio adicional para implementarlo su complejidad
espacial es O(1).

Entonces al decir que la complejidad temporal de un algoritmo es O(f(n))
(siendo f(n) una funcin en la variable n), decimos que dada una entrada de
tamao n, el tiempo que requiere el algoritmo para dar una respuesta es
proporcional a f(n). Al referirnos a complejidad espacial del orden O(f(n))
expresamos que la cantidad de espacio (i.e memoria) que un algoritmo requiere
para completarse en el pero de los casos cuando procesa una entrada de
tamao n es proporcional a f(n).
Recorridos y otras operaciones con rboles binarios
Un rbol binario puede recorrerse de diversas formas, hay 3 de estas formas que
se presentan a continuacin junto como implementaciones en Ocaml que usan el
siguiente TAD:
1

type 'a arbin = ABvacio | ABcons of 'a arbin * 'a * 'a arbin;;

let izq= function
| ABvacio -> failwith ("vacio")
| ABcons (i,_,_) -> i
;;
let der=function
| ABvacio -> failwith ("vacio")
| ABcons (_,_,d) -> d
;;
let raiz= function
| ABvacio -> failwith ("vacio")
| ABcons (_,r,_) -> r
;;
- Preorden. Primero informacin del vrtice, luego subrbol izquierdo y
luego subrbol derecho.
- let rec preorden a=if a=ABvacio then
- []
- else
- (raiz a)::(preorden (izq a))@(preorden (der a))
- ;;
- Inorden. Primero subrbol izquierdo, luego vrtice y finalmente subrbol
derecho.
- let rec inorden a=if a=ABvacio then
- []
- else
- (inorden (izq a))@[raiz a]@(inorden (der a))
- ;;
- Postorden.
- let rec postorden a=if a=ABvacio then
- []
- else
- (postorden (izq a))@(postorden (der a))@[raiz a]
- ;;
Note que los nombres de las funciones recuerdan el sitio donde se ubica la raz.

Llamamos altura de un rbol a la cantidad de vrtices del sendero ms largo que
exista en el rbol (tngase en cuenta que un rbol aqu se ha definido como un
grafo dirigido, as que el sendero ms largo debe partir de la raz y terminar en
una hoja). Para calcularla puede emplearse la siguiente funcin:
let rec altura = function
| ABvacio -> 0
| ABcons(i,_,d) ->
1 + (max (altura i) (altura d))
;;
Bsqueda en rboles binarios ordenados
Buscar un elemento en un rbol binario puede lograrse con ms eficiencia si:
- La informacin que se mantiene en sus vrtices
2
cuenta con un criterio de
orden (i.e con un orden total). Por ejemplo si se trata de enteros con las
relaciones de orden tpicas entre enteros o en el caso de cadenas
empleando orden lexicogrfico.
- Se mantiene un invariante que permita mantener la informacin ordenada,
por ejemplo que todo hijo izquierdo de todo vrtice tenga informacin
menor que la del vrtice y que todo hijo derecho tenga informacin mayor
o igual.
En tal caso se habla de un rbol binario ordenado.


Figure 2.1: Ejemplo de rbol binario ordenado


Note que el rbol presentado en la figurar 2.1 es un rbol binario ordenado. Por
ejemplo para buscar el 12 se requieren 3 comparaciones. Note adems que un
recorrido en inorden da la secuencia de elementos ordenada.

La implementacin de este tipo en Ocaml puede hacerse con base en el mismo
tipo arbin antes presentado
3
, pero ahora debe verificarse el siguiente invariante
(no expresable como parte de la sentencia type):
open Arbin;;
type 'a arbinord = 'a arbin;;
let rec inv = function
| ABvacio -> true
| ABcons(i,v,d) ->
if (i<>ABvacio) then
(v>(raiz i)) && (inv i)
else
true
&&
if (d<>ABvacio) then
(v<=(raiz d)) && (inv i)
else
true
;;
El invariante expresado por esArbinord debe ser mantenido por funciones para
insertar y eliminar, y puede ser aprovechado para efectuar bsquedas ms rpidas
para ciertos rboles.
rboles AVL: binarios, ordenados y balanceados
Note que un rbol binario ordenado podra tener todos sus elementos en un
sendero iniciado en la raz y terminado en una nica hoja, en tal caso buscar el
menor elemento se realizar en tiempo proporcional al orden del rbol.

Para evitar situaciones como esta pueden agregarse condiciones al invariante de
rbol binario ordenado, para mantener un rbol mejor distribuido, o en otras
palabras un rbol balanceado:
- No hay vrtices repetidos
4

- En todo vrtice la altura del subrbol izquierdo (digamos altura(i)) y la
altura del rbol derecho (digamos altura(d)) deben cumplir:
altura(i)=altura(d) v altura(i)=altura(d)+1 v altura(i)+1=altura(d)
Si se logra mantener este invariante toda bsqueda se realizar con complejidad
temporal O(log
2
n) ---que es la complejidad temporal ptima para el problema de
bsqueda.

Para lograr mantenerlo deben implementarse con atencin las operaciones para
insertar y eliminar elementos. Dado que estas operaciones deben mantener un
invariante que requiere conocer altura de subrbol derecho e izquierdo, puede
mantenerse esta informacin actualizada en los vrtices del rbol (lo cual puede
disminuir tiempo requerido para calcular la altura cuando se hace el balanceo,
pero aumentar espacio empleado para mantener la informacin).


Figure 2.2: Ejemplo de rbol AVL


Una posibilidad es hacer el balanceo a medida que se inserta o elimina un nodo,
otra opcin es hacer una insercin o una eliminacin como si el rbol fuera slo
un rbol binario ordenado y despus balancear el rbol resultante. Para realizar
tal balance (tras haber insertado o eliminado slo un dato) pueden considerarse
casos como los presentados en la figura 2.3 que permiten generalizar la solucin.


Figure 2.3: Ejemplo de casos para balancear


Por ejemplo puede balancearse el primer caso haciendo como una rotacin a la
derecha para obtener el grafo que tiene en su raz el 5, como subrbol izquierdo
la hoja con 8 y como subrbol izquierdo la hoja con 4.
2.1.2 Haca la prctica
Visualizar un grafo (o un rbol) es un problema comn, hay varias herramientas
que ayudan entre las que se encuentra Graphviz que es multiplataforma, de libre
redistribucin y que puede usarse con bastante facilidad.

Graphviz se basa en un formato de texto plano (.dot) que especifica un grafo y
en un lenguaje que facilita la presentacin grfica de estos (lefty).

Entre las herramientas que ofrece este paquete estn:
- dot que lee un grafo en formato .dot y genera una grfica. Por ejemplo
una vez generado el archivo grafo1.dot puede generarse una grfica en
formato PostScript
5
con: dot -Tps grafo1.dot > grafo1.ps. Una imagen
en formato gif podra generarse de forma anloga usando -Tgif para
despus convertirla a jpeg
6
por ejemplo con convert grafo1.gif
grafo1.png (convert es una herramienta que hace parte del paquete de
libre redistribucin ImageMagick).
- dotty que es una interfaz grfica adaptable (con lefty). Sin hacerle
adaptaciones permite visualizar y manipular un grafo. Puede visualizarse
el grafo grafo1.dot con: dotty grafo1.dot.
Por ejemplo el grafo presentado como ejemplo en la gua 1 (ver [ejem1]), se
escribi en un archivo ejem1.dot con el siguiente contenido:
digraph "ejemplo1" {

graph [rankdir = "LR"];
node [fontsize = "16" shape = "ellipse"];
"a"
"b"
"c"

"a" -> "c" [dir="none"]
"c" -> "b" [dir="none"]
}
Note que se comienza con digraph seguido del nombre del grafo, despus entre
corchetes se agregan elementos los cuales pueden ser:
- Vertices: Se declaran entre comillas pueden ir seguidos de atributos
(declarados entre parntesis cuadrados). Por ejemplo puede definirse el
estilo y color de relleno o atributos de las fuentes.
- Arcos: Se definen indicando vrtice inicial y vrtice final cada uno entre
comillas, con los signos -> entre ellos. Pueden ir seguidos de atributos
como direccin y estilo de lnea.
- Otras especificaciones usadas por ejemplo para controlar el algoritmo
empleado por dot para localizar vrtices y arcos.
En la implementacin del TAD rbol binario que acompaa esta gua se incluye
una funcin dot_of_arbin: string -> ('a -> string) -> 'a arbin que permite
generar un rbol binario en formato .dot.
2.1.3 Lecturas recomendadas
Desde el punto de vista de programacin funcional, puede verse el uso de rboles
de bsqueda en [5], desde el punto de vista de programacin imperativa en [11].
Puede consultase ms sobre Graphviz en [2].
2.1.4 Ejercicios para afianzar teora
1. Usando el tipo presentado al comienzo de esta gua puede escribirse el
rbol:

(ABcons(ABcons(ABvacio,3,ABvacio),2,
ABcons(ABcons(ABvacio,3,ABvacio),5,ABvacio)))

Dibuje una representacin grfica de este rbol, escriba las listas que
resultan de recorrerlo en preorden, en inorden y en postorden.
2. Algunos lenguajes de programacin facilitan la creacin de estructuras
polimrficas (en algunos contexto llamadas paramtricas o genricas). Por
ejemplo un TAD rbol Binario Ordenado en Ocaml podra basarse en el
tipo presentado al comienzo de esta gua.

Que podra despus emplearse con enteros, cadenas o cualquier otro tipo.
Dado que Ocaml es un lenguaje con un recolector de basura, el
programador en casos sencillos no debe preocuparse por liberar memoria,
detalle que puede ser difcil en lenguajes sin recolector de basura (y por
tanto ms eficientes en tiempo de ejecucin) como C o C++. Como
podra implementar un rbol polimrfico en C? Cmo puede implementar
una funcin para liberar memoria de una estructura como la que plantee?
3. Hay diversas formas de implementar eliminacin en un rbol binario
ordenado, explique (o implemente) por lo menos dos algoritmos para esto.
4. Indique los rboles resultantes tras balancear los casos presentados en la
figura (2.3).
5. Escriba en formato .dot el rbol 2.2 y visualicelo con dotty.
2.1.5 Ejercicios de programacin
1. Implemente un TAD que representa un conjunto de enteros, empleando
una lista. Las operaciones mnimas que debe tener este TAD son:
o ce_vacio: -> conjent constructora que retorna un conjunto vacio
o ce_ad: conjent -> int -> conjent constructora que agrega un
entero a un conjunto.
o ce_miembro: conjent -> int -> bool selectora que decide si un
entero pertenece o no a un conjunto.
o ce_esVacio: conjent -> bool selectora que decide si un conjunto es
vaci.
o ce_cardinalidad: conjent -> int selectora que retorna la cantidad
de elementos en el conjunto.
o ce_inv: conjent -> bool que decide si la estructura de datos que
recibe es un conjunto de enteros (por ejemplo verificando que no
haya elementos repetidos).
o ce_elim: conjent -> int -> conjent que elimina un elemento de
un conjunto.

Fije algunos casos de pruebas de diversa longitud (e.g 0, 10, 100, 10000) y
mida el tiempo que tarda la funcin ce_miembro al buscar un elemento que
no est en el conjunto (Ayuda: Para medir el tiempo que toma la ejecucin
de un programa --digamos prog-- puede emplear desde la lnea de
comandos: time prog. Con este mtodo diferenciar hasta milsimas de
segundo).

Cual es la complejidad de la funcin de bsqueda?
2. Implemente el TAD del ejercicio anterior pero empleando una rbol
binario ordenado (Ayuda: puede emplear la implementacin disponible
con estas guas enhttp://structio.sourceforge.net/guias/arbgraf/).
Empleando los mismos casos de prueba del punto anterior determine
tiempo que tarda la funcin ce_miembro al buscar un elemento que no est
en el conjunto. Cual es la complejidad de esa funcin con esta
implementacin?
3. Implemente el TAD del ejercicio anterior, excepto la funcin de eliminar,
pero empleando una rbol AVL . Realice pruebas anlogas a las de los
puntos anteriores e indique la complejidad de la funcince_miembro.
2.2 Complejidad y Montculos
Indicadores de logro:
- indicador: Calcula informalmente complejidad de funciones sencillas
- indicador: Emplea montculos y diferencia sus ventajas con respecto a
otras estructuras estudiadas
- indicador: Implementa y usa un TAD conjunto de enteros acotados
eficiente
2.2.1 Teora
Clculo de complejidad
Note que nuestra mtrica de complejidad es independiente de multiplicacin por
constantes, i.e para todo k= 0, O(f(n))=O(k f(n)). As que O(1) es la mismo
que O(5), mientras que O(n) es lo mismo que O(3n).

La complejidad temporal de una funcin puede determinarse contando cuantas
veces se realiza cierta operacin bsica escogida (por ejemplo comparaciones o
sumas o productos), en el peor de los casos cuando el tamao de la entrada es n.
Considere la funcin esta del TAD rbol binario ordenado:
let rec esta e a=
match a with
| ABvacio -> false
| ABcons(i,v,d) ->
if v=e then
true
else if (e<v) then
esta e i
else
esta e d
;;
Las bsquedas ms ineficientes ocurren cuando buscamos en un rbol nada
balanceado de n elementos, los cuales estn sobre un mismo camino de la raz a
una nica hoja. En un rbol as podra buscarse un elemento que no est y podra
requerirse recorrer todos los nodos para decidirlo, de lo cual concluimos que la
complejidad espacial es orden de n i.e O(n).

Para comprobarlo formalmente puede plantearse un conteo del nmero de
comparaciones realizadas en funcin del orden del rbol, tanto para el caso trivial
como para otros casos en la peor de las situaciones:
C(0)=0
C(n)=2+C(n-1)
Note que se tiene una ecuacin de recurrencia, para resolverla por ejemplo
puede:
1. Probar con algunos valores buscando encontrar un patrn que despus
debe comprobar
2. Dependiendo del tipo de ecuacin, buscar y emplear un mtodo de
solucin apropiado (no para toda ecuacin de recurrencia se conocen
frmulas cerradas que la solucionen).
En este caso al probar con unos pocos valores de n puede sugerirse un patrn:

n C(n)
0 0
1 2
2 4
3 6
:

n 2n

La solucin propuesta puede comprobarse, verificando que satisface la ecuacin
(i.e remplazando C(n)=2n en los 2 casos de la ecuacin de recurrencia):
- Al remplazar en C(0)=0 se tiene 2 0 = 0 que es cierto.
- Al remplazar en C(n)=2+C(n-1) se tiene 2n=2+2(n-1), igualdad que
tambin se cumple.
Entonces la complejidad temporal ser O(2n) que como se indic antes es lo
mismo que O(n).

Para determinar complejidad espacial puede emplearse un mtodo anlogo que
permita contar cuanto espacio se emplea en el pero de los casos. Para el ejemplo
de la funcin esta como no se emplea espacio adicional la complejidad espacial
es O(1).

Para comparar, note que en un AVL la altura ser de la forma 1+log
2
(n), como las
bsquedas siempre recorren a lo sumo un camino de la raz a una hoja, la
complejidad temporal ser O(log
2
(n)).
Montculos
En el caso de rboles AVL la complejidad temporal de una funcin para extraer
el mnimo elemento es O(log
2
(n)), en un montculo la complejidad de esta
operacin es O(1), aunque la complejidad de una bsqueda en un montculo
es O(n) mientras que en un AVL es O(log
2
n).

As que un montculo es un tipo de rbol binario que privilegia la operacin de
determinar el mnimo elemento. Para esto mantiene el siguiente invariante:
1. No hay elementos repetidos
2. Todo vrtice es menor que sus hijos izquierdo y derecho
3. Es un rbol binario balanceado
4. Todo subrbol es montculo
A continuacin se anotan algunos detalles de las operaciones sobre esta
estructura:
- menor: El menor elemento siempre est en la raz
- buscar un elemento: Al buscar un elemento mayor que la raz debe
buscarse tanto en subrbol izquierdo como en derecho.
- insertar: Para mantener el invariante de balanceo debe insertar en el
subrbol de menor altura. Para mantener el orden debe remplazarse en
algunos casos la raz (si el elemento por insertar es menor) y en ese caso
insertar la antigua raz en el subrbol apropiado.
- eliminar: Al encontrar el elemento por eliminar puede ponerse como
nueva raz, la raz del subrbol ms alto y en ese subrbol entrar en
recursin para eliminar la raiz.
La complejidad de las operaciones mencionadas es:

Funcin Compl. temporal Compl. Espacial
menor O(1) O(1)
esta O(n) O(1)
inserta O(log
2
(n)) O(1)
elimina O(log
2
(n)) O(1)

Table 2.1: Complejidad de funciones sobre montculos.


2.2.2 Haca la prctica
El TAD conjunto de enteros
Como ya se ha experimentado es posible implementar el TAD conjunto de
enteros con las estructuras hasta ahora introducidas.

Sin embargo hay aplicaciones que requieren an ms eficiencia en espacio y en
las diversas operaciones. Si por ejemplo slo se usarn enteros entre 0 y 31 una
posibilidad es representar un conjunto de estos enteros con un entero de 32 bits.
El bit i-simo en 1 indicara que el nmero i-1 est en el conjunto.

Por ejemplo el conjunto 0, 3, 8 se representa con el entero (en binario)
100001001 que tiene en 1 las posiciones (contando de derecha a izquierda) 1, 4 y
9.

Las diversas operaciones del TAD conjunto se implementan aprovechando
operadores lgicos a nivel de bits. Por ejemplo para determinar si un entero v es
miembro de un conjunto, puede hacerse la conjuncin lgica entre el entero que
representa el conjunto y el entero que tiene el (v+1)-simo bit en 1 y los dems en
0.

Esta idea es empleada por ejemplo en la implementacin de conjuntos del
generador de compiladores PCCTS (ver [7]). Este puede soportar cualquier rango
de enteros representando cada conjunto como una secuencia de enteros (y no
como un slo entero).
2.2.3 Lecturas recomendadas
Puede consultar ms sobre montculos en [5]. PCCTS es un generador de
compiladores de dominio pblico (antecesor de otro llamada Antares), puede ver
ms sobre este en [7].
2.2.4 Ejercicios para afianzar teora
1. Revise el TAD montculo en las implementaciones que acompaan estas
guas, calcule la complejidad de la insercin y justifique su respuesta.
2. Haga tablas anlogas a al tabla 2.1 que indiquen complejidad de las
diversas funciones de los TADs rbol binario, rbol binario ordenado y
AVL.
3. Escriba los montculos que se obtienen tras insertar los siguientes
elementos a un montculo inicialmente vaco: 4, 3, 1, 2, 8, -6, 5
4. Descargue las fuentes de PCCTS, revise la implementacin de conjuntos
sobre bits de secuencias de enteros. La funcin set_deg retorna la cantidad
de elementos de un conjunto. Revisando esta funcin y el
encabezado set.h descubra que representa el campo n de la
estructura set y su relacin con el campo setword.

Opcional: Cmo podra implementarse la funcin set_deg sin usar el
vector bitmaks en una plataforma de 32 bits?
2.2.5 Ejercicios de programacin
1. Pueden mezclarse de forma eficiente dos montculos (lo cual no es fcil
en el caso de rboles binarios ordenados). Implemente una
funcin mezcla: monticulo -> monticulo -> monticulo que mezcle dos
montculos en un tercero y calcule la complejidad temporal y espacial de
su solucin.
2. Escriba una funcin que reciba un montculo y retorne una lista con los
elementos del montculo ordenados de menor a mayor.
3. Escriba una funcin que reciba una lista de elementos (ordenables) y que
retorne un montculo con los mismos elementos. Calcule la complejidad
de la funcin que escribi.

Note que esta operacin junto con la funcin del punto anterior, permiten
ordenar una lista. Si esta operacin se realiza de manera eficiente se tendr
una implementacin de un algoritmo conocido como HeapSort.
4. Usando las ideas presentadas en esta gua, implemente el TAD conjunto
de enteros en el rango 0 a 31 con un entero de 32 bits (mdulo Int32 en el
caso de Ocaml). Implemente por lo menos las funciones sugeridas en los
ejercicios de la gua sobre rboles de bsquedas.
2.3 rboles n-arios: rboles de sintaxis y rboles B
Indicadores de logro:
- indicador: Emplea rboles de sintaxis
- indicador: Emplea rboles B
2.3.1 Teora
En un rbol n-ario cada nodo puede tener un nmero variable de subrboles,
puede modelarse en Ocaml con un tipo como:
type 'a arbnario= ANvacio | ANcons of 'a * ('a arbnario) list;;
junto con un invariante para evitar representar con diversa sintaxis el mismo
rbol: El constructor ANvacio no aparece en la lista de un constructor ANcons.
rboles de sintaxis abstracta
Un rbol de sintaxis abstracta permite representar ciertos elementos de un
lenguaje para despus analizarlo o transformarlo. Por ejemplo para un lenguaje
simple que permita realizar operaciones aritmticas basta el siguiente rbol (note
que algunos nodos son binarios, mientras que otros unarios y otros slo permiten
representar hojas
7
):
type exprar = Const of int | InvAd of exprar | Suma of exprar * exprar |
Resta of exprar * exprar | Prod of exprar * exprar |
Div of exprar * exprar;;
usndolo, la expresin 3*(-5+4) se representa como:
Prod(Const(3), Suma(InvAd(Const(5)),Const(4)))
Es posible hacer una funcin que reciba una cadena con la sintaxis apropiada y
genere un rbol de estos. A tal funcin se le llama un reconocedor
8
para el
lenguaje. De esta manera ser fcil implementar funciones que empleen tales
expresiones.

El rbol de sintaxis para expresiones regulares del analizador lxico ocamllex es
9
:
type regular_expression =
Epsilon
| Characters of char
| Eof
| Sequence of regular_expression * regular_expression
| Alternative of regular_expression * regular_expression
| Repetition of regular_expression
| Bind of regular_expression * string
En este rbol se representan expresiones regulares como:
- "pa" que slo corresponder con la cadena "pa" y que se representa
con Sequence(Characters('p'),Characters('a')).
- 'p' 'a'* 'l' que corresponder entre otras con las cadenas "pl", "pal",
"paal" y que se representa
con Sequence(Characters('p'),Sequence(Repetition(Characters('a')),C
haracter('l'))).
- ('p' 'a')* que corresponder entre otras con la cadena vaca, con "pa",
"papa", "papapa". Se representa
con Repetition(Sequence(Characters('p'), Characters('a'))).
- ('p' | 'a')* que corresponder entre otras con la cadena vaca, con "p",
"pp", "aaaa", "ppaaap". Se representa
con Repetition(Alternative(Characters('p'), Characters('a'))).
Un rbol de sintaxis para una porcin del formato de graphviz puede ser
10
:
(** Identificacin de un nodo *)
type idNodo=string;;

(** Un arco puede conectar un nodo o un campo de un nodo registro *)
type arco_ext=Id_nodo of idNodo | Id_field of idNodo * string;;

(** Un atributo tiene una identificacin y un valor. *)
type atributo=string*string ;;

(** Un arco tiene un nodo fuente, un destino y una lista de atributos *)
type arco=arco_ext*arco_ext*(atributo list);;

(** Un nodo tiene una identificacin y una lista de atributos *)
type nodo=string*(atributo list);;

(** Un grafo tiene una identificacin, una lista de nodos y una lista de
arcos *)
type dot_graph=string*(nodo list*arco list);;
Incluso es posible proponer rboles de sintaxis para lenguajes naturales como el
espaol o para porciones de este.

En general estos rboles no cumplen invariante alguno, aunque de una aplicacin
a otra pueden imponerse invariantes por ejemplo para mejorar eficiencia.
rboles B
En diversas aplicaciones se requiere mantener en cada nodo del rbol una llave
junto con los datos que se desean representar. De esta forma el ordenamiento de
los nodos puede hacerse con las llaves. Esta es una situacin tpica en bases de
datos, pues cada tabla debe tener una llave, que facilita ubicar registros
completos.

Por ejemplo el tipo rbol binario antes estudiado podra definirse y usarse as:
type ('a,'b) arbindat = ABDvacio |
ABDcons of (('a,'b) arbindat * ('a*'b) * ('a,'b) arbindat);;

let ej=ABDcons(ABDvacio,(10,"Magdalena"),ABDvacio);;
Note que el rbol polimrfico tiene dos parmetros: 'a que ser el tipo de la llave
y 'b que ser el tipo de los datos. En el ejemplo presentado las llaves son enteras,
mientras que los datos mantenidos son cadenas.

Adems de esto en una base de datos debe buscarse minimizar las transferencias
de bloques de datos de disco a memoria y viceversa. En un rbol AVL el
balanceo que debe hacerse despus de insertar o eliminar elementos puede
requerir hacer varios intercambios en el rbol (i.e varias transferencias en disco
en el caso de una B.D). Para disminuir la posibilidad de balancear puede
mantenerse ms de un dato en cada nodo hasta un cierto mximo, as al insertar
slo debe balancearse si se crea un nuevo nodo cuando no haya espacio para ms
datos en otros nodos y al eliminarse slo debe balancearse cuando desaparezca
un nodo despus de que todos los datos que tuviera hubieran sido eliminados.

Un rbol B es un rbol n-ario balanceado sin llaves repetidas, que en cada nodo
mantiene el siguiente invariante:
- Tiene de 0 a m llaves (k
i
) en orden, siendo m un nmero no superior a una
constante positiva M, i.e. k
i
<k
i+1
donde 1s i < m s M.
- La cantidad de subrboles hijos es una ms que la de llaves, i.e s
i
es i-
simo subrbol con 0s is m+1s M+1.
- Todas las llaves del subrbol s
i
son menores que k
i
.
- Todas las llaves del subrbol s
m+1
son mayores que k
m
.
- En todo nodo, excepto en la raiz, la cantidad de llaves es mayor o igual
a M/2 ( y menor o igual a M.
Una representacin grfica de un rbol B se presenta en la figura ??.


Figure 2.4: Ejemplo de rbol B genrico


La altura de un rbol B con n llaves es ( log
m
(n) ().

Pueden verse estas ideas en la prctica en la base de datos con fuentes de
dominio pblico SQLite (ver [3]).
2.3.2 Haca la prctica
Lineamientos de programacin
Examinando las fuentes de SQLite (ver [3]) pueden inferirse los siguientes
lineamientos, que resultan tiles para cualquier proyecto en C:
- Emplear TADs para implementar solucin. Dividir las fuentes en mdulos,
para cada TAD se sugiere un mdulo (preferiblemente independiente de la
aplicacin para que sea reusable).
- Emplear nombres de variables y funciones dicientes (puede ser ms
efectivo que muchos comentarios en las fuentes).
- Emplear comentario slo para aclarar porciones de cdigo que no se
entiendan con facilidad al ver nombres (de variables y funciones) y
cdigo.
- Adoptar y seguir un formato de indentacin y nomenclatura.
- Distinguir entre precondiciones y situaciones de error. Las precondiciones
son restricciones que el programador se impone a si mismo (por ejemplo
que una funcin slo recibir un entero positivo como entrada). Las
situaciones de error se producen por entradas invalidas por parte del
usuario o por condiciones del ambiente en el que se ejecuta la aplicacin
(por ejemplo si se agota la memoria). Una situacin de error en general
debe manejarse para dar oportunidad al usuario de volver a efectuar la
operacin, por otra parte una precondicin no cumplida indica que hay una
falla de programacin (y en algunos casos la nica alternativa para el
programa es terminar).
- Verificar precondiciones de cada funcin con assert.
- Para manejar error en lenguajes sin excepciones (como C) emplear el
estilo UNIX:
o Hacer que el tipo retornado por toda funcin que pueda fallar
sea int, un valor retornado 0 significa que no hay error, otros
nmeros corresponden a cdigos de error definidos para la
aplicacin (o estndar del sistema operativo). Otra informacin que
deba ser retornada por la funcin, retornarla en parmetros que
deben llegar por referencia.
o Cada vez que se llame una funcin que pueda fallar, revisar si ha
fallado o no. Si fall retornar el mismo cdigo de error recibido y de
requerirse liberar memoria que hubiera sido localizada antes de
llamar la funcin.

- Procurar escribir fuentes portables a diversas arquitecturas y sistemas
operativos. Emplear lenguajes de programacin estndares que hayan sido
portados a varias plataformas. En el caso de C/C++ emplear un mdulo
separado como interfaz con el sistema operativo (es decir se usan
funciones de este mdulo en lugar de funciones del sistema operativo). De
esta forma se facilita portar la aplicacin de un sistema a otro.
2.3.3 Lecturas recomendadas
Puede consultar ms sobre rboles B y B+ en [8], y una descripcin de insercin
y eliminacin en rboles B en [1]. SQLite es un motor de bases de datos
relacionales implementado en C, es de dominio pblico, puede consultarse ms
en [3].
2.3.4 Ejercicios para afianzar teora
1. Revise la implementacin del TAD rbol n-ario que acompaa estas guas
y proponga una definicin alterna para la funcin altura.
2. En la documentacin de Ocaml, revise la sintaxis de expresiones regulares
que acepta ocamllex, despus escriba ejemplos de cadenas que
correspondan con cada una de las siguientes y una expresin que las
represente usando el rbol de sintaxis introducido en la gua:
o ['a' - 'c']
o 'a'+
o 'b'('a'?)
o 'b' as x ('a'?)

3. De un ejemplo del uso del rbol de sintaxis para el formato de Graphviz,
presentando la sintaxis concreta de su ejemplo y su representacin usando
la estructura de datos dada.
4. Consulte un algoritmo para insercin en un rbol B y de un ejemplo.
5. Obtenga las fuentes de SQLite y revise la implementacin de la
funcin fileBtreeMoveto que busca una llave en un rbol B. Descubra para
que se usa el cursor pCur y el campo idx de tal cursor.
2.3.5 Ejercicios de programacin
1. Implemente las siguientes funciones para rboles n-arios:
o orden que retorne el orden de un rbol
o balanceado que indique si un rbol n-ario est o no balanceado
o menores que decide si un rbol n-ario cumple este invariante: todo
vrtice tiene un valor menor que los valores en subrboles hijos.

2. Haga funciones que muestren la representacin como cadenas de cada
uno de los 3 rboles de sintaxis presentados como ejemplo.
3. Describa un lenguaje de programacin sencillo (o parte de un lenguaje)
que conozca y proponga un rbol de sintaxis abstracta para este. Despus
haga una funcin que a partir de un rbol de esto retorne una
representacin como cadena.
4. Proponga un tipo para un rbol B, e implemente una funcin que verifique
el invariante.

Opcional: Implemente una funcin de insercin.

1
Disponible como arbin.ml entre las implementaciones distribuidas con
estas guas http://structio.sourceforge.net/guias/arbgraf/.
2
Con propsitos prcticos, puede asociarse informacin a los vrtices o a
los arcos de un grafo.
3
Este TAD est disponible en las implementaciones que acompaan esta
gua en el mdulo arbinord.ml
4
Si se permiten vrtices repetidos junto con la convencin de que estn en
subrbol derecho, no podran balancearse muchos rboles con elementos
repetidos. Si no se sigue convencin alguna --i.e pueden haber repetidos a
izquierda o derecha-- no podra aprovecharse que el rbol est ordenado en
bsqueda de ocurrencias del elemento repetido.
5
El formato PostScript es estndar de varias impresoras laser, es apropiado
para incluir en documentos de TeX o LaTeX.
6
La conversin de GIF a otros formatos es fuertemente sugerida, pues GIF
emplea un algoritmo de compresin patentado por Unisys.
7
Este ejemplo es solucin a un ejercicio de la seccin ``Tipos definidos por
usuario'' de [10].
8
Del ingls parser.
9
Ver archivo lex/syntax.mli de la distribucin de fuentes de Ocaml 3.07
10
El rbol presentado se basa en la implementacin de [9].
Captulo 3 Grafos
- logro: Emplea grafos para representar informacin y aplicar algoritmos
eficientes
3.1 Expresiones regulares y autmatas finitos
Indicadores de logro:
- indicador: Define y emplea lenguajes y lenguajes regular
- indicador: Representa autmatas finitos con grafos e implementa
algoritmos tpicos
3.1.1 Teora
Las expresiones regulares se emplean para describir una serie de cadenas de
manera concisa. Se han introducido en guas anteriores y son usadas por diversas
herramientas (como grep, lex, sed, awk, perl),

Como caso de estudio del uso de grafos en esta gua presentamos una forma de
implementar un reconocedor de expresiones regulares usando autmatas finitos
determinsticos.

Adems de introducir definiciones formales, se estudian algoritmos que
permiten:
1. transformar una expresin regular primero a un autmata finito no
determinstico
2. despus transformar el autmata finito no determinstico a uno
determinstico eficiente.
Lenguajes
Un lenguaje es un conjunto de cadenas sobre un alfabeto dado. Un alfabeto es un
conjunto finito de smbolos, una cadena es una secuencia finita de tales smbolos.

Por ejemplo sobre el alfabeto E={0,2,5} un lenguaje posible
es L={000,205,5,5555 }.

La cadena vaca se denota c, el lenguaje {c} contiene nicamente la cadena
vaca.

Dados dos lenguajes A y B podemos definir algunas operaciones:
- Concatenacin A.B={ab | ae A . be B}.
- Iteracin A
0
=c. Si i>0, A
i
=A.A
i-1
.
- Unin A B={x | xe A v xe B}.
- Clausura A
*
=
i=0
inf
A
i

Un reconocedor para un lenguaje es un programa que dada una cadena s decide si
pertenece o no al lenguaje.
Expresiones regulares
Una expresin regular denota un lenguaje
1

- La expresin regular c denota el lenguaje {c}.
- La expresin regular a, donde a es un smbolo de un alfabeto, denota el
lenguaje {a}.
- Si R y S son expresiones regulares que denotan los
lenguajes L
R
y L
S
respectivamente:
o R|S denota L
R
L
S
.
o RS denota L
R
.L
S

o R* denota L
R
*

En cuanto a sintaxis concreta, de estos operadores, * tiene precedencia mxima,
mientras que | tendr precedencia mnima, pueden emplearse parntesis para
cambiar la precedencia y como convencin los caracteres de escape \\, \*, \|, \( y
\) denotarn los caracteres \, *, |, ( y ) respectivamente.

En la seccin sobre rboles de sintaxis se introdujo un tipo que puede adaptarse
(eliminando el constructor Eof) para representar las expresiones regulares aqu
presentadas.
Autmatas Finitos
Un autmata finito es un grafo directo decorado
2
. Se usa como reconocedor de
lenguajes, los nodos representan posibles estados durante el reconocimiento, y
los arcos representan posibles transiciones de un estado a otro. Hay un nodo
inicial y un conjunto de nodos finales (cuando se comienza el reconocimiento de
un nuevo texto, el autmata comienza en el estado inicial y la cadena pertenece al
lenguaje si alcanza un estado final cuando la cadena se procesa por completo).
Cada etiqueta tiene una letra que indica cuando puede ocurrir una transicin.


Figure 3.1: Ejemplo de autmata finito



En la figura 3.1, hay un arco del vrtice 1 al vrtice 2 con etiqueta a. El nodo
inicial es 1 que se indica por el smbolo !, mientras que el nodo final es 2 que se
indica por el smbolo #.

Si durante un reconocimiento el estado es 1, ir al estado 2 slo si el siguiente
carcter del texto reconocido es a.

Hay dos clases de autmatas finitos: determinsticos (AFD) y no-determinsticos
(AFN), las diferencias son:
- Un AFN permite etiquetas vacas mientras que en un AFD todos los arcos
deben estar decorados con un carcter.
- Un AFN permite que varios arcos que partan de un nodo tengan la misma
etiqueta. En un AFD todas las etiquetas de los arcos que parten de un nodo
deben ser diferentes.
Para efectos de implementacin es ms sencillo hacer un reconocedor con un
AFD, pues los cambios de estado se determinan con una sola comparacin.
De expresiones regulares a autmatas finitos eficientes
Es relativamente fcil generar un AFN que reconozca el lenguaje representado
por una expresin regular, basta aplicar las transformaciones de la figura ??.


Figure 3.2: Transformaciones de expresiones regulares en autmatas finitos no
determinsticos



Una caracterstica de esta transformacin es que da un AFN que tienen un slo
estado final. En el primer caso, el de un smbolo, el estado inicial lo
representamos con i mientras que el estado final con f.

Note que a representa un smbolo cualquiera del alfabeto, mientras que R y S son
expresiones regulares. Las elipses N
R
y N
S
representan el autmata finito que
resulta de transformar R y S respectivamente, el primero tiene como estado
inicial i
1
y como estado final f
1
, los anlogos para N
S
son i
2
y f
2
.

Por ejemplo para transformar la expresin regular "(ab)|c*": pueden crearse
subgrafos siguiendo las reglas descritas hasta obtener el grafo que corresponde a
la expresin completa, como se presenta en la figura ??.


Figure 3.3: Ejemplo de transformacin de la expresin (ab)|c*



Por facilidad y eficiencia al implementar un reconocedor de lenguajes regulares
puede resultar buena opcin transformar el AFN que se obtiene tras traducir la
expresin regular en un AFD mnimo, labor que puede hacer en dos pasos: (1)
transformando el AFN en un AFD y (2) minimizando el nmero de estados del
AFD.

Transformacin de un AFN en un AFD

La idea es identificar muchos nodos de un AFN en un slo nodo de un AFD.
Todos los vrtices de un AFN a los que pueda llegarse desde un nodo dado
pasando slo por arcos con etiqueta c deben identificarse como un nico nodo en
el AFD (la clausura vaca de un conjunto de nodos N consta justamente de todos
los nodos a los que puede llegarse desde nodos de N pasando slo por arcos con
etiqueta c).

En el siguiente algoritmo D ser el AFD que se construye, cada vrtice de D ser
un conjunto de nodos del AFN.
I=clausura\_epsilon(nodo inicial del AFN)
D=({I},{})
Si I contiene un nodo final marcarlo como vrtice final de D
I no ha sido visitado
mientras (haya vrtices no visitados en D)
N=Tomar un vrtice (conjunto) no visitado de D
marcar N como visitado
para cada etiqueta posible l
S=conjunto de nodos a los que se puede llegar desde
nodos en N pasando por arcos con etiqueta l
T=clausura_epsilon(S)
si (T ya es vrtice de D) entonces
agregar en D un arco de N a T con etiqueta l
sino
agregar T como vrtice no marcado a D
si T contiene el vrtice final del NFA marcar T
como final
agregar un arco de N a T con etiqueta l
fin-si
fin-para
fin-mientras
Minimizacin de la cantidad de estados de un DFA

Dados todos los estados de un DFA, la idea es hacer una particin P de estos
estados identificando en el mismo subconjunto todos los vrtices que tengan las
mismas salidas (i.e todos ellos tienen arcos que parten a los mismo subconjuntos
con las mismas etiquetas).

Inicialmente divida los estados en dos grupos F y NF donde F contiene todos los
estados finales y NF los estados no finales, P={F,NF}.
mientras (se haya modificado P)
para cada posible etiqueta c del DFA inicial
para cada conjunto S de P
escoja un elemento x de S del que salga un arco con etiqueta c
S1={y en S | y va al mismo conjunto de P que x por una etiqueta c}
S2=S-S1
eliminar S de P
agregar S1 a P
si S2 no es vaco agregar S2 a P
fin-para
fin-para
fin-mientras

3.1.2 Lecturas recomendadas
La fuente de consulta fundamental ha sido [4], libro clsico y muy recomendado.
3.1.3 Ejercicios para afianzar teora
1. Sobre un alfabeto E={x,y,7,2}, se definen los lenguajes A={xx, xy, x72}
y B={x
i
| ie Nat} donde x
0
=c, x
1
=x, x
2
=xx, x
3
=xxx y as sucesivamente. A
qu lenguaje corresponden: A.A, A
3
, A A
3
, A*, A B,B
2
, (A B)*.
2. Qu lenguajes representan las siguientes expresiones regulares
o a
o m*
o x|y
o (%)
o \\\*
o
o ab|c
o a|b*
o a*|b
o ab*
o (ab)*c(d|e)


3. Escriba AFNs o AFDs que reconozcan cada uno de los lenguajes descritos
por las expresiones regulares del punto anterior.
4.

Figure 3.4: AFD



Dado el AFD de la figura 3.4 indique cuales de las siguientes cadenas
reconoce:
o casa
o cas
o faa
o fabdadasbl
o casb
o dasa

5. Transforme cada una de las siguientes expresiones regulares a un AFN
siguiendo el algoritmo descrito en la gua, despus transforme el AFN
resultante en un AFD siguiendo el algoritmo descrito en la gua.
o xy*z*u
o db*(c(d|e))*
o (ab)|(de)*
o x*x*x*


6. Minimice los estados de cada uno de los AFDs del ejercicio anterior,
siguiendo el algoritmo descrito en la gua.
3.1.4 Ejercicios de programacin
1. Empleando el tipo
2. type expreg=
3. Epsilon
4. | Car of char
5. | Secuencia of expreg * expreg
6. | Alternativa of expreg * expreg
7. | Repeticion of expreg
8. ;;
(adaptado de uno introducido en la gua anterior) escriba la
funcin reconoce_expreg: int -> int -> string -> expreg que recibe
como tercer parmetro una cadena con una expresin regular (con la
sintaxis concreta descrita en esta gua), como primer parmetro una
posicin inicial dentro de la cadena y como segundo parmetro una
posicin final dentro de la cadena. Retorna la expresin regular que puede
reconocer entre las posiciones inicial y final (incluidas).
9. Implemente un tipo paramtrico ('a,'b) afd para representar AFDs con
nodos tipo 'a y etiquetas tipo 'b, e implemente la
funcin afd_reconocedor: string -> afd -> bool que retorne verdadero
slo si el autmata reconoce la cadena que recibe.
10. Para representar autmatas finitos no determinsticos con un slo estado
inicial y un slo estado final podra emplearse el tipo: type ('a,'b)
afn='a list * ('a*'a*'b option) list * 'a option * 'a option;;

La primera lista es de vrtices, la segunda de arcos etiquetados, el tercer
elemento de la tupla es el vrtice inicial y el ltimo el vrtice final. La
etiqueta c se representa con None. El NFA vacio sera ([],[],None,None),
los dems NFAs deben tener nodo inicial y final diferentes a None
(i.e Some x).

Usando este tipo (o uno anlogo en un lenguaje diferente a Ocaml) y el
tipo expreg del primer ejercicio de esta gua, implemente la
funcin afn_de_expreg : int -> expreg -> ((int,char) afn, int)que
traduce una expresin regular a un AFN con el algoritmo descrito en la
gua. Los vrtices los numera con enteros comenzando con el entero que
recibe como segundo parmetro. Retorna el AFN y el siguiente entero que
no se uso para numerar vrtices.

Opcional: Los AFN que resultan del algoritmo de traduccin descrito
tienen una caracterstica que puede aprovecharse para hacer una estructura
de datos ms eficiente. De todo vrtice salen a lo sumo dos arcos y cuando
salen dos ambos tienen etiquetas c. Proponga una estructura de datos que
aproveche esta caracterstica e indique que cambios deben hacerse
a afn_de_expreg para que la use.
11. Empleando el tipo del ejercicio anterior, un tipo para AFDs ('a, 'b) afd, y
un TAD conjunto de enteros conjent, implemente la funcin afd_de_afn:
(int, char) afn -> (conjent, char) afd que transforme un AFN en un
AFD con el algoritmo descrito en la gua.

Opcional: La eficiencia de esta transformacin depende en buena medida
del TAD conjunto de enteros que se emplee. Mejore la implementacin de
conjunto de enteros como bits en enteros de 32 bits, para que emplee un
vector de enteros en lugar de un slo entero, y verifique que funciona con
la funcin de este ejercicio.
12. Escriba una funcin que renombre los estados de un AFD para que sean
enteros: numest_afd: ('a, 'b) afd -> (int, 'b) afd. Cul es la
complejidad de esta funcin?
13. Escriba una funcin que implemente el algoritmo de minimizacin de
estados de un AFD descrito en la gua: minest_afd: (int, char) afd ->
(conjent, char) afd.

1
Los lenguajes que una expresin regular puede denotar se llaman
lenguajes regulares.
2
Un grafo es decorado si a cada arco se le asocia un valor. Es decir un grafo
dirigido decorado con valores en un conjunto D, es una tupla G=(V,A,ea)
donde V es conjunto de vrtices, A es conjunto de arcos (parejas ordenadas
de vrtices) y ea:A D. Grficamente puede representarse agregando sobre
cada arco el valor asociado.
Bibliografa
[1]
B-tree algorithms. http://www.semaphorecorp.com/btp/algo.html, 2004.
[2]
Graphviz - open source graph drawing software.
http://www.research.att.com/sw/tools/graphviz/, 2004.
[3]
Sqlite: An enbeddable sql database engine. http://www.sqlite.org/, 2004.
[4]
Alfred V. Aho and Jeffrey D. Ullman. Principles of Compiler Design.
Addison Wesley, 1978.
[5]
Richard Bird. Introduccin a la Programacin Funcional con Haskell.
Prentice Hall, 2000.
[6]
Bla Boolobs. Graph Theory: An Introductory Course. Springer Verlag,
1979.
[7]
Tom Moog. Pccts resources. http://www.polhode.com/pccts.html, 2004.
[8]
John Morris. Data structures and algorithms.
http://ciips.ee.uwa.edu.au/ morris/Year2/PLDS210/ds_ToC.html, 2004.
[9]
Vladimir Tmara Patio. Restricted design spaces: Visualization and
consistency tools. Technical Report 03/01, Sonderforschungsbereich 501,
Teilprojekt B5, Universitt Kaiserslautern, "http://www-
madlener.informatik.uni-kl.de/ag-madlener/publications/2001/sfb501-03-
01.ps.gz", 2001.
[10]
Vladimir Tmara and Carlos Fidel Rodriguez. Programacin en ocaml.
http://structio.sourceforge.net/guias/arbgraf, 2004.
[11]
Jorge Villalobos, Alejandro Quintero, and Mario Otero. Estructuras de
Datos: Un Enfoque desde Tipos Abstractos. Mc-Graw Hill. Ediciones
Uniandes, 1988.

También podría gustarte