You are on page 1of 26

Prlogo

Antes de que existieran las computadoras, existan


algoritmos. Pero ahora que hay computadoras, hay an ms
algoritmos, y los algoritmos estn en el corazn de la
computacin. Este libro proporciona una introduccin
completa al estudio moderno de los algoritmos informticos.
Presenta muchos algoritmos y los cubre con una profundidad
considerable, pero hace que su diseo y anlisis sean
accesibles a todos los niveles de lectores. Hemos tratado de
mantener las explicaciones elementales sin sacar la
profundidad de la cobertura o el rigor matemtico.
Cada captulo presenta un algoritmo, una tcnica de diseo,
un rea de aplicacin o un tema relacionado. Los algoritmos
se describen en ingls y en un pseudocdigo diseado para
ser ledo por cualquiera que haya hecho un poco de
programacin. El libro contiene 244 figuras, muchas con
mltiples partes, que ilustran cmo funcionan los
algoritmos. Puesto que enfatizamos la eficacia como criterio
de diseo, incluimos anlisis cuidadosos de los tiempos de
ejecucin de todos nuestros algoritmos.
El texto est pensado principalmente para su uso en cursos
de licenciatura o postgrado en algoritmos o estructuras de
datos. Debido a que discute temas de ingeniera en el diseo
de algoritmos, as como aspectos matemticos, es
igualmente adecuado para el autoestudio por parte de
profesionales tcnicos.
En esta tercera edicin hemos vuelto a actualizar todo el
libro. Los cambios abarcan un amplio espectro, incluyendo
nuevos captulos, pseudocdigo revisado y un estilo de
escritura ms activo.

Al profesor
Hemos diseado este libro para que sea verstil y completo.
Debe ser til para una variedad de cursos, desde un curso de
licenciatura en estructuras de datos hasta un curso de
postgrado en algoritmos. Debido a que hemos
proporcionado mucho ms material del que se puede
proporcionar en un curso tpico de un trimestre, puedes
considerar este libro como un "buffet" o "smorgasbord" del
cual puedes escoger y elegir el material que mejor apoye el
curso que deseas ensear.
Es fcil organizar su curso en torno a los captulos que
necesite. Hemos hecho captulos relativamente
autosuficientes, de modo que no tiene que preocuparse por
una dependencia inesperada e innecesaria de un captulo a
otro. Cada captulo presenta el primer material ms fcil y el
material ms difcil ms tarde, con lmites de seccin
marcando los puntos de parada naturales. En un curso de
pregrado, usted podra usar solamente las secciones
anteriores de un captulo; en un curso de postgrado, usted
podra cubrir todo el captulo. Hemos incluido 957 ejercicios
y 158 problemas. Cada seccin termina con ejercicios y cada
captulo termina con problemas. Los ejercicios son
generalmente preguntas cortas que prueban el dominio
bsico del material. Algunos son simples ejercicios de
pensamiento de autocomprobacin, mientras que otros son
ms sustanciales y adecuados como tarea asignada. Los
problemas son casos de estudio ms elaborados que a
menudo introducen nuevo material; a menudo consisten en
varias preguntas que llevan al estudiante a travs de los
pasos requeridos para llegar a una solucin. Partiendo de
nuestra prctica en ediciones anteriores de este libro, hemos
puesto a disposicin del pblico soluciones a algunos, pero
de ninguna manera a todos los problemas y ejercicios.
Nuestro sitio web, http://mitpress.mit.edu/algorithms/,
enlaza con estas soluciones. Usted querr comprobar este
sitio para asegurarse de que no contiene la solucin a un
ejercicio o problema que usted planea asignar. Esperamos
que el conjunto de soluciones que publicamos crezca
lentamente con el tiempo, por lo que tendr que comprobarlo
cada vez que imparta el curso.
Hemos protagonizado (?) las secciones y ejercicios ms
adecuados para estudiantes de postgrado que para
estudiantes universitarios. Una seccin con estrellas no es
necesariamente ms difcil que una seccin sin estrellas,
pero puede requerir un entendimiento de matemticas ms
avanzadas. Del mismo modo, los ejercicios con estrellas
pueden requerir un fondo avanzado o una creatividad
superior a la media.

Al estudiante
Esperamos que este libro de texto le proporcione una
introduccin agradable al campo de los algoritmos. Hemos
intentado hacer que cada algoritmo sea accesible e
interesante. Para ayudarle a encontrar algoritmos
desconocidos o difciles, describimos cada uno de ellos paso
a paso. Tambin proporcionamos explicaciones cuidadosas
de las matemticas necesarias para entender el anlisis de los
algoritmos. Si usted ya tiene alguna familiaridad con un
tema, encontrar los captulos organizados para que pueda
hojear secciones introductorias y proceder rpidamente al
material ms avanzado.
Este es un libro grande, y su clase probablemente cubrir
slo una parte de su material. Hemos tratado, sin embargo,
de hacer de este libro un libro que le ser til ahora como
libro de texto del curso y tambin ms tarde en su carrera
como una referencia de escritorio matemtico o un manual
de ingeniera.
Cules son los requisitos previos para leer este libro?
Deberas tener experiencia en programacin. En particular,
debe comprender los procedimientos recursivos y las
estructuras de datos sencillas, como matrices y listas
enlazadas.
Usted debe tener alguna facilidad con pruebas matemticas,
y especialmente pruebas por induccin matemtica. Algunas
porciones del libro se basan en algn conocimiento de
clculo elemental. Ms all de eso, las Partes I y VIII de este
libro te ensean todas las tcnicas matemticas que
necesitars.
Hemos escuchado, alto y claro, el llamamiento a aportar
soluciones a los problemas y ejercicios. Nuestro sitio web,
http://mitpress.mit.edu/algorithms/, contiene enlaces a
soluciones para algunos de los problemas y ejercicios.
Sintase libre de comparar sus soluciones con las nuestras.
Sin embargo, le pedimos que no nos enve sus soluciones.
Al profesional
La amplia gama de temas de este libro lo convierte en un
excelente manual sobre algoritmos. Debido a que cada
captulo es relativamente autnomo, usted puede enfocarse
en los temas que ms le interesan.
La mayora de los algoritmos que discutimos tienen una gran
utilidad prctica. Por lo tanto, abordamos los problemas de
implementacin y otras cuestiones de ingeniera. A menudo
proporcionamos alternativas prcticas a los pocos
algoritmos que son principalmente de inters terico. Si
usted desea implementar cualquiera de los algoritmos,
debera? y la traduccin de nuestro pseudocode a su lenguaje
de programacin favorito debera ser una tarea bastante
sencilla. Hemos diseado el pseudocdigo para presentar
cada algoritmo de forma clara y sucinta. En consecuencia,
no abordamos el manejo de errores y otros problemas de
ingeniera de software que requieren suposiciones
especficas sobre su entorno de programacin. Intentamos
presentar cada algoritmo de forma simple y directa sin
permitir que las idiosincrasias de un lenguaje de
programacin en particular oscurezcan su esencia.
Entendemos que, si usted est usando este libro fuera de un
curso, es posible que no pueda comparar sus soluciones a los
problemas y ejercicios con las soluciones proporcionadas
por un instructor. Nuestro sitio web,
http://mitpress.mit.edu/algorithms/, enlaza con las
soluciones a algunos de los problemas y ejercicios para que
pueda comprobar su trabajo. Por favor, no nos enve sus
soluciones.

A nuestros colegas
Hemos suministrado una extensa bibliografa e indicadores
a la literatura actual. Cada captulo termina con un conjunto
de notas de captulo que dan detalles histricos y erencias.
Sin embargo, las notas del captulo no proporcionan una
referencia completa al conjunto de algoritmos. Aunque
puede ser difcil de creer para un libro de este tamao, las
limitaciones de espacio nos impidieron incluir muchos
algoritmos interesantes. A pesar de las innumerables
peticiones de los estudiantes para encontrar soluciones a los
problemas y ejercicios, hemos optado por la poltica de no
proporcionar referencias para problemas y ejercicios, para
eliminar la tentacin de que los estudiantes busquen una
solucin en lugar de buscarla ellos mismos.

Cambios para la tercera edicin


Qu ha cambiado entre la segunda y tercera edicin de este
libro? La magnitud de los cambios est a la par con los
cambios entre la primera y segunda edicin. Como dijimos
sobre los cambios de la segunda edicin, dependiendo de
cmo lo mires, el libro cambi poco o bastante.
Un vistazo al ndice de contenidos muestra que la mayora
de los captulos y secciones de la segunda edicin aparecen
en la tercera edicin. Hemos eliminado dos captulos y una
seccin, pero hemos aadido tres nuevos captulos y dos
nuevas secciones aparte de estos nuevos captulos.
Guardamos la organizacin hbrida de las primeras dos
ediciones. En lugar de organizar los captulos slo por temas
problemticos o segn tcnicas, este libro tiene elementos de
ambos. Contiene captulos tcnicos basados en divide-and-
conquer, programacin dinmica, algoritmos codiciosos,
anlisis amortizado, NP-Completitud y algoritmos de
aproximacin. Pero tambin tiene partes enteras sobre
ordenacin, sobre estructuras de datos para conjuntos
dinmicos y sobre algoritmos para problemas de grficos. Y
aunque usted necesita saber cmo aplicar tcnicas para
disear y analizar algoritmos, los problemas raramente le
anuncian qu tcnicas son las ms adecuadas para
resolverlos.
He aqu un resumen de los cambios ms significativos para
la tercera edicin:
Aadimos nuevos captulos sobre los rboles van Emde
Boas y algoritmos multithreaded, y hemos desarollado
material sobre las bases de la matriz en su propio captulo
del apndice.
Revisamos el captulo sobre las recurrencias para cubrir ms
ampliamente la tcnica de divisin y conquista, y sus dos
primeras secciones aplican la divisin y conquista para
resolver dos problemas. La segunda seccin de este captulo
presenta el algoritmo de Strassen para la multiplicacin
matricial, que hemos desplazado del captulo sobre
operaciones matriciales.
Quitamos dos captulos que rara vez se enseaban: las pilas
binomiales y las redes de clasificacin. Una idea clave en el
captulo de clasificacin de redes, el principio 0-1, aparece
en esta edicin dentro del Problema 8-7 como el lema de
clasificacin 0-1 para algoritmos de comparacin e
intercambio. El tratamiento de los heaps de Fibonacci ya no
se basa en heaps binomiales como precursor.
Hemos revisado nuestro tratamiento de la programacin
dinmica y los algoritmos codiciosos. La programacin
dinmica da paso ahora a un problema ms interesante, el
corte de varillas, que el problema de la programacin en
cadena de montaje de la segunda edicin. Adems,
enfatizamos un poco ms la memorizacin que en la segunda
edicin, e introducimos la nocin de grfico de subproblema
como una forma de entender el tiempo de ejecucin de un
algoritmo de programacin dinmica. En nuestro ejemplo
inicial de algoritmos codiciosos, el problema de seleccin de
actividad, llegamos al algoritmo codicioso ms directamente
que en la segunda edicin.
La forma en que eliminamos un nodo de los rboles de
bsqueda binarios (que incluye rboles rojos-negros) ahora
garantiza que el nodo solicitado para borrado es el nodo que
realmente se elimina. En las dos primeras ediciones, en
ciertos casos, se borrara algn otro nodo, moviendo su
contenido al nodo pasado al procedimiento de borrado. Con
nuestra nueva forma de borrar nodos, si otros componentes
de un programa mantienen punteros a nodos en el rbol, no
terminarn errneamente con punteros rancios a nodos que
han sido borrados.
El material en redes?ow ahora se basa?ows enteramente en
los bordes. Este enfoque es ms intuitivo que el net?ow
utilizado en las dos primeras ediciones.
Con el material sobre los fundamentos de la matriz y el
algoritmo de Strassen movido a otros captulos, el captulo
sobre operaciones de matriz es ms pequeo que en la
segunda edicin.
Hemos modificado nuestro tratamiento del algoritmo de
concordancia de cadenas Knuth-Morris-Pratt.
Hemos corregido varios errores. La mayora de estos errores
fueron publicados en nuestro sitio web de segunda edicin
de erratas, pero algunos no lo fueron.
Basndonos en muchas peticiones, cambiamos la sintaxis
(como si fuera) de nuestro pseudocdigo. Ahora usamos "D"
para indicar la asignacin y "==" para probar la igualdad, tal
como lo hacen C, C++, Java y Python. De la misma manera,
hemos eliminado las palabras clave y luego hemos adoptado
"//" como nuestro smbolo de principio a fin de lnea. Ahora
tambin utilizamos la anotacin de puntos para indicar los
atributos del objeto. Nuestro pseudocdigo sigue siendo
procesal y no orientado a objetos. En otras palabras, en lugar
de ejecutar mtodos sobre objetos, simplemente llamamos
procedimientos, pasando objetos como parmetros.
Aadimos 100 nuevos ejercicios y 28 nuevos problemas.
Tambin actualizamos muchas entradas bibliogrficas y
aadimos varias nuevas.
Finalmente, revisamos todo el libro y reescribimos
oraciones, prrafos y secciones para hacer la escritura ms
clara y activa.
Web site
You can use our Web site,
http://mitpress.mit.edu/algorithms/, to obtain supplementary
information and to communicate with us. The Web site links
to a list of known errors, solutions to selected exercises and
problems, and (of course) a list explaining the corny
professor jokes, as well as other content that we might add.
The Web site also tells you how to report errors or make
suggestions.
How we produced this book
A Like the second edition, the third edition was produced in
L TEX 2 " . We used the Times font with mathematics
typeset using the MathTime Pro 2 fonts. We thank Michael
Spivak from Publish or Perish, Inc., Lance Carnes from
Personal TeX, Inc., and Tim Tregubov from Dartmouth
College for technical support. As in the previous two
editions, we compiled the index using Windex, a C program
that we wrote, and the bibliography was produced with B IB
TEX. The PDF les for this book were created on a
MacBook running OS 10.5.
We drew the illustrations for the third edition using
MacDraw Pro, with some of the mathematical expressions
in illustrations laid in with the psfrag package A for L TEX
2 " . Unfortunately, MacDraw Pro is legacy software, having
not been marketed for over a decade now. Happily, we still
have a couple of Macintoshes that can run the Classic
environment under OS 10.4, and hence they can run Mac-
Draw Promostly. Even under the Classic environment, we
nd MacDraw Pro to be far easier to use than any other
drawing software for the types of illustrations that
accompany computer-science text, and it produces beautiful
output. 1 Who knows how long our pre-Intel Macs will
continue to run, so if anyone from Apple is listening: Please
create an OS X-compatible version of MacDraw Pro!
Acknowledgments for the third edition
We have been working with the MIT Press for over two
decades now, and what a terric relationship it has been! We
thank Ellen Faran, Bob Prior, Ada Brunstein, and Mary
Reilly for their help and support. We were geographically
distributed while producing the third edition, working in the
Dartmouth College Department of Computer Science, the
MIT ComputerPreface xix Science and Articial
Intelligence Laboratory, and the Columbia University
Department of Industrial Engineering and Operations
Research. We thank our respective universities and
colleagues for providing such supportive and stimulating
environments.
Julie Sussman, P.P.A., once again bailed us out as the
technical copyeditor. Time and again, we were amazed at the
errors that eluded us, but that Julie caught. She also helped
us improve our presentation in several places. If there is a
Hall of Fame for technical copyeditors, Julie is a sure-re,
rst-ballot inductee. She is nothing short of phenomenal.
Thank you, thank you, thank you, Julie! Priya Natarajan also
found some errors that we were able to correct before this
book went to press. Any errors that remain (and
undoubtedly, some do) are the responsibility of the authors
(and probably were inserted after Julie read the material).
The treatment for van Emde Boas trees derives from Erik
Demaines notes, which were in turn inuenced by Michael
Bender. We also incorporated ideas from Javed Aslam,
Bradley Kuszmaul, and Hui Zha into this edition.
The chapter on multithreading was based on notes originally
written jointly with Harald Prokop. The material was
inuenced by several others working on the Cilk project at
MIT, including Bradley Kuszmaul and Matteo Frigo. The
design of the multithreaded pseudocode took its inspiration
from the MIT Cilk extensions to C and by Cilk Artss Cilk++
extensions to C++.
We also thank the many readers of the rst and second
editions who reported errors or submitted suggestions for
how to improve this book. We corrected all the bona de
errors that were reported, and we incorporated as many
suggestions as we could. We rejoice that the number of such
contributors has grown so great that we must regret that it
has become impractical to list them all.
Finally, we thank our wivesNicole Cormen, Wendy
Leiserson, Gail Rivest, and Rebecca Ivryand our
childrenRicky, Will, Debby, and Katie Leiserson; Alex
and Christopher Rivest; and Molly, Noah, and Benjamin
Steinfor their love and support while we prepared this
book. The patience and encouragement of our families made
this project possible. We affectionately dedicate this book to
them.

T HOMAS H. C ORMEN Lebanon, New Hampshire


C HARLES E. L EISERSON Cambridge, Massachusetts
R ONALD L. R IVEST Cambridge, Massachusetts
C LIFFORD S TEIN New York, New York
February 2009

1 We investigated several drawing programs that run under Mac OS X, but all
had signicant short-comings compared with MacDraw Pro. We briey attempted
to produce the illustrations for this book with a different, well known drawing
program. We found that it took at least ve times as long to produce each
illustration as it took with MacDraw Pro, and the resulting illustrations did not
look as good. Hence the decision to revert to MacDraw Pro running on older
Macintoshes.
Introduccin

Esta parte comenzar a pensar en el diseo y anlisis de algoritmos. Se pretende


que sea una introduccin suave a la forma en que especificamos los algoritmos,
algunas de las estrategias de diseo que usaremos a lo largo de este libro, y
muchas de las ideas fundamentales utilizadas en el anlisis de algoritmos. Las
partes posteriores de este libro se basarn en esta base.

El captulo 1 proporciona una visin general de los algoritmos y su lugar en los


sistemas informticos modernos. Este captulo describe lo que es un algoritmo y
enumera algunos ejemplos. Tambin argumenta que debemos considerar los
algoritmos como una tecnologa, tecnologas de largo plazo tales como hardware
rpido, interfaces grficas de usuario, sistemas orientados a objetos y redes.

En el captulo 2, vemos nuestros primeros algoritmos, que resuelven el problema


de ordenar una secuencia de n nmeros. Estn escritos en un pseudocdigo que,
aunque no es directamente traducible a ningn lenguaje de programacin
convencional, transmite la estructura del algoritmo de forma suficientemente
clara como para que usted pueda implementarlo en el idioma de su eleccin. Los
algoritmos de clasificacin que examinamos son de insercin, que utiliza un
enfoque incremental, y de fusin, que utiliza una tcnica recursiva conocida como
"dividir y conquistar", aunque el tiempo que cada uno requiere aumenta con el
valor de n, la tasa de incremento difiere entre los dos algoritmos. Determinamos
estos tiempos de ejecucin en el captulo 2, y desarrollamos una notacin til para
expresarlos.

El captulo 3 precisamente de?nes esta notacin, que llamamos notacin


asinttica. Comienza por de?ning varias notaciones asintticas, que utilizamos
para delimitar el algoritmo de ejecucin de tiempos desde arriba y/o abajo. El
resto del captulo 3 es principalmente una presentacin de notacin matemtica,
ms para asegurar que su uso de notacin coincida con el de este libro que para
ensearle nuevos conceptos matemticos.

El captulo 4 profundiza ms en el mtodo de divisin y conquista introducido en


el captulo 2. Ofrece ejemplos adicionales de algoritmos de dividir y conquistar,
incluyendo el sorprendente mtodo de Strassen para multiplicar dos matrices
cuadradas. El captulo 4 contiene mtodos para resolver las recurrencias, que son
tiles para describir los tiempos de ejecucin de los algoritmos recursivos. Una
tcnica poderosa es el "mtodo maestro", que a menudo usamos para resolver las
recurrencias que surgen de los algoritmos de divisin y conquista. Aunque gran
parte del Captulo 4 est dedicado a probar la correccin del mtodo maestro,
usted puede omitir esta prueba y aun as emplear el mtodo maestro.
El captulo 5 presenta el anlisis probabilstico y los algoritmos aleatorios.
Tpicamente utilizamos el anlisis probabilstico para determinar el tiempo de
ejecucin de un algoritmo en casos en los que, debido a la presencia de una
distribucin de probabilidad inherente, el tiempo de ejecucin puede diferir en
diferentes entradas del mismo tamao. En algunos casos, suponemos que las
entradas se ajustan a una distribucin de probabilidad conocida, por lo que
estamos promediando el tiempo de ejecucin sobre todas las entradas posibles.
En otros casos, la distribucin de probabilidad no proviene de las entradas sino
de las elecciones aleatorias hechas durante el curso del algoritmo. Un algoritmo
cuyo comportamiento est determinado no slo por su entrada sino tambin por
los valores producidos por un generador de nmeros aleatorios es un algoritmo
aleatorio. Podemos utilizar algoritmos aleatorizados para forzar una distribucin
de probabilidad en las entradas -asegurndonos de que ninguna entrada en
particular cause siempre un rendimiento deficiente- o incluso para limitar la tasa
de error de los algoritmos que pueden producir resultados incorrectos de forma
limitada.

Los Apndices A-D contienen otro material matemtico que le ser de utilidad
para leer este libro. Es probable que usted haya visto mucho del material en los
captulos del apndice antes de haber ledo este libro (aunque las de?niciones
especficas y las convenciones notacionales que usamos pueden diferir en algunos
casos de lo que ha visto en el pasado), y por lo tanto debera pensar en los
Apndices como material de referencia. Por otra parte, es probable que no hayan
visto ya la mayor parte del material de la Parte I. Todos los captulos de la Parte
I y los Apndices estn escritos con un tutorial?avor.
1 El papel de los algoritmos en la informtica

Qu son los algoritmos? Por qu vale la pena estudiar los algoritmos? Cul es
el papel de los algoritmos en relacin con otras tecnologas utilizadas en
ordenadores? En este captulo responderemos a estas preguntas.

1.1 Algoritmos

Informalmente, un algoritmo es cualquier procedimiento computacional bien


organizado que toma algn valor, o conjunto de valores, como entrada y produce
algn valor, o conjunto de valores, como salida. Un algoritmo es una secuencia
de pasos computacionales que transforman la entrada en salida.

Tambin podemos ver un algoritmo como una herramienta para resolver un


problema computacional bien especificado. La declaracin de las especificidades
del problema en trminos generales la relacin de entrada/salida deseada. El
algoritmo describe un procedimiento computacional especfico para lograr esa
relacin de entrada/salida.

Por ejemplo, podramos necesitar ordenar una secuencia de nmeros en un orden


no decreciente. Este problema surge con frecuencia en la prctica y proporciona
un terreno frtil para introducir muchas tcnicas de diseo estndar y herramientas
de anlisis. As es como formalmente desarticulamos el problema de
clasificacin:

Input: A sequence of n numbers h a 1 ; a 2 ; : : : ; a n i . 0 0 0

Output: A permutation (reordering) h a 1 ; a 2 ; : : : ; a n i of the input sequence


such 0 0 0 that a 1 a 2 a n .

Por ejemplo, dado la secuencia de entrada h 31;41;59;59;26;41;41;58 i, un


algoritmo de clasificacin devuelve como salida la secuencia h
26;31;41;41;41;58;59 i. Esta secuencia de entrada se llama una instancia del
problema de clasificacin. En general, una instancia de un problema consiste en
el insumo (satisfaciendo cualquier restriccin impuesta en la declaracin del
problema) necesario para calcular una solucin al problema.

Debido a que muchos programas lo utilizan como un paso intermedio, la


clasificacin es una operacin fundamental en la informtica. Como resultado,
tenemos a nuestra disposicin un gran nmero de buenos algoritmos de
clasificacin. El algoritmo que mejor se adapte a una aplicacin dada depende,
entre otros factores, del nmero de tems a clasificar, el grado en que los tems ya
estn algo ordenados, las posibles restricciones en los valores de los tems, la
arquitectura del ordenador y el tipo de dispositivos de almacenamiento a utilizar:
memoria principal, discos o incluso cintas.

Se dice que un algoritmo es correcto si, para cada instancia de entrada, se detiene
con la salida correcta. Decimos que un algoritmo correcto resuelve el problema
computacional dado. Un algoritmo incorrecto puede no detenerse en absoluto en
algunas instancias de entrada, o puede detenerse con una respuesta incorrecta.
Contrariamente a lo que se puede esperar, los algoritmos incorrectos a veces
pueden ser tiles, si podemos controlar su tasa de error. Veremos un ejemplo de
un algoritmo con una tasa de error controlable en el captulo 31 cuando
estudiemos algoritmos para encontrar grandes nmeros primos. Normalmente, sin
embargo, slo nos ocuparemos de los algoritmos correctos.

Un algoritmo se puede especificar en ingls, como programa de ordenador o


incluso como diseo de hardware. El nico requisito es que la especificacin debe
proporcionar una descripcin precisa del procedimiento de clculo que debe
seguirse.

Qu tipos de problemas se resuelven con algoritmos?

La clasificacin no es de ninguna manera el nico problema computacional para


el que se han desarrollado algoritmos. Las aplicaciones prcticas de los algoritmos
son ubicuas e incluyen los siguientes ejemplos:

El Proyecto del Genoma Humano ha hecho grandes progresos hacia los objetivos
de identificar todos los 100.000 genes del ADN humano, determinar las
secuencias de los 3.000 millones de pares de bases qumicas que componen el
ADN humano, almacenar esta informacin en bases de datos y desarrollar
herramientas para el anlisis de datos. Cada uno de estos pasos requiere
algoritmos sofisticados. Aunque las soluciones a los diversos problemas
involucrados estn fuera del alcance de este libro, muchos mtodos para resolver
estos problemas biolgicos usan ideas de varios de los captulos de este libro,
permitiendo as a los cientficos realizar tareas mientras usan los recursos
eficientemente. Los ahorros son en tiempo, tanto humanos como mquinas, y en
dinero, ya que se puede extraer ms informacin de las tcnicas de laboratorio.

Internet permite a las personas de todo el mundo acceder y recuperar rpidamente


grandes cantidades de informacin. Con la ayuda de algoritmos inteligentes, los
sitios en Internet son capaces de gestionar y manipular este gran volumen de
datos. Ejemplos de problemas que hacen un uso esencial de los algoritmos
incluyen la bsqueda de buenas rutas en las que los datos viajarn (las tcnicas
para resolver tales problemas aparecen en el captulo 24), y el uso de un motor de
bsqueda para encontrar rpidamente las pginas en las que reside determinada
informacin (tcnicas relacionadas estn en los captulos 11 y 32).
El comercio electrnico permite que los bienes y servicios sean negociados e
intercambiados electrnicamente, y depende de la privacidad de la informacin
personal como nmeros de tarjetas de crdito, contraseas y estados de cuenta
bancarios. Las tecnologas bsicas utilizadas en el comercio electrnico incluyen
la criptografa de clave pblica y las firmas digitales (que se describen en el
captulo 31), que se basan en algoritmos numricos y la teora de nmeros.

Las empresas manufactureras y otras empresas comerciales a menudo necesitan


asignar recursos escasos de la manera ms beneficiosa. Una compaa petrolera
puede desear saber dnde colocar sus pozos para maximizar sus ganancias
esperadas. Un candidato poltico puede querer determinar dnde gastar dinero
para comprar publicidad de campaa de compra con el fin de maximizar las
posibilidades de ganar una eleccin. Una aerolnea puede desear asignar
tripulaciones a los vuelos de la manera ms barata posible, asegurndose de que
cada vuelo est cubierto y de que se cumplan las regulaciones gubernamentales
en cuanto a la programacin de la tripulacin. Un proveedor de servicios de
Internet puede desear determinar dnde colocar recursos adicionales para servir a
sus clientes de manera ms eficaz. Todos estos son ejemplos de problemas que se
pueden resolver mediante la programacin lineal, que estudiaremos en el captulo
29.A

Aunque algunos de los detalles de estos ejemplos estn ms all del alcance de
este libro, s damos tcnicas subyacentes que se aplican a estos problemas y reas
problemticas. Tambin mostramos cmo resolver muchos problemas
especficos, incluyendo los siguientes:

Se nos da un mapa de carreteras en el que se marca la distancia entre cada par de


intersecciones adyacentes, y queremos determinar la ruta ms corta de una
interseccin a otra. El nmero de rutas posibles puede ser enorme, incluso si no
permitimos rutas que se crucen entre s. Cmo elegir cul de todas las rutas
posibles es la ms corta? Aqu, modelamos la hoja de ruta (que es en s misma un
modelo de los caminos actuales) como una grfica (que nos reuniremos en la Parte
VI y el Apndice B), y deseamos encontrar el camino ms corto de un vrtice a
otro en la grfica. En el captulo 24 veremos cmo resolver eficazmente este
problema.

Se nos dan dos secuencias ordenadas de smbolos, X D hx1; x2;::::::; xmi e Y D


hy1; y2;:::; yni, y deseamos encontrar una referencia comn ms larga de X e Y.
La longitud de una recomendacin comn ms larga de X e Y da una medida de
cun similares son estas dos secuencias. Por ejemplo, si las dos secuencias son
pares de bases en hebras de ADN, entonces podramos considerarlas similares si
tienen una larga tradicin comn. Si X tiene smbolos m y Y tiene smbolos n,
entonces X e Y tienen 2m y 2n criterios posibles, respectivamente. Seleccionar
todos los posibles criterios de X e Y y emparejarlos podra tomar un tiempo
prohibitivamente largo a menos que m y n sean muy pequeos.

En el captulo 15 veremos cmo utilizar una tcnica general conocida como


programacin dinmica para resolver este problema de forma mucho ms
eficiente.

Se nos da un diseo mecnico en trminos de una biblioteca de partes, donde cada


parte puede incluir instancias de otras partes, y necesitamos listar las partes en
orden para que cada parte aparezca antes que cualquier parte que la use. Si el
diseo comprende n partes, entonces hay n posibles pedidos, donde n denota
la funcin factorial.

Debido a que la funcin factorial crece ms rpido que una funcin exponencial,
no podemos generar de manera factible cada orden posible y luego verificar que,
dentro de ese orden, cada parte aparezca antes que las partes que la usan (a menos
que tengamos slo unas pocas partes). Este problema es un ejemplo de
clasificacin topolgica, y veremos en el captulo 22 cmo resolver este problema
de manera eficiente.

Se nos dan n puntos en el plano, y deseamos encontrar el casco convexo de estos


puntos. El casco convexo es el polgono convexo ms pequeo que contiene los
puntos. Intuitivamente, podemos pensar en cada punto como representado por un
clavo que sobresale de una tabla. El casco convexo estara representado por una
banda elstica apretada que rodea todos los clavos. Cada clavo alrededor del cual
gira la banda elstica es un vrtice del casco convexo. ) Cualquiera de los
subconjuntos 2n de los puntos puede ser los vrtices del casco convexo. Tampoco
es suficiente saber qu puntos son vrtices del casco convexo, ya que tambin
necesitamos conocer el orden en que aparecen. Hay muchas opciones, por lo
tanto, para los vrtices del casco convexo.

El captulo 33 da dos buenos mtodos para encontrar el casco convexo.

These lists are far from exhaustive (as you again have probably surmised from
this books heft), but exhibit two characteristics that are common to many
interesting algorithmic problems:

1. They have many candidate solutions, the overwhelming majority of which do


not solve the problem at hand. Finding one that does, or one that is best, can
present quite a challenge.

2. They have practical applications. Of the problems in the above list, finding the
shortest path provides the easiest examples. A transportation firm, such as a
trucking or railroad company, has a financial interest in finding shortest paths
through a road or rail network because taking shorter paths results in lower labor
and fuel costs. Or a routing node on the Internet may need to find the shortest path
through the network in order to route a message quickly. Or a person wishing to
drive from New York to Boston may want to find driving directions from an
appropriate Web site, or she may use her GPS while driving.

Not every problem solved by algorithms has an easily identified set of candidate
solutions. For example, suppose we are given a set of numerical values
representing samples of a signal, and we want to compute the discrete Fourier
transform of these samples. The discrete Fourier transform converts the time
domain to the frequency domain, producing a set of numerical coefficients, so
that we can determine the strength of various frequencies in the sampled signal.
In addition to lying at the heart of signal processing, discrete Fourier transforms
have applications in data compression and multiplying large polynomials and
integers. Chapter 30 gives an efficient algorithm, the fast Fourier transform
(commonly called the FFT), for this problem, and the chapter also sketches out
the design of a hardware circuit to compute the FFT.

Data structures

This book also contains several data structures. A data structure is a way to store
and organize data in order to facilitate access and modifications. No single data
structure works well for all purposes, and so it is important to know the strengths
and limitations of several of them.

Technique

Although you can use this book as a cookbook for algorithms, you may
someday encounter a problem for which you cannot readily find a published
algorithm (many of the exercises and problems in this book, for example). This
book will teach you techniques of algorithm design and analysis so that you can
develop algorithms on your own, show that they give the correct answer, and
understand their efficiency.

Different chapters address different aspects of algorithmic problem solving. Some


chapters address specific problems, such as finding medians and order statistics
in Chapter 9, computing minimum spanning trees in Chapter 23, and determining
a maximum flow in a network in Chapter 26. Other chapters address techniques,
such as divide-and-conquer in Chapter 4, dynamic programming in Chapter 15,
and amortized analysis in Chapter 17.

Hard problems

Most of this book is about efficient algorithms. Our usual measure of efficiency
is speed, i.e., how long an algorithm takes to produce its result. There are some
problems, however, for which no efficient solution is known. Chapter 34 studies
an interesting subset of these problems, which are known as NP-complete.

Why are NP-complete problems interesting? First, although no efficient algorithm


for an NP-complete problem has ever been found, nobody has ever proven that
an efficient algorithm for one cannot exist. In other words, no one knows whether
or not efficient algorithms exist for NP-complete problems. Second, the set of
NP-complete problems has the remarkable property that if an efficient algorithm
exists for any one of them, then efficient algorithms exist for all of them. This
relationship among the NP-complete problems makes the lack of efficient
solutions all the more tantalizing. Third, several NP-complete problems are
similar, but not identical, to problems for which we do know of efficient
algorithms. Computer scientists are intrigued by how a small change to the
problem statement can cause a big change to the efficiency of the best known
algorithm.

You should know about NP-complete problems because some of them arise
surprisingly often in real applications. If you are called upon to produce an
efficient algorithm for an NP-complete problem, you are likely to spend a lot of
time in a fruitless search. If you can show that the problem is NP-complete, you
can instead spend your time developing an efficient algorithm that gives a good,
but not the best possible, solution.

As a concrete example, consider a delivery company with a central depot. Each


day, it loads up each delivery truck at the depot and sends it around to deliver
goods to several addresses. At the end of the day, each truck must end up back at
the depot so that it is ready to be loaded for the next day. To reduce costs, the
company wants to select an order of delivery stops that yields the lowest overall
distance traveled by each truck. This problem is the well-known traveling-
salesman problem, and it is NP-complete. It has no known efficient algorithm.
Under certain assumptions, however, we know of efficient algorithms that give
an overall distance which is not too far above the smallest possible. Chapter 35
discusses such approximation algorithms.

Parallelism

For many years, we could count on processor clock speeds increasing at a steady
rate. Physical limitations present a fundamental roadblock to ever-increasing
clock speeds, however: because power density increases superlinearly with clock
speed, chips run the risk of melting once their clock speeds become high enough.
In order to perform more computations per second, therefore, chips are being
designed to contain not just one but several processing cores. We can liken
these multicore computers to several sequential computers on a single chip; in
other words, they are a type of parallel computer. In order to elicit the best
performance from multicore computers, we need to design algorithms with
parallelism in mind. Chapter 27 presents a model for multithreaded algorithms,
which take advantage of multiple cores. This model has advantages from a
theoretical standpoint, and it forms the basis of several successful computer
programs, including a championship chess program.
Ejercicios

1.1-1

D un ejemplo del mundo real que requiera clasificacin o un ejemplo del mundo
real que requiera computar un casco convexo.

1.1-2

Aparte de la velocidad, qu otras medidas de eficiencia se podran utilizar en el


mundo real?

1.1-3

Seleccione una estructura de datos que haya visto anteriormente y discuta sus
fortalezas y limitaciones.

1.1-4

Cmo son similares los problemas de camino ms corto y de vendedor


ambulante mencionados anteriormente?

En qu se diferencian?

1.1-5

Proponga un problema del mundo real en el que slo la mejor solucin bastar.
Luego, invente una solucin en la que una solucin que sea "aproximadamente"
la mejor sea lo suficientemente buena.

1.2 Algoritmos como tecnologa

Supongamos que las computadoras eran infinitamente rpidas y la memoria de la


computadora era libre. Tiene alguna razn para estudiar algoritmos? La
respuesta es s, si por cualquier otra razn que no sea la de demostrar que su
mtodo de solucin termina y lo hace con la respuesta correcta.

Si las computadoras fueran infinitamente rpidas, cualquier mtodo correcto para


resolver un problema sera suficiente. Probablemente deseara que su
implementacin estuviera dentro de los lmites de una buena prctica de
ingeniera de software (por ejemplo, su implementacin debera estar bien
diseada y documentada), pero lo ms frecuente es que utilice el mtodo que sea
ms fcil de implementar.

Por supuesto, las computadoras pueden ser rpidas, pero no son infinitamente
rpidas. Y la memoria puede ser barata, pero no es gratis. El tiempo de
computacin es por lo tanto un recurso limitado, y tambin lo es el espacio en la
memoria. Usted debe utilizar estos recursos sabiamente, y los algoritmos que son
eficientes en trminos de tiempo o espacio le ayudarn a hacerlo.

Efficiency

Different algorithms devised to solve the same problem often differ dramatically
in their efficiency. These differences can be much more significant than
differences due to hardware and software.

As an example, in Chapter 2, we will see two algorithms for sorting. The first,
known as insertion sort, takes time roughly equal to c1n2 to sort n items, where
c1 is a constant that does not depend on n. That is, it takes time roughly
proportional to n2. The second, merge sort, takes time roughly equal to c2n lg n,
where lg n stands for log2 n and c2 is another constant that also does not depend
on n. Insertion sort typically has a smaller constant factor than merge sort, so that
c1 < c2.

We shall see that the constant factors can have far less of an impact on the running
time than the dependence on the input size n. Lets write insertion sorts running
time as c1n n and merge sorts running time
as c2n lg n. Then we see that where insertion
sort has a factor of n in its running time, merge sort has a factor of lg n, which is
much smaller. (For example, when n D 1000, lg n is approximately 10, and when
n equals one million, lg n is approximately only 20.) Although insertion sort
usually runs faster than merge sort for small input sizes, once the input size n
becomes large enough, merge sorts advantage of lg n vs. n will more than
compensate for the difference in constant factors. No matter how much smaller
c1 is than c2, there will always be a crossover point beyond which merge sort is
faster.

For a concrete example, let us pit a faster computer (computer A) running


insertion sort against a slower computer (computer B) running merge sort. They
each must sort an array of 10 million numbers. (Although 10 million numbers
might seem like a lot, if the numbers are eight-byte integers, then the input
occupies about 80 megabytes, which fits in the memory of even an inexpensive
laptop computer many times over.) Suppose that computer A executes 10 billion
instructions per second (faster than any single sequential computer at the time of
this writing) and computer B executes only 10 million instructions per second, so
that computer A is 1000 times faster than computer B in raw computing power.
To make the difference even more dramatic, suppose that the worlds craftiest
programmer codes insertion sort in machine language for computer A, and the
resulting code requires 2n2 instructions to sort n numbers. Suppose further that
just an average programmer implements merge sort, using a high-level language
with an inefficient compiler, with the resulting code taking 50n lg n instructions.
To sort 10 million numbers, computer A takes

2 .107/2 instructions

1010 instructions/second D 20,000 seconds (more than 5.5 hours) ; while


computer B takes

You might also like