Proyecto 1: Dilema del prisionero

Usted debe desarrollar un programa para llevar a cabo simulaciones de torneos basados en el dilema del prisionero iterado de Axelrod. En términos generales el dilema del prisionero clásico es el siguiente:

El OIJ arresta a dos miembros A y B de una banda criminal. No hay pruebas suficientes para determinar quién es el autor principal del crimen. Tras haberlos separado, se les visita a cada uno y se les ofrece la oportunidad de reducir su condena delatando al otro, o de cooperar con el otro guardando silencio. Puede entonces ocurrir lo siguiente:

  1. Si A delata a B, y B guarda silencio, B será condenado a la pena total de diez años y A será liberado.
  2. Si A calla, y B delata a A, entonces A recibirá la pena de diez años y B saldrá libre.
  3. Si ambos delatan al otro, ambos serán condenados a seis años.
  4. Si ambos callan, serán encerrarlos durante un año por cargos menores.

Para efectos de esta tarea se utilizará la siguiente información de los posibles resultados:

Prisionero A Prisionero B Prisionero A Prisionero B Ambos
Calla Calla 1 año de cárcel 1 año de cárcel 2 años de cárcel
Calla Delata a A 10 años de cárcel 0 años de cárcel 10 años de cárcel
Delata a B Calla 0 años de cárcel 10 años de cárcel 10 años de cárcel
Delata a B Delata a A 6 años de cárcel 6 años de cárcel 12 años de cárcel

Lo interesante del dilema del prisionero es que muestra que dos individuos completamente racionales podrían no cooperar, incluso aunque eso vaya en contra de sus intereses. Para ejemplificarlo mediante cmputadora, Robert Axelrod propuso torneos donde se enfrentaban programas, en los cuales los prisioneros se comportan como agentes. Al igual que las personas, los agentes podrán tener sus preferencias personales y memoria de los resultados obtenidos en las iteraciones anteriores dentro del mismo torneo. Ustedes deben escribir un programa que tenga disponibles 6 tipos de prisioneros diferentes:

  1. El prisionero egoísta que siempre delata con el fin de obtener 0 años de cárcel.
  2. El prisionero ingenuo que siempre opta por callar.
  3. El prisionero aleatorio selecciona aleatoriamente en cada momento si esa vez delata o calla.
  4. Un prisionero imitador que hace lo que su rival hizo en el turno anterior. Al inicio decide aleatoriamente qué hacer.
  5. Un prisionero imitador con traición que al inicio calla, pero tiene un 90% de probabilidad de hacer lo mismo que hizo su rival en el turno anterior y un 10% de probabilidad de delatar.
  6. Un prisionero original cuya estrategia ustedes definirán tratando de obtener la menor cantidad promedio de años de cárcel si se enfrenta con prisioneros de los otros tipos.

Su programa servirá para ejecutar experimentos grupales o enfrentamientos específicos.

Experimentos grupales

Los experimentos grupales son rondas de enfrentamientos de todos contra todos. En una ronda se crearán seis prisioneros competidores y seis rivales. Cada competidor se enfrentará una vez contra cada uno de los seis prisioneros rivales (incluso contra otro prisionero de su mismo tipo). Es decir, cada ronda constará de 36 enfrentamientos prisionero contra prisionero.

Sin embargo, como algunos prisioneros se comportan distinto en el primer turno que en los demás, cada enfrentamiento se repetirá cerca de 10 turnos.

Durante cada turno de un enfrentamiento, un juez es el responsable de juzgar a ambos prisioneros y dar el veredicto acorde a si confiesan o callan. El veredicto del juez debe informar a cada uno cuántos años de cárcel acaba de ser condenado y así cada uno sabrá qué fue lo que el otro hizo.

Con el fin de obtener estadísticas, la simulación ejecutará un número arbitrario de rondas indicado por el usuario. Se recomienda que este número sea grande. En cada ronda, los 36 enfrentamientos se repetirán un número de turnos escogidos aleatoriamente entre 1 y 10.

La simulación calculará es la cantidad de años cárcel acumulada a la que son sentenciados los seis prisioneros competidores luego de ejecutar todas las rondas. La estadística principal que se desea reportar es el porcentaje de años de prisión al que fue condenado cada tipo de prisionero con respecto al total de años que pudo haber ido (10 años máximo por cada enfrentamiento).

La simulación debe reportar:

  1. La cantidad de años que fue cada tipo de prisionero a la cárcel.
  2. El porcentaje de años de cárcel de cada tipo de prisionero.
  3. El prisionero que obtuvo la menor cantidad de años de cárcel (mejor estrategia).
  4. El prisionero que obtuvo la mayor cantidad de años de cárcel (peor estrategia).

Un ejemplo de interacción podría ser el siguiente:

$ java Prisioner
Simulation [1=groups 2=specific]: 1
Rounds [N>=1]: 1000
Turns [-1=random N>=1]: 5

PRISIONER  YEARS  AVERAGE  REMARKS
Selfish    28300     1.26
Naive      27800     1.24
Random     35150     1.56  (worst)
Imitator   26705     1.19
Original   24825     1.10  (best)

Su programa también debe poder correr en lote sin interacción. Los parámetros de la simulación se deben proveer entonces por argumentos en línea de comandos. Por ejemplo:

$ java Prisioner groups -r 1000
PRISIONER  YEARS  AVERAGE  REMARKS
Selfish    28300     1.26
Naive      27800     1.24
Random     35150     1.56  (worst)
Imitator   26705     1.19
Traitor    30150     1.34
Original   24825     1.10  (best)

Si los turnos no se especifican en la lista de parámetros, se debe asumir que se escogerán al azar. La cantidad de rondas debe especificarse obligatoriamente, de lo contrario se debe producir un mensaje de error en el error estándar.

Enfrentamientos específicos

En esta opción el programa llevará a cabo un enfrentamiento entre dos tipos de prisionero seleccionados por el usuario. En este caso la cantidad de turnos no es aleatoria sino que será definida por el usuario.

Se debe reportar el resultado de cada enfrentamiento particular, con el fin de permitir a los investigadores rastrear el proceso. Se deberá reportar las mismas estadísticas que los experimentos grupales.

Un ejemplo de interacción podría ser el siguiente

$ java Prisioner
Simulation [1=groups 2=specific]: 2
Prisioner 1 [selfish naive random imitator traitor original]: naive
Prisioner 2 [selfish naive random imitator traitor original]: imitator
Turns [-1=random N>=1]: 2

TURN  NAIVE  IMITATOR
   1     10         0
   2      2         2

PRISIONER  YEARS  AVERAGE  REMARKS
Naive         12     0.60  (worst)
Imitator       2     0.10  (best)

Su programa también debe poder correr en lote sin interacción. Los parámetros de la simulación se deben proveer entonces por argumentos en línea de comandos. Por ejemplo:

$ java Prisioner specific -p1 naive -p2 imitator -t 2
TURN  NAIVE  IMITATOR
   1     10         0
   2      2         2

PRISIONER  YEARS  AVERAGE  REMARKS
Naive         12     0.60  (worst)
Imitator       2     0.10  (best)

Ayuda del programa

Si su programa se llama con el parámetro -help deberá proveer ayuda al usuario. Ustedes pueden implementar las opciones que se proponen a continuación y que se han usado en ejemplos de ejecución anterior, o pueden sugerir alternativas.

$ java Prisioner -help
Simulation of Prisioner's dilemma v1.0 [2017-Sep-20]
Author 1 <email1@address> and Author 2 <email2@address>

Usage: java Prisioner [Type] [Options]

Type:
  groups          Runs a group experiment simulation
  specific        Runs a specific confrontation

Options:

  -r ROUNDS       Number of rounds to run the simulation
  -t TURNS        Number of turns to repeat each confrontation
  -p1 PRISIONER   Chooses the first prisioner type. See below
  -p2 PRISIONER   Chooses the second prisioner type. See below

Suported prisioners:
  selfish, naive, random, imitator, traitor, original

Examples:

  java Prisioner
    Run simulation in interactive mode, asking for all the parameters.

  java Prisioner groups -r 1000
    Run a group experiment of 1000 rounds each with random-selected turns

  java Prisioner specific -p1 naive -p2 imitator -t 2
    Run a specific confrontation of 2 turns between a naive prisioner and
    an imitator one

Entregable 1 [28-Set-2017]

Se entregará un repositorio, documentación general, y una aplicación inicial que reconoce parámetros.

  1. [10%] Repositorio de control de versiones en BitBucket.
  2. [15%] Documentación general del proyecto en Markdown (README.md).
  3. [15%] Diagrama de clases.
  4. [15%] Diagrama de interacción general.
  5. [20%] Programa en Java que imprime ayuda (interfaz con el usuario) y textos indicativos de cada comando.
  6. [15%] Documentación interna: JavaDoc y comentarios en cuerpos de métodos.
  7. [10%] Buenas prácticas de programación

Entregable 2 [12-Oct-2017]

La aplicación será capaz de ejecutar enfrentamientos específicos, tanto en forma interactiva como en lote.

Entregable 3 [27-Oct-2017]

La aplicación será capaz de ejecutar experimentos grupales, tanto en forma interactiva como en lote.