Table Of ContentBaase
•
Van Gelder
Introducción al análisis y diseño, Tercera edición
Sara Baase, San Diego State University
Allen Van Gelder, University of California at Santa Cruz
Introducción al análisis y diseño
“La redacción es lúcida, organizada e invita a leer.”
Abdou Youssef, George Washington University
“La mejor introducción a P y NP que he visto en cualquier libro de texto.”
Tercera
Iliana Bjorling-Sachs, Lafayette College
Edición
Aprovechando la experiencia docente que reúnen ambos autores, los Profesores Sara Baase y Allen
Van Gelder han hecho una revisión extensa de este best seller sobre diseño y análisis de algoritmos
para convertirlo en el libro más actual y accesible que puede conseguirse. Esta edición hace mayor
hincapié en las técnicas de diseño de algoritmos como divide y vencerás y algoritmos codiciosos, e
incluye temas y ejercicios nuevos. As,í continúa la tradición de explicar los conceptos en forma de- I
n
tallada, exacta y una redacción clara que hizo a este libro tan popular en ediciones anteriores. t
r
(cid:1) o
Hace hincapié en el desarrollo de algoritmos mediante un proceso paso por paso; d
no se limita a presentar simplemente el resultado final. u
c
c
(cid:1) Subraya la importancia del proceso de análisis de algoritmos, reevaluando, i
ó
modificando y tal vez rechazando continuamente los algoritmos hasta lograr n
PUNTOS DESTACADOS una solución satisfactoria. a
l
(cid:1) a
Ofrece un tratamiento amplio de la recursión con un repaso claro y altamente n
didáctico de su funcionamiento y de las razones por las que es una valiosa á
l
técnica de programación. i
s
i
(cid:1)(cid:2)Emplea un pseudocódigo similar a Java; incluye un apéndice con ejemplos en s
y
Java.
d
i
Sara Baase es Profesora de Ciencias de la Computación en la San Diego State University y ha esta- s
e
do enseñando Ciencias de la Computación durante 25 años. La doctora Baase ha sido galardonada ñ
o
tres veces con el Outstanding Faculty Award de la San Diego State University Alumni Association y
ha escrito varios libros de texto en las áreas de algoritmos, lenguaje ensamblador y aspectos so-
ciales y éticos de la computación. Obtuvo su doctorado en la University of California, Berkeley.
Allen Van Gelder es Profesor de Ciencias de la Computación en la University of California at Santa
Cruz, donde ha estado enseñando Ciencias de la Computación desde hace 12 años. Él recibió su
grado de doctor en Ciencias de la Computación de la Stanford University y ha sido galardonado
con el Presidential Young Investigator Award.
Puede consultar la información más reciente acerca de los libros de Addison-Wesley visitándonos
Tercera Baase
en la World Wide Web en www.awlonline.com/cs
Edición
Van Gelder
Visítenos en:
www.pearsonedlatino.com
www.FreeLibros.me
www.FreeLibros.me
www.FreeLibros.me
Algoritmos
computacionales
Introducción al análisis y diseño
TERCERA EDICIÓN
Sara Baase
San Diego State University
Allen Van Gelder
University of California at Santa Cruz
TRADUCCIÓN:
Roberto L. Escalona García
Universidad Nacional Autónoma de México
REVISIÓNTÉCNICA:
Saúl de la O. Torres
Escuela Superior de Cómputo
Instituto Politécnico Nacional
www.FreeLibros.me
BAASE, SARA y GELDER ALLEN VAN
Algoritmos computacionales.
Introducción al análisis y diseño
México, 2002
970-26-0142-8
Formato: 18.5 (cid:1) 23.5 cm 704
Versión en español de la obra titulada Computer Algorithms:Introduction to Design and Analysis,Third Edition,de Sara Baase y Allen
Van Gelder,publicada originalmente en inglés por Addison-Wesley Longman,Inc.,Reading Massachusetts,U.S.A.
Esta edición en español es la única autorizada.
Original English Language Title byAddison-Wesley Longman,Inc.
Copyright ©2000
All rights reserved
Published by arrangement with the original publisher,Addison-Wesley Longman,Inc.,
A Pearson Education Company
ISBN 0-201-61244-5
Edición en español:
Editor:Guillermo Trujano Mendoza
e-mail:[email protected]
Editor de desarrollo:Felipe de Jesús Castro Pérez
Supervisor de producción:José D. Hernández Garduño
Edición en inglés:
Acquisitions Editor:Maite Suarez-Rivas
Assistant Editor:Jason Miranda
Composition/Art:Paul C. Anagnostopoulos,Windfall Software
Copy Editor:Joan Flaherty
Proofreader:Brooke Albright
Cover Illustration:Janetmarie Colby
Cover Design:Lynne Reed
Manufacturing Coordinator:Timothy McDonald
TERCERA EDICIÓN,2002
D.R. ©2002 por Pearson Educación de México,S.A. de C.V.
Calle 4 Núm. 25-2do. piso
Fracc. Industrial Alce Blanco
53370 Naucalpan de Juárez,Edo. de México
e-mail:[email protected]
Cámara Nacional de la Industria Editorial Mexicana Reg. Núm. 1031.
Addison Wesley es una marca registrada de Pearson Educación de México,S.A. de C.V.
Reservados todos los derechos. Ni la totalidad ni parte de esta publicación pueden reproducirse,registrarse o transmitirse,por un sistema
de recuperación de información,en ninguna forma ni por ningún medio,sea electrónico,mecánico,fotoquímico,magnético o electroóptico,
por fotocopia,grabacióno cualquier otro,sin permiso previo por escrito del editor.
El préstamo,alquiler o cualquier otra forma de cesión de uso de este ejemplar requerirá también la autorización del editor o de sus repre-
sentantes.
ISBN 970-26-0142-8
Impreso en México. Printed in Mexico.
1 2 3 4 5 6 7 8 9 0 - 04 03 02
www.FreeLibros.me
Para Keith siempre partícipe de lo que hago S.B.
Para mis padres,quienes fueron mis primeros
maestros,y los más importantes A.V.G.
www.FreeLibros.me
Prefacio
Objetivo
Este libro fue escrito para un curso completo sobre algoritmos; cuenta con suficiente material co-
mo para adoptar diversas orientaciones.
El objetivo del mismo incluye tres aspectos. Pretende enseñar algoritmos que se aplicarán en
la resolución de problemas reales que se presentan a menudo en aplicaciones para computadora,
enseñar principios y técnicas básicos de complejidad computacional (comportamiento de peor
caso y caso promedio,consumo de espacio y cotas inferiores de la complejidad de un problema),
e introducir las áreas de los problemas NP-completos y los algoritmos paralelos.
Otra de las metas del libro,no menos importante que enseñar los temas que contiene,es de-
sarrollar en el lector el hábito de siempre responder a un algoritmo nuevo con las preguntas:¿Qué
tan bueno es? ¿Hay una manera mejor? Por ello, en lugar de presentar una serie de algoritmos
completos,“sacados de la manga”,con su análisis,el libro normalmente comenta primero un pro-
blema,considera una o más estrategias para resolverlo (como podría hacer el lector que enfrenta
el problema por primera vez) y luego comienza a desarrollar un algoritmo,lo analiza y lo modifi-
ca o lo rechaza hasta obtener un resultado satisfactorio. (Los enfoques alternativos que finalmente
se rechazan también se examinan en los ejercicios; para el lector es útil saber por qué se les re-
chazó.)
Preguntas del tipo de ¿Cómo puede hacerse esto de forma más eficiente? ¿Qué estructura de
datos sería útil en este caso? ¿En qué operaciones debemos concentrarnos para analizar este al-
goritmo? ¿Qué valor inicial debe asignarse a esta variable (o estructura de datos)?, aparecen a
menudo en todo el texto. Por lo general damos la respuesta inmediatamente después de la pregun-
ta,pero sugerimos a los lectores hacer una pausa antes de continuar la lectura y tratar de idear su
propia respuesta. El aprendizaje no es un proceso pasivo.
Tenemos la esperanza de que los lectores también aprendan a visualizar cómo se comporta
en la realidad un algoritmo con diversas entradas; es decir, ¿Qué ramas sigue? ¿Qué patrón de
crecimiento y encogimiento siguen las pilas? ¿Cómo afecta al comportamiento presentar las en-
tradas en diferentes formas (por ejemplo,enumerando los vértices o aristas de un grafo en distin-
tos órdenes)? Tales preguntas se plantean en algunos de los ejercicios,pero no hacemos hincapié
en ellas en el texto porque requieren un estudio minucioso de los pormenores de un gran número
de ejemplos.
Casi todos los algoritmos que presentamos tienen utilidad práctica; decidimos no hacer hin-
capié en los que tienen un buen comportamiento asintótico pero no se desempeñan bien con entra-
das de tamaño útil (aunque sí incluimos algunos por su importancia). Los algoritmos específicos
se escogieron por diversas razones que incluyen la importancia del problema,la ilustración de téc-
www.FreeLibros.me
vi Prefacio
nicas de análisis,la ilustración de técnicas (como la búsqueda primero en profundidad) que dan
pie a numerosos algoritmos,y la ilustración del desarrollo y mejoramiento de técnicas y algorit-
mos (como los programas Unión-Hallar).
Requisitos previos
El libro supone que el lector está familiarizado con estructuras de datos como listas ligadas,pilas
y árboles,también asume que ha tenido contacto con la recursión. No obstante,incluimos un repa-
so,con especificaciones,de las estructuras de datos estándar y de algunas especializadas. También
añadimos un repaso de la recursión que los estudiantes no deberán tener problemas para entender.
En el análisis de algoritmos utilizamos propiedades sencillas de los logaritmos y algo de
cálculo(diferenciación para determinar el orden asintótico de una función e integración para apro-
ximar sumatorias),aunque prácticamente no se usa cálculo más allá del capítulo 4. Hemos visto
que muchos estudiantes se asustan al ver el primer logaritmo o signo de integral porque ha pasa-
do un año o más desde su último curso de cálculo. Los lectores sólo necesitarán unas cuantas pro-
piedades de los logaritmos y unas cuantas integrales del primer semestre de cálculo. En la sección
1.3 se repasan algunos de los temas necesarios de matemáticas,y la sección 1.5.4 ofrece una guía
práctica.
Técnicas de diseño de algoritmos
Varias técnicas importantes de diseño de algoritmos vuelven a aparecer en muchos algoritmos.
Ellas incluyen divide y vencerás, métodos codiciosos, búsqueda primero en profundidad (para
grafos) y programación dinámica. Esta edición hace más hincapié que la segunda en las técnicas
de diseño de algoritmos. La programación dinámica,igual que antes,tiene su propio capítulo,y
la búsqueda primero en profundidad se presenta con muchas aplicaciones en el capítulo sobre re-
corrido de grafos (capítulo 7). Casi todos los capítulos están organizados por área de aplicación,
no por técnica de diseño,por lo que a continuación presentaremos una lista de lugares en los que
el lector hallará algoritmos que usan técnicas de divide y vencerás y codiciosas.
La técnica de dividir y vencer se describe en la sección 4.3 y se usa en la Búsqueda Binaria
(sección 1.6),en casi todos los métodos de ordenamiento (capítulo 4),en la determinación de me-
dianas y en el problema de selección general (sección 5.4), en los árboles de búsqueda binaria
(sección 6.4),en la evaluación de polinomios (sección 12.2),en la multiplicación de matrices (sec-
ción 12.3),en la Transformada Rápida de Fourier (sección 12.4),en el coloreado aproximado de
grafos (sección 13.7) y,en una forma un poco distinta,en la computación en paralelo en la sec-
ción 14.5.
Los algoritmos codiciosos se usan para hallar árboles abarcantes mínimos y caminos más
cortos en el capítulo 8,y en varios algoritmos de aproximación para problemas de optimización
NP-completos,como llenado de cajones,mochila,coloreado de grafos y vendedor viajero (véan-
se las secciones 13.4 a 13.8).
Cambios respecto a la segunda edición
Esta edición tiene tres capítulos y muchos temas que son nuevos. En todo el libro se han vuelto a
escribir numerosas secciones incorporando cambios extensos. Unos cuantos temas de la segunda
edición se han pasado a otros capítulos donde, creemos, encajan mejor. Añadimos más de 100
ejercicios nuevos,muchas citas bibliográficas y un apéndice con ejemplos de Java. Los capítulos
2,3 y 6 son prácticamente nuevos en su totalidad.
www.FreeLibros.me
Prefacio vii
El capítulo 2 repasa los tipos de datos abstractos (TDA) e incluye especificaciones para va-
rios TDA estándar. En todo el libro se hace hincapié en el papel de los tipos de datos abstractos
en el diseño de algoritmos.
El capítulo 3 repasa la recursión y la inducción,haciendo hincapié en la conexión entre los
dos y su utilidad en el diseño de programas y en la demostración de que son correctos. En este ca-
pítulo también se desarrollan los árboles de recursión,que proporcionan una representación visual
e intuitiva de las ecuaciones de recurrencia que surgen durante el análisis de algoritmos recursi-
vos. Las soluciones para patrones que se presentan a menudo se resumen con el fin de facilitar su
uso en capítulos posteriores.
El capítulo 6 aborda el hashing o dispersión,los árboles rojinegros para árboles binarios equi-
librados,las colas de prioridad avanzadas y las relaciones de equivalencia dinámica (Unión-Ha-
llar). Este último tema se trataba en otro capítulo en la segunda edición.
Reescribimos todos los algoritmos en un pseudocódigo basado en Java. No es necesario sa-
ber Java; cualquiera que esté familiarizado con C o C++ podrá leer fácilmente los algoritmos. El
capítulo 1 incluye una introducción al pseudocódigo basado en Java.
Hemos ampliado considerablemente la sección que trata las herramientas matemáticas para
el análisis de algoritmos en el capítulo 1 con el fin de proporcionar un mejor repaso y una referen-
cia de las matemáticas que se usan en el libro. El tratamiento del orden asintótico de las funciones
de la sección 1.5 se diseñó pensando en ayudar a los estudiantes a dominar mejor los conceptos y
técnicas relacionados con el orden asintótico. Añadimos reglas, en lenguaje informal, que resu-
men los casos más comunes (véase la sección 1.5.4).
El capítulo 4 contiene una versión acelerada de Heapsort en la que el número de comparacio-
nes de claves se recorta casi a la mitad. En el caso de Quicksort,usamos el algoritmo de partición
de Hoare en el texto principal. El método de Lomuto se introduce en un ejercicio. (En la segunda
edición se hizo al revés.)
Hemos dividido el antiguo capítulo sobre grafos en dos,y cambiamos el orden de algunos te-
mas. El capítulo 7 se concentra en los algoritmos de recorrido (en tiempo lineal). La presentación
de la búsqueda primero en profundidad se modificó exhaustivamente destacando la estructura ge-
neral de la técnica y mostrando más aplicaciones. Añadimos ordenamiento topológico y análisis
de rutas críticas como aplicaciones,en vista de su valor intrínseco y su relación con la programa-
ción dinámica. Presentamos el algoritmo de Sharir,en vez del de Tarjan,para determinar compo-
nentes conectados.
El capítulo 8 trata los algoritmos codiciosos para problemas de grafos. Las presentaciones del
algoritmo de Prim para árboles abarcantes mínimos y del algoritmo de Dijkstra para caminos más
cortos se reescribieron tratando de hacer hincapié en el papel que desempeñan las colas de prio-
ridad y de ilustrar la forma en que el uso de tipos de datos abstractos puede conducir al diseñador
a implementaciones eficientes. Se menciona la implementación asintóticamente óptima Θ(m+ n
log n),pero no se analiza a fondo. Trasladamos el algoritmo de Kruskal para árboles abarcantes
mínimos a este capítulo.
La presentación de la programación dinámica (capítulo 10) se modificó sustancialmente a fin
de hacer hincapié en un enfoque general para hallar soluciones de programación dinámica. Aña-
dimos una nueva aplicación,un problema de formateo de texto,para subrayar el punto de que no
todas las aplicaciones requieren un arreglo bidimensional. Pasamos la aplicación de cotejo apro-
ximado de cadenas (que en la segunda edición estaba en este capítulo) al capítulo sobre cotejo de
cadenas (sección 11.5). Los ejercicios incluyen otras aplicaciones nuevas.
www.FreeLibros.me
viii Prefacio
Nuestra experiencia docente ha revelado áreas específicas en que los estudiantes tuvieron di-
ficultad para captar conceptos relacionados con P y NP (capítulo 13), sobre todo algoritmos no
deterministas y transformaciones polinómicas. Reescribimos algunas definiciones y ejemplos pa-
ra dejar más claros los conceptos. Añadimos una sección corta sobre algoritmos de aproximación
para el problema del vendedor viajero y una sección acerca de la computación por ADN.
A los profesores que usaron la segunda edición seguramente les interesará saber que modifi-
camos algunas convenciones y términos (casi siempre para adecuarlos al uso común). Los arreglos
de índices ahora principian en 0 en vez de 1 en muchos casos. (En otros,en los que la numera-
ción a partir de 1 era más clara,la dejamos así.) Ahora usamos el término profundidaden lugar
de nivelpara referirnos a la ubicación “vertical”de un nodo dentro de un árbol. Usamos alturaen
vez de profundidadpara referirnos a la profundidad máxima de cualquier nodo de un árbol. En la
segunda edición,un caminoen un grafo se definía como lo que comúnmente se conoce como ca-
mino simple; en esta edición usamos la definición más general de caminoy definimos camino sim-
pleaparte. Ahora un grafo dirigido puede contener una auto-arista.
Ejercicios y programas
Algunos ejercicios son un tanto “abiertos”. Por ejemplo,uno de ellos podría pedir una buena co-
ta inferior para la complejidad de un problema,en lugar de pedir a los estudiantes demostrar que
una función dada es una cota inferior. Hicimos esto por dos razones. Una fue hacer más realista
el planteamiento de la pregunta; las soluciones se tienen que descubrir,no nada más verificarse.
La otra es que para algunos estudiantes podría ser difícil demostrar la mejor cota inferior conoci-
da (o hallar el algoritmo más eficiente para un problema), pero incluso en esos casos habrá una
gama de soluciones que podrán ofrecer para demostrar su dominio de las técnicas estudiadas.
Algunos temas y problemas interesantes se introducen únicamente en los ejercicios. Por
ejemplo, el problema del conjunto independiente máximo para un árbol es un ejercicio del ca-
pítulo 3,el problema de la sumatoria de subsucesión máxima es un ejercicio del capítulo 4,y el
problema de hallar un sumidero para un grafo es un ejercicio del capítulo 7. Varios problemas NP-
completos se introducen en ejercicios del capítulo 13.
Las capacidades,antecedentes y conocimientos matemáticos de los estudiantes de diferentes
universidades varían considerablemente,lo que dificulta decidir exactamente cuáles ejercicios de-
ben marcarse (con un asterisco) como “difíciles”. Marcamos los ejercicios que requieren matemá-
ticas más allá de las básicas, los que requieren mucha creatividad y para los que se debe seguir
una cadena de razonamiento larga. Unos cuantos ejercicios tienen dos asteriscos. Algunos ejerci-
cios con asterisco tienen sugerencias.
Los algoritmos presentados en este libro no son programas; es decir,se han omitido muchos
detalles que no son importantes para el método o para el análisis. Claro que los estudiantes deben
saber cómo implementar algoritmos eficientes en programas eficientes sin errores. Muchos profe-
sores podrían impartir este curso como curso “teórico”puro,sin programación. Para quienes desean
asignar proyectos de programación,casi todos los capítulos incluyen una lista de tareas de progra-
mación:sugerencias breves que los profesores que decidan usarlas tal vez necesitarán ampliar.
Cómo seleccionar temas para un curso
Es evidente que la cantidad de material y la selección específica de los temas a cubrir dependerán
del curso específico y de la población de estudiantes. Presentaremos cuadros sinópticos de ejem-
plo para dos cursos de licenciatura y uno de posgrado.
www.FreeLibros.me