You are on page 1of 121

Algoritmos Avanzados

Tema 1

1.1

RESOLUCIN DE PROBLEMAS

La habilidad de programar ordenadores constituye una de las bases necesarias de todo


profesional de las ciencias de la computacin. Pero, por encima del nivel de
programacin, la caracterstica fundamental de un profesional del rea es su capacidad
para resolver problemas. La resolucin de problemas informticos en la vida real implica
otras muchas mas habilidades que nicamente saber programar habilidades que
distinguen a un ingeniero de un simple programador. Implica comprender y analizar las
necesidades de los problemas, saber modelarlos de forma abstracta diferenciando lo
importante de lo irrelevante, disponer de una variada batera de herramientas
conceptuales que se puedan aplicar en su resolucin, trasladar un diseo abstracto a un
lenguaje y entorno concretos y, finalmente, ser capaz de evaluar la correccin,
prestaciones y posibles inconvenientes de la solucin planteada.
Las herramientas que surgen en el desarrollo de programas son esencialmente de dos
clases: estructuras de datos y algoritmos. Las estructuras de datos representan la
parte esttica de la solucin al problema, el componente almacenado, donde se
encuentran los datos de entrada, de salida y los necesarios para posibles clculos
intermedios. Los algoritmos representan la parte dinmica del sistema, el componente que
manipula los datos para obtener la solucin. Algoritmos y estructuras de datos se
relacionan de forma muy estrecha: las estructuras de datos son manipuladas mediante
algoritmos que aaden o modifican valores en las mismas; y cualquier algoritmo necesita
manejar datos que estaran almacenados en cierta estructura. La idea se puede resumir
en la frmula magistral de Niklaus Wirth:

Algoritmos + Estructuras de datos = Programas

En ciertos mbitos de aplicacin predominara la componente algortmica como, por


ejemplo, en problemas de optimizacin y clculo numrico - y en otros la componente de
estructuras como en entornos de bases de datos y sistemas de informacin, pero
cualquier aplicacin requerir siempre de ambos. Esta dualidad aparece en el nivel
abstracto: un tipo abstracto esta formado por un dominio de valores (estructura abstracta)
y un conjunto de operaciones (algoritmos abstractos). Y la dualidad se refleja tambin en
el nivel de implementacin: un mdulo (en lenguajes estructurados) o una clase (en
lenguajes orientados a objetos) estn compuestos por una estructura de atributos o
variables, y una serie de procedimientos de manipulacin de los anteriores.
Antes de entrar de lleno en el estudio de los algoritmos y las estructuras de datos, vamos
a analizar los pasos que constituyen el proceso de resolucin de problemas.

Lic. Carmen Mollinedo

Algoritmos Avanzados

1.1.1 ANLISIS DE REQUISITOS DE PROBLEMA


El proceso de resolucin de problemas parte siempre de un problema, de un enunciado
ms o menos claro que alguien plantea. El primer paso es la comprensin del problema,
entender las caractersticas y peculiaridades de lo que se necesita. Este anlisis de los
requisitos del problema puede ser, de por si, una de las grandes dificultades; sobre todo
en grandes aplicaciones, donde los documentos de requisitos son ambiguos, incompletos
y contradictorios.
El anlisis debe producir como resultado un modelo abstracto del problema. El modelo
abstracto es un modelo conceptual, una abstraccin del problema, que reside
exclusivamente en la mente del individuo y donde se desechan todas las cuestiones
irrelevantes para la resolucin del problema. Supongamos, por ejemplo, los dos siguientes
problemas, con los cuales trabajaremos en el resto de los puntos.
Ejemplo 1 El problema de las cifras. Dado un conjunto de seis nmeros enteros, que
pueden ser del 1 al 10, 25, 50, 75 100, encontrar la forma de conseguir otro entero dado
entre 100 y 999, combinando los nmeros de partida con las operaciones de suma, resta,
producto y divisin entera. Cada uno de los seis nmeros iniciales slo se puede usar una
vez.

Ejemplo 2 El problema de deteccin de caras humanas. Dada una imagen en color en un


formato cualquiera (por ejemplo, bmp, jpeg o gif) encontrar el nmero de caras humanas
presentes en la misma y la posicin de cada una de ellas

Lic. Carmen Mollinedo

Algoritmos Avanzados

Ambos enunciados representan categoras de problemas muy distintas. El problema 1


tiene un enunciado ms o menos claro, aunque cabran algunas dudas. Es de tipo
matemtico, se puede modelar formalmente y es previsible que exista un algoritmo
adecuado.
El problema 2 tiene un enunciado ms corto pero mucho ms ambiguo, no est claro
exactamente lo que se pide. Es ms, incluso tenindolo bien claro, el problema parece
ms adecuado para ser resuelto por un humano, pero difcil de implementar en un
ordenador. Aun as, ambos problemas tienen algo en comn: son de inters, as que
necesitamos resolverlos de la mejor forma que podamos.

1.1.2 MODELADO DEL PROBLEMA Y ALGORITMOS ABSTRACTOS


El primer paso sera crear un modelo abstracto, en el que nos quedamos con lo esencial
del problema. Normalmente, este modelo se crea a travs de una analoga con algo
conocido previamente. Por ejemplo, para ensear a un alumno inexperto lo que es un
algoritmo (concepto para l desconocido) se utiliza la analoga con una receta de cocina,
y las estructuras de datos se asimilan con la disposicin de armarios, cajones y
recipientes donde se guardan los ingredientes y el bizcocho resultante.

1.1.3. DISEO DE LA SOLUCIN


Una vez que tengamos un modelo completo y adecuado, significar que hemos entendido
bien el problema. Como hemos visto en los ejemplos, el modelo conlleva tambin un
algoritmo informal, que no es ms que una vaga idea de cmo resolver el problema. El
siguiente paso de refinamiento consistira en disear una solucin. Usando otra analoga,
el diseo de un programa es equivalente a los planos de un arquitecto: el diseo describe
el aspecto que tendr el programa, los materiales que se necesitan y dnde y cmo
colocarlos. El diseo es siempre un paso previo a la implementacin, pero que se olvida
muy a menudo por los programadores primerizos. Un ingeniero informtico debera ser
tan consciente del error de programar sin partir de un buen diseo previo, como lo es un
arquitecto del fallo de hacer un puente sin tener antes los planos.
El diseo de un programa consta de dos clases de elementos: tipos de datos y algoritmos.
Los tipos de datos usados a nivel de diseo son tipos abstractos, en los cuales lo
importante son las operaciones que ofrecen y no la representacin en memoria. Los
algoritmos son una versin refinada de los algoritmos abstractos del paso anterior. No
obstante, son an algoritmos en pseudocdigo, donde se dan cosas por supuestas.
Definir los tipos de datos para almacenar la solucin suele ser mucho ms difcil que
definirlos para los datos de entrada. Adems, modificaciones en los algoritmos pueden
requerir cambios en los tipos de datos y viceversa.

1.1.4. IMPLEMENTACIN DEL DISEO


El siguiente paso en la resolucin del problema es la implementacin. La implementacin
parte del diseo previo, que indica qu cosas se deben programar, cmo se estructura la
solucin del problema, dnde colocar cada funcionalidad y qu se espera en concreto de
cada parte en la que se ha descompuesto la solucin. Esta descripcin de lo que debe
hacer cada parte es lo que se conoce como la especificacin. Una implementacin ser

Lic. Carmen Mollinedo

Algoritmos Avanzados
correcta si cumple su especificacin. La dualidad tipos/algoritmos del diseo se traslada
en la implementacin a estructuras/ algoritmos. Para cada uno de los tipos de datos del
diseo, se debe elegir una estructura de datos adecuada. Por ejemplo, los dos ejemplos
de problemas analizados necesitan listas. Una lista se puede representar mediante una
variedad de estructuras: listas enlazadas con punteros o cursores, mediante celdas
adyacentes en un array, enlazadas simple o doblemente, con nodos cabecera o no, etc.
La eleccin debe seguir los criterios de eficiencia en cuanto a tiempo y a uso de
memoria que se hayan especificado para el problema. En cada caso, la estructura ms
adecuada podr ser una u otra.

1.1.5. VERIFICACIN Y EVALUACIN DE LA SOLUCIN


La resolucin de un problema no acaba con la implementacin de un programa. Los
programas deberan ser comprobados de forma exhaustiva, verificando que se ajustan a
los objetivos deseados, obtienen los resultados correctos sin provocar fallos de ejecucin.
En la prctica, hablamos de un proceso cclico de desarrollo: implementar, verificar,
corregir la implementacin, volver a verificar, volver a corregir, etctera. En cierto
momento, puede que tengamos que cambiar el diseo, e incluso puede que lo que est
fallando sea el modelo abstracto. Cuanto ms atrs tengamos que volver, ms tiempo
habremos perdido haciendo cosas que luego resultan intiles.

Ciclo del desarrollo del software

1.2 ALGORITMOS
Como ya hemos visto, los algoritmos junto con las estructuras de datos constituyen los
dos elementos imprescindibles en el proceso de resolucin de problemas. Los primeros
definen el componente manipulador y los segundos el componente almacenado, y se
combinan estrechamente para crear soluciones a los problemas.
No est de ms recordar que la historia de los algoritmos es mucho anterior a la aparicin
de los ordenadores. De hecho, podramos datar la aparicin de los algoritmos al primer
momento en que los seres humanos se plantearon resolver problemas de forma genrica.
Histricamente uno de los primeros algoritmos inventados, para la resolucin de
problemas de tipo matemtico, es el algoritmo de Euclides de Alejandra, Egipto,
propuesto alrededor del ao 300 a.C. Euclides propone el siguiente mtodo para calcular
el mximo comn divisor de dos nmeros enteros.

Lic. Carmen Mollinedo

Algoritmos Avanzados
Ejemplo 3 Algoritmo de Euclides para calcular el mximo comn divisor de dos nmeros
enteros, a y b, siendo a > b.
1. Hacer r= a mdulo b
2. Si r = 0 entonces el mximo comn divisor es b
3. En otro caso:
3.1. Hacer a= b
3.2. Hacer b= r
3.3. Volver al paso 1
Pero el honor de dar nombre al trmino algoritmo lo recibe el matemtico rabe del siglo
IX Muhammad ibn Musa al-Khwarizmi (que significa algo as como Mohamed hijo de
Moiss de Khorezm, en Oriente Medio). Sus tratados sobre la resolucin de ecuaciones
de primer y segundo grado ponen de relieve la idea de resolver clculos matemticos a
travs de una serie de pasos predefinidos. Por ejemplo, para resolver ecuaciones de
segundo grado del tipo: x2 + bx = c, define la siguiente serie de pasos7.
Ejemplo .4 Algoritmo de al-Khwarizmi para resolver la ecuacin x2 + bx = c.
Se muestra el ejemplo x2 + 10x = 39, el mismo que al-Khwarizmi utiliza en su libro Hisab
al-jabr wal-muqabala (El clculo de reduccin y restauracin), sobre el ao 825 d.C.
1. Tomar la mitad de b. (En el ejemplo, 10/2 = 5)
2. Multiplicarlo por s mismo. (En el ejemplo, 5 * 5 = 25)
3. Sumarle c. (En el ejemplo, 25 + 39 = 64)
4. Tomar la raz cuadrada. (En el ejemplo,64 = 8)
5. Restarle la mitad de b. (En el ejemplo, 8 10/2 = 8 5 = 3)
El resultado es
, expresado algortmicamente. El matemtico bagdad
es tambin considerado como el introductor del sistema de numeracin arbigo en
occidente, y el primero en usar el nmero 0 en el sistema posicional de numeracin.

1.2.1. DEFINICIN Y PROPIEDADES DE ALGORITMO


En la siguiente figura se destaca la concepcin de algoritmo como caja negra

Interpretacin de los algoritmos como cajas negras


A continuacin se presentan dos definiciones formales de algoritmos:

Lic. Carmen Mollinedo

Algoritmos Avanzados

Definicin 1 Un algoritmo es una serie de reglas que dado un conjunto de datos de


entrada (posiblemente vaco) produce unos datos de salida (por lo menos una) y cumple
las siguientes propiedades:
 Definibilidad. El conjunto de reglas debe estar definido sin ambigedad, es
decir, no pueden existir dudas sobre su interpretacin.
 Finitud. El algoritmo debe constar de un nmero finito de pasos, que se ejecuta
en un tiempo finito y requiere un consumo finito de recursos.

Definicin 2:
Un algoritmo es un conjunto de instrucciones sencillas, claramente
especificadas, que se debe seguir para resolver un problema. Una vez
que se da un algoritmo para un problema y se decide que es correcto,
un paso importante es determinar la cantidad de recursos, como
tiempo o espacio, que requerir

DEFINICIN DE KNUTH
Una definicin ms formal de algoritmo se puede encontrar en el libro de Knuth:
Definicin 1.1 Un mtodo de clculo es una cuaterna (Q, I,W,f)
donde:
Q es un conjunto que contiene a I y W, y
f : Q Q con f(w) = w para todo w perteneciente a W.
Q es el conjunto de estados del clculo,
I es el conjunto de estados de entrada,
W es el conjunto de estados de salida y
f es la regla de clculo.
Definicin 1.2 Una secuencia de clculo es x0, x1, x2; . . . donde x0 I
y k 0 f(xk) = xk+1. La secuencia de clculo acaba en n
pasos si n es el menor entero con xn W.

Veamos cmo esta definicin formal de algoritmo (el mtodo de clculo) cumple las
propiedades que debe de cumplir un algoritmo:

Se cumplir el concepto de finitud si toda secuencia de clculo a la que pueda dar


lugar el mtodo de clculo es finita.
Existe un conjunto de posibles entradas, que es I en la definicin.
Existe un conjunto de posibles salidas, que es W en la definicin.

Lic. Carmen Mollinedo

Algoritmos Avanzados

En cuanto a la definibilidad, el algoritmo est definido con el mtodo de clculo,


pero, dado un mtodo de clculo, se puede hacer un programa?,en qu
lenguaje?, en un tiempo razonable?
El mtodo de clculo ser eficiente si el valor de n en cada secuencia de clculo
un valor "razonable".

No todo lo que aparece en informtica son algoritmos. Un ejemplo tpico de algo que no
es un algoritmo es un sistema operativo. El sistema operativo consta de una serie de
instrucciones, pero no se le prev una ejecucin finita, sino que debera poder ejecutarse
mientras no se requiera lo contrario.
Algoritmos deterministas y no deterministas
Segn un algoritmo produzca o no siempre los mismos valores de salida para las mismas
entradas, clasificamos los algoritmos en dos tipos:
Algoritmos deterministas. Para los mismos datos de entrada producen siempre los
mismos datos de salida.
Algoritmos no deterministas. Para los mismos datos de entrada pueden producir
diferentes salidas.
El no determinismo puede chocar un poco con la idea de definibilidad. Sin embargo,
ambas propiedades no son contradictorias. Por ejemplo, el resultado de un algoritmo
paralelo, que se ejecuta en distintos procesadores, puede depender de cuestiones de
temporizacin que no forman parte de los datos del problema. La existencia del no
determinismo hace que un algoritmo no siempre se pueda ver como una funcin en
sentido matemtico de la forma f : ENTRADA SALIDA.

1.3 LA DISCIPLINA DE LA ALGORTMICA


Si bien, como hemos visto, la historia de los algoritmos se remonta muy atrs, el estudio
de los algoritmos no se concibi como una disciplina propia hasta bien entrada la mitad
del pasado siglo XX. Actualmente, entendemos la algortmica como la disciplina, dentro
del mbito de la informtica, que estudia tcnicas para construir algoritmos eficientes y
tcnicas para medir la eficiencia de los algoritmos. En consecuencia, la algortmica consta
de dos grandes reas de estudio: el anlisis y el diseo de algoritmos.
Pero, cul es el objetivo ltimo de la algortmica?, qu es lo que motiva su estudio? El
objetivo ltimo es dado un problema concreto ser capaz de resolverlo de la mejor forma
posible, de forma rpida, corta, elegante y fcil de programar. Y recordemos que en esta
resolucin entran tambin en juego las estructuras de datos, que son manejadas por los
algoritmos. En definitiva, todos los ejemplos, tcnicas, mtodos y esquemas que vamos a
estudiar tienen como finalidad ltima servir de herramientas tiles en el momento de
afrontar la resolucin de un problema completamente nuevo y desconocido.
La Algoritmia nos permite evaluar el efecto de los diversos factores externos sobre los
algoritmos disponibles, de tal modo que sea posible seleccionar el que ms se ajusta a
nuestras circunstancias particulares; tambin es la ciencia que nos indica la forma de
disear un nuevo algoritmo para una tarea concreta.

Lic. Carmen Mollinedo

Algoritmos Avanzados

La algoritmia es uno de los pilares de la programacin y su relevancia se muestra en el


desarrollo de cualquier aplicacin, ms all de la mera construccin de programas. Este
es un texto introductorio sobre anlisis y diseo de algoritmos que pretende exponer al
lector las tcnicas bsicas para su diseo e implementacin, as como presentar unas
herramientas que le permitan medir su efectividad y eficiencia.

1.4 PARADIGMAS DE LA PROGRAMACION


Un paradigma est constituido por los supuestos tericos generales, las leyes y las
tcnicas para su aplicacin que adoptan los miembros de una determinada comunidad
cientfica.

Las leyes explcitamente establecidas y los supuestos tericos. Por ejemplo, las leyes
de movimiento de Newton forman parte del paradigma newtoniano y las ecuaciones
de Maxwell forman parte del paradigma que constituye la teora electromagntica
clsica.
El instrumental y las tcnicas instrumentales necesarios para hacer que las leyes del
paradigma se refieran al mundo real. La aplicacin en astronoma del paradigma
newtoniano requiere el uso de diversos telescopios, junto con tcnicas para su
utilizacin y diversas tcnicas para corregir los datos recopilados.
Un componente adicional de los paradigmas lo constituyen algunos principios
metafsicos muy generales que guan el trabajo dentro del paradigma. Todos los
paradigmas, adems, contienen prescripciones metodolgicas muy generales tales
como: "Hay que intentar seriamente compaginar el paradigma con la naturaleza".

Podemos decir que, los paradigmas son marcos de referencia que imponen reglas
sobre cmo se deben hacer las cosas, indican qu es vlido dentro del paradigma y
qu est fuera de sus lmites. Un paradigma distinto implica nuevas reglas, elementos,
lmites y maneras de pensar, o sea implica un cambio. Los paradigmas pueden ser
considerados como patrones de pensamiento para la resolucin de problemas. Desde
luego siempre teniendo en cuenta los lenguajes de programacin, segn nuestro
inters de estudio. Los paradigmas de Programacin representan un enfoque
particular o filosofa para la construccin del software. No es mejor uno que otro sino
Lic. Carmen Mollinedo

Algoritmos Avanzados
que cada uno tiene ventajas y desventajas. Tambin hay situaciones donde un
paradigma resulta ms apropiado que otro.
Generalmente los autores clasifican los paradigmas de modos similares, siempre
destacan el imperativo, el orientado a objetos, el funcional y el lgico. Algunos autores
o profesores, mencionan paradigmas heursticos, concurrentes, procedimentales,
declarativos y demostrativos.

1.4.1 PARADIGMA FUNCIONAL


Modelo matemtico de composicin funcional donde el resultado de un clculo es la
entrada del siguiente, y as sucesivamente hasta que una composicin produce el
valor deseado.
El paradigma funcional est representado por la familia de lenguajes LISP, en
particular Scheme o Haskell.

1.4.2 PARADIGMA IMPERATIVO


El paradigma imperativo es considerado el ms comn y est representado, por
ejemplo, por el C o por BASIC.
El Paradigmas Imperativo es un modelo abstracto que consiste en un gran
almacenamiento de memoria donde la computadora almacena una representacin
codificada de un clculo y ejecuta una secuencia de comandos que modifican el
contenido de ese almacenamiento.
Algoritmos + Estructura de Datos = Programa.

1.4.3 PARADIGMA ORIENTADO A OBJETOS


Disciplina de ingeniera de desarrollo y modelado de software que permite construir ms
fcilmente sistemas complejos a partir de componentes individuales.
Objetos + Mensajes = Programa.

Lic. Carmen Mollinedo

Algoritmos Avanzados

Tema 2

2.1. INTRODUCCIN
El anlisis de algoritmos es la parte de la algortmica que estudia la forma de medir la
eficiencia de los algoritmos. Pero cundo decimos que un algoritmo es ms o menos
eficiente? Utilizando un punto de vista empresarial, podemos definir la eficiencia como la
relacin entre recursos consumidos y productos obtenidos. Se trata, por lo tanto, de una
nueva formulacin de la bien conocida ley del mnimo esfuerzo: maximizar los resultados,
minimizando el esfuerzo. Los resultados que ofrece un algoritmo pueden ser de distintos
tipos:
 Un algoritmo puede resolver el problema de forma muy precisa, si es de tipo
matemtico, o garantizar el ptimo, en problemas de optimizacin, o encontrar
siempre la solucin, si es de satisfaccin de restricciones.
 Otro algoritmo puede ser que slo encuentre soluciones aproximadas, o ms o
menos cercanas al ptimo, pero siempre encuentre alguna.
 Finalmente, otro algoritmo puede que encuentre soluciones slo en determinados
casos, buenas o malas, y en otros casos acabe sin devolver ninguna respuesta.
Por otro lado, los recursos que consume un algoritmo pueden ser de distintos tipos. Entre
los ms importantes tenemos:





Tiempo de ejecucin, desde el inicio del programa hasta que acaba.


Utilizacin de memoria principal.
Nmero de accesos a disco, a la red o a otros perifricos externos.
Nmero de procesadores usados, en el caso de los algoritmos paralelos, etc.

En aplicaciones distintas puede que el recurso crtico sea diferente. En la mayora de los
casos, el recurso clave es el tiempo de ejecucin, por lo que muchas veces se asocia
eficiencia con tiempo. Pero, recordemos, ni el tiempo es el nico recurso, ni el tiempo por
s solo mide la eficiencia, si no que se debe contrastar con los resultados obtenidos. En
conclusin, un algoritmo ser mejor cuanto ms eficiente sea. No obstante, el sentido
comn nos dice que habrn otros muchos criterios para decidir lo bueno que es un
algoritmo. Por ejemplo, ser importante: que sea fcil de entender y de programar, que sea
corto en su extensin, que sea robusto frente a casos extraos, que se pueda reutilizar en
otros problemas, que se pueda adaptar, etc.
Lic. Carmen Mollinedo

10

Algoritmos Avanzados

2.2 FACTORES EN LA MEDICIN DE RECURSOS


Supongamos el siguiente algoritmo sencillo, que realiza una bsqueda secuencial dentro de
un array de enteros. La cuestin que se plantea es cuntos recursos, de tiempo de
ejecucin y memoria, consume el algoritmo?
Ejemplo 1
operacin BusquedaSec (x, n: entero; a: array [1..n] de entero): entero
i= 0
repetir
i:= i + 1
hasta a[i] = x or i<=n
devolver i
Muy difcilmente se habr contestado algo como tarda 3 segundos o requiere 453
Kbytes.... Como mnimo, est claro que el tiempo y la memoria dependen de n, de los
datos de entrada, del procesador, de que estemos grabando un CD al mismo tiempo y de
otras mil cosas ms. Podemos clasificar todos los factores que intervienen en el consumo de
recursos en tres categoras.
Factores externos. No indican nada relevante sobre las caractersticas del algoritmo; son,
ms bien, cuestiones externas al algoritmo, relacionadas con el entorno en el que se
implementa y ejecuta. Entre los principales factores externos tenemos: el ordenador donde
se ejecuta el algoritmo, el uso de procesador por parte de otras tareas, el sistema operativo,
el lenguaje de programacin usado, el compilador (incluyendo las opciones de compilacin
usadas), la implementacin concreta que se haga del algoritmo, etc.


Tamao del problema. El tamao es el volumen de datos de entrada que debe


manejar el algoritmo. Normalmente, el tamao viene dado por uno o varios nmeros
enteros. La relacin del tiempo con respecto al tamao s que resulta interesante
sobre las caractersticas del algoritmo.

Contenido de los datos de entrada. Para un tamao de entrada fijo y bajo las
mismas condiciones de ejecucin, un algoritmo puede tardar distinto tiempo para
diferentes entradas. Hablamos de diferentes casos: mejor caso, es el contenido de
los datos de entrada que produce la ejecucin ms rpida del algoritmo (incluso para
tamaos de entrada grandes); peor caso, es el que da lugar a la ejecucin ms lenta
para un mismo tamao; caso promedio, es el caso medio de todos los posibles
valores de entrada.

Por ejemplo, en el anterior algoritmo de bsqueda secuencial, el tamao del problema viene
dado por n. No es lo mismo aplicar el algoritmo con n = 5 que con n =5.000.000. Pero la
ejecucin con n = 5.000.000 puede tardar menos que con n = 5, si el x buscado se encuentra
en la primera posicin. As pues, el mejor caso ser que a[1] = x, independientemente de lo
que valga n. El peor caso ser que x no se encuentre en el array, con lo cual la bsqueda
Lic. Carmen Mollinedo

11

Algoritmos Avanzados

acabar al llegar a a[n + 1]. El caso promedio sera la media de todas las posibles entradas.
Supongamos que x est en a con probabilidad p y que, en caso de estar, todas las posiciones
tienen la misma probabilidad. Entonces se recorrern n/2 posiciones con probabilidad p, y
n+ 1 posiciones con probabilidad 1 p.
En resumen, para la estructura repetitiva el Tiempo de Ejecucin depende de los valores
que toman x y n
Mejor caso. Se encuentra x en la 1 posicin:
Tiempo(N) = 1
Peor caso. No se encuentra x:
Tiempo(N) =N
Existen dos enfoques para medir la eficiencia:
Enfoque emprico o a posteriori: Consiste en programar todos los algoritmos candidatos e
ir probndolos en distintos casos con ayuda de una computadora.
Enfoque terico o a priori. Que consiste en determinar matemticamente la cantidad de
recursos necesarios para cada uno de los algoritmos como funcin del tamao de los casos
considerados. Lo recursos que ms nos interesan son el tiempo de computacin y el espacio
de almacenamiento.

2.3 TIPOS DE ANLISIS DE EFICIENCIA


Se definen distintos tipos de anlisis:
a) Anlisis en el peor caso: se considera el mximo entre las cantidades de recursos
insumidas por todas las instancias de tamao n.
b) Anlisis caso promedio: se considera el promedio de las cantidades de recursos
insumidas por todas las instancias de tamao n.
c) Anlisis probabilstico: se considera la cantidad de recursos de cada instancia de
tamao n pesado por su probabilidad de ser ejecutada.
d) Anlisis en el mejor caso: se considera el mnimo entre las cantidades de recursos
insumidas por todas las instancias de tamao n.
Nos concentraremos en general a analizar el peor caso, debido a que: constituye una cota
superior al total de los recursos insumidos por el algoritmo. Conocerla nos asegura que no
se superar a esa cantidad. Para muchos algoritmos, el peor caso es el que ocurre ms
seguido debido al uso de la notacin asinttica, el caso promedio o probabilstico es
muchas veces el mismo que el peor caso.
No se necesita conocer la distribucin de probabilidades para todas las instancias de un
mismo tamao, como ser necesario en el anlisis probabilstico. Se considerar entonces
que un algoritmo es ms eficiente que otro para resolver el mismo problema si su tiempo de
ejecucin (o espacio) en el peor caso tiene un crecimiento menor.

Lic. Carmen Mollinedo

12

Algoritmos Avanzados

2.4 MODELO DE ANLISIS


Para analizar algoritmo en un marco formal, se necesita un modelo de computacin.
Nuestro modelo es bsicamente un computador normal, en el cual las instrucciones se
ejecutan de modo secuencial. El modelo tiene el repertorio estndar de instrucciones
sencillas, como adicin, multiplicacin, comparacin y asignacin, pero a diferencia de
los computadores reales, este tarda exactamente una unidad de tiempo en hacer
cualquier operacin sencilla. Para ser razonable, se supondr que, como un computador
moderno, este modelo tiene enteros de tamao fijo y que no tienen instrucciones
refinadas, como la inversin de matrices o la clasificacin, que claramente no se pueden
hacer en una unidad de tiempo.

A continuacin se definen algunas reglas bsicas para la asignacin de tiempos:


Operaciones bsicas aritmticas y lgicas (+, -, *, :=,...): Una unidad de tiempo, o
alguna constante.
Operaciones de entrada salida: Otra unidad de tiempo, o una constante diferente.
En ambos casos T(n)=1

Ejemplo 3

a) z=z+1
b) a>b
Tienen un T(n)=1, donde n es el tamao (no conocido en este ejemplo) de la entrada
2.5 NOTACIONES PARA EXPRESAR LA COMPLEJIDAD EN TIEMPO
Una medida asinttica es un conjunto de funciones que muestran un comportamiento
similar cuando los argumentos toman valores muy grandes. Las medidas asintticas se
definen en trminos de una funcin de referencia f.
T(n) tiempo de ejecucin de un programa con una entrada de tamao n
Notacin () Una funcin T(n) es (g(n)) s y solo s existen unas constantes c y n0 tales
que cg(n) T(n) cuando n0n
Notacin () Una funcin T(n) es (h(n)) s y solo s se cumple que existen unas constantes
positivas c1, c2 y n0 independientes de n tales que:
c1g(n) T(n) c2g(n) n0n

Lic. Carmen Mollinedo

13

Algoritmos Avanzados

Notacin O(): De manera formal se dice que una funcin f(n) es de orden O(g(n)) sii se
cumple que existen unas constantes positivas c y n0 , ambas independientes tales que:
f(n) c g(n) , n n0
donde decidir que f(n) es O(g(n)) supone que cg(n) es una cota superior del tiempo de
ejecucin del algoritmo
Las notaciones se interpretan tambin de la siguiente forma:
O(T): Orden de complejidad de T.
(T): Orden inferior de T, u omega de T.
(T): Orden exacto de T.

2.5.1 PROPIEDADES DE LA NOTACIN O()


Para cualquier par de funciones f(n) y g(n) se verifican las siguientes propiedades:
Pr1: cO(f(n)) es O(f(n)), donde c es una constante
Pr2: Regla de la suma:
O(f(n) + g(n)) es max(O(f(n)), O(g(n))
Pr3: O(f(n)) + O(g(n)) es O(f(n)+g(n))
Pr4: O(f(n))O(g(n)) es O(f(n)g(n))
Pr5: O(O(f(n))) es O(f(n))
Lo que buscamos es determinar matemticamente la cantidad de recursos

Ejemplo 2 Determine O(g(n))


T(n)=2n es O(n), donde 2 es una constante
T(n)=n3 + n2 + log n es O(n3) puesto que n3 es el mayor
T(n)=nm+n es O(nm), si la entrada depende de n y m
O(O(n3)) es O(n3)
T(n) = 2n2/5 + 3/2; T(n) O(n2). O T(n) e O(n)
Ejemplo 3
a) Sea el segmento de algoritmo
X=1 . . . . . .1
Z=6 . . . . . . 1

El tiempo de ejecucin es T(n)= 1+1= 2 aplicando la regla de la suma lo cual es O(1)


por la propiedad Pr3

Lic. Carmen Mollinedo

14

Algoritmos Avanzados

Ejemplo 4
Sea el segmento de algoritmo
For i=1 to 10 do
Begin
x=x+1 ..............1
y=y/i.................1
end
T(n)=T(for)*T(instrucciones internas del for)=10*2=12 por la propiedad de la
multiplicacin y es O(1) por Pr 2

2.5.2 ORDENES DE COMPLEJIDAD

donde:
O(1) O(log n) O(n ) O(n) O(n log n) O(n2) O(n3) ... O(nk)
...O(2n ) O(n!)
2.6 ANLISIS DE ALGORITMOS
A continuacin se enumeran algunas reglas importantes para el anlisis de programas.
a) Ciclos for
El tiempo de ejecucin de un ciclo for, es a lo ms el tiempo de ejecucin de las
instrucciones que estn en el interior del ciclo for (incluyendo las condiciones), por el
nmero de iteraciones. Generalmente se usa el smbolo de sumatoria
Ejemplo 5
for i:=1 to n do
x:=x+1;

Lic. Carmen Mollinedo

15

Algoritmos Avanzados
n

Ta (n) = T(for_i) * T(instr_internas) = 1 = n


i =1

b) Ciclos for anidados


Analizar de adentro hacia fuera. El tiempo de ejecucin total de una proposicin dentro del
grupo, de ciclos for anidados es el tiempo de ejecucin de la proposicin multiplicada por
el producto de los tamaos de todos los ciclos for.
T(For/nivel1)*T(For/Nivel2)* . . . *T(For/nivelN)

Ejemplo 6
for i:=1 to n do
for j:=1 to n do
for k:=1 to n do
x:=x+1;
n n
n n n n
Ta ( n) = T(for_i) * T(for_j) * T(for_k) * 1 = 1 = n = (n * n ) = n * n * n = n 3
i =1 j =1 k =11
i =1 j =1
i =1

que es O(n3) orden cbico

c) Para If / Else

T(IF_THEN) = T(condicin)+T(Then)
T(IF_THEN_ELSE) = T(condicin)+max(T(Then),T(Else))

Ejemplo 7
i)
if N mod 2 = 0 then
for i:=1 to n do
x:=x+1;

ii)
if N> 0 then
x:=x+N;
else

Lic. Carmen Mollinedo

Ta(n)= T(if_then)=T(condicin)+T(then)
n

= 1 + 1 = 1 + n es O(n)orden lineal
i =1

Tb(n)= T(if_then_else)
= T(condicin)+max(T(then),T(else))
= 1 + max(1,2) = 1 + 2 = 3
es O(1)orden lconstante

16

Algoritmos Avanzados

begin
N=N+100
Z=z+N
Endlse
La nocin de esta estructura selectiva se puede extender al uso del CASE (seleccin
mltiple)

d) While
Se realiza generalmente un anlisis inductivo exhaustivo mediante una variable axiliar t
cuya misin es contar el tiempo del while. Adems se realiza el anlisi del peor de los casos
de entrada al bucle.
Ejemplo 8
Cuntas multiplicaciones realiza el siguiente algoritmo para calcular potencias, en el peor
de los casos?
Funcion potencia1(y : num; z : nat): nat
p := 1
1
mientras z > 0 hacer
p := p * y
1
z := z 1
1
z+1
fmientras
funcin
Analizando solamente la sentencia mientras se tiene

t=0
mientras z > 0 hacer
z = z -1
t = t +1

z
4
3
2
1
0

t
0
1
2
3
4

El tiempo del mientras (while) es:


z +1
la ctte 1 se adiciona debido a la
ltima pregunta de condicin del
while

Finalmente:
Tpotencia1(z) = 1 + (z+1)2 = 1 + 2z + 2 = 3 + 2z que es O(z) orden lineal

Lic. Carmen Mollinedo

17

Algoritmos Avanzados

2.7 LLAMADAS A PROCEDIMIENTOS Y FUNCIONES


Si se tiene un programa con procedimientos no recursivos es posible calcular el tiempo de
ejecucin de los distintos procedimientos, uno a la vez partiendo de aquellos que no llaman
a otros.
Las siguientes formulas sern tiles para la resolucin de ejercicios y algunas sern usadas
en esta seccin
n

a) 1 = n
i =1
n

b) 1 = (n a + 1).
i=a
n

c ) i =
i =1

n(n + 1)
.
2

d ) i 2 =
i =1
n

e) i r =
i =1

Lic. Carmen Mollinedo

n(n + 1)(2n + 1)
6
n r +1
(r + 1) + p r (n)

18

Algoritmos Avanzados

2.8 EJERCICIOS RESUELTOS

Mediante la notacin asinttica, obtnganse los tiempos de ejecucin del peor caso
supuesto para cada uno de los procedimientos siguientes como una funcin de n
Ejercicio 1
i:=1;
while I<= n do
begin
x:=x+1;
I:=I+1;
End
Aadiendo una variable t que controlar el nmero de veces que se ingresa a la estructura
while

T=0
i:=1;
while i<= n do
i:=i+1;
t = t +1

i
1
2
3
4
5

t
0
1
2
3
4

n
4

El tiempo del while es:


n +1

Finalmente realizamos el anlisis del segmento de algoritmo del Ejercicio 1:


T(n) = 1 + T(while)*2 = 1+(n+1)*2 = 1 + 2n + 2 = 3 + 2n es O(n) orden lineal
Ejercicio 2
for i:=1 to n do
for j:=1 to i do
x:=x+1;
n i
n
n(n + 1) 1 2 1
T (n) = 1 = i =
= n + n es O(n2) orden cuadrtico
2
2
2
i =1 j =1
i =1

Ejercicio 3
procedure pord_mat(n: integer);
var
I,j,k:integer;
Begin
For i:=:1 to n do
Lic. Carmen Mollinedo

19

Algoritmos Avanzados

For j:=1 to n do
begin
C[i,j]:=0; - - - - - - - - - - - - - - 1
For k:=1 to n do
C[i,j]:=C[i,j]+A[i,k] * B[k,j]: - - 1
End;
End;
n n

Tprod_mat(n) = ( (1+1)) = n ( n (1+ n )) = n (n+n2) = n2 + n3


I=1 j=1

k=1

Que es O(n3) orden cbico.


La simplificacin de las sumatorias se realiza directamente, porque no existen variables
dependientes.
Ejercicio 4
procedure misterio1(n: integer);
var
i,j,k:integer;
begin
for i:=:1 to n-1 do
for j:=i+1 to n do
for k:=1 to j do
{alguna proposicin que requiera tiempo O(1) }
end;

n 1

n 1

n 1

i =1

j =i +1

i =1

j =1

j =1

Tmisterio1 (n ) = ( ( 1)) = ( j ) = ( j j )
i =1

n 1

Tmisterio1 (n ) = (
i =1

Tmisterio1 (n ) =

j =i +1 k =1

n( n + 1) i (i + 1) n 1 n ( n + 1) 1 n 1 2

) = (
) (i + i )
2
2
2
2 i =1
i =1

( n 1)n (n + 1) 1 n 1 2 n1
( n 2 n )( n + 1) 1 (n 1)n (2n 1) ( n 1)n
( i + i ) =
(
+
)
2
2 i =1
2
2
6
2
i =1

es O(n3) orden cbico


Ejercicio 5
procedure misterio2(n: integer);
var
x, cuenta:integer;

Lic. Carmen Mollinedo

20

Algoritmos Avanzados

begin
cuenta:=0;
x:=2;
while x<n do
begin
x:=2*x;
cuenta:=cuenta+1;
end;
writeln (cuenta)
end;
Primero analizamos la sentencia WHILE

t=0
x=2
while x<n do
x=2*x
t=t+1

x
2
4
8
16
32

t
0
1
2
3
4

n
31 El tiempo del mientras (while) es:
2t+1 = x de la condicin del while 2t+1 < n
despejando t se tiene
t <log2n 1
para que se de una equivalencia entre ambos trminos
t +a log2n 1 t log2n 1 a +1
se adiciona la ctte 1 debido a la ltima pregunta que se
realiza en la sentencia while

Finalmente:

Tincognita 2 ( n ) = 1 + 1 + (log 2 n 1 a + 1)(1 + 1) = 2 + (log 2 n a )2


Tincognita 2 ( n ) = 2 + 2 log 2 n 2a
Es O(log n) orden logartmico

Ejercicio 6
Se tiene un fragmento de programa sencillo para calcular i3 a continuacin:
Function suma(n:intertger)
var
i,suma_parcial: integer
begin
(1) suma_parcial=0;

Lic. Carmen Mollinedo

21

Algoritmos Avanzados

(2) for i:=1 to n do


(3) suma_parcial:= suma_parcial +i*i*i;
end for
(4) suma:=suma_parcial
end suma
Calcular el tiempo de ejecucin en el peor de los casos
Sol. El tiempo de ejecucin para (1), (3) y (4) es 1, en el caso del for es una sumatoria de la
siguiente forma:
n

Tsuma(n) = 1+ 1 + 1
i=1

Tsuma(n) = 1+ n + 1 = 2+n es O(n) orden lineal


2.9 RESOLUCIN DE ECUACIONES DE RECURRENCIA
Existen tres enfoques distintos para resolver ecuaciones de recurrencia:
1.

Expansin de recurrencias

Utilizar la recurrencia misma para sustituir m<n por cualquier T(m) en la derecha, hasta
que todo, los trminos T(m) par m>1 se hayan reemplazado por formulas que impliquen
solo T(1) como T( 1) siempre es constante, so tiene una formula para T(n) en funcin de n
y de algunas constantes
2.-

Suposicin de una solucin

Suponer una solucin f(n) y usar la recurrencia para mostrar que T(n)<=f(n). Algunas veces
solo se supone la forma f(n) dejando algunos parmetros sin especificar. y deduciendo
valores adecuados para los parmetros al intentar demostrar que T(n)<=f(n) para todo n.

3.-

Solucin general para una clase grande de problemas

Emplear Ia solucin general para ciertas ecuaciones de recurrencias de tipos comunes.


Si T(n) es el tiempo para resolver un problema de tamao n. Se tiene

n= 1

( *)T(n) =
aT(n/b)+d(n) n>=2
Donde

Lic. Carmen Mollinedo

22

Algoritmos Avanzados

a: es el nmero de llamadas recursivas.


h: es el nmero de partes en que se divide la entrada.
d(n): funcin motriz
Para resolver (*) se aplica la tcnica de sustituciones repetidas para T en el lado derecho.

Una vez que se resuelve por expansion de recurrencias, se obtiene los siguientes tres casos:

CASO I
CASO II
CASO Ill:

Si ak >d(b)k => O(ak)


Si ak <d(b)k => O(d(b)k)
Si ak = d(b)k => O(d(b)k k)

En particular cuando se trata de algoritmos correspondientes a la tcnica Divide y


Vencers, se tiene la siguiente forma:

Lic. Carmen Mollinedo

23

Algoritmos Avanzados

2.10 EJERCICIOS RESUELTOS


Ejercicio 1 Sea el siguiente programa recursivo para calcular factoriales, encontrar el
tiempo de ejecucin en el peor de los casos.
int Factorial(int n)
{
if(n<=1) return 1;
else
return Factorial(n-1)*n;
}
So I
Para este ejercicio se tiene la siguiente ecuacin caracterstica que representa el tiempo:
Primera forma

Segunda forma
c

TFactorial (n) =
T ( n-1) + d

n=1

1
TFactorial (n) =
T ( n-1) + 1

n>1

n=1
n>1

Aplicando la tcnica de Expansin de recurrencia:


T(n)=T(n-1) + d = T(n-2) + d + d = T(n-3)+ d + d + d
Generalizando, obtenemos el Patron de Recurrencia:
T(n) = T(n-k) + kd

(*)

Por ltimo, el caso base se presenta cuando el argumento de la funcin T(n) es 1 es decir
para T(1), entonces:
n-k=1 => k=n 1
luego se reemplaza k en (*)
T(n) = T(n (n-1)) + (n-1)*d = T(1) + (n-1)*d
T(n) = c + dn d
que es O(n) orden lineal

Lic. Carmen Mollinedo

24

Algoritmos Avanzados

Ejercicio 2. Obtngase la cota O rnayscula de la siguiente ecuacin:


d

n= 1

T(n)=
2T(n/2)+ cn

n<1

Para aplicar eI mtodo expansin de recurrencia se realizan las siguientes operaciones


auxiliares

n
T(n) = 2T + cn
2
n
n n
T = 2T 2 + c
2
2 2
n
n n
T 2 = 2T 3 + c 2
2
2 2
Realizando repetidos reemplazos en T(n)
n
T(n) = 2T + cn
2
n n
n
n
n
n
n
T(n) = 2 2T 2 + c + cn = 2 2 T 2 + 2c + cn = 2 2 T 2 + 2c + cn = 2 2 T 2 + 2cn
2
2
2
2
2
2 2
n n
T(n) = 2 2 2T 3 + c 2
2 2

n
3 n
2 n
3 n
+ c + cn = 2 T 3 + 2 c 2 + 2cn = 2 T 3 + 3cn
2
2
2
2

El patrn de recurrencia ser:


n
T (n) = 2 k T k + kcn
2
El caso base se da cuando:

n
= 1 n = 2 k k = log n n
k
2
Reemplazando el valor de k en el patron de recurrencia:

T (n) = 2 log 2 n T (1) + cn log 2 n


T (n) = nT (1) + cn log 2 n = nd + cn log 2 n

Lic. Carmen Mollinedo

25

Algoritmos Avanzados

es O(nlogn)orden cuasilineal
Ejercicio 3. Obtngase Ia cota 0 mayscula de la siguiente recurrencia:

T(n)=

2T( n/2 )+2 n> 2


1
n= 2
0
n=I

T ( n )= 2T ( n/2)+2
Para n/2

T( n/2 )=2T( n/4 )+2

T(n) = 2[2T(n/4)+2]+2
para n/4

T(n/4) = 2T(n/8)+2

T(n)=2*2T(n/8)+8+4+2
El patron de recurrencia ser
T (n ) = 2 k T ( n

) + 2 i 2
i =1

Si n=2t

T (n) = 2 k T (2

i
k ) + 2
i =1

Por ltirno cuando k=t-1, se obtiene

T (n) = 2 t 1 T (2

t 1

i
t 1 ) + 2 =
i =1

t 1
2t
T ( 2) + 2 i
2
i =1

Debemos resolver la siguiente sumatoria, por induccin:


t 1

S = 2i = 2t 2
i =1

luego reeemplazando S en el Patron de recurrencia y con n=2t


T(n)=n/2 + 2t-2 0 n/2 +n-2=3/2n-2 es O(n)

Lic. Carmen Mollinedo

26

Algoritmos Avanzados

Ejercicio 4
C

n=1

2T(n/2) +

n3 e.o.c.

T(n) =

Respuesta:
Mediante la tcnica de "anlisis de expansin" o Expansin de Recurrencias,
reemplazamos sobre T(n) de la siguiente forma:
n
T ( n ) = 2T ( ) + n 3
2
3
n n 3
n
3
2 n

T ( n ) = 2 2T 2 + + n = 2 T 2 + 2 + n 3
2 2
2 2

3
3
3
n n 3
n
n
n
n
T ( n ) = 2 2 2T 3 + 2 + 2 + n 3 = 2 3 T 3 + 2 2 2 + 2 + n 3
2 2
2
2
2
2

Generalizando llegamos al Patrn de Recurrencia


3

3
k 1
k 1
2i
n k 1 i n
k n
i n
k n
3
T (n) = 2 T k + 2 i = 2 T k + 2 i 3 = 2 T k + n i 3
2 i =0 2
2 i =0 2
2
i =0 2
k

Primero resolveremos la siguiente sumatoria:


k 1

2 k 1 1
3 = 2 =S

i =0 2
i =0 2
1 1
1
1
S = 1 + + 2 + ......... + k 2 + k 1
4 4
4
4
1
1 1
1
1
S = + 2 + ......... + k 1 + k
4
4 4
4
4
1
1
S (1 ) = 1 k
4
4
4
1
S=
3 3.4 K 1

Lic. Carmen Mollinedo

27

Algoritmos Avanzados

La determinacin de O se deja como ejercicio


Ejercicio 5 Resuelva la siguiente recurrencia por el mtodo Solucin General para una
clase grande de recurrencias
1
n= 2
T(n)=
4T( n/2 )+n3 n> 1

Sc tiene a=4 v b=2


d(n)=n funcin Motriz. d(2)=8
Abora Comparemos con los tres casos se tiene que
a>d( 2) => 4<8

(Caso II)

=> T(n)= O(8logn)


Por propiedades de log se tiene O(n3)

Lic. Carmen Mollinedo

28

Algoritmos Avanzados

Tema 3

Para procesar informacin en un computador es necesario hacer una abstraccin de los


datos que tomamos del mundo real. Se hace una seleccin de los datos ms representativos
de la realidad a partir de los cuales pueda trabajar el computador para obtener unos
resultados.

RECUERDE abstraccin en el sentido de que se ignoran algunas


propiedades de los objetos reales, es decir, se simplifican

El objetivo de las Estructuras de Datos, es el estudio de la representacin de la informacin


(datos) que permitan obtener un algoritmo lo ms sencillo posible.
Identificar y desarrollar de modo formal las entidades y las operaciones que definen la
informacin que se trata, as como determinar qu tipos de problemas pueden resolverse
utilizando estas operaciones y entidades.
Determinar la representacin ms idnea de estas estructuras abstractas e implementarlas.

3.1 CONCEPTOS FUNDAMENTALES


3.1.1 TIPOS DE DATOS
Cualquier lenguaje suministra una serie de tipos de datos simples, como son los
nmeros enteros, caracteres, nmeros reales. En realidad suministra un subconjunto
de stos, pues la memoria del ordenador es finita. Los punteros (si los tiene) son
Lic. Carmen Mollinedo

23

Algoritmos Avanzados
tambin un tipo de datos. El tamao de todos los tipos de datos depende de la
mquina y del compilador sobre los que se trabaja.
En principio, conocer la representacin interna de estos tipos de datos no es necesaria
para realizar un programa, pero s puede afectar en algunos casos al rendimiento.
Por otra parte es posible definir otros tipos de estructuras de datos compuestos, entre
las cuales se encuentran los arreglos, registros y otros.

Los lenguajes de programacin (LP) proporcionan herramientas para manejar distintos


tipos de datos.

Tipos predefinidos
o
proporcionados por el LP
o
slo nos preocupamos de su uso

Tipos definidos por el usuario


o
S puede elegir y definir una estructura de datos de las
proporcionadas por el LP para su representacin
o
Se debe elegir y definir operaciones de manipulacin
o
Se debe garantizar el correcto comportamiento del tipo

3.1.2 ESTRUCTURA DE DATOS


Se trata de un conjunto de variables de un determinado tipo agrupadas y organizadas
de alguna manera para representar un comportamiento. Lo que se pretende con las
estructuras de datos es facilitar un esquema lgico para manipular los datos en
funcin del problema que haya que tratar y el algoritmo para resolverlo. En algunos
casos la dificultad para resolver un problema radica en escoger la estructura de datos
adecuada. Y, en general, la eleccin del algoritmo y de las estructuras de datos que
manipular estarn muy relacionadas.
Segn su comportamiento durante la ejecucin del programa distinguimos estructuras
de datos:
o
o

Estticas: su tamao en memoria es fijo. Ejemplo: arrays.


Dinmicas: su tamao en memoria es variable. Ejemplo: listas enlazadas con
punteros, ficheros, etc.

Las estructuras de datos que trataremos aqu son los arrays, las pilas y las colas, los
rboles, y algunas variantes de estas estructuras.

3.1.3 TIPOS ABSTRACTOS DE DATOS

Lic. Carmen Mollinedo

24

Algoritmos Avanzados

Los tipos abstractos de datos (TAD) permiten describir una estructura de datos en
funcin de las operaciones que pueden efectuar, dejando a un lado su implementacin.
Los TAD mezclan estructuras de datos junto a una serie de operaciones de
manipulacin. Incluyen una especificacin, que es lo que ver el usuario, y una
implementacin (algoritmos de operaciones sobre las estructuras de datos y su
representacin en un lenguaje de programacin), que el usuario no tiene necesariamente
que conocer para manipular correctamente los tipos abstractos de datos.
Se caracterizan por el encapsulamiento. Es como una caja negra que funciona
simplemente conectndole unos cables. Esto permite aumentar la complejidad de los
programas pero manteniendo una claridad suficiente que no desborde a los
desarrolladores. Adems, en caso de que algo falle ser ms fcil determinar si lo que
falla es la caja negra o son los cables.
Por ltimo, indicar que un TAD puede definir a otro TAD. Por ejemplo, en prximos
apartados se indicar como construir pilas, colas y rboles a partir de arrays y listas
enlazadas. De hecho, las listas enlazadas tambin pueden construirse a partir de arrays y
viceversa.
3.2 RECURSIVIDAD
La recursin es una tcnica para resolver problemas. Muchas veces resulta ms fcil
desarrollar un algoritmo recursivo que uno iterativo.
Definicin: Una funcin f es recursiva si en su cuerpo contiene
una aplicacin de f, es decir, si se puede activarse a si misma.

Si la llamada sucede dentro de la propia funcin se dice que es directamente recursiva. En


cambio si la funcin llama a otra y esta a su vez llama a la primera se dice que es recursin
indirecta.
El objetivo del programa recursivo, es realizar una serie de llamadas hasta que la secuencia
se define en un punto.
Las directrices para una funcin recursiva son:
Cada vez que se hace una llamada recursiva en una funcin, el programa deber comprobar
que se satisface una condicin bsica con un determinado parmetro puesto al valor
mnimo.
Cada vez que se hace la llamada a la funcin, los parmetros enviados a la misma, debern
ser de algn modo ms simple, es decir, su valor debe tender a la condicin bsica.
Adems por lo general en las funciones recursivas se suelen identificar dos casos:
Caso base, que implica el caso de parada de la recursin
Caso base, que implica realizar las llamadas recursivas

Lic. Carmen Mollinedo

25

Algoritmos Avanzados

Ejemplo
La funcin Factorial puede ser desarrollada iterativamente o recursivamente1.

Matemticamente de define como:


1
n!=
n(n 1)

si n = 0 1
si n > 1

Anlogamente su expresin funcional ser la siguiente:


si n = 0 1
1
fac(n) =
n * fac (n 1) si n > 1
Codificacin
Como funcin la codificacin es la siguiente:
Private Function factorial(ByVal n As Integer)
As Integer
If n = 1 Then
factorial = 1
Else
factorial = n * factorial(n - 1)
End If
End Function

Prueba
Para N=5
Llamadas recursiva
Factorial(5)=factorial(4)*5
Factorial(4)=factorial(3)*4
Factorial(3)=factorial(2)*3
Factorial(2)=factorial(1)*2
Factorial(1)=1

Lic. Carmen Mollinedo

Evaluacin de resultados
Factorial(1)=1
Factorial(2)=factorial(1)*2 =
Factorial(3)=factorial(2)*3 =
Factorial(4)=factorial(3)*4 =
Factorial(5)=factorial(4)*5 =

1*2 =2
2*3 =6
6*4 =24
24*5 =120

26

Algoritmos Avanzados

Como procedimiento se tiene la siguiente codificacin:

Private Sub fac(ByVal n As Integer, ByRef resul As


Integer)
Dim resp_aux As Integer
If n = 1 OR n = 0 Then
resul = 1
Else
fac n - 1, resp_aux
resul = resp_aux * n
End If

Ejemplo: Otro ejemplo clsico es la secuencia de fibonacci cuyos trminos son 1, 1, 2, 3,


5, 8, ... los cuales se determinan por la funcin:

Expresin funcional
si n = 1 2
1
fib(n) =
fib(n 1) + fib(n 2) si n > 2

Codificacin
Private
Integer

Function

fibonacci(ByVal

As

Integer)

As

If n = 0 Or n = 1 Then
fibonacci = 1
Else
fibonacci = fibonacci(n - 1) + fibonacci(n 2)
End If
End Function

Lic. Carmen Mollinedo

27

Algoritmos Avanzados

Lic. Carmen Mollinedo

28

Algoritmos Avanzados

Prueba
Para fib(5) se tienen las siguientes entradas y salidas.

Llamadas recursiva
Fibonacci(5)=fibonacci(4)+ fibonacci(3)
Fibonacci(4)=fibonacci(3)+ fibonacci(2)
Fibonacci(3)=fibonacci(2)+ fibonacci(1)
Fibonacci(2)=1
Fibonacci(1)=1

Evaluacin de resultados
Fibonacci(1)=1
Fibonacci(2)=1
Fibonacci(3)=fibonacci(2)+ fibonacci(1)=1+1=2
Fibonacci(4)=fibonacci(3)+ fibonacci(2)=2+1=3
Fibonacci(5)=fibonacci(4)+ fibonacci(3)=3+2=5

En este caso se puede observar que la solucin planteada de fibonacci es impracticable para
valores de n grandes. Cada fibonacci() realiza dos llamadas, por lo que el nmero de
llamadas aumenta en proporcin geomtrica.

Conviene usar recursin siempre? Qu pasa con la memoria?


Veamos el caso de implementar la misma secuencia de fibonacci iterativamente:
Private Function fiboRec(ByVal n As Integer) As
Integer
Dim a As Integer, b As Integer, c As Integer, i As
Integer
a = 0
b = 1
c = 1
Print c
For i = 2 To n
c = a + b

Print c
a = b
b = c
Next i
fiboRec = c
EL lector podr verificar la eficiencia de la versin recursiva con respecto de la iterativa

Lic. Carmen Mollinedo

29

Algoritmos Avanzados

3.2.1 EJERCICIOS RESUELTOS


Ejercicio 1 Multiplicar dos nmeros por sumas sucesivas
Solucin
Como es sabido, la multiplicacin es una suma abreviada, en tal sentido se puede
realizar la operacin de la siguiente forma:
A*B = A+A+A+ . . . . . . . . . +A , Es decir sumar A, B veces
Entonces para el caso general:
B 1

A * B = Multi( A, B) = i =1 A = i =1 A + A
B

Es decir A*B se puede expresar como la sumatoria desde 1 hasta B de A, lo cual si se saca
de la expresin al ltimo termino, el resto continua siendo sumatoria.
El caso base es mucho ms simple, nos preguntamos cul es el valor ms qequeo que
puede toma B, para que el resultado sea trivial, es posible elegir entre las siguientes
alternativas

A*B=A
cuando B=1
A*B=0 cuando B=0

Cualquiera de estas expresiones puede representar al caso base.

Expresin funcional
si B = 1
A
Multi( A, B) =
Multi( A, B 1) + A

si B > 1

Algoritmo
Private Function multiplica(ByVal A As Integer, ByVal
B As Integer) As Integer
If B = 1 Then
multiplica = A
Else
multiplica = multiplica(A, B - 1) + A
End If
End Function

Lic. Carmen Mollinedo

30

Algoritmos Avanzados

Codificacin completa

Option Explicit
Dim num As Integer
Dim num2 As Integer
Private Function multiplica(ByVal A As Integer, ByVal B As Integer)
As Integer
If B = 1 Then
multiplica = A
Else
multiplica = multiplica(A, B - 1) + A
End If
End Function
Private Sub Command1_Click()
num = Val(Text1.Text)
num2 = Val(Text2.Text)
MsgBox "El resulatdo es " & multiplica(num, num2), vbCritical,
"RESULTADO"
End Sub
Private Sub Command2_Click()
End
End Sub
Private Sub Text1_KeyPress(KeyAscii As Integer)
Select Case KeyAscii
Case 13
Text2.SetFocus
Case Asc(0) To Asc(9)
Case Else
KeyAscii = 0
End Select
End Sub

Lic. Carmen Mollinedo

31

Algoritmos Avanzados

Private Sub Text2_KeyPress(KeyAscii As Integer)


Select Case KeyAscii
Case 13
Command1.SetFocus
Case Asc(0) To Asc(9)
Case Else
KeyAscii = 0
End Select

End Sub

Ejercicio 2 intercalar los dgitos de dos nmeros, los nmeros tiene la misma longitud.
Solucin
La funcin modulo nos permite sacar el ltimo digito de cada nmero y componer un
nuevo numero, cuando numA y numB sean de un solo dgito, es decir menores a 10 se
habr llegado al caso base.
Expresin funcional
si A < 10 B < 10
A *10 + B
Intercala( A, B) =
Intercala( Adiv10, Bdiv10) * 100 + ( A mod 10) * 10 + ( B mod 10) eoc
Algoritmo
Private Function intercala(ByVal numA As Integer, ByVal
numB As Integer) As Double
Dim ma As Integer, mb As Integer, nuevoNum As Integer
If numA < 10 Then
intercala = numA * 10 + numB
Else
ma = numA Mod 10
mb = numB Mod 10
nuevoNum = ma * 10 + mb
intercala = intercala(numA \ 10, numB \ 10) * 100 +
nuevoNum
End If

Lic. Carmen Mollinedo

32

Algoritmos Avanzados

Prueba
Intercala(345,796) = Intercala(34,79)*100 + 56 =3749*100 + 56 = 374956
Intercala(34,79)
Intercala(3,7)

= Intercala(3,7)*100 + 49 = 37*100 +49 = 3749


= 37

Ejercicio 3 Hallar la sumatoria de los N primero nmeros pares


Solucin
La sumatoria de los n primero nmeros pares est dada por:
SumaPares(n) = 2 + 4 + 6 + . . . . . .+ 2*(n-1) + 2*n
Sacando el ultimo elemento de la sumatoria, logramos identificar el caso general:
SumaPares(n) = SumaPares(n-1)+ 2*n
Para el caso general, se considera que valor debe tomar n para generar el primer numero
par.

Algoritmo
Private Function sumaPares(n As Integer)
If n = 1 Then
sumaPares = 2
Else
sumaPares = sumaPares(n - 1) + 2 * n
End If
End Function

Codificacin completa

Lic. Carmen Mollinedo

33

Algoritmos Avanzados

Option Explicit
Dim num As Integer
Private Function sumaPares(ByVal n As Integer) As Integer
If n = 1 Then
sumaPares = 2
List1.AddItem 2
Else
sumaPares = sumaPares(n - 1) + 2 * n
List1.AddItem (2 * n)
End If
End Function

Private Sub Form_Load()


Option1.Value = False
Option2.Value = True
End Sub
Private Sub Option1_Click()
num = Val(Text1.Text)
MsgBox sumaPares(num), vbExclamation
End Sub
Private Sub Option2_Click()
Text1 = ""
List1.Clear
End Sub
Private Sub Option3_Click()
End
End Sub

Lic. Carmen Mollinedo

34

Algoritmos Avanzados

Ejercicio 4 Dado un nmero entero generar otro nmero solo compuesto por los nmeros
naturales.
Ejemplo:
N=1
genera 1
N=2
genera 12
N=3
genera 123
Expresin funcional
si n = 1
1
Genera(n) =
Genera(n 1) *10 + n si n > 1

Algoritmo

Prueba

Private Function genera(ByVal n As


Integer) As Double
If n = 1 Then
genera = 1
Else
genera = genera(n - 1) * 10 + n
End If
End Function

Para n=5
Llamadas recursiva
genera(5) = genera(4) * 10 + 5
genera(4) = genera(3) * 10 + 4
genera(3) = genera(2) * 10 + 3
genera(2) = genera(1) * 10 + 2
genera(1) = 1

Evaluacin de resultados
genera(1) = 1
genera(2) = genera(1) * 10 + 2 = 1*10+2 = 12
genera(3) = genera(2) * 10 + 3 = 12*10+3=123
genera(4) = genera(3) * 10 + 4 = 123*10+4=1234
genera(5) = genera(4) * 10 + 5 = 1234*10+5=
.....................12345

Ejercicio 5 Invertir un vector


Solucin
in

fi
1 2 3 4 5 6 7

Lic. Carmen Mollinedo

35

Algoritmos Avanzados

La solucin consiste en cambiar el primer V(ini) y ltimo V(fin) elementos usando un


auxiliar:
aux = v(ini)
v(ini) = v(fin)
v(fin) = aux
luego realizar la llamada recursiva de manera de cambiar el segundo V(ini+1) con el
penltimo V(fin-1) elemento:
Invierte ini + 1, fin - 1
el proceso se repite mientras ini sea menor o igual que fin.
Algoritmo
Private Sub Invierte(ByVal ini As
Integer, ByVal fin As Integer)
Dim aux As Integer
If ini < fin Then
aux = v(ini)
v(ini) = v(fin)
v(fin) = aux
Invierte ini + 1, fin - 1
End If
End Sub
Codificacin completa

Dim tam As Integer


Dim v(1 To 10) As String
Private Sub LlenaVector(ByVal n As Integer)
Dim i As Integer
List1.Clear
For i = 1 To n
v(i) = InputBox("Ingrese el elemento V[" & i & "] =>", "Ingreso de
datos al Vector", 0)
List1.AddItem v(i)
Next
End Sub
Private
MostrarLista2(ByVal n As Integer)
Lic.
CarmenSub
Mollinedo
36
Dim i As Integer
List2.Clear
For i = 1 To n
List2.AddItem v(i)

Algoritmos Avanzados

Private Sub Command2_Click()


Invierte 1, tam
MostrarLista2 tam
End Sub
Private Sub Command3_Click()
End
End Sub

3.3 ARREGLOS
Supongamos que nos enfrentamos a un problema como este: Una empresa que cuenta con
150 empleados, desea establecer una estadstica sobre los salarios de sus empleados, y
quiere saber cual es el salario promedio, y tambin cuantos de sus empleados gana entre
$1250.00 y $2500.00.
Si tomamos la decisin de tratar este tipo de problemas con datos simples, pronto nos
percataramos del enorme desperdicio de tiempo, almacenamiento y velocidad. Es por eso
que para situaciones de este tipo la mejor solucin son los datos estructurados.
Lic. Carmen Mollinedo

37

Algoritmos Avanzados

Un arreglo puede definirse como un grupo o una coleccin finita, homognea y ordenada
de elementos. Los arreglos pueden ser de los siguientes tipos:
o De una dimensin.
o De dos dimensiones.
o De tres o ms dimensiones

3.4 PILAS
Una pila (stack) es una coleccin ordenada de elementos en la cual se
pueden insertar nuevos elementos por un extremo y se pueden retirar otros
por el mismo extremo; ese estremos se llama ``la parte superior'' de la
pila.
Si tenemos un par de elementos en la pila, uno de ellos debe estar en la parte superior de la
pila, que se considera ``el ms alto'' en la pila que el otro. En la figura 3.1 el elemento F es
el ms alto de todos los elementos que estn en la pila. El elemento D es el ms alto de los
elementos A,B,C, pero es menor que los elementos E y F.

Figura 3.1: Pila con 6 elementos

Lic. Carmen Mollinedo

38

Algoritmos Avanzados

Para describir cmo funciona esta estructura, debemos agregar un nuevo elemento, el
elemento G. Despus de haber agregado el elemento G a la pila, la nueva configuracin es
la que se muestra en la figura 3.2

Figura 3.2: Operacin de insertar el elemento G en la pila P


De acuerdo con la definicin, existe solamente un lugar en donde cualquier elemento puede
ser agregado a la pila. Despus de haber insertado el nuevo elemento, G ahora es el
elemento en la cima. Debemos aclarar en qu pila deseamos insertar elementos, puesto que
es posible tener ms de una pila al mismo tiempo.
Cuando se desea retirar un elemento de la pila, solo basta ordenar que sea retirado un
elemento; no podemos decir ``retira C de la pila'', porque C no est en la cima de la pila y
solamente podemos retirar el elemento que est en la cima. Para que la sentencia ``retira C
de la pila'' tenga sentido, debemos replantear las rdenes a algo como:
Retira de la pila hasta que el elemento retirado sea C.
Y solamente se puede sacar un elemento a la vez.
Siguiendo nuestro ejemplo, ahora deseamos retirar de la pila P. La configuracin global de
la pila es como se muestra en la figura 3.3

Figura 3.3: Operacin de retirar de la pila P

Lic. Carmen Mollinedo

39

Algoritmos Avanzados

El concepto de pila es muy importante en computacin y en especial en teora de lenguajes


de programacin. En lenguajes procedurales como Pascal o C, la pila es una estructura
indispensable, debido a las llamadas a funcin.
Resulta que el flujo de instrucciones va de arriba hacia abajo, y cuando ocurre una llamada
a alguna funcin, el estado global del sistema se almacena en un registro y ste en una pila.
As que la pila va a contener todas las llamadas a procedimientos que se hagan.
Cuando se termina de ejecutar algn procedimiento, se recupera el registro que est en la
cima de la pila. En ese registro estn los valores de las variables como estaban antes de la
llamada a la funcin, o algunas pueden haber cambiado si valor, dependiendo del mbito de
las variables.
Cada elemento en la pila que es retirado, significa que se ha terminado de ejecutar alguna
funcin. Cuando se termina de ejecutar el programa, la pila de llamadas a subprogramas
debe haber quedado en 0 tambin, de otro modo podra causar algun tipo de error.
La manera en cmo entran los datos a la estructura de datos y cmo salen, se denomina
fifo, que viene del ings first in first out (primero en entrar, primero en salir).
3.5 COLAS
Las colas son una estructura de datos similar a las pilas. Recordemos que las pilas
funcionan en un depsito en donde se insertan y se retiran elementos por el mismo
extremo. En las colas sucede algo diferente, se insertan elementos por un extremo y
se retiran elementos por el otro extremo. De hecho a este tipo de dispositivos se les
conoce como dispositivos ``fifo'' (first in, first out) porque funcionan como una
tubera, lo que entra primero por un extremo, sale primero por el otro extremo.
En una cola hay dos extremos, uno es llamado la parte delantera y el otro extremo se
llama la parte trasera de la cola. En una cola, los elementos se retiran por la parte
delantera y se agregan por la parte trasera.

Figura 3.4: Dinmica de una cola.


a) estado actual con una cola con tres
elementos a,b,c;
b) estado de la cola cuando se agrega el
elemento d;
c) estado de la cola cuando se elimina el
elemento a del frente de la cola

Lic. Carmen Mollinedo

40

Algoritmos Avanzados

En la figura 3.4 se muestra una actividad tpica de la cola, en donde se muestra que se
agregan datos por la parte trasera de la cola y se eliminana datos por el frente de la cola.
Si Q es una cola y x es un elemento, se pueden hacer tres operaciones bsicas con las colas:
o insert(Q,x), que inserta el elemento x en la parte trasera de la cola Q.
o x=remove(Q), que almacena en x el valor del elemento retirado de la parte
frontal de la cola Q.
o empty(Q), que es un predicado de valor booleano, y es true cuando la cola Q
tiene 0 elementos, y es false cuando la cola Q tiene al menos un elemento, en
cuyo caso, ese nico elemento es la parte frontal y la parte trasera de la cola
al mismo tiempo.
Tericamente no hay lmite para el tamao de la cola, asi que siempre se debera poder
insertar elementos a una cola, sin embargo, al igual que las pilas, normalmente se deja un
espacio de memoria para trabajar con esta estructura. Por el contrario, la operacin remove
solamente se puede hacer si la cola no est vaca.
3.6 LISTAS
Una lista es una estructura de datos secuencial.

Una manera de clasificarlas es por la forma de acceder al siguiente elemento:


o lista densa: la propia estructura determina cul es el siguiente elemento de la lista.
Ejemplo: un array.
o lista enlazada: la posicin del siguiente elemento de la estructura la determina el
elemento actual. Es necesario almacenar al menos la posicin de memoria del
primer elemento. Adems es dinmica, es decir, su tamao cambia durante la
ejecucin del programa.
Una lista enlazada o encadenada es una coleccin de elementos
nodos, en donde cada uno contiene datos y un enlace o liga.

Lic. Carmen Mollinedo

41

Algoritmos Avanzados

Un nodo es una secuencia de caracteres en memoria dividida en campos (de cualquier


tipo). Un nodo siempre contiene la direccin de memoria del siguiente nodo de
informacin si este existe.
Un apuntador es la direccin de memoria de un nodo
La figura siguiente muestra la estructura de un nodo:

El campo liga, que es de tipo puntero, es el que se usa para establecer la liga con el
siguiente nodo de la lista. Si el nodo fuera el ltimo, este campo recibe como valor
NIL (vaco).
A continuacin se muestra el esquema de una lista :

3.7 RBOLES
3.7.1 RBOLES BINARIOS
A los rboles ordenados de grado dos se les conoce como rboles binarios ya que cada
nodo del rbol no tendr ms de dos descendientes directos. Las aplicaciones de los
rboles binarios son muy variadas ya que se les puede utilizar para representar una
estructura en la cual es posible tomar decisiones con dos opciones en distintos puntos.
3.7.1.1 Representacin

La representacin grfica de un rbol binario es la siguiente:

Hay dos formas tradicionales de representar un rbol binario en memoria:

o Por medio de datos tipo punteros tambin conocidos como variables


dinmicas o listas.

Lic. Carmen Mollinedo

42

Algoritmos Avanzados

o Por medio de arreglos.


Sin embargo la ms utilizada es la primera, puesto que es la ms natural para tratar
este tipo de estructuras. Los nodos del rbol binario sern representados como
registros que contendrn como mnimo tres campos. En un campo se almacenar la
informacin del nodo. Los dos restantes se utilizarn para apuntar al subarbol
izquierdo y derecho del subarbol en cuestin.
Cada nodo se representa grficamente de la siguiente manera:

3.7.1.2 Clasificacin de rboles Binarios

Existen cuatro tipos de rbol binario:.


a.
b.
c.
d.

B. Distinto.
B. Similares.
B. Equivalentes.
B. Completos.

A continuacin se har una breve descripcin de los diferentes tipos de rbol binario
as como un ejemplo de cada uno de ellos.
a. A. B. DISTINTO
Se dice que dos rboles binarios son distintos cuando sus estructuras son
diferentes. Ejemplo:

b. A. B. SIMILARES
Dos rboles binarios son similares cuando sus estructuras son idnticas, pero la
informacin que contienen sus nodos es diferente. Ejemplo:

Lic. Carmen Mollinedo

43

Algoritmos Avanzados

c. A. B. EQUIVALENTES
Son aquellos rboles que son similares y que adems los nodos contienen la
misma informacin. Ejemplo:

d. A. B. COMPLETOS
Son aquellos rboles en los que todos sus nodos excepto los del ultimo nivel, tiene dos
hijos; el subrbol izquierdo y el subrbol derecho.
3.7.1.3 Recorrido de un Arbol Binario
Hay tres manera de recorrer un rbol : en inorden, preorden y postorden. Cada una
de ellas tiene una secuencia distinta para analizar el rbol como se puede ver a
continuacin:
INORDEN
Recorrer el subarbol izquierdo en inorden.
Examinar la raz.
Recorrer el subarbol derecho en inorden.
PREORDEN
Examinar la raz.
Recorrer el subarbol izquierdo en preorden.
recorrer el subarbol derecho en preorden.
POSTORDEN
Recorrer el subarbol izquierdo en postorden.
Recorrer el subarbol derecho en postorden.
Examinar la raz.
A continuacin se muestra un ejemplo de los diferentes recorridos en un rbol
binario.
Inorden: GDBHEIACJKF
Preorden: ABDGEHICFJK
Postorden: GDHIEBKJFCA

Lic. Carmen Mollinedo

44

Algoritmos Avanzados

3.7.1.4 rboles Enhebrados


Existe un tipo especial de rbol binario llamado enhebrado, el cual contiene hebras
que pueden estar a la derecha o a la izquierda. El siguiente ejemplo es un rbol
binario enhebrado a la derecha.

ARBOL ENHEBRADO A LA DERECHA. Este tipo de rbol tiene un apuntador


a la derecha que apunta a un nodo antecesor.
ARBOL ENHEBRADO A LA IZQUIERDA. Estos rboles tienen un apuntador a
la izquierda que apunta al nodo antecesor en orden.
3 .7.1.5 rboles binarios de bsqueda
Un rbol de bsqueda binaria es una estructura apropiada para muchas de las
aplicaciones que se han discutido anteriormente con listas. La ventaja especial de
utilizar un rbol es que se facilita la bsqueda.
Un rbol binario de bsqueda es aquel en el que el hijo de la izquierda (si existe) de
cualquier nodo contiene un valor ms pequeo que el nodo padre, y el hijo de la
derecha (si existe) contiene un valor ms grande que el nodo padre.
Un ejemplo de rbol binario de bsqueda es el siguiente:

Lic. Carmen Mollinedo

45

Algoritmos Avanzados

3.7.2 RBOLES GENERALES


Los rboles representan las estructuras no lineales y dinmicas de datos ms
importantes en computacin . Dinmicas porque las estructuras de rbol pueden
cambiar durante la ejecucin de un programa. No lineales, puesto que a cada
elemento del rbol pueden seguirle varios elementos.
Los rboles pueden ser construidos con estructuras estticas y dinmicas. Las
estticas son arreglos, registros y conjuntos, mientras que las dinmicas estn
representadas por listas.
La definicin de rbol es la siguiente:
es una estructura jerrquica aplicada sobre una coleccin de elementos u
objetos llamados nodos; uno de los cuales es conocido como raz. adems
se crea una relacin o parentesco entre los nodos dando lugar a trminos
como padre, hijo, hermano, antecesor, sucesor, ansestro, etc..
Formalmente se define un rbol de tipo T como una estructura
homognea que es la concatenacin de un elemento de tipo T junto con
un nmero finito de arboles disjuntos, llamados subarboles. Una forma
particular de rbol puede ser la estructura vaca.

La figura siguiente representa a un rbol general.

Se utiliza la recursin para definir un rbol porque representa la forma ms apropiada y


porque adems es una caracterstica inherente de los mismos.
Los rboles tienen una gran variedad de aplicaciones. Por ejemplo, se pueden utilizar
para representar frmulas matemticas, para organizar adecuadamente la informacin,
para construir un rbol genealgico, para el anlisis de circuitos elctricos y para
numerar los captulos y secciones de un libro.
3.7.2.1 Terminologa
La terminologa que por lo regular se utiliza para el manejo de arboles es la siguiente:

Lic. Carmen Mollinedo

46

Algoritmos Avanzados

o HIJO. X es hijo de Y, s y solo s el nodo X es apuntado por Y. Tambin se dice


que X es descendiente directo de Y.
o PADRE. X es padre de Y s y solo s el nodo X apunta a Y. Tambin se dice
que X es antecesor de Y.
o HERMANO. Dos nodos sern hermanos si son descendientes directos de un
mismo nodo.
o HOJA. Se le llama hoja o terminal a aquellos nodos que no tienen
ramificaciones (hijos).
o NODO INTERIOR. Es un nodo que no es raz ni terminal.
o GRADO. Es el nmero de descendientes directos de un determinado nodo.
o GRADO DEL ARBOL Es el mximo grado de todos los nodos del rbol.
o NIVEL. Es el nmero de arcos que deben ser recorridos para llegar a un
determinado nodo. Por definicin la raz tiene nivel 1.
o ALTURA. Es el mximo nmero de niveles de todos los nodos del rbol.
o PESO. Es el nmero de nodos del rbol sin contar la raz.
o LONGITUD DE CAMINO. Es el nmero de arcos que deben ser recorridos
para llegar desde la raz al nodo X. Por definicin la raz tiene longitud de
camino 1, y sus descendientes directos longitud de camino 2 y as
sucesivamente.
3.7.2.2 Transformacin de un rbol Gral. en un rbol Binario.
En esta seccin estableceremos los mecanismos necesarios para convertir un rbol
general en un rbol binario. Para esto, debemos seguir los pasos que se describen a
continuacin:
o Enlazar los hijos de cada nodo en forma horizontal (los hermanos).
o Enlazar en forma vertical el nodo padre con el nodo hijo que se encuentra ms a
la izquierda. Adems, debe eliminarse el vnculo de ese padre con el resto de sus
hijos.
o Rotar el diagrama resultante aproximadamente 45 grados hacia la izquierda, y
as se obtendr el rbol binario correspondiente
3.8 GRAFOS
Un grafo dirigido G consiste en un conjunto de vrtices V y un conjunto de arcos o aristas
A. Los vertice se denominan tambin nodos o puntos.
Un arco, es un par ordenado de vrtices(V,W) donde V es el vrtice inicial y W es el vrtice
terminal del arco. Un arco se expresa como: V-->W y se representa de la siguiente manera:

Los vrtice de un grafo pueden usarse para representar objetos. Los arcos se utilizan para
representar relaciones entre estos objetos.
Las aplicaciones ms importantes de los grafos son las siguientes:

Lic. Carmen Mollinedo

47

Algoritmos Avanzados

o Rutas entre ciudades.


o Determinar tiempos mximos y mnimos en un proceso.
o Flujo y control en un programa.
3.8.1 TERMINOLOGIA

o La terminologa que manejaremos regularmente para el uso de grafos es la


siguiente:
o
o
o
o
o
o
o
o
o

o
o

o
o
o
o
o

CAMINO.Es una secuencia de vrtices V1, V2, V3, ... , Vn, tal que cada uno de estos V1-&gtV2,
V2-&gtV3, V1-&gtV3.
LONGITUD DE CAMINO. Es el nmero de arcos en ese camino.
CAMINO SIMPLE. Es cuando todos sus vrtices, excepto tal vez el primero y el ltimo son
distintos.
CICLO SIMPLE. Es un camino simple de longitud por lo menos de uno que empieza y termina en
el mismo vrtice.
ARISTAS PARALELAS. Es cuando hay ms de una arista con un vrtice inicial y uno terminal
dados.
GRAFO CICLICO. Se dice que un grafo es cclico cuando contiene por lo menos un ciclo.
GRAFO ACICLICO. Se dice que un grafo es aciclco cuando no contiene ciclos.
GRAFO CONEXO. Un grafo G es conexo, si y solo si existe un camino simple en cualesquiera dos
nodos de G.
GRAFO COMPLETO FUERTEMENTE CONEXO.Un grafo dirigido G es completo si para
cada par de nodos (V,W) existe un camino de V a W y de W a V (forzosamente tendrn que
cumplirse ambas condiciones), es decir que cada nodo G es adyacente a todos los dems nodos de G.
GRAFO UNILATERALMENTE CONEXO.Un grafo G es unilateralmente conexo si para cada
par de nodos (V,W) de G hay un camino de V a W o un camino de W a V.
GRAFO PESADO ETIQUETADO. Un grafo es pesado cuando sus aristas contienen datos
(etiquetas). Una etiqueta puede ser un nombre, costo un valor de cualquier tipo de dato. Tambin a
este grafo se le denomina red de actividades, y el nmero asociado al arco se le denomina factor de
peso.
VERTICE ADYACENTE. Un nodo o vrtice V es adyacente al nodo W si existe un arco de m a n.
GRADO DE SALIDA.El grado de salida de un nodo V de un grafo G, es el nmero de arcos o
aristas que empiezan en V.
GRADO DE ENTRADA.El grado de entrada de un nodo V de un grafo G, es el nmero de aristas
que terminan en V.
NODO FUENTE.Se le llama as a los nodos que tienen grado de salida positivo y un grado de
entrada nulo.
NODO SUMIDERO.Se le llama sumidero al nodo que tiene grado de salida nulo y un grado de
entrada positivo.

3.8.2

EJEMPLOS DE GRAFOS

081.- Grafo regular: Aquel con el mismo grado en todos los vrtices. Si ese grado es k lo
llamaremos k-regular.
Por ejemplo, el primero de los siguientes grafos es 3-regular, el segundo es 2regular y el tercero no es regular

Lic. Carmen Mollinedo

48

Algoritmos Avanzados

2.- Grafo bipartito: Es aquel con cuyos vrtices pueden formarse dos conjuntos
disjuntos de modo que no haya adyacencias entre vrtices pertenecientes al mismo conjunto
Ejemplo.- de los dos grafos siguientes el primero es bipartito y el segundo no lo es

3.- Grafo completo: Aquel con una arista entre cada par de vrtices. Un grafo completo con
n vrtices se denota Kn.
A continuacin pueden verse los dibujos de K3, K4, K5 y K6

Todo grafo completo es regular porque cada vrtice tiene grado |V|-1 al estar conectado con
todos los otros vrtices.
Un grafo regular no tiene por qu ser completo.

Lic. Carmen Mollinedo

49

Algoritmos Avanzados

4.- Un grafo bipartido regular se denota Km,n donde m, n es el grado de cada conjunto
disjunto de vrtices.
A continuacin ponemos los dibujos de K1,2, K3,3, y K2,5

Lic. Carmen Mollinedo

50

Algoritmos Avanzados

3.8.3 REPRESENTACION DE GRAFOS

Lic. Carmen Mollinedo

51

Algoritmos Avanzados

4 TECNICAS DE DISEO DE ALGORITMOS


4.1 DIVIDE Y VENCERS
Consiste en descomponer el caso que hay que resolver en subcasos ms pequeos, resolver
independientemente los subcasos y por ltimo combinar las soluciones de los subcasos para
obtener la solucin del caso original.
4.1.1 ALGORITMO GENERAL

Consideremos un problema arbitrario, y sea A un algoritmo sencillo capaz de resolver el


problema. A debe ser eficiente para casos pequeos y lo denominamos subalgoritmo
bsico.
El caso general de los algoritmos de divide y vencers es como sigue:
funcin DV(x)
si x es suficientemente pequeo o sencillo entonces
devolver A(x)
descomponer x en casos ms pequeos x1, x2, x3 , ... , xl
para i 1 hasta l hacer
yi DV(xi)
recombinar los yi para obtener una solucin y de x
devolver y

El nmero de subejemplares l suele ser pequeo e independiente del caso particular que
haya que resolverse.

Para aplicar la estrategia divide y vencers es necesario que se


cumplan tres condiciones:

Tiene que ser posible descomponer el caso en subcasos y recomponer las soluciones
parciales de forma eficiente.
Los subcasos deben ser en lo posible aproximadamente del mismo tamao.
En la mayora de los algoritmos de DV el tamao de los l subcasos es
aproximadamente m/b, para alguna constante b, en donde m es el tamao del caso
(o subcaso) original (cada subproblema es aproximadamente del tamao 1/b del
problema original).

4.1.2 COMPLEJIDAD

El anlisis de tiempos de ejecucin para estos algoritmos es el siguiente:

Lic. Carmen Mollinedo

50

Algoritmos Avanzados

Sea g(n) el tiempo requerido por DV en casos de tamao n, sin contar el tiempo necesario
para llamadas recursivas. El tiempo total t(n) requerido por este algoritmo de divide y
vencers es parecido a:
t(n) = l t(n/b) + nk para 1 l y 2 b

siempre que n sea suficientemente grande. Si existe un entero k 0. Donde adems:


l: Nmero de llamadas recursivas
b: En cuanto se divide el problema

4.1.3. EJEMPLOS

Ejemplo 1. BSQUEDA DEL MXIMO Y MNIMO

Estudiaremos el ejemplo del clculo del mximo y mnimo de los elementos almacenados
en un array. Este ejemplo es muy sencillo y slo tiene inters para hacer un estudio
detallado de los tiempos de ejecucin.
a) Mtodo directo
Un algoritmo para resolver el problema sin aplicar la tcnica divide y vencers puede
ser:
Clculo del mximo y mnimo, mtodo directo, compilado en Delphi 5
PROCEDURE MaxMin(a:TVector ;VAR max,min:integer);
VAR
i:INTEGER;
BEGIN
max := a[1];
min := a[1];
FOR i := 2 TO n DO
BEGIN
IF a[i] < min THEN
min := a[i];
Lic. Carmen Mollinedo

51

Algoritmos Avanzados

IF a[i] > max THEN


max := a[i];
END;
END;
Analizando el algoritmo, observamos que el nmero de comparaciones es
TMaxMin(n) = T(for)*(T(if-then)+ T(if-then))
= (n-1)*(2+2)
= 4n-4
Entonces es: O(n) de orden lineal

b) Aplicando Divide y Vencers dividimos el vector en 2 hasta llegar a un solo elemento


que se considera el caso base
PROCEDURE maxminDV(v:TVector;i,j:INTEGER;VAR
may,min:INTEGER);
VAR
med,amay,bmay,amin,bmin:INTEGER;
BEGIN
IF i=j THEN
BEGIN
may:=v[i];
min:=v[i];
END
ELSE
BEGIN
med:=(i+j)DIV 2;
maxminDV(V,i,med,amay,amin);
maxminDV(V,med+1,j,bmay,bmin);
IF amay>bmay THEN
may:=amay
ELSE
may:=bmay;
IF amin<bmin THEN
min:=amin
ELSE
min:=bmin;
END;//fin de else
END;//fin de maxminDV
El programa en ejecucin se ver de la siguiente forma:

Lic. Carmen Mollinedo

52

Algoritmos Avanzados

Analizando el algoritmo DV, observamos que el nmero de comparaciones es


T(n) = 3 cuando n=1, en el caso base

T(n) = 2T(n/2)+ 7 cuando n>1


El problema se divide en dos
2 llamadas recursivas
aplicando la frmula general tenemos:
l=2
b=2
k=0

donde 2>20

entonces

T(n) es ( n log 2 2 ) ( n)

Ejemplo 2. BSQUEDA BINARIA

Sea T[1..n] un arreglo ordenado por orden no decreciente, esto es, T[i] T[ j], siempre que
1 i j n.
Sea x un elemento que no necesariamente se encuentra en T. El problema consiste en buscar
en que posicin se encuentra x en el arreglo T, si es que se encuentra.
Formalmente, se desea encontrar el ndice i tal que 1 i n+1
La aproximacin evidente es examinar secuencialmente el arreglo hasta que se encuentre el
elemento buscado o hasta llegar al final del arreglo, sin embargo el lector podr observar
que esta es la alternativa ms costosa, puesto que en el peor de los casos.
Indudablemente la Bsqueda Binaria es ms beneficiosa. En la siguiente figura buscamos el
nmero 25

Lic. Carmen Mollinedo

53

Algoritmos Avanzados

Ini

fin

medio x

1
5
5
6

8
8
6
6

4
6
6

25

A continuacin se presenta el algoritmo codificado en Vbasic


Function BusquedaBinaria(ByVal x As Integer) As Integer
Dim Ini, Fin, Centro As Integer
Ini = 1
Fin = Val(Text1)
Centro = Int((Ini + Fin) / 2)
Do While Ini <= Fin And Vec(Centro) <> x
If x < Vec(Centro) Then
Fin = Centro - 1
Else
Ini = Centro + 1
End If
If Fin < 1 Or Ini > Val(Text1) Then Exit Do
Centro = Int((Ini + Fin) / 2)
Loop fin del do while
If x = Vec(Centro) Then
Busqueda=Centro
Else
Busqueda= -1
End If
End Function
La ejecucin del algoritmo ser de la siguiente forma:

Lic. Carmen Mollinedo

54

Algoritmos Avanzados

El algoritmo DV es el siguiente:

Private Function BusquedaBinariaDV(ByVal x As Integer, ini As Integer, _


fin As Integer) As Integer
Dim Centro As Integer
If ini = fin Then
If x = V(ini) Then
BusquedaBinariaDV = ini
Else
BusquedaBinariaDV = -1
End If
Else
Centro = Int((ini + fin) / 2)
If V(Centro) = x Then
BusquedaBinariaDV = Centro
Else
If V(Centro) < x Then
BusquedaBinariaDV = BusquedaBinariaDV(x, Centro + 1, fin)
Else
BusquedaBinariaDV = BusquedaBinariaDV(x, ini, Centro - 1)
End If
End If
End If
End Function

Anlisis

Es diferente el comportamiento del algoritmo recursivo vs. el iterativo?


NO en el contexto general del tiempo de ejecucin
La complejidad de tiempo es diferente, pero por un valor constante
Por lo tanto, el orden es el mismo: O(log n), veamos:

Lic. Carmen Mollinedo

55

Algoritmos Avanzados

T(n) = 3 cuando n=1, en el caso base

T(n) = 1T(n/2)+ d cuando n>1, d es ctte


El problema se divide en dos
1 llamadas recursiva, puesto que se ejecuta solamente la llamada then
o la llamada else
aplicando la frmula general tenemos:
l=1
b=2
k=0

donde 1=20

entonces

T(n) es ( n 0 log n) (log n)

Ejemplo 3 MATRIZ BOOLEANA

El problema consiste en generar una matriz de la siguiente forma:

Algoritmo
void BooleDV(int m[][20], int ini, int fin, int col)
{int medio,i;
if(ini==fin-1) { m[ini][col]=0; m[fin][col]=1;}
else
{

Lic. Carmen Mollinedo

56

Algoritmos Avanzados

medio=(ini+fin)/2;
for(i=ini;i<=medio;i++) m[i][col]=0;
for(i=medio+1;i<=fin;i++) m[i][col]=1;
BooleDV(m,ini,medio,col+1);
BooleDV(m,medio+1,fin,col+1);
}
}
Ejemplo 4 ORDENACIN

Sea T[1..n] un arreglo de n elementos. El problema consiste en ordenar estos elementos por
orden ascendente.
Posibles soluciones:
Ordenacin por seleccin
Ordenacin por insercin
Los algoritmos que ordenan por seleccin o por insercin requieren un tiempo que est en
(n2) para el caso peor.
Dos algoritmos de ordenacin que siguen la estrategia divide y vencers son la
ordenacin por fusin (mergesort) y la ordenacin rpida (quicksort).
a) ORDENACIN POR FUSIN
Se divide el arreglo T en dos partes de tamao aproximadamente igual, se ordenan
recursivamente las dos partes y despus se fusionan las dos partes ordenadas cuidando
de mantener el orden.
En la siguiente figura se puede apreciar el proceso para ordenar un vector T

Lic. Carmen Mollinedo

57

Algoritmos Avanzados

Algoritmo

void OrdDV(int v[],int ini,int fin)


{
int m,a[20],b[20],ta,tb;
//ta. Tamao del vector a
//tb.Tamao del vector b
if(ini==fin) return;
else
{
medio=(ini+fin)/2;
ta=m;
tb=fin-m;
copiav(v,ini,medio,a);
copiav(v,medio+1,fin,b);
OrdDV(a,1,ta);
OrdDV(b,1,tb);
Merge(a,ta,b,tb,v);
}
}
Se necesita un algoritmo eficiente para fusionar dos arreglos ordenados U y V en un nico
arreglo T cuya longitud es la longitud de la suma de las longitudes de U y V.

void Merge(int a[], int ta,int b[], int tb,int c[])


{int i=1,j=1,k=1,h;

while((i<=ta)&&(j<=tb))
{
if(a[i]<b[j]) { c[k]=a[i]; i++; k++; }
else { c[k]=b[j]; j++; k++;}
}
if(i<=ta) for(h=i;h<=ta;h++)
c[k]=a[h]; k++;
else for(h=j;h<=tb;h++)
c[k]=b[h]; k++;
}
Para realizar la copia en los subvectores
void copiav(int a[],int ini,int fin,int b[])
{int j=ini;
for(int i=1;i<=(fin-ini)+1;i++)
{
b[i]=a[j];
j++;
Lic. Carmen Mollinedo

58

Algoritmos Avanzados

}
}
Anlisis

Porqu no es un anlisis every-case?El algoritmo Merge tiene comportamiento


distinto dependiendo del caso. En el peor de los casos se realizar ta + tb = n comparaciones
Para el algoritmo copiaVec, se copia primero una mitad en a ms la otra mitad en b,
entonces se tiene n/2+n/2

Entonces tenemos:
T(n) = T(n/2) + T(n/2) + n/2+n/2+n
Tiempo para
ordenar
el primer
subarreglo

Tiempo para
ordenar
el segundo
subarreglo

Tiempo para
copiar en los
subvectores A
yB

Tiempo para
ejecutar el
modulo UNE

Para:
T(n) = 2T(n/2)+ 2n + d cuando n>1, d es ctte
El problema se divide en dos
2 llamadas recursiva
aplicando la frmula general tenemos:
l=2
b=2
k=1

donde 2=21

entonces

T(n) es ( n1 log n) ( n log n)


b) ORDENACIN RPIDA (QUICKSORT)
A diferencia de la ordenacin por fusin, la mayor parte del trabajo no recursivo se invierte
en construir los subcasos, y no en combinar sus soluciones.
Como primer paso, el algoritmo selecciona como pivote a uno de los elementos del
arreglo que hay que ordenar.

Lic. Carmen Mollinedo

59

Algoritmos Avanzados

A continuacin, el arreglo se parte a ambos lados del pivote: se desplazan los elementos de
tal manera que los que sean mayores que el pivote queden a su derecha, mientras que los
dems (menores o iguales) quedan a su izquierda.
Enseguida, las partes del arreglo a ambos lados del pivote se ordenan independientemente
mediante llamadas recursivas del algoritmo. El resultado final es un arreglo ordenado.
Idealmente, para que los dos subcasos tuvieran aproximadamente el mismo tamao, el
pivote debera ser la mediana del arreglo. Sin embargo, encontrar la mediana requiere un
tiempo excesivo, por lo que nos limitaremos a utilizar como pivote un elemento arbitrario
del arreglo.
Supongamos que se descompondr el subarreglo T[i..j] usando como pivote a p=T[i] (el
primer elemento). Para hacerlo se recorre el arreglo una sola vez empezando por los
extremos. Los punteros k y l se inicializan en i y j+1, respectivamente. A continuacin, se
incrementa el puntero k hasta que T[k] > p (el primer elemento mayor que el pivote) y se
decrementa el puntero l hasta que T[l] p (el ltimo elemento no mayor que el pivote).
Despus se intercambian T[k] y T[l]. Este proceso contina mientras k < l. Finalmente se
intercambian T[i] y T[l] para poner el pivote en su posicin correcta.

fuente: Apuntes de Roman Martinez


El algoritmo de ordenacin ser.

Lic. Carmen Mollinedo

60

Algoritmos Avanzados

Anlisis

La particin del arreglo es variable, depende del pivote.


Cul es el peor caso si la operacin de comparacin (al hacer la Particin) es la que
determina la complejidad del algoritmo?
Cuando la particin genera un subarreglo vaco y el otro con n-1 datos
Se hacen n - 1 comparaciones
Sea T(n) el peor tiempo para hacer el Quick Sort a un arreglo de n elementos
T(n)

Tiempo para
ordenar
el subarreglo
vaco = 0

T(0) +

T(n-1)

Tiempo para
ordenar
el segundo
subarreglo

n-1

Tiempo para
ejecutar el
mdulo
PARTICIN

Para:
T(n) = T(n-1) + n-1 es O(n2)

EJEMPLO 5: ALGORITMO DE STRASSEN PARA MULTIPLICAR MATRICES

El anlisis matemtico de Strassen, descubri que para:


c11 c12
c12
c21 c22
Lic. Carmen Mollinedo

a11 a12
a12

b11 b12
b12

61

Algoritmos Avanzados

Existen los valores:


m1 = (a11 + a22) * (b11 + b22)
m2 = (a21 + a22) * b11
m3 = a11 * (b12 - b22)
m4 = a22 * (b21 - b11)
m5 = (a11 + a12) * b22
m6 = (a21 - a11) * (b11 + b12)
m7 = (a12 - a22) * (b21 + b22)

Tales que
c11 = m1 + m4 - m5 + m7
c12 = m3 + m5
c21 = m2 + m4
c22 = m1 + m3 - m2 + m6

Dividir cada una de las matrices en 4 submatrices, y resolver por el


mtodo de Strassen el problema

4.1.4

PROBLEMAS RESUELTOS

Realizar un algoritmo que utilizando la tcnica de divide y vencers encuentre el


mayor y segundo mayor elemento de un array.

Solucin:
Haremos un procedimiento al que mandaremos los ndices del array sobre los que
estamos trabajando, y dos valores max1 y max2 que contendrn el mximo y el
segundo mayor.
M y m sern variables pues hay que devolverlos al procedimiento que los llam para
combinarlos:
procedure maximos(ini, fin: enteros; var ;max1, max2: datos)
var
medio: entero
amax1,bmax1,amax2,bmax2:datos

Lic. Carmen Mollinedo

62

Algoritmos Avanzados

begin
si ini = fin
max1 = a[ini]
max2 = -
en otro caso si fin - ini = 1
si a[ini] > a[fin]
max1 = a[ini]
max2 = a[fin]
en otro caso
max1 = a[fin]
max2 = a[ini]
fin_si
en otro caso // No es suficientemente pequeo
medio = (ini + fin) div 2
maximos(ini, medio, amax1;amax2)
maximos(medio + 1, fin, bmax1;bmax2)
/*Se combinan los resultados:*/
si M1 > M2 M = M1
si M2 > m1
m = M2
en otro caso
m = m1
fin_si
en otro caso
M = M2
si M1 > m2
m = M1
en otro caso
m = m2
fin_si
fin_si
fin_si
fin_maximos
La primera llamada se har con maximos(1, n, a, b) estando los datos en un array de ndices
de 1 a n.

El Problema consiste en que dos amigos se ponen como juego para matar el tiempo, ver si
uno de ellos adivina el nmero que estas pensando el otro preguntando si el nmero que ha
pensado es menor.
Solucin al problema: A ver si adivinas el numero que estoy pensando?

Lic. Carmen Mollinedo

63

Algoritmos Avanzados

El Problema consiste en que dos amigos se ponen como juego para matar el tiempo, ver si
uno de ellos adivina el nmero que estas pensando el otro preguntando si el nmero que ha
pensado es menor.

Primero se debe determinar un rango de trabajo para el problema, Ejemplo: Juan le pide a
Pedro que piense un nmero entre el 1 y el 100. este 1 ser nuestro inicio(ini), y el 10
nuestro final (fin). Supongamos que Pedro tiene es su mente el nmero 2.
Luego debemos de encontrar la mitad del problema, que para nuestro ejemplo sera el 5:
Inicio(Ini)

Medio

medio =

Final(fin)

10

(ini + fin )
2

Algoritmo
// Algoritmo desarrollado por Heber Huanca y Felicidad Silva
// para la materia de algoritmos avanzados
void BuscarNumero( int ini,int fin, int *res )
{int medio,x,n,r1=0,r2=0,sol;
medio=(fin+ini)/2;
cout<<"el numero es=> "<<medio<<"?";
cout<<"(presionamos 1=si y 2=no)";
n=leer(n);
if(n==1)
cout<<"\n el numero que pensaste es el=>"<<medio;
else
{ cout<<"es menor (1=si y 2 =no)=>";
x=leer(x);
if(x==1)

Lic. Carmen Mollinedo

64

Algoritmos Avanzados

{ BuscarNumero (ini,medio,&r1); }
else
{ BuscarNumero (medio+1,fin,&r2); }
}
}

Entonces para determinar el tiempo de ejecucin (T(n)) tenemos el siguiente resultado:

T(n) = 2T(n/2) + 4

n>1 en el peor caso

Entonces

l=1
b=2
k=0

donde 1=20

entonces

T(n) es ( n 0 log n) (log n)

Lic. Carmen Mollinedo

65

4.2 ALGORITMOS VORACES


Los algoritmos voraces o de avance rpido (greedy en ingls) se utilizan normalmente
para obtener soluciones iniciales aproximadas en problemas de optimizacin,
realizndose despus una bsqueda local para obtener una solucin ptima. Se trata de
obtener una solucin que debe cumplir unas ciertas condiciones dadas por ecuaciones y
minimizar o maximizar una funcin de coste.
Una solucin se obtiene tomando de entre una serie de entradas unas determinadas en
un orden determinado, y esto se hace en varios pasos, decidiendo en cada uno de los
pasos la inclusin en la solucin de una entrada, teniendo en cuenta que esta inclusin
no debe hacer que la nueva solucin parcial lleve a transgredir las condiciones que debe
cumplir una solucin
4.2.1 ALGORITMO GENERAL

procedimiento voraz (C: conjunto):


//C es el conjunto de candidatos
S // se construye la solucin en el conjunto S
mientras C y no solucin(S) hacer
x seleccionar(C) // x es el mejor candidato
C C \{x}
si factible ( S {x}) entonces
S S {x}
Fin_mientras
si solucin(S) entonces
devolver S
sino
devolver ..no hay soluciones..
Fin_si
Fin_Procedimiento

66

En cada paso tenemos los siguientes conjuntos:






Candidatos seleccionados para la solucin S.


Candidatos seleccionados pero rechazados luego.
Candidatos pendientes de seleccionar C.

4.2.2 CARACTERSTICAS GENERALES DE LOS ALGORITMOS VORACES

Para construir la solucin del problema se dispone de un conjunto (o una lista)


de candidatos.
A medida que avanza el algoritmo se van acumulando dos conjuntos: uno
contiene candidatos que ya han sido considerados y seleccionados, y el otro
contiene candidatos que han sido considerados y rechazados.
Existe una funcin que comprueba si un cierto conjunto de candidatos constituye
una solucin del problema, ignorando por el momento si es o no ptima.
Existe otra funcin que comprueba si un cierto conjunto de candidatos es
factible, esto es, si es posible o no completar el conjunto aadiendo otros
candidatos para obtener al menos una solucin del problema.
Existe una funcin de seleccin que indica en cualquier momento cul es el ms
prometedor de los candidatos restantes, que no han sido seleccionados ni
rechazados.
Existe una funcin objetivo que da el valor de la solucin que se ha encontrado.
Algunos algoritmos voraces pueden no tener alguna de estas caractersticas
(explcitamente).

Generalmente se identifican las siguientes funciones:

solucin (S). Comprueba si un conjunto de candidatos es una solucin


(independientemente de que sea ptima o no)

seleccionar (C). Devuelve el elemento ms prometedor del conjunto de


candidatos pendientes (no seleccionados ni rechazados).

factible (C). Indica si a partir del conjunto de candidatos C es posible construir


una solucin (posiblemente aadiendo otros elementos).

Insertar un elemento en la solucin. Adems de la insercin, puede ser


necesario hacer otras cosas.

Funcin objetivo (S). Dada una solucin devuelve el coste asociado a la misma
(resultado del problema de optimizacin).

67

4.2.4 EJEMPLOS
Ejemplo 1. PROBLEMA DEL CAMBIO DE MONEDAS.

Disponemos de monedas de 5 Bs, 2 Bs, 1Bs, 0.50 ctvs, 0.20 ctvs y 0.10 ctvs

Construir un algoritmo que dada una cantidad P devuelva esa cantidad con
monedas de estos tipos, usando un nmero mnimo de monedas.

Por ejemplo: para devolver 18.70Bs un posible conjunto solucin sera.: 3 monedas de
5Bs, 1 moneda de 2Bs, 1 moneda de 1Bs, 1 moneda de 0,50 ctvs y 1 moneda de 0.20
ctvs es decir S1={3,1,1,1,1,0}
Podemos aplicar la tcnica voraz y en cada paso aadir una moneda nueva a la solucin
actual, hasta que el valor llegue a P.
Candidatos iniciales: todos los tipos de monedas disponibles. Supondremos que C
contiene la cantidad de elementos
Solucin: conjunto de monedas que suman la cantidad P.
Una solucin ser de la forma (x1, x2, x3, x4, x5, x6, x7, x8), donde xi es el nmero de
monedas de tipo i. Suponemos que la moneda i vale ci.
Funciones:
o solucin. El valor actual ser solucin si

xici=P

o objetivo. La funcin a minimizar es xi, el nmero de monedas resultante.

68

o seleccionar. Elegir en cada paso la moneda de valor ms alto posible, pero


menor que el valor que queda por devolver.
o factible. Valdr siempre verdad si xi+S <= P
Algoritmo

funcin DevolverCambio (n): conjunto de monedas


//Da el cambio de n unidades utilizando el menor nmero posible
//de monedas. La constante C especifica las monedas disponibles
const C = {100, 25, 10, 5, 1}
S //el conjunto S contendr la solucin
s 0 //s es la suma de los elementos de S
mientras s n hacer
x el mayor elemento de C tal que s + x n
si no existe ese elemento entonces
devolver ..no encuentro la solucin..
S S {una moneda de valor x}
ss+x
fin_mientras
devolver S
fin_funcin

Ejemplo 2.EL PROBLEMA DE LA MOCHILA

Se tienen n objetos y una mochila. Para i = 1, 2, ..., n,


el objeto i tienen un peso positivo wi y un valor
positivo vi. La mochila puede llevar un peso que no
sobrepase W.
El objetivo es llenar la mochila de manera que se
maximice el valor de los objetos transportados sin
pasar del peso mximo W.

20 Kg.

Por ejemplo : n = 3; M = 20
Donde n es el nmero de elementos y M la capacidad de la mochila
w = (18, 15, 10)
v = (25, 24, 15)

Solucin 1: S = (1, 2/15, 0)

69

Valor total = 25 + 24*2/15 = 28.2


Solucin 2: S = (0, 2/3, 1)
Valor total = 15 + 24*2/3 = 31
Diseo de la solucin. Utilizando un algoritmo voraz para resolver el problema.
Supondremos que los objetos se pueden partir en trozos ms pequeos de manera que se
pueda seleccionar un fraccin xi del objeto i, con 0 xi . 1
El objeto i contribuye en xiwi al peso total de la mochila, y en xivi al valor de la carga.

La solucin se podr plantear de la siguiente forma.


n

Funcin objetivo

i =1

Restriccin

x
i =1

vi

wi M

donde vi > 0, wi > 0 y 0 xi . 1 para 0 i n

Los candidatos son los objetos disponibles.


Una solucin es un vector S= (x1, ... , xn ) que indica qu fraccin de cada
objeto hay que incluir.
Una solucin es factible si se respetan las restricciones mencionadas.
La funcin objetivo es el valor total de los objetos en la mochila.

Si

w
i =1

W lo ptimo es meter todos los objetos en la mochila.


n

El problema es ms interesante cuando

i =1

>W

La solucin ptima debe llenar exactamente la mochila, pues de lo contrario se podra


aadir una fraccin de alguno de los objetos restantes e incrementar el valor total. Por lo
n

tanto, en una solucin ptima tenemos wi = W


i =1

Para encontrar la solucin la estrategia ser:

Seleccionar cada objeto por turno en algn orden adecuado.

70

Poner la mayor fraccin posible del objeto seleccionado en la mochila.


Detenerse cuando la mochila est llena.

Algoritmo
El siguiente representa un algoritmo general, donde an no s dtrmin con exactitud la
funcin de seleccin

funcin mochila ( w[1..n], v[1..n], W ) : arreglo[1..n]


// Inicializacin del vector solucin
para i 1 hasta n hacer
x[i] 0
peso 0
// bucle voraz
mientras peso < W hacer
i el mejor objeto restante
si peso + w[i] . W entonces
x[i] 1
peso peso + w[i]
sino
x[i] (W - peso)/w[i]
peso W
fin_si
fin_mientras
devolver x
fin_mochila

Cmo seleccionar el candidato ms prometedor?


Hay tres posibilidades:
1) Seleccionar el objeto ms valioso
2) Seleccionar el objeto ms ligero
3) Seleccionar el objeto cuyo valor por unidad de peso sea el mayor posible
Por ejemplo

W = 100

w
v
v/w

10
20
2.0

20
30
1.5

30
66
2.2

40
40
1.0

50
60
1.2

71

Si se seleccionan por orden decreciente de valor, la solucin es x = [0, 0, 1, 0.5,


1]. Valor total: 66 + (0.5)40 + 60 = 146
Si se seleccionan por orden creciente de peso, la solucin es x = [1, 1, 1, 1, 0].
Valor total: 20 + 30 + 66 + 40 = 156.
Si se seleccionan por orden decreciente de vi / wi, la solucin es x = [1, 1, 1,0,
0.8]. Valor total: 20 + 30 + 66 + (0.8)60 = 164.

Teorema
Si se seleccionan los objetos por orden decreciente de vi / wi ,
entonces el algoritmo de la mochila encuentra una solucin ptima.

Anlisis del Algoritmo


La ordenacin por orden decreciente de vi / wi se encuentra en (n log n) y el bucle
voraz est en (n). Por lo tanto el algoritmo est en (n log n).
4.2.5 RBOLES DE RECUBRIMIENTO MNIMO

Sea G = <N, A> un grafo conexo no dirigido en donde N es el conjunto de nodos y A es


el conjunto de aristas. Cada arista posee una longitud no negativa.
El problema consiste en hallar un subconjunto T de las aristas de G tal que utilizando
solamente las aristas de T, todos los nodos deben quedar conectados (sin formar ciclos),
y adems, la suma de las longitudes de las aristas de T debe ser tan pequea como sea
posible.
Dado que G es conexo, debe existir al menos una solucin. Sin embargo, puede haber
ms de una solucin (donde la suma mnima de longitudes sea igual).
En lugar de longitudes, tambin podemos hablar de costo. El problema consiste
entonces en hallar un subconjunto T de aristas con costo total mnimo.
Si n es el nmero de nodos en N (del grafo G), entonces, si G es conexo, el nmero
mnimo de aristas en G es n .1. Por lo tanto, este es el nmero de aristas en T. De hecho,
si un grafo tiene ms de n-1 aristas, entonces tiene por lo menos un ciclo.
Sea G = <N, T>. El grafo G se denomina rbol de recubrimiento mnimo (o rbol de
cobertura mnimo) para el grafo G. Este problema tiene muchas aplicaciones. Por
ejemplo, supongamos que los nodos de G representan ciudades, y sea el costo de una
arista {a, b} el costo de tender una lnea telefnica desde a hasta b. Entonces un rbol
.

72

de recubrimiento mnimo representa la red ms barata posible para dar servicio a todas
las ciudades.
Para resolver este tipo de problemas con algoritmos voraces:

El conjunto de candidatos son las aristas de G.


Un conjunto de aristas es una solucin si constituye un rbol de recubrimiento
para los nodos de N.
Un conjunto de aristas es factible si no contiene ningn ciclo.
La funcin de seleccin depender del algoritmo.
La funcin objetivo que hay que minimizar es la longitud total de las aristas de
la solucin.

Definicin 1

Se dice que un conjunto de aristas factible es prometedor si se puede extender para


producir una solucin ptima.
El conjunto vaco siempre es prometedor (ya que siempre existe una solucin ptima);
adems, si un conjunto de aristas prometedor ya es una solucin, la extensin
requerida es irrelevante, y esta solucin debe ser ptima.

Definicin 2

Se dice que una arista sale de un conjunto de nodos dado si esa arista tiene
exactamente un extremo en el conjunto de nodos. Una arista puede no salir de un
conjunto de nodos ya sea porque ninguno de sus extremos est en el conjunto, o bien
porque sus dos extremos se encuentre en el conjunto.
Lema:
Sean:
G = <N, A> un grafo conexo no dirigido en el cual las aristas tienen longitudes
no negativas
B N un subconjunto propio de los nodos de G,
T A un conjunto prometedor de aristas tal que no hay ninguna arista de T que
salga de B y
v la arista ms corta que salga de B (o una de las ms cortas, si hay ms de
una).
Entonces T {v} es prometedor.

73

El conjunto de aristas T est vaco inicialmente y se le van aadiendo aristas a medida


que progresa el algoritmo. Mientras no se haya encontrado una solucin, el grafo parcial
formado por los nodos de G y las aristas de T consta de varias componentes conexas (un
nodo aislado es una componente conexa).

Los elementos de T que se incluyen en una componente conexa dada forman un rbol de
recubrimiento mnimo para los nodos de esa componente.

Al final del algoritmo, slo queda una componente conexa, as que T es un rbol de
recubrimiento mnimo para todos los nodos de G. Para construir componentes conexas
cada vez ms grandes, se examinan las aristas de G por orden creciente de longitudes. Si
una arista une a dos nodos de componentes conexas distintas, se aade a T, y las dos
componentes conexas forman ahora una nica componente. En caso contrario, se
rechaza la arista (porque une a dos nodos de la misma componente conexa formando un
ciclo).

El algoritmo se detiene cuando slo tiene una componente conexa.

Teorema

El algoritmo de Kruskal halla un rbol de recubrimiento mnimo.

Las componentes conexas se manejan como conjuntos de nodos. Se necesitan dos


operaciones: buscar(x) que indica en qu componente conexa se encuentra el nodo x, y
fusionar(A, B), para fusionar dos componentes conexas.
Algoritmo

74

Ejemplo:

Ordenar las aristas por orden no decreciente de


longitud:
{1,2}, {2,3}, {4,5}, {6,7}, {1,4}, {2,5}, {4,7}, {3,5},
{2,4}, {3,6},

{5,7} y {5,6}.

Paso Arista

considerada

Inicializacin
{1},{2},{3},{4},{5},{6},{7}
1
{1,2}
2
{2,3}
3
{4,5}
4
{6,7}
5
{1,4}
6
{2,5}

Componentes conexas

{1,2},{3},{4},{5},{6},{7}
{1,2,3},{4},{5},{6},{7}
{1,2,3},{4,5},{6},{7}
{1,2,3},{4,5},{6,7}
{1,2,3,4,5},{6,7}
rechazado (forma ciclo)

Anlisis del Algoritmo

75

Sea n el nmero de nodos y a el nmero de aristas. Se requiere un tiempo en el orden de


(a log a) para ordenar las aristas, lo cual es equivalente a
(a log n), porque n -1 a n(n- 1)/2 y cuando n , log a = log nk,
donde 1 k . 2 (y log nk = k log n)
(n) para iniciar los n conjuntos disjuntos
(a) para todas las operacin buscar y fusionar, donde es aproximadamente
constante (funcin de crecimiento lento) cuando se utilizan estructuras de
particin (de hecho, (a) (log n) )
(a) para las operaciones restantes en el caso peor
Por lo tanto, el tiempo total para el algoritmo est en (a log n).

4.2.5.1 ALGORITMO DE PRIM


En el algoritmo de Kruskal, la funcin de seleccin escoge las aristas por orden
creciente de longitud, sin preocuparse por la conexin con las aristas seleccionadas
anteriormente (slo cuidando que no se forme un ciclo). Por esto mismo, se crea un
bosque de rboles hasta que todas las componentes del bosque se fusionan en un
slo rbol.

En el algoritmo de Prim, el rbol de recubrimiento mnimo crece de forma natural,


comenzando por una raz arbitraria. En cada fase se aade una nueva rama al rbol ya
construido.El algoritmo se detiene cuando se han alcanzado todos los nodos. Sea B un
conjunto de nodos, y sea T un conjunto de aristas. Inicialmente B contiene un nico
nodo arbitrario y T est vaco.
En cada paso se busca la arista ms corta posible {u, v} tal que uB y v N \ B.
Entonces se aade v a B y {u, v} a T. As, las aristas de T forman en todo momento un
rbol de recubrimiento mnimo para los nodos de B. El algoritmo termina cuando B = N.
Algoritmo

Teorema

76

El algoritmo de Prim halla un rbol de recubrimiento mnimo.


Otra versin del algoritmo de Prim que se puede implementar ms fcilmente en una
computadora es la siguiente:
Supongamos que los nodos de G estn numerados de 1 a n.
Supongamos tambin que hay una matriz L que da la longitud de todas las
aristas con L[i, j] = si no existe la arista correspondiente.
Se utilizarn dos arreglos: para todo nodo i N \ B, ms_prximo[i] proporciona
el nodo de B que est ms prximo a i, y distmin[i] da la distancia desde i hasta
este nodo ms prximo. Para un nodo i B, se hace distmin[i] = .1 (as podemos
saber si un nodo est o no en B ).

Ejemplo:
Seleccionar el nodo 1 el como inicial
Paso

Inicializacin
1
2
3
4
5
6

Arista considerada

{1,2}
{2,3}
{1,4}
{4,5}
{4,7}
{7,6}

Componentes
Conexas
{1}
{1,2}
{1,2,3}
{1,2,3,4}
{1,2,3, 4,5}
{1,2,3,4,5,7}
{1,2,3,4,5,6,7}

77


T = {{1,2}, {2,3}, {1,4}, {4,5}, {4,7}, {7,6}}

4.2.5.2 ALGORITMO DE DIJKSTRA

(Implementado por Ruth Chirinos y Wilson Poma)


ANLISIS

Suponga que en su andar cotidiano tiene que ir a 4 lugares diferentes durante 4 das de
la semana, es decir:
DIA
Lunes

Martes
Jueves
Viernes

ACTIVIDAD
Ir al Cine
Estreno de la Pelcula MATRIX RECARGADO
CINE MONJE CAMPERO EL PRADO
Ir al Stadium
Clsico Bolivar vs. The Strtongest
Cita con el dentista
Plaza San Francisco, Perez Velasco
Ira pagar el consumo del telfono a COTEL
Av. Mcal. Santa Cruz

Tomando como ejemplo la actividad del da Lunes. Qu camino tomaras t para llegar
a tu destino?
Las flechas representan las calles que pueden llevarte a tu destino.
Suponiendo que la cantidad de minutos desde su casa hacia cada lugar y de cualquier
lugar a otro, respetando las calles (flechas) de direccin, es la siguiente:

10

5
10

3
2

1
5

78

Un buen observador se habr dado cuenta que el grfico anterior se


parece a un grafo
CASA CINE STADIUM DENTISTA COTEL
0
50
30
100
10
CASA
0
0
0
0
0
CINE
0
5
0
0
0
STADIUM
0
20
50
0
0
DENTISTA
0
0
0
10
0
COTEL
Qu caminos tomaras t para legar ms rpido desde tu casa a los diferentes
lugares?. A simple vista podemos decir que:
De tu casa al cine slo 35 minutos, realizando un desvo por el
Stadium.
De tu casa al Stadium slo 30 minutos. En ruta directa
De tu casa al dentista 20 minutos, realizando un desvo por COTEL.
De tu casa a COTEL slo 10 minutos. En ruta directa

Este ejemplo es muy sencillo pero, que sucedera si estuviramos a cargo una empresa
de transporte?, los destinos son ms de 64 y las calles o avenidas para llegar a esos
destinos son el doble de 64 o ms.
Entonces cmo nos ayuda el Algoritmo Vors de Dijkstra?
El Algoritmo de Dijkstra halla los caminos ms cortos desde un nico origen
hasta los dems nodos del grafo.

Ms arriba dijimos que la grfica se pareca a un grafo, pues s, los problemas de


caminos se solucionan ms frecuentemente con grafos. Por ello nosotros manejaremos
grafos para el desarrollo del algoritmo.
Cmo resolverlo?
En primer lugar debemos recordar en que consiste un Algoritmo Vorz,
Es como un glotn que va devorando todo lo va encontrando, claro mientras exista algo
que comer.

79

En nuestro caso el algoritmo analizar todos los caminos uno a uno, mientras exista
caminos que analizar.
Entonces podemos tener 2 grupos:
o Caminos Seleccionados
o Caminos no Seleccionados
En el primer paso de inicializacin se tendr:

o Lugares Seleccionados: por default (por defecto), conjunto S


TU CASA, de donde partirs a los dems lugares. En este conjunto contendr aquellos
lugares que ya han sido seleccionados. La distancia mnima desde el origen ya es conocida
para todos los lugares de S

o Lugares No Seleccionados (candidatos), conjunto C

LUGARES donde quieres llegar, para ellos su distancia mnima desde tu casa hacia ellos
an no ha sido hallada y son candidatos a ser seleccionados posteriormente.

Conjunto D
En otro conjunto D, se irn almacenando los minutos que se tarda para llegar desde tu
casa hacia otro lugar. Llamado camino especial, porque todos los lugares intermedios a
lo largo del camino pertenecen al conjunto de los lugares seleccionados (conjunto S).
Por ejemplo : Supongamos que el Stadium ya pertenece al conjunto de lugares
seleccionados, entonces el camino ms corto de tu casa al Cine es a travs de un
desvo por el Stadium.

30

80

D= Duracin= 35 minutos.
Cundo se detiene el algoritmo?
Cuando todos los lugares (nodos) que se quieren llegar se encuentran en el conjunto de
lugares seleccionados(S), por tanto todos los caminos desde el origen hasta algn otro
nodo son especiales. Consiguientemente los valores que hay en D (conjunto de cantidad
de minutos), dan la solucin del problema de caminos mnimos.

81

Observaciones
No solamente se pueden aplicar a caminos con respecto a sus minutos de viaje, sino a la
cantidad de Km.

PSEUDOCDIGO

82

Por induccin:
o Si un nodo i 6= 1 est en S , D [ i ] es la longitud del camino ms corto desde el
origen a i .
o Si un nodo i no est en S , D [ i ] es la longitud del camino especial ms corto
desde el origen a i .
Base: Slo 1 est en S .
o se cumple trivialmente y
o se cumplen por cmo se inicializa D .(conjunto de cant. de minutos)

Hiptesis de induccin: (a) y (b) son ciertos justo antes de aadir v (candidato lugar) a
S.
Paso inductivo (a): Hay que probar que despus de aadir v sigue cumplindose
(a).
Para los nodos que ya estaban, no cambia nada .
Hay que comprobar que D [ v ] es el camino ms corto a v (candidato lugar).

Vamos a ver que no hay otro camino a v de longitud menor .


d(1;v)=d(1;x)+d(x;v)
=D[x]+d(x;v)D[v]
Paso inductivo (b): Cuando v se aade a S o bien el camino especial ms corto a
w no cambia, o bien ahora pasa por v (candidato lugar)
El algoritmo compara D [ w ] con D [ v ] + G [ v ; w ] y se queda con el menor .

83

CODIFICACION

La siguiente codificacin est hecha en Visual Basic 6.0.

Por qu llenamos estos


vectores desde 2 hasta
tam (cantidad de lugares
o nodos)?, Porque al
inicializar el programa
en S se almacena 1, y en
C, D, P se almacenan los
dems lugares

Por qu Do While es
hasta n-2?
El Comportamiento de C
y D es:
C
{2,3,4,5}
{2,3,4}
{2,3}
{2}

D
{50,30,100,10}
{50,30,20,10}
{40,30,20,10}
{35,30,20,10}

Claramente D no
cambiara si se
hiciera una iteracin
ms para eliminar el
ltimo elemento de C

Porqu el for toma esos


parmetros? Porque v toma un lugar
de C y utiliza una variable
auxiliar w para que vaya
recorriendo todos los lugares
posibles mnimos, claro, la
condicin se ve en el if que est
dentro de el For.

Function dijkstra()
Dim i,w, v As Integer
For i=2 To tam
c(i)=i
d(i)=g(1,i)
p(i)=1
Next
Do While(n-2>0)
v=c(n)
n=n-1
For w=v To w<=2 Step -1
If(((d(v)+g(v,w))<d(w)) And (g(v,w)<>0) And v<> w)
Then
d(w)=d(v)+g(v,w)
p(w)=v
End If
Next
Loop
End Function

Qu hace el If?
If interacta con D
y con P (para saber
por dnde pasarn
los caminos, estos
se almacenan en P)
Pregunta si D mas
la distancia del
nodo seleccionado
es mayor a D, y
adems la distancia
del nodo es
diferente de 0, y
adems si el lugar
elegido v es
diferente a W,
que es el nodo que
estamos revisando.

84

Las pantallas anteriormente mostradas son las salidas que dio el programa, los resultados
son los caminos mnimos desde el Origen hasta cada uno de los dems nodos. Entonces
llegamos a la conclusin de que:

30

5
35 minutos para llegar al cine, con un desvo por el
Stadium.

30
30 minutos para llegar al Stadium, ruta directa.

10

10

20 minutos para llegar al Dentista, con desvo por COTEL.

10
10 minutos para llegar a COTEL, con
ruta directa.

85

Algoritmos Avanzados

4.3 PROGRAMACIN DINMICA


En algunos problemas que se resuelven con llamadas recursivas a subproblemas de
menor tamao se repiten llamadas a problemas idnticos, con lo que se repiten clculos
innecesariamente pues se podran haber guardado las soluciones obtenidas
anteriormente.
Esto ocurre por ejemplo si calculamos los nmeros de Fibonacci por la ecuacin f(n) = f(n
1) + f(n 2). Con la tcnica de la programacin dinmica se trata de evitar estos clculos
repetidos guardando una tabla de resultados parciales, es por tanto un mtodo
ascendente, donde partimos de problemas de tamao mnimo y vamos obteniendo
resultados de problemas de tamao cada vez mayor hasta llegar al tamao del problema
a resolver. Se diferencia de la tcnica divide y vencers en que este mtodo es
descendente.
Se aplica a problemas de optimizacin en los que una solucin viene dada como una
secuencia de decisiones (en el problema de la mochila podra ser decidir si se incluye un
elemento o no, o qu elemento se incluye primero) y se utiliza el principio de optimalidad
que dice que cuando se ha tomado una secuencia ptima de decisiones cada
subsecuencia debe ser ptima, por lo que si se han tomado una serie de decisiones la
siguiente subsecuencia de decisiones debe ser ptima para el problema en que nos
encontremos en ese momento.
El principio de optimalidad no siempre se cumple por lo que, para aplicar este mtodo,
deberemos comprobar que s se puede aplicar en nuestro problema. Por ejemplo, en el
problema de calcular el camino mnimo entre las ciudades A y D con el mapa de
carreteras de la figura:

una primera decisin sera tomar direccin a B o C. En este momento es ptima A B, pero
tomar esta decisin nos lleva a una solucin no ptima. Da la impresin de que se cumple
el principio de optimalidad ya que en la solucin A B D las dos decisiones que se han
tomado son ptimas en un cierto sentido: la decisin de tomar A B es ptima pues es la
menor de las dos posibilidades en ese momento, y la decisin de tomar B D es ptima
pues es la nica posibilidad en ese momento.
Pero sin embargo no llegamos a una solucin ptima por lo que no puede cumplirse el
principio de optimalidad.

Lic. Carmen Mollinedo

86

Algoritmos Avanzados
Si enfocamos el problema considerando que una solucin es ptima si se compone de
dos decisiones ptimas en el sentido: la primera solucin es ptima para pasar de A a B o
C y la segunda decisin es ptima para pasar de B o C a D; es cierto que una solucin
compuesta de dos soluciones ptimas de los subproblemas es una solucin ptima
global, pero no podemos asegurar que una solucin ptima se pueda descomponer en
soluciones ptimas de subproblemas con el tipo de subproblemas que hemos
considerado, por lo que no se cumple el principio de optimalidad. Pero s se cumple el
principio de optimalidad si consideramos que una solucin ptima para ir de A a D debe
estar compuesta de dos soluciones ptimas para ir de A a B o para ir de A a C y para ir de
B a D o para ir de C a D. De esta manera se ve que para resolver algunos problemas es
necesario resolver subproblemas de menor tamao y que tengamos que guardar las
soluciones de estos subproblemas para poder reconstruir a partir de ellas la solucin del
problema inicial. Como no sabemos a priori cules de estas soluciones ptimas de
subproblemas van a dar lugar a soluciones ptimas del problema global tenemos que
guardar toda la informacin, lo que hace que se necesite mucha memoria y que se hagan
clculos que a la postre se van a revelar como innecesarios.
4.3.1 CARACTERISTICAS
La programacin dinmica se suele utilizar en problemas de optimizacin, donde una
solucin est formada por una serie de decisiones.
Igual que la tcnica divide y vencers, resuelve el problema original combinando las
soluciones para subproblemas ms pequeos.
Sin embargo, la programacin dinmica no utiliza recursividad, sino que almacena los
resultados de los subproblemas en una tabla, calculando primero las soluciones para los
problemas pequeos.
Con esto se pretende evitar el problema de divide y vencers de calcular varias veces la
solucin para problemas pequeos.
4.3.2 CARACTERSTICAS COMUNES
Hay un conjunto de caractersticas que son comunes a estos dos ejemplos y a todos los
problemas de programacin dinmica.
El problema se puede dividir en niveles, se requiere una decisin en cada nivel.
En el problema de inversin de capital los niveles fueron las asignaciones para cada
planta, la decisin fue cunto gastar. En el problema de la ruta ms corta, los niveles se
definieron siguiendo la estructura del grafo, la decisin fue ir al siguiente.
Cada nivel tiene un conjunto de estados asociados a l. Los estados para el problema de
asignacin de capital corresponden a la cantidad gastada en ese punto en ese instante de
tiempo. Los estados de la ruta ms corta fueron los nodos visitados.
La decisin en un nivel transfoma un estado en un estado en el siguiente nivel.
En asignacin de capital : la decisin de cunto gastar dado una cantidad total gastada en
el siguiente nivel. En la ruta ms corta: la decisin de donde seguir dado la llegada en el
siguiente nivel.
Dado el estado actual, la decisin ptima para cada uno de los estados que faltan no
depende de los estados o de decisiones previas.
En asignacin de capital : no es necesario conocer cmo se gast el dinero en los niveles
previos, slo cunto se gast. En la ruta ms corta: no fue necesario conocer cmo se

Lic. Carmen Mollinedo

87

Algoritmos Avanzados
lleg

al

nodo,

slo

se

necesitaba

saber

que

se

lleg

ese

nodo.

Hay una relacin de recursividad que identifica la decisin ptima para el nivel j, dado
que el nivel j+1 ya fue resuelto.
El nivel final debe resolverse por si mismo.
Las dos ltimas propiedades obedecen a las relaciones de recursividad dadas
anteriormente.
La potencialidad de la programacin dinmica, y el arte involucrado, es tomar un
problema y determinar sus niveles y estados, tal que las caractersticas mencionadas se
cumplan. Si esto es posible, entonces la relacin de recursividad permite encontrar los
valores en una forma relativamente fcil. La dificultad est en la determinacin de los
niveles y de los estados, para visualizar este aspecto se recomienda estudiar y analizar
los siguientes ejemplos.

4.3.4 EJEMPLOS
Ejemplo 1. CLCULO DE LOS NMEROS DE FIBONACCI.
Con divide y vencers
Fibonacci (n: integer)
Si n<2 Devolver n
Sino Devolver Fibonacci (n-1) + Fibonacci (n-2)
Problema: Muchos clculos estn repetidos, tiempo de ejec. exponencial.
Solucin: Calcular los valores de menor a mayor empezando por 0, e ir guardando los
resultados en una tabla.
Con programacin dinmica.
Fibonacci (n: integer)
T[0]:= 0; T[1]:= 1;
for i:= 2 to n do
T[i]:= T[i-1] + T[i-2];
Devolver T[n];
Se utiliza la misma frmula que en la versin anterior, pero de forma ms inteligente. El
tiempo de ejecucin es (n).
Ejemplo 2. CLCULO DEL COEFICIENTE BINOMIAL

Lic. Carmen Mollinedo

88

Algoritmos Avanzados

Para calcularlo directamente:


funcion C(n,k)
si k=0 o k=n entonces devolver 1
sino devolver(C(n-1,k-1)+C(n-1,k))
fin_funcion
Para calcular C(5,3):
C(5,3) = C(4,2)+C(4,3) = C(3,1)+C(3,2)+C(3,2)+C(3,3) =
= C(2,0)+C(2,1)+C(2,1)+C(2,2)+C(2,1)+C(2,2) =
= 1+C(1,0)+C(1,1)+1+C(1,0)+C(1,1)+1+1 = 10

Muchos valores C(i,j) i<n , j<n se calculan muchas veces  C(2,2) o C(2,1)
La repeticin de clculos tiene orden exponencial
Se puede mejorar el algoritmo utilizando una tabla de resultados intermedios (tringulo de
Pascal), alcanzndose (nk)

Ejemplo 3 EL PROBLEMA DE LA MOCHILA


Planteamiento
Consideramos en este caso el problema de la mochila 0/1 (no se pueden introducir en la
mochila porciones de elementos) con lo que cada xi es 0 1 dependiendo de que no se
introduzca o s se introduzca el elemento en la mochila.
En principio tenemos n objetos numerados de 1 a n y una capacidad de la mochila M, y
podemos llamar a este problemaMochila(1; n;M). Para resolverlo tendremos que resolver
problemas ms pequeos que llamaremos Mochila(i; j; Y ), que corresponden al problema
de la mochila 0/1 con los objetos numerados de i a j y con capacidad de la mochila Y , por
lo que Mochila(i; j; Y ) ser maximizar
Pj
k=i pkxk sujeto a
Pj
k=i wkxk _
Lic. Carmen Mollinedo

89

Algoritmos Avanzados
Y y xk = 0 xk = 1 8k; i _ k _ j.
Para resolver el problema suponemos que hay que tomar n decisiones correspondientes
a si se mete o no un elemento en la mochila. Por lo tanto, una solucin ser
una secuencia de n ceros y unos, y la solucin ptima se podr_ encontrar por bsqueda
exhaustiva, tal como se puede ver en la _gura:

correspondiente al ejemplo n = 3, p = (1; 2; 5), w = (2; 3; 4), M = 6. En este rbol cada


nivel corresponde a una decisin sobre si incluir o no un elemento, y los pares de los
nodos corresponden al peso y bene_cio acumulado, los nodos terminales corresponden
la soluciones y la solucin ptima ser la correspondiente al nodo con peso seis y mayor
bene_cio. En este ejemplo el bene_cio mximo es 6 y corresponde a incluir en la mochila
los elementos 1 y 3.
Solucin por programacin dinmica
Existe otra forma de formular el problema de la mochila. Esto ilustrar cun arbitraria
puede ser la definicin de niveles, estado y decisiones. Adems, da una visin de la
flexibilidad de las reglas en programacin dinmica. Se va a trabajar con una recursividad
forward (hacia adelante). Para el problema de la mochila se indexarn los niveles por w, el
peso que se lleva. La decisin es determinar el ltimo item agregado para llegar al peso
w. Luego, hay slo un estado por nivel. Sea g(w) el mximo beneficio que se puede ganar
de una mochila con un peso w. Continuamos usando
y
como el peso y beneficio,
respectivamente, para el item j. Lo siguiente relaciona g(w) con valores de g calculados
previamente:

Intuitivamente, para tener una mochila con un peso de w, se debe terminar agregando
algn item. Si se agrega el item j, terminaremos con una mochila de tamao
disponible para ser llenada.

Ejemplo 4 EL PROBLEMA DEL VENDEDOR VIAJERO


El problema del vendedor viajero es visitar un conjunto de ciudades con una mnima
distancia. Por ejemplo, un poltico comienza en New York y tiene que visitar Miami, Dallas,

Lic. Carmen Mollinedo

90

Algoritmos Avanzados
y Chicago antes de volver a New York. Cmo podra minimizar la distancia recorrida?.
Las distancias se muestran en la Tabla siguiente.

Un problema del vendedor viajero (TSP).


La dificultad est una vez ms en definir los niveles, estados y decisiones. Una forma
natural es que el nivel t represente las ciudades t visitadas, y la decisin es donde ir a
continuacin. Cules son los estados?. Supongamos que elegimos la ciudad en la que
estamos como un estado. No se podra tomar la decisin de donde seguir a continuacin
ya que no sabemos lo que se ha realizado anteriormente. En consecuencia, el estado
debe incluir informacin acerca de todas las ciudades visitadas, ms la ciudad a donde
queremos terminar. Luego, un estado estar representado por el par (i,S) donde S es el
conjunto de t ciudades ya visitadas e i es la ltima ciudad visitada ( as i debe estar en
S). Usando recursividad se tiene:
Los clculos en el nivel 3 son:

Para los otros niveles, la recursin es:


Se recomienda realizar los clculos. Un aspecto importante de este problema es la NPcompletitud. El espacio de bsqueda es tan grande que llega a ser imposible encontrar
una solucin, an para problemas de tamao pequeo. Por ejemplo suponga un problema
con 20 ciudades, el nmero de estados en el 10-simo nivel es ms de un milln. Para 30
ciudades, el nmero de estados en el nivel 15 es ms de un billn. Y para 100 ciudades,
el
nmero
de
estados
en
el
nivel
50
es
ms
de
5,000,000,000,000,000,000,000,000,000,000. Este no es un problema fcil de resolver
an con una configuracin computacional ideal.

Ejemplo 6 REEMPLAZO DE EQUIPAMIENTO


Suponga que un negocio necesita tener una mquina en los prximos 5 aos. Cada
mquina nueva tiene un costo $1000. El costo de mantener la mquina durante el ao isimo de operacin es:
,
, y
. Una mquina se
puede usar por tres aos y luego ser rematada. El valor de remate de la mquina despus
de
i
aos
es
,
,
y
Cmo podra minimizar los costos el dueo del negocio sobre un perodo de 5 aos?.

Lic. Carmen Mollinedo

91

Algoritmos Avanzados
Los niveles sern asociados a cada ao. El estado ser la edad de la mquina en ese
ao. Las decisiones son ya sea mantener la mquina o rematarla y reemplazarla por una
nueva. Sea
el mnimo costo desde el instante t al 5, dado que la mquina tiene x
aos de antiguedad en el instante t.
Ya que se debe rematar en el instante 5,
Ahora se consideran los otros perodos de tiempo. Si se tiene en el instante t una mquina
con 3 aos de antiguedad, sta se debe rematar en:

Si tiene dos aos de antiguedad, se puede rematar o mantenerla:


Costo remate

Costo Mantenerla
.
As, la mejor decisin con una mquina que tiene dos aos de antiguedad es el mnimo de
los dos costos.
Anlogamente,

Finalmente, en el instante inicial, se debe comprar

Usando una recursividad backward (hacia atrs) se tiene:


Nivel 5.

Nivel 4.

Lic. Carmen Mollinedo

92

Algoritmos Avanzados
Nivel 3.

Nivel 2.

Nivel 1.

Nivel 0.

El costo es de 1280, y una solucin es rematarla en los aos 1 y 2. Existen otras


soluciones ptimas, se recomienda determinarlas.
4.3.5 PROBLEMAS RESUELTOS
1. Veamos un problema simple de inversin de capital. Una corporacin tiene $5 millones
para invertir en sus tres plantas para una posible expansin. Cada planta ha presentado
un nmero de propuestas sobre como pretende gastar el dinero. Cada propuesta entrega
el costo de la expansin (c) y la ganancia esperada (r). La siguiente tabla resume las
propuestas:

Lic. Carmen Mollinedo

93

Algoritmos Avanzados

Posibilidades de Inversin
Cada planta slo podr realizar un de sus propuestas. El objetivo es maximizar el retorno
de la firma dada su inversin de $5 millones. Se supondr que si no se gastan los $5
millones completamente, ese dinero se perder.
Una forma de resolver este problema es intentar todas las posibilidades y elegir la mejor.
En ese caso, hay solo
formas de invertir el dinero. Muchas de estas
son infactibles (por ejemplo, propuestas 3, 4 y 1 para las tres plantas cuesta $6 millones).
Otras propuestas son factibles, pero son muy pobres en retorno (como propuestas 1, 1 y
2, con un retorno de slo $4 millones.)
Desventajas de una enumeracin completa:
Para problemas de gran tamao la enumeracin de todas las posibles soluciones puede
no ser factible computacionalmente.
Las combinaciones infactibles no pueden ser detectadas a priori, llevando a una
ineficiencia.
Informacin sobre combinaciones previamente investigadas no se usan para eliminar
otras combinaciones menos buenas, o infactibles.
Cabe hacer notar que este problema no puede ser formulado como un problema de
programacin lineal, porque los retornos no son funciones lineales.
Un mtodo para calcular la solucin es:
Dividamos el problema en 3 niveles: cada nivel representa el dinero asignado a una nica
planta. Asi el nivel 1 representa el dinero asignado a la planta 1. Artificialmente se dar un
orden a los niveles, asumiendo que primero se asignar a la planta 1, luego a la planta 2 y
finalmente a la planta 3.
Cada nivel est dividido en estados. Un estado guarda la informacin requerida para ir
desde un nivel al siguiente nivel.
En este caso los estados por nivel 1, 2 y 3 son:
{0,1,2,3,4,5}: cantidad de dinero gastado en la planta 1, representado como
,
{0,1,2,3,4,5}: cantidad de dinero gastado en las plantas 1 y 2 (
), y
{5}: cantidad de dinero gastado en las plantas 1, 2, y 3 (
).
Es necesario notar que diferentemente a lo que es programacin lineal, las
no
representan variables de decisin: ellas son simplemente representaciones de un estado
genrico
en
el
nivel.
Un retorno es asociado a cada estado. Se debe notar que para tomar una decisin en el
estado 3, es slo necesario conocer cuanto fue gastado en las plantas 1 y 2, no cmo
esto fue gastado. Tambin note que se desea que
sea 5 Determinando los retornos
asociados a cada estado, lo ms fcil es en el nivel 1, los estados
Tabla entrega el
retorno asociado con
.

Lic. Carmen Mollinedo

94

Algoritmos Avanzados

Clculos en el nivel 1
Ahora se pueden calcular para el nivel 2. En este caso, deseamos encontrar la mejor
solucin tanto para la planta 1 como para la planta 2. Si se desea calcular el mejor retorno
para un
dado,simplemente se analizarn todas las propuestas de la planta 2,
asignando la cantidad requerida a la planta 2 y usar la tabla anterior para ver cmo la
planta 1 gastar el excedente. Por ejemplo, supongamos que deseamos determinar la
mejor asignacin para el estado
siguientes

. En el nivel 2 se puede hacer una de las


propuestas:

Propuesta 1 da un retorno de 0, deja 4 para el nivel 1, el cual retorna 6. Total: 6.


Propuesta 2 da un retorno de 8, deja 2 para el nivel 1, el cual retorna 6. Total: 14.
Propuesta 3 da un retorno de 9, deja 1 para el nivel 1, el cual retorna 5. Total: 14.
Propuesta 4 da un retorno de 12, deja 0 para el nivel 1, el cual retorna 0. Total: 12.
Lo mejor que se puede hacer con 4 unidades es la propuesta 1 para la planta 2 y la
propuesta 2 para la planta 1, con un retorno de 14, o la propuesta 2 para la planta 2 y la
propuesta 1 para la planta 1, tambin con un retorno de 14. En cualquier caso, el retorno
para este nivel es

es 14.

El resto de la tabla se puede interpretar anlogamente. .

Clculos en el nivel 2 .
Ahora se puede analizar el nivel 3. El nico valor en el que estamos interesados
es
.
Nuevamente, se analizr todas las propuestas para este nivel, determinando la cantidad

Lic. Carmen Mollinedo

95

Algoritmos Avanzados
de dinero remanente y usando la ltima tabla para decidir el valor de los niveles previos.
Asi se puede realizar lo siguiente en la planta 3:
Propuesta1 da un retorno 0, deja 5. Niveles previos dan 17. Total: 17.
Propuesta 2 da un retorno 4, deja 4. Niveles previos dan 14. Total: 18.
De esta manera, la solucin ptima es implementar la propuesta 2 de la planta 3,
propuesta 2 o 3 en la planta 2 y la propuesta 3 o 2 (respectivamente) en la planta 1. Esto
da un retorno de 18.
Si se estudia este procedimiento, uno puede observar que los clculos son efectuados
recursivamente. Los clculos en el nivel 2 estn basados en el nivel 1, el nivel 3 slo en el
nivel 2. A su vez, estando en un estado, todas las futuras decisiones son tomadas
independientemente de como se lleg a ese estado. Este es el prinicipio de optimalidad
en el cual se sustenta la programacin dinmica.
Se pueden resumir estos clculos en las siguientes frmulas:
Sea

el retorno para la propuesta

correspondiente. Sea
siguientes clculos:

en el estado

el retorno del stado

j,y por

el costo

en el nivel j. Luego se harn los

Los clculos fueron llevados a cabo por un procedimiento forward. Sin embargo, tambin
se
calcularon
"cosas"
desde
el
ltimo
nivel
hacia
el
primero.
Se define:
= cantidad asignada a los niveles 1, 2, y 3,
= cantidad asignada a los niveles 2 y 3, y
= cantidad asignada al nivel 3.
Esto define una recursividad backward. Grficamente esto se ilustra en la Figura 1.

Lic. Carmen Mollinedo

96

Algoritmos Avanzados

Forward vs. Backward Recursividad


Las frmulas correspondientes son:
Sea

el retorno ptimo para el nivel 3, dado por

es el retorno ptimo para los niveles 2 y 3, dados por


es el retorno ptimo para los estados 1, 2 y 3 dado por
Las frmulas de recursividad son:

,y
.

y
Si lleva a cabo todos estos clculos llegar al mismo resultado.
Aunque la recursividad forward parezca ms natural, se introdujo una recursividad hacia
backward. En este caso particular l orden de los niveles no es relevante. En otros casos
puede haber ventajas computacionales en la eleccin uno versus otro orden. En general,
la recursividad backward es ms efectiva.

4.3.6 PROBLEMAS PROPUESTOS


Aplicar el algoritmo de programacin dinmica para el problema del cambio de monedas
sobre el siguiente ejemplo: n = 3, P = 9, c = (1, 3, 4). Qu ocurre si multiplicamos P y c
por un valor constante, por ejemplo por 100? Ocurre lo mismo con el algoritmo voraz?
Cmo se podra solucionar?

Lic. Carmen Mollinedo

97

Algoritmos Avanzados

El nmero de combinaciones de m objetos entre un conjunto de n, denotado por ,


m
para n 1 y 0 m n, se puede definir recursivamente por:

n
Si m = 0 m = n
= 1
m
n n 1 n 1
Si 0 < m < n
=
+

m m m 1
Conociendo que el resultado puede ser calculado tambin con la frmula:
n!/(m!(n-m)!)

Dar una funcin recursiva para calcular , usando la primera de las definiciones. Cul
m

ser el orden de complejidad de este algoritmo? Sugerencia: la respuesta es inmediata.

Disear un algoritmo de programacin dinmica para calcular . Nota: la tabla


m
construida por el algoritmo es conocida como el tringulo de Pascal. Cul ser el
tiempo de ejecucin en este caso?
Una variante del problema de la mochila es la siguiente. Tenemos un conjunto de enteros
(positivos) A = {a1, a2, ..., an} y un entero K. El objetivo es encontrar si existe algn
subconjunto de A cuya suma sea exactamente K.
Desarrollar un algoritmo para resolver este problema, utilizando programacin dinmica.
Cul es el orden de complejidad del algoritmo?
Mostrar cmo se puede obtener el conjunto de objetos resultantes (en caso de existir
solucin) a partir de las tablas utilizadas por el algoritmo.
Aplicar el algoritmo sobre el siguiente ejemplo A = {2, 3, 5, 2}, K= 7. Cmo se puede
comprobar que la solucin no es nica?
Considerar el problema del cambio de monedas. Tenemos monedas de n tipos distintos
(cada uno con valor ci), y queremos devolver una cantidad P. Dar un algoritmo, con
programacin dinmica, para calcular el nmero de formas diferentes de devolver la
cantidad P (independientemente del nmero de monedas que se use). Cul es el orden
de complejidad de este algoritmo?
Aplicar el algoritmo sobre el siguiente ejemplo: n= 4, c= {1, 3, 4, 7}, P= 7.
En el problema del cambio de monedas, en lugar de utilizar la ecuacin de recurrencia:
Cambio (i, Q) = min (Cambio(i-1, Q), Cambio(i, Q - ci)+1)
Decidimos usar la siguiente:
Cambio (i, Q) = mink=0, ..., Q/c[i] { k + Cambio (i - 1, Q - kc[i]) }
Es correcta esta ecuacin de recurrencia para encontrar la solucin? Explicar cul es el
significado de esta frmula.

Lic. Carmen Mollinedo

98

Algoritmos Avanzados
Suponiendo que modificamos el algoritmo de programacin dinmica para usar la
segunda frmula, mostrar el resultado del algoritmo para el siguiente ejemplo: n= 4, c= {1,
3, 4}, P= 7.
Estimar el orden de complejidad del algoritmo. Compararlo con el algoritmo visto en clase.
* Resolver con programacin dinmica el problema de minimizar el nmero de monedas a
devolver para dar una cantidad C si tenemos monedas de n tipos, estando los tipos de las
monedas en un array tipos: array[1,..,n] of integer, y teniendo de cada tipo una cierta
cantidad de monedas, estando estas cantidades almacenadas en un array cantidad:
array[1,..,n] of integer (de la moneda de tipo tipos[i] podemos dar una cantidad entre 0 y
cantidad[i]). No habr que programar la resolucin, pero s habr que dar la ecuacin
recurrente con la que se resuelve el problema, indicar qu tablas se utilizan y cmo se
rellenan, cmo se recompone la solucin, cules son y qu valores tienen los casos base,
y estudiar el tiempo de ejecucin.
Una agencia de turismo realiza planificaciones de viajes areos. Para ir de una ciudad A a
B puede ser necesario coger varios vuelos distintos. El tiempo de un vuelo directo de I a J
ser T[I, J] (que puede ser distinto de T[J, I]). Hay que tener en cuenta que si cogemos un
vuelo (de A a B) y despus otro (de B a C) ser necesario esperar un tiempo de escala
adicional en el aeropuerto (almacenado en E[A, B, C]).
Disear una solucin para resolver este problema utilizando programacin dinmica.
Explicar cmo, a partir de las tablas, se puede obtener el conjunto de vuelos necesarios
para hacer un viaje concreto.
Mostrar la ejecucin del algoritmo sobre la siguiente matriz T, suponiendo que todos los
E[A, B, C] tienen valor 1. Cul es el orden de complejidad del algoritmo?
T[i, j]
A
B
C
D

A
7
2
3

B
2
2
4

C
1
9
8

D
3
2
1
-

* Supongamos una serie de n trabajos denominados a, b, c, ... y una tabla B[1..n, 1..n],
en la que cada posicin B[i, j] almacena el beneficio de ejecutar el trabajo i y a
continuacin el trabajo j. Se quiere encontrar la sucesin de m trabajos que d un
beneficio ptimo. No hay lmite en el nmero de veces que se puede ejecutar un trabajo
concreto.
Idear un algoritmo por programacin dinmica que resuelva el problema. Para ello, definir
un subproblema (que permita realizar la combinacin de problemas pequeos para
resolver problemas grandes), especifica la ecuacin de recurrencia para el mismo (con
sus casos base) y despus describe las tablas necesarias y cmo son rellenadas.
Ejecutar el algoritmo sobre la siguiente tabla, suponiendo que m= 5.
B[i, j]
A
B
C

Lic. Carmen Mollinedo

a
2
4
3

b
2
1
2

c
5
3
2

99

Algoritmos Avanzados

Estimar el tiempo de ejecucin del algoritmo. El tiempo estimado es un orden exacto o


una cota superior del peor caso?
En una cierta aplicacin del problema de la mochila 0/1, los pesos de los objetos estn
definidos como valores reales. Por ejemplo, tenemos 5 objetos con pesos w = (3.32, 2.15,
2.17, 3.21, /2) y beneficios v = (10.2, 9.2, 8.3, 9.1, 6.5) y capacidad de la mochila M =
7.7. Qu problema ocurre al intentar aplicar el algoritmo de programacin dinmica?
Intenta resolverlo de alguna forma y muestra el resultado. La solucin encontrada es la
ptima?
Dada una tabla de tamao nxn de nmeros naturales, se pretende resolver el problema
de obtener el camino de la casilla (1, 1) a la casilla (n, n) que minimice la suma de los
valores de las casillas por las que pasa. En cada casilla (i, j) habrn slo dos posibles
movimientos: ir hacia abajo (i+1, j), o hacia la derecha (i, j+1).
Resolver el problema utilizando programacin dinmica. Indica la ecuacin de recurrencia
usada, con los casos base necesarios, las tablas para llegar a la solucin ptima y para
recomponer el camino correspondiente a esa solucin ptima.
Mostrar la ejecucin del algoritmo sobre la siguiente entrada.
2
5
1
3

8
3
2
4

3
4
2
6

4
5
1
5

Formular el principio de optimalidad de Bellman sobre este problema y comprobar si se


cumple.
Los algoritmos de divide y vencers y los de programacin dinmica se basan en la
resolucin de un problema en base a subproblemas. Usando las mismas ecuaciones de
recurrencia de los problemas vistos en el tema 5 (cambio de monedas, mochila 0/1 y
multiplicacin encadenada de matrices), disear algoritmos que resuelvan esos
problemas pero con divide y vencers. Compara la complejidad obtenida con los dos tipos
de algoritmos.
En los dos primeros casos, por qu los algoritmos no son comparables (al menos de
forma directa) con los algoritmos voraces correspondientes?
En el algoritmo para el cambio de monedas visto en clase, es posible que al acabar de
ejecutarse obtengamos que D[n, P] = +? En caso afirmativo, qu indica esta situacin?
Mustralo con un ejemplo. En caso contrario, por qu no es posible esa situacin?
* Considerar el siguiente problema: dado un conjunto de nmeros enteros X = {x1, x2, ...,
xn} y otro entero P, queremos encontrar si existe algn subconjunto {y1, ..., yk} de X, tal
que P = y1*y2*...*yk.
Resolver el problema utilizando programacin dinmica. No es necesario programar el
algoritmo, habr que dar una ecuacin recurrente para resolver el problema, con los
casos base, indicar cmo son las tablas que se deben utilizar y la forma de rellenarlas.
A partir de las tablas, mostrar cmo podemos saber si existe tal conjunto o no, y en caso
de existir cmo se puede obtener el conjunto solucin {y1, y2, ..., yk}.
Hacer una estimacin del orden de complejidad del algoritmo.
Lic. Carmen Mollinedo

100

Algoritmos Avanzados
Ejecutar sobre el siguiente ejemplo: X= {2, 4, 3, 9, 10}, P= 18.
Nota: tener en cuenta que el problema no es de optimizacin, sino de encontrar si existe
una solucin o no.
En el problema de la mochila (igual que en el problema del cambio de monedas) puede
existir en general ms de una solucin ptima para unas entradas determinadas. Cmo
se puede comprobar si una solucin ptima es nica o no, suponiendo que hemos
resuelto el problema utilizando programacin dinmica? Dar un algoritmo para que, a
partir de las tablas resultantes del problema de la mochila, muestre todas las soluciones
ptimas existentes.
En el problema de la multiplicacin encadenada de matrices, la tabla deba ser rellenada
por diagonales, empezando por la diagonal 1 hasta la n. Especificar de forma ms
detallada (en notacin Pascal) cmo se podra implementar el rellenado de la tabla para
que los clculos fueran realizados en este orden. Ejecutar sobre el siguiente ejemplo, n =
6, tamaos d = (23, 40, 2, 20, 6, 40, 12).
Un play off por el descenso se juega al mejor de 2n-1 partidos. Los dos equipos juegan
varios partidos hasta que uno gane n encuentros. Ese equipo ser el que permanece y el
otro desciende a 3 regional. Supongamos que se enfrentan Real Murcia y Las Palas. Si
en un momento dado el Real Murcia ha ganado i partidos y perdido j, queremos calcular
la probabilidad de que permanezca que llamaremos P(i, j). Suponer que la probabilidad de
que el Real Murcia gane un partido es 0.3 y la probabilidad de que pierda 0.7 (no
posibilidad de empate).
Aplicarla tcnica de programacin dinmica para resolver este problema. Para ello, definir
la ecuacin de recurrencia de P(i, j) (con sus casos base), la estructura de las tablas
utilizadas y la forma de rellenarlas. Idea: dada la situacin (i partidos ganados, j partidos
perdidos) considerar qu puede ocurrir en el siguiente partido. Tener en cuenta que si uno
llega a n entonces se acaba la competicin.
* Usando la frmula recursiva para el problema de la mochila 0/1 (vista en clase, en
programacin dinmica), escribe un procedimiento que resuelva el problema pero con
divide y vencers. El cuerpo del procedimiento debe ser:
Mochila(i: entero; M: entero; v, w: array[1..n] of entero):entero;
Siendo:
i = Nmero de objetos a usar (desde 1 hasta i). M = Capacidad de la mochila.
v, w = Beneficio y peso de los objetos. Valor devuelto = Beneficio ptimo.
* Un sistema dispone de m procesadores (P1, P2, ..., Pm), que deben ejecutar un conjunto
de n tareas distintas (T1, T2, ..., Tn), disponibles en el instante inicial. De cada tarea se
conoce el nmero de instrucciones que ejecuta ti (se supone que todas las instrucciones
requieren el mismo tiempo), y de cada procesador se tiene su velocidad de procesamiento
vi, en nmero de instrucciones por segundo. Se supone que cada procesador ejecuta las
tareas de manera secuencial, es decir sin partirlas.
El objetivo consiste en dar una planificacin que minimice el tiempo medio de finalizacin
de las tareas. Una planificacin consistir en asignar cada tarea a un procesador, y en un
orden determinado. El tiempo medio de finalizacin ser la media de los tiempos que cada
tarea tiene que esperar, desde el instante inicial hasta que acaba de ejecutarse.

Lic. Carmen Mollinedo

101

Algoritmos Avanzados
Dar una buena solucin para el problema, usando la tcnica que creas ms adecuada de
entre las siguientes: divide y vencers, algoritmos voraces o programacin dinmica. Se
pide explicar el funcionamiento del algoritmo y dar un esquema en pseudocdigo de su
estructura.
Ejecutar el algoritmo diseado sobre el siguiente ejemplo: m= 3, n= 6,
t= (35, 40, 20,
25, 10, 50), v= (5, 1, 10).
Hacer una estimacin del orden de complejidad del algoritmo.
El algoritmo diseado, obtiene siempre la solucin ptima?
* Un sistema de ecuaciones sobredeterminado (con muchas ms ecuaciones m que
incgnitas n), puede expresarse matricialmente como: AX = B, siendo:
A (mxn): matriz de coeficientes,
X (nx1): vector de incgnitas,
B (mx1): vector de trminos independientes.
La solucin de mnimos cuadrados puede calcularse con:
X = (ATA)-1ATB
Encuentra todos los posibles rdenes en los que se pueden hacer las multiplicaciones
matriciales para calcular X. Para cada uno de ellos, estima el nmero de productos
escalares necesario, en funcin de m y de n. Se supone que se usa el mtodo clsico de
multiplicacin de matrices (y no el mtodo de Strassen). No es necesario contar las
operaciones necesarias para el clculo de la inversa o de la transpuesta.
Cul es el orden ptimo para calcular X? Compara el valor anterior con el nmero de
multiplicaciones requeridas en otro orden que no sea ptimo. Qu se puede decir, en
cuanto al tiempo de ejecucin y al orden de complejidad (el orden O(..) y la o-pequea)?

Lic. Carmen Mollinedo

102

Algoritmos Avanzados

4.4 BACKTRACKING - VUELTA ATRS


4.4.1 INTRODUCCIN
Los algoritmos de vuelta atrs se utilizan para encontrar soluciones a un problema. No
siguen unas reglas para la bsqueda de la solucin, simplemente una bsqueda
sistemtica, que ms o menos viene a significar que hay que probar todo lo posible hasta
encontrar la solucin o encontrar que no existe solucin al problema. Para conseguir este
propsito, se separa la bsqueda en varias bsquedas parciales o subtareas. Asimismo,
estas subtareas suelen incluir ms subtareas, por lo que el tratamiento general de estos
algoritmos es de naturaleza recursiva.
Por qu se llaman algoritmos de vuelta atrs?. Porque en el caso de no encontrar una
solucin en una subtarea se retrocede a la subtarea original y se prueba otra cosa distinta
(una nueva subtarea distinta a las probadas anteriormente).
Puesto que a veces nos interesa conocer mltiples soluciones de un problema, estos
algoritmos se pueden modificar fcilmente para obtener una nica solucin (si existe) o
todas las soluciones posibles (si existe ms de una) al problema dado.
Los algoritmos de vuelta atrs tienen un esquema genrico, segn se busque una o todas
las soluciones, y puede adaptarse fcilmente segn las necesidades de cada problema
4.4.2 ESQUEMA PARA UNA SOLUCIN
procedimiento ensayar (paso : TipoPaso)
repetir
seleccionar_candidato
if factible then
begin
anotar_candidato
if solucion_incompleta then
begin
ensayar(paso_siguiente)
if no acertado then borrar_candidato
end
else begin
anotar_solucion
acertado <- cierto;
end
hasta que (acertado = cierto) o
(candidatos_agotados)
fin procedimiento

Lic. Carmen Mollinedo

102

Algoritmos Avanzados

4.4.3 ESQUEMA PARA TODAS LAS SOLUCIONES


procedimiento ensayar (paso : TipoPaso)
para cada candidato hacer
seleccionar candidato
if factible then
begin
anotar_candidato
if solucion_incompleta then
ensayar(paso_siguiente)
else
almacenar_solucion
borrar_candidato
end
hasta que candidatos_agotados
fin procedimiento

Por ltimo, se exponen una serie de problemas tpicos que se pueden resolver fcilmente
con las tcnicas de vuelta atrs. El primero que se expone es muy conocido. Se trata de
la vuelta del caballo. Muchos problemas de los pasatiempos de los peridicos pueden
resolverse con la ayuda de un ordenador y en esta web se muestran algunos de ellos.
4.4.4 EJEMPLOS
Ejemplo 1. LA VUELTA DEL CABALLO
Se dispone de un tablero rectangular, por ejemplo el tablero de ajedrez, y de un caballo,
que se mueve segn las reglas de este juego. El objetivo es encontrar una manera de
recorrer todo el tablero partiendo de una casilla determinada, de tal forma que el caballo
pase una sola vez por cada casilla. Una variante es obligar al caballo a volver a la
posicin de partida en el ltimo movimiento. Por ltimo se estudiar como encontrar todas
las soluciones posibles partiendo de una misma casilla.
Para resolver el problema hay que realizar todos los movimientos posibles hasta que ya
no se pueda avanzar, en cuyo caso hay que dar marcha atrs, o bien hasta que se cubra
el tablero. Adems, es necesario determinar la organizacin de los datos para
implementar el algoritmo.
Cmo se mueve un caballo?. Para aquellos que no sepan
jugar al ajedrez se muestra un grfico con los ocho
movimientos que puede realizar. Estos movimientos sern
los ocho candidatos.
Con las coordenadas en las que se encuentre el caballo y las
ocho coordenadas relativas se determina el siguiente
movimiento.

Las coordenas relativas se guardan en dos arrays:


ejex = [2, 1, -1, -2, -2, -1, 1, 2]
ejey = [1, 2, 2, 1, -1, -2, -2, -1]

Lic. Carmen Mollinedo

103

Algoritmos Avanzados
El tablero, del tamao que sea, se representar mediante un array bidimensional de
nmeros enteros. A continuacin se muestra un grfico con un tablero de tamao 5x5 con
todo el recorrido partiendo de la esquina superior izquierda.
Cuando se encuentra una solucin, una variable que se
pasa por referencia es puesta a 1 (cierto). Puede hacerse
una variable de alcance global y simplificar un poco el
cdigo, pero esto no siempre es recomendable.
Para codificar el programa, es necesario considerar
algunos aspectos ms, entre otras cosas no salirse de los
lmites del tablero y no pisar una casilla ya cubierta
(seleccin del candidato). Se determina que hay solucin
cuando ya no hay ms casillas que recorrer.
A continuacin se expone un cdigo completo en C, que
recubre un tablero cuadrado de lado N partiendo de la
posicin (0,0).
#include <stdio.h>
#define N 5
#define ncuad N*N
void mover(int tablero[][N], int i, int pos_x, int pos_y, int *q);
const int ejex[8] = { -1,-2,-2,-1, 1, 2, 2, 1 },
ejey[8] = { -2,-1, 1, 2, 2, 1,-1,-2 };
int main(void)
{
int tablero[N][N]; /* tablero del caballo. */
int i,j,q;
/* inicializa el tablero a cero */
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
tablero[i][j] = 0;
/* pone el primer movimiento */
tablero[0][0] = 1;
mover(tablero,2,0,0,&q);
if (q) { /* hay solucion: la muestra. */
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
printf("%3d ", tablero[i][j]);
putchar('\n');
}
}
else
printf("\nNo existe solucion\n");

Lic. Carmen Mollinedo

104

Algoritmos Avanzados
return 0;
}
void mover(int tablero[][N],int i, int pos_x, int pos_y, int *q)
{
int k, u, v;
k = 0;
*q = 0;
do {
u = pos_x + ejex[k]; v = pos_y + ejey[k]; /* seleccionar
candidato */
if (u >= 0 && u < N && v >= 0 && v < N) { /* esta dentro de
los limites? */
if (tablero[u][v] == 0) { /* es valido? */
tablero[u][v] = i; /* anota el candidato */
if (i < ncuad) { /* llega al final del recorrido? */
mover(tablero,i+1,u,v,q);
if (!*q) tablero[u][v] = 0; /* borra el candidato */
}
else *q = 1; /* hay solucion */
}
}
k++;
} while (!*q && k < 8);
}
Cambiando el valor de N puede obtenerse una solucin para un tablero cuadrado de
tamao N.
A continuacin, se muestra una adaptacin del procedimiento que muestra todas las
soluciones. Si se ejecuta para N = 5 se encuentra que hay 304 soluciones partiendo de la
esquina superior izquierda. Cuando se encuentra una solucin se llama a un
procedimiento (no se ha codificado aqu) que imprime todo el tablero.
void mover(int tablero[][N],int i, int pos_x, int pos_y)
{
int k, u, v;
for (k = 0; k < 8; k++) {
u = pos_x + ejex[k]; v = pos_y + ejey[k];
if (u >= 0 && u < N && v >= 0 && v < N) { /* esta dentro de los
limites */
if (tablero[u][v] == 0) {
tablero[u][v] = i;
if (i < ncuad)
mover(tablero,i+1,u,v);
else imprimir_solucion(tablero);
tablero[u][v] = 0;
}
}
}
}

Lic. Carmen Mollinedo

105

Algoritmos Avanzados

Ejemplo 2.EL PROBLEMA DE LAS OCHO REINAS


Continuamos con problemas relacionados con el ajedrez. El problema que ahora se
plantea es claramente, como se ver, de vuelta atrs. Se recomienda intentar resolverlo a
mano.
Se trata de colocar ocho reinas sobre un tablero de ajedrez, de tal forma que ninguna
amenace (pueda comerse) a otra. Para los que no sepan ajedrez deben saber que una
reina amenaza a otra pieza que est en la misma columna, fila o cualquiera de las cuatro
diagonales.
La dificultad que plantea este problema es la representacin de los datos. Se puede
utilizar un array bidimensional de tamao 8x8, pero las operaciones para encontrar una
reina que amenace a otra son algo engorrosas y hay un truco para evitarlas. La solucin
aqu expuesta vuelve a ser tomada de Wirth
Es lgico que cada reina debe ir en una fila distinta. Por tanto, en un array se guarda la
posicin de cada reina en la columna que se encuentre. Ejemplo: si en la tercera fila hay
una reina situada en la quinta columna, entonces la tercera posicin del array guardar un
5. A este array se le llamar col. Hace falta otro array que determine si hay puesta una
reina en la fila j-sima. A este array se le llamar fila. Por ltimo se utilizan dos arrays
ms para determinar las diagonales libres, y se llamarn diagb y diagc.
Para poner una reina se utiliza esta instruccin:
col[i] = j ; fila[j] = diagb[i+j] = diagc[7+i-j] = FALSE;
Para quitar una reina esta otra:
fila[j] = diagb[i+j] = diagc[7+i-j] = TRUE;

Se considera vlida la posicin para este caso:


if (fila[j] && diagb[i+j] && diagc[7+i-j]) entonces proceder ...

A continuacin se expone el cdigo completo en C. Se han utilizado tipos enumerados


para representar los valores booleanos.
#include <stdio.h>
enum bool {FALSE, TRUE};
typedef enum bool boolean;
void ensayar(int i, boolean *q, int col[], boolean fila[], boolean
diagb[], boolean diagc[]);
int main(void)
{
int i;
boolean q;

Lic. Carmen Mollinedo

106

Algoritmos Avanzados
int col[8];
boolean fila[8],diagb[15], diagc[15];
for (i = 0; i < 8; i++) fila[i] = TRUE;
for (i = 0; i < 15; i++) diagb[i] = diagc[i] = TRUE;
ensayar(0,&q,col,fila,diagb,diagc);
if (q) {
printf("\nSolucion:");
for (i = 0; i < 8; i++) printf(" %d", col[i]);
} else printf("\nNo hay solucion");
return 0;
}
void ensayar(int i, boolean *q, int col[], boolean fila[], boolean
diagb[], boolean diagc[])
{
int j;
j = 0;
*q = FALSE;
do {
if (fila[j] && diagb[i+j] && diagc[7+i-j]) {
col[i] = j; fila[j] = diagb[i+j] = diagc[7+i-j] = FALSE;
if (i < 7) { /* encuentra solucion? */
ensayar(i+1,q,col,fila,diagb,diagc);
if (!*q)
fila[j] = diagb[i+j] = diagc[7+i-j] = TRUE;
} else *q = TRUE; /* encuentra la solucion */
}
j++;
} while (!*q && j < 8);
}
Por ltimo, se deja al lector que implemente un procedimiento que encuentre todas las
soluciones. Si se desea complicar ms entonces se puede pedir que encuentre todas las
soluciones distintas, es decir, aquellas que no sean rotaciones o inversiones de otras
soluciones.
Ahora que se conoce el mtodo general, puede hacerse extensible a mltiples piezas
simultneamente.
Ejemplo 3 EL PROBLEMA DE LA MOCHILA (SELECCIN PTIMA)
Con anterioridad se ha estudiado la posibilidad de encontrar una nica solucin a un
problema y la posibilidad de encontrarlas todas. Pues bien, ahora se trata de encontrar la
mejor solucin, la solucin ptima, de entre todas las soluciones.
Partiendo del esquema que genera todas las soluciones expuesto anteriormente se puede
obtener la mejor solucin (la solucin ptima, seleccionada entre todas las soluciones) si
se modifica la instruccin almacenar_solucion por esta otra: si f(solucin) > f(optimo)

Lic. Carmen Mollinedo

107

Algoritmos Avanzados
entonces optimo <- solucin siendo f(s) funcin positiva, optimo es la mejor solucin
encontrada hasta el momento, y solucin es una solucin que se est probando.
El problema de la mochila consiste en llenar una mochila con una serie de objetos que
tienen una serie de pesos con un valor asociado. Es decir, se dispone de n tipos de
objetos y que no hay un nmero limitado de cada tipo de objeto (si fuera limitado no
cambia mucho el problema). Cada tipo i de objeto tiene un peso wi positivo y un valor vi
positivo asociados. La mochila tiene una capacidad de peso igual a W. Se trata de llenar
la mochila de tal manera que se maximice el valor de los objetos incluidos pero
respetando al mismo tiempo la restriccin de capacidad. Notar que no es obligatorio que
una solucin ptima llegue al lmite de capacidad de la mochila.
Ejemplo: se supondr:
n=4
W=8
w() = 2, 3, 4, 5
v() = 3, 5, 6, 10
Es decir, hay 4 tipos de objetos y la mochila tiene una capacidad de 8. Los pesos varan
entre 2 y 5, y los valores relacionados varan entre 3 y 10.
Una solucin no ptima de valor 12 se obtiene introduciendo cuatro objetos de peso 2, o 2
de peso 4. Otra solucin no ptima de valor 13 se obtiene introduciendo 2 objetos de peso
3 y 1 objeto de peso 2. Cul es la solucin ptima?.
A continuacin se muestra una solucin al problema, variante del esquema para obtener
todas las soluciones.
void mochila(int i, int r, int solucion, int *optimo)
{
int k;
for (k = i; k < n; k++) {
if (peso[k] <= r) {
mochila(k, r - peso[k], solucion + valor[k], optimo);
if (solucion + valor[k] > *optimo) *optimo =
solucion+valor[k];
}
}
}
Dicho procedimiento puede ser ejecutado de esta manera, siendo n, W, peso y valor
variables globales para simplificar el programa:
n = 4,
W = 8,
peso[] = {2,3,4,5},
valor[] = {3,5,6,10},
optimo = 0;
...
mochila(0, W, 0, &optimo);
Observar que la solucin ptima se obtiene independientemente de la forma en que se
ordenen los objetos.

Lic. Carmen Mollinedo

108

Algoritmos Avanzados

5 ALGORITMOS PROBABILISTAS
5.1 INTRODUCCIN
Existen muchos problemas en los que llegado a cierto punto, se ha de tomar una
decisin ptima. A menudo, la bsqueda de esta decisin toma un tiempo excesivo
A veces es mejor no tomar esta decisin ptima, sino tomar una buena decisin
En algunas ocasiones tomar decisiones aleatorias nos puede llevar a la solucin
deseada
En trminos de la Teora de Algoritmos: cuando se tenga que realizar una eleccin en
un algoritmo, a veces es preferible hacerlo aleatoriamente en vez de perder tiempo en
decidir cul de las posibles alternativas es la correcta
Esta eleccin aleatoria debe se, en promedio, ms eficiente que la decisin, aunque en
algn caso el proceso aleatorio tome, por mala suerte, ms tiempo
En estos casos hablamos de tiempo esperado de ejecucin y no de orden de
complejidad
En este tema se vern algoritmos que, basados en la Teora de la Probabilidad,
encuentran una solucin aproximada o una solucin exacta (aunque a veces no la
encuentran o dan una solucin errnea)

5.2 CLASIFICACIN
PROBABILISTAS:

DE

LOS

ALGORITMOS

Numricos: solucin aproximada


Monte Carlo: solucin exacta; pero a veces se equivocan
Las Vegas: nunca devuelven una solucin errnea, pero a veces no la
encuentran
Sherwood: siempre encuentran la solucin y siempre es correcta
Cada uno de ellos se debe aplicar bajo ciertas condiciones especficas y todos buscan
soluciones de destina forma e incluso encuentran (a veces no) distinto tipo de soluciones

5.3 GENERADORES DE NMEROS ALEATORIOS


No se puede definir un nmero como aleatorio por si mismo
Lo que si se pueden definir son series de nmeros aleatorios: cuando, de entre
un rango de valores posibles, la distribucin de los nmeros de la serie es
uniforme
Encontrar un mtodo que nos permita obtener series de nmeros aleatorios en
un ordenador es una tarea difcil, pero no lo es obtener series de nmeros
pseudoaleatorios: nmeros que a todo el mundo le parezcan aleatorios excepto al
programador que sabe el mtodo

Lic. Carmen Mollinedo

109

Algoritmos Avanzados

5.3.1. Propiedades que deben cumplir las series de nmeros aleatorios:


_

Los nmeros han de estar uniformemente distribuidos


Han de ser estadsticamente independientes
Han de ser reproducibles
Que requieran poco espacio en memoria
Que se obtengan rpidamente
Ejemplo Para obtener series de nmeros pseudoaleatorios. Ejemplo simple:
escoger un nmero de n cifras, elevarlo al cuadrado, coger las k cifras centrales
del resultado obtenido, siendo stas el siguiente nmero de la serie.
Para n=k=4:

Este mtodo no tiene nada de aleatorio, pero lo parece. No tiene ninguna


propiedad aceptable, ya que no se puede comprobar absolutamente nada, por lo
que es impredecible cundo comenzarn a repetirse los nmeros (comenzar con
el 2500)
Una serie de nmeros es aleatoria cuando no se descubre en ella ninguna
propiedad: de crecimiento, repeticin, siguiente, etc.

5.3.2 Definicin de Lehmer de serie de nmeros pseudoaleatoria:


nocin vaga que encierra la idea de una sucesin de nmeros en la que cada trmino es
impredecible para la persona ajena al problema y cuyos dgitos se someten a un cierto
nmero de pruebas estadsticas

5.3.3 Generacin de nmeros aleatorios:


los mtodos ms comunes son los llamados mtodos congruenciales. El ms famoso es
el de Lehmer, en el cual se utilizan tres datos segn la frmula:

Tipos de generacin de nmeros aleatorios:


_ Generador congruencial mixto: aquel en el que c _ 0
_ Generador congruencial multiplicativo: aquel en el que c = 0

Lic. Carmen Mollinedo

110

Algoritmos Avanzados
Diferencias: los multiplicativos son ms rpidos, aunque tienen una menor longitud de
ciclo
Propiedades del generador de esta naturaleza: fcilmente reproducible (comenzando por
la misma semilla), se obtiene rpidamente y ocupa poco espacio de memoria. Hay que
esforzarse en conseguir que cumpla tambin las dos primeras propiedades: uniformidad e
independencia
Teorema: La sucesin congruencial definida por X0, a, c y m es de
perodo mximo si y slo si:
C es primo relativo a m (su mximo comn divisor es 1)
a-1 es mltiplo de p, p primo que divida a m
a-1 es mltiplo de 4 si m es mltiplo de 4
Ejemplo: a = 21, c = 27 y m = 20
Generador que cumple las 5 reglas: el propuesto por Lehmer:
a = 48.271; c = 0; m = 231 1 = 2.147.483.647
Problema: produce overflow con algunos valores
Solucin: Reducir la expresin a:

donde Q = m div a, R = m mod a y f(m) = 0 si la suma de los dos primeros sumandos de la


frmula es mayor o igual que 0 y f(m) = m en caso contrario

5.4 ALGORITMOS MONTECARLO


En contraposicin a los algortimos numricos, los algoritmos MonteCarlo siempre
encuentran soluciones exactas, aunque a veces se equivocan
La caracterstica ms importante de estos algoritmos es que suele ser posible reducir
arbitrariamente la probabilidad de error a costa de un ligero aumento del tiempo de clculo
La precisin de la respuesta va en funcin del tiempo de ejecucin, por lo que su
eficiencia estar en orden inverso a su precisin

Lic. Carmen Mollinedo

111

Algoritmos Avanzados
El objetivo de estos algoritmos es que en sucesivas llamadas a la rutina principal, se
rebaje la probabilidad de error
Nunca se debe dar como vlido un algoritmo MonteCarlo que falle
siempre para una misma instancia de un problema

5.4.1 DEFINICINES
o Algoritmo MonteCarlo p-correcto, (con < p < 1): algoritmo que devuelve una
solucin correcta con una probabilidad no menor que p sea cual sea el caso
considerado
o Algoritmo MonteCarlo consistente: devuelve siempre la misma solucin correcta
para la misma entrada
Los algoritmos resultantes de aplicar la tcnica MonteCarlo son extremadamente
simples y eficientes

Lic. Carmen Mollinedo

112

You might also like