El tipo abstracto de datos de las colas de prioridad

1. El tipo abstracto de datos de las colas de prioridad

Una cola de prioridad es una cola en la que cada elemento tiene asociada una prioridad. La operación de extracción siempre elige el elemento de menor prioridad.

Las operaciones que definen a tipo abstracto de datos (TAD) de las colas de prioridad (cuyos elementos son del tipo a) son las siguientes:

tales que

  • vacia es la cola de prioridad vacía.
  • (inserta x c) añade el elemento x a la cola de prioridad c.
  • (primero c) es el primer elemento de la cola de prioridad c.
  • (resto c) es el resto de la cola de prioridad c.
  • (esVacia c) se verifica si la cola de prioridad c es vacía.

Las operaciones tienen que verificar las siguientes propiedades:

  • inserta x (inserta y c) == inserta y (inserta x c)
  • primero (inserta x vacia) == x
  • Si x <= y, entonces primero (inserta y (inserta x c)) == primero (inserta x c)
  • resto (inserta x vacia) == vacia
  • Si x <= y, entonces resto (inserta y (inserta x c)) == inserta y (resto (inserta x c))
  • esVacia vacia
  • not (esVacia (inserta x c))

2. Las colas de prioridad en Haskell

2.1. El tipo abstracto de datos de las colas de prioridad en Haskell

El TAD de las colas de prioridadd se encuentra en el módulo ColaDePrioridad.hs cuyo contenido es el siguiente:

Para usar el TAD hay que usar una implementación concreta. En principio,
solo considearemos una que usa las listas.

2.2. Implementación de las colas de prioridad mediante listas

La implementación se encuentra en el módulo ColaDePrioridadConListas.hs cuyo contenido es el siguiente:

3. Las colas de prioridad en Python

3.1. El tipo abstracto de las colas de prioridad en Python

La implementación se encuentra en el módulo ColaDePrioridad.py cuyo contenido es el siguiente:

Para usar el TAD hay que usar una implementación concreta. En principio, consideraremos solo una que usa las listas.

3.2. Implementación de las colas de prioridad mediante listas

La implementación se encuentra en el módulo ColaDePrioridadConListas.py en el que se define la clase CPrioridad con los siguientes métodos:

  • inserta(x) añade x a la cola.
  • primero() es el primero de la cola.
  • resto() elimina el primero de la cola.
  • esVacia() se verifica si la cola es vacía.

Por ejemplo,

Además se definen las correspondientes funciones. Por ejemplo,

Finalmente, se define un generador aleatorio de colas de prioridad y se comprueba que las colas de prioridad cumplen las propiedades de su especificación.

El problema de la mochila (mediante espacio de estados)

Se tiene una mochila de capacidad de peso p y una lista de n para colocar en la mochila. Cada objeto i tiene un peso w(i) y un valor v(i). Considerando la posibilidad de colocar el mismo objeto varias veces en la mochila, el problema consiste en determinar la forma de colocar los objetos en la mochila sin sobrepasar la capacidad de la mochila colocando el máximo valor posible.

Para solucionar el problema se definen los siguientes tipos:

  • Una solución del problema de la mochila es una lista de objetos.

  • Los objetos son pares formado por un peso y un valor

  • Los pesos son número enteros

  • Los valores son números reales.

  • Los estados del problema de la mochila son 5-tupla de la (v,p,l,o,s) donde v es el valor de los objetos colocados, p es el peso de los objetos colocados, l es el límite de la capacidad de la mochila, o es la lista de los objetos colocados (ordenados de forma creciente según sus pesos) y s es la solución parcial.

Usando el procedimiento de búsqueda en profundidad, definir la función

tal que mochila os l es la solución del problema de la mochila para la lista de objetos os y el límite de capacidad l. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell


Soluciones en Python

El problema de las n reinas (mediante búsqueda por anchura en espacios de estados)

El problema de las n reinas consiste en colocar n reinas en un tablero cuadrado de dimensiones n por n de forma que no se encuentren más de una en la misma línea: horizontal, vertical o diagonal.

Las posiciones de las reinas en el tablero se representan por su columna y su fila.

Una solución del problema de las n reinas es una lista de posiciones.

Usando el procedimiento de búsqueda en anchura, definir las funciones

tales que

  • solucionesNR n es la lista de las soluciones del problema de las n reinas, por búsqueda de espacio de estados en anchura. Por ejemplo,

  • primeraSolucionNR n es la primera solución del problema de las n reinas, por búsqueda en espacio de estados por anchura. Por ejemplo,

  • nSolucionesNR n es el número de soluciones del problema de las n reinas, por búsqueda en espacio de estados. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell


Soluciones en Python

Búsqueda por anchura en espacios de estados

Las características de los problemas de espacios de estados son:

  • un conjunto de las posibles situaciones o nodos que constituye el espacio de estados (estos son las potenciales soluciones que se necesitan explorar),
  • un conjunto de movimientos de un nodo a otros nodos, llamados los sucesores del nodo,
  • un nodo inicial y
  • un nodo objetivo que es la solución.

Definir la función

tal que buscaAnchura s o e es la lista de soluciones del problema de espacio de estado definido por la función sucesores s, el objetivo o y estado inicial e obtenidas mediante búsqueda en anchura.

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell


Soluciones en Python

El problema de las n reinas (mediante búsqueda por profundidad en espacios de estados)

El problema de las n reinas consiste en colocar n reinas en un tablero cuadrado de dimensiones n por n de forma que no se encuentren más de una en la misma línea: horizontal, vertical o diagonal.

Las posiciones de las reinas en el tablero se representan por su columna y su fila.

Una solución del problema de las n reinas es una lista de posiciones.

Usando el procedimiento de búsqueda en profundidad, definir las funciones

tales que

  • solucionesNR n es la lista de las soluciones del problema de las n reinas, por búsqueda de espacio de estados en profundidad. Por ejemplo,

  • primeraSolucionNR n es la primera solución del problema de las n reinas, por búsqueda en espacio de estados por profundidad. Por ejemplo,

  • nSolucionesNR n es el número de soluciones del problema de las n reinas, por búsqueda en espacio de estados. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell


Soluciones en Python

Búsqueda en espacios de estados por profundidad

Las características de los problemas de espacios de estados son:

  • un conjunto de las posibles situaciones o nodos que constituye el espacio de estados (estos son las potenciales soluciones que se necesitan explorar),
  • un conjunto de movimientos de un nodo a otros nodos, llamados los sucesores del nodo,
  • un nodo inicial y
  • un nodo objetivo que es la solución.

Definir la función

tal que buscaProfundidad s o e es la lista de soluciones del problema de espacio de estado definido por la función sucesores s, el objetivo o y estado inicial e obtenidas mediante búsqueda en profundidad.

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell


Soluciones en Python

Rompecabeza del triominó mediante divide y vencerás

Un poliominó es una figura geométrica plana formada conectando dos o más cuadrados por alguno de sus lados. Los cuadrados se conectan lado con lado, pero no se pueden conectar ni por sus vértices, ni juntando solo parte de un lado de un cuadrado con parte de un lado de otro. Si unimos dos cuadrados se obtiene un dominó, si se juntan tres cuadrados se construye un triominó.

Sólo existen dos triominós, el I-triomino (por tener forma de I) y el L-triominó (por su forma de L) como se observa en las siguientes figuras

El rompecabeza del triominó consiste en cubrir un tablero cuadrado con 2^n filas y 2^n columnas, en el que se ha eliminado una casilla, con L-triominós de formas que cubran todas las casillas excepto la eliminada y los triominós no se solapen.

La casilla eliminada se representará con -1 y los L-triominós sucesiones de tres números consecutivos en forma de L. Con esta representación una solución del rompecabeza del triominó con 4 filas y la fila eliminada en la posición (4,4) es

Definir la función

tal que (triomino n p) es la solución, mediante divide y vencerás, del rompecabeza del triominó en un cuadrado nxn en el que se ha eliminado la casilla de la posición p. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell


Soluciones en Python

Algoritmo divide y vencerás

La técnica divide y vencerás consta de los siguientes pasos:

  • Dividir el problema en subproblemas menores.
  • Resolver por separado cada uno de los subproblemas:
    • si los subproblemas son complejos, usar la misma técnica recursivamente;
    • si son simples, resolverlos directamente.
  • Combinar todas las soluciones de los subproblemas en una solución simple.

Definir la función

tal que divideVenceras ind resuelve divide combina pbInicial resuelve el problema pbInicial mediante la técnica de divide y vencerás, donde

  • ind pb se verifica si el problema pb es indivisible
  • resuelve pb es la solución del problema indivisible pb
  • divide pb es la lista de subproblemas de pb
  • combina pb ss es la combinación de las soluciones ss de los subproblemas del problema pb.
  • pbInicial es el problema inicial

Usando la función DivideVenceras, definir las funciones

tales que

  • ordenaPorMezcla xs es la lista obtenida ordenando xs por el procedimiento de ordenación por mezcla. Por ejemplo,

  • ordenaRapida xs es la lista obtenida ordenando xs por el procedimiento de ordenación rápida. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell


Soluciones en Python