Descubrir la algoritmia

Conceptos básicos

1. Un primer ejemplo de algoritmo

Si el burgués gentilhombre de Molière, el señor Jourdain, practicaba la prosa sin ser consciente de ello, todos nosotros, sin darnos cuenta, utilizamos un modo de pensar racional y analítico que puede compararse, en cierto sentido, a un algoritmo. Nuestra vida personal y profesional está llena de objetivos que nos fijamos, o que nos asignan, y que intentamos alcanzar de la mejor manera posible. Por lo general, para lograrlo descomponemos el camino —a veces, un laberinto— en etapas y acciones que nos conducen desde la idea del objetivo hasta su realización. Ilustrémoslo con un ejemplo trivial tomado de nuestra vida cotidiana: una receta de cocina.

Supongamos que es usted un cocinero novato, con una vitrocerámica y la capacidad de utilizar utensilios de cocina, incluida una cacerola. Se acerca la hora de comer y decide preparar un plato rápido de pasta con mantequilla. Para ello, realiza la siguiente secuencia de acciones:

Tomar un cazo  
Llenarlo de agua  
Llevar el agua a ebullición  
Tomar la pasta  
Sumergirla en el agua cuando empiece a hervir  
Programar 7 minutos en el temporizador 
Apagar los fogones cuando suene el temporizador  
Retirar la cacerola del fuego  
Escurrir la pasta con un escurridor  
Servir la pasta en un plato  
Tomar la barra de mantequilla  
Agarrar un cuchillo  
Cortar una nuez de mantequilla con el cuchillo  
Mezclar la mantequilla con la pasta 

Al preparar este almuerzo, acaba de ejecutar un algoritmo sin darse cuenta; es decir, formulado en pocas palabras, ha efectuado una secuencia de acciones para alcanzar un objetivo.

El resultado de este algoritmo es un plato de pasta con mantequilla elaborado con dos ingredientes: pasta y mantequilla.

Diremos que los ingredientes (pasta y mantequilla) constituyen las entradas del algoritmo, mientras que el plato preparado (pasta con mantequilla) es la salida del algoritmo.

Supongamos, además, que las acciones realizadas en esta secuencia son elementales...

Algoritmos y programación

Veremos un modelo sencillo de pseudocódigo en la siguiente sección de este capítulo, pero primero interesémonos por la creación o el diseño del algoritmo. ¿Cómo se puede facilitar esta etapa clave? Las tres secciones siguientes describen los componentes de lo que llamaremos el marco del algoritmo. Creemos que la elaboración de este marco es, en sí misma, un método para facilitar la fase de creación del algoritmo.

1. El objetivo del algoritmo

El punto de partida es, naturalmente, el objetivo del programa y, por tanto, el del algoritmo. El objetivo responde a la pregunta qué, que a su vez se deriva de la razón de ser del programa, o por qué. El algoritmo, por su parte, responde a la pregunta cómo, es decir, cómo poner en práctica el objetivo o cómo enlazar las entradas con la salida, escribiendo el camino como una secuencia de primitivas.

Es necesario que el objetivo describa el resultado esperado del programa con la mayor precisión. También es posible, e incluso deseable, especificar las limitaciones de esa salida. La formulación del objetivo también puede describir las entradas al programa, pero es posible que, en esta fase, las entradas necesarias para producir la salida aún no estén perfectamente claras en la mente del desarrollador. 

Considere el siguiente objetivo simple: «Calcular el resto de la división entera de dos números enteros naturales».

En este ejemplo, hemos descrito claramente la salida esperada (el resto de una división entera) y también hemos indicado las entradas del algoritmo (dos números naturales). Podríamos añadir una restricción; por ejemplo, «El resto debe ser un número entero natural», lo que implicaría que no puede ser negativo.

2. Ejecución paso a paso de un ejemplo para inducir un principio más general

El principio del algoritmo expresa, preferiblemente en una frase, la idea que permite crear un posible camino que vincule entradas y salida. Pero ¿cómo se establece este principio? En ciencias, una de las formas de producir conocimiento se llama inducción, que consiste en generalizar, es decir, partir de ejemplos para inferir una ley más general. Este enfoque puede utilizarse en algoritmos para...

Rudimentos de formalización

Vamos a ver cómo escribir algoritmos sencillos utilizando pseudocódigo simple. Al final del capítulo, un ejemplo ilustrará la traducción del pseudocódigo a dos lenguajes de destino elegidos por nosotros, R y Python.

Hay que señalar que el formalismo presentado está fuertemente inspirado en el ya antiguo libro Introducción a la programación de J. Biondi y G. Clavel (publicado por la editorial Elsevier - Masson), con el que el propio autor de estas líneas, entonces estudiante, aprendió algorítmica. Ni que decir tiene que recomiendo este libro (y sus otros dos volúmenes) a cualquier lector que desee profundizar en el estudio de los algoritmos.

1. Datos y acciones elementales

Como hemos dicho, los algoritmos manipulan los datos de entrada para calcular los de salida. Además, suelen necesitar otros datos internos para realizar cálculos intermedios.

Todos estos datos pueden ser constantes o variables. Por definición, los datos constantes son invariables.

Aunque las constantes pueden aparecer de forma «dura» en el algoritmo, es decir, explícitamente, recomendamos darles un nombre para facilitar la lectura del pseudocódigo. Obviamente, el número π es más fácil de leer que 3,14159265358979.

Por tanto, un dato es una constante o una variable, tiene un nombre y se le puede dar o asignar un valor. La primera asignación se denomina inicialización; antes de esto, el dato tiene un valor indeterminado, es decir, desconocido.

Anotaremos la asignación de un valor a un elemento de datos denominado NOMBRE_DEL_DATO de la siguiente manera:

NOMBRE_DEL_DATO <- valor 

El valor asignado a un dato puede ser el resultado de una operación:

SUMA <- 10 + 5 

El tipo del valor asignado debe ser idéntico o compatible con el de los datos. Cuando son diferentes pero compatibles, se realiza implícitamente una conversión.

Por ejemplo, NUM NÚMERO <- ’4’implica la conversión del carácter ’4’en un número. En este caso, consulte la ayuda o la guía del lenguaje de programación en cuestión para conocer las reglas de conversión que se aplican de un tipo de datos a otro.

Antes hemos mencionado la noción de tipificación de datos, que define...

Minicaja de herramientas de algoritmos

Hemos seleccionado un pequeño número de temas para ilustrar el poder del pensamiento algorítmico y ofrecerle algunos ejemplos útiles.

Esta caja de herramientas incluye, por supuesto, el algoritmo MapReduce que vimos con anterioridad y que trataremos de nuevo. Además, en el capítulo Guía de iniciación a Python - TL;DR, echamos un breve vistazo al tema de la selección de una lista.

La mayoría de los algoritmos de referencia son objeto de paquetes dedicados y lo más frecuente es que tenga que elegir entre estas implementaciones, en lugar de implementar usted mismo su código. En nuestra opinión, esta elección será tanto más pertinente si se ha preocupado de comprender sus características y ha dedicado algún tiempo a escribir sus propias versiones de algunos de ellos. Dicho esto, hemos comprobado en varias ocasiones que, a veces, es más saludable escribir una versión sencilla de un algoritmo que conoce bien que no utilizar a ciegas un paquete «mágico».

1. Equilibrio de la carga (load balancing)

Es habitual tener que repartir el esfuerzo de procesamiento (CPU, volúmenes, etc.) entre varios procesadores, discos, etc. Este es el tema del equilibrio de carga (load balancing).

El objetivo aquí es equilibrar y distribuir la carga de un servicio entre varias entidades. A menudo tenemos que elegir el algoritmo que mejor se adapte a nuestro contexto, por ejemplo: «cómo distribuir el acceso a la información ubicada en varios ordenadores, entre varias personas, en paralelo y favoreciendo o no un comportamiento global determinado».

Este tipo de algoritmo comprende dos familias (las dos listas no son exhaustivas):

  • Algoritmos estáticos:

    Round-robin: las peticiones de los clientes se envían a diferentes instancias del servicio en orden secuencial. Por lo general, los servicios no deben tener estado.

    Sticky round-robin: es una mejora del algoritmo round-robin. Si la primera solicitud se envía al servicio A, las siguientes solicitudes del mismo cliente también se envían al servicio A.

    Weighted round-robin: el administrador puede especificar el peso de cada servicio. Los servicios con mayor ponderación procesan más solicitudes que los demás.

  • Algoritmos dinámicos, más...