Dispongo de un código que simula un juego de señales entre jugadores (ver código abajo). El juego consta de 4 jugadores y 4 señales, que juegan en parejas durante 3 rondas (ver def main()
).
Definidas también en main()
, existen en el juego unas variables s1
y s2
(llamémoslas sigmas) que afectan la dinámica del juego. De tal manera que en def with_b
la variable s1
afecta la ecuación que utilizan los jugadores 1 y 2, y la variable s2
afecta la ecuación que utilizan los jugadores 3 y 4.
Estas variables s1
y s2
permanecen constantes a lo largo del juego tal y como está ahora: s1=[1,0,0,0]
y s2=[0,0,0,1]
En el juego, para cada ronda
, cada jugador
genera una lista aux
que representa la señal producida. Así, cada ronda, cada jugador producirá su aux
, que podrá ser una de las siguientes: [1,0,0,0]
o [0,1,0,0]
o [0,0,1,0]
o [0,0,0,1]
.
Objetivo
Lo que se pretende ahora es que, para cada ronda y jugador, si su aux
coincide con su sigma (s1
en caso de jugadores 1 y 2, s2
en caso de jugadores 3 y 4), se modifique el valor de sigma para ese jugador concreto según unos facotres de corrección:
s1 = [1,0,0,0] s2 = [0,0,0,1] cf_pos = 0.9 cf_neg = 0.1
Para jugadores 1 y 2:
if s1 == aux: s1[:] = [x * cf_pos for x in s1] else: s1[:] = [x * cf_neg for x in s1]
Para jugadores 3 y 4:
if s2 == aux: s2[:] = [x * cf_pos for x in s2] else: s2[:] = [x * cf_neg for x in s2]
Un problema que observo es que en el código actual aux
la estoy generando al escribir el archivo csv no en el juego en sí. También, que al ser s1
y s2
variables constantes, no sé cómo podría cambiarlas dinámicamente (de ronda en ronda) para cada jugador sin que ello cambiara también su valor de sigma para el resto de jugadores. Digamos que cada uno debería evolucionar su sigma independientemente.
Muchas gracias de antemano.
from __future__ import division from random import random, sample from bisect import bisect from collections import deque import csv import math class Partida(): def __init__(self, jugadores, emparejamientos, senales, s1, s2, b, x, m): self.emparejamientos = emparejamientos self.senales = senales self.s1 = s1 self.s2 = s2 self.b = b self.x = x self.m = m self.jugadores = {nombre: Partida.Jugador(senales) for pareja in emparejamientos[0] for nombre in pareja} self.memoria = list() self.entropy = float() def generar_senales(self): def with_b(muestra, observa, s1, s2, r, nombre): if nombre <=2: if not (muestra == observa == 0): result = ((0.98) * (1.0 - self.b) * (1.0 - self.x) * muestra / r) + ( (0.98) * (1.0 - self.b) * (self.x) * observa / r) + ((0.98) * self.b * s1) + ((self.m / 8)) else: result = ((0.98) * (1.0 - 0) * (1.0 - self.x) * muestra / r) + ( (0.98) * (1.0 - 0) * (self.x) * observa / r) + ((0.98) * 0 * s1) + ((self.m / 8)) else: if not (muestra == observa == 0): result = ((0.98) * (1.0 - self.b) * (1.0 - self.x) * muestra / r) + ( (0.98) * (1.0 - self.b) * (self.x) * observa / r) + ((0.98) * self.b * s2) + ((self.m / 8)) else: result = ((0.98) * (1.0 - 0) * (1.0 - self.x) * muestra / r) + ( (0.98) * (1.0 - 0) * (self.x) * observa / r) + ((0.98) * 0 * s2) + ((self.m / 8)) return result def choice(opciones, probs): probAcumuladas = list() aux = 0 for p in probs: aux += p probAcumuladas.append(aux) r = random() * probAcumuladas[-1] op = bisect(probAcumuladas, r) return opciones[op] yield dict(zip(self.jugadores.keys(), self.senales)) r = 1 while True: eleccs = dict.fromkeys(self.jugadores.keys()) for nombre, inst in self.jugadores.items(): probs = [with_b(inst.mem_mostradas[op], inst.men_observadas[op], self.s1[indx],self.s2[indx], r, nombre) for indx, op in enumerate(self.senales)] eleccs[nombre] = choice(self.senales, probs) r += 1 yield eleccs def jugar(self): gen_sens = self.generar_senales() for n, ronda in enumerate(self.emparejamientos): senales = next(gen_sens) self.memoria.append(senales) for jugador1, jugador2 in ronda: self.jugadores[jugador1].men_observadas[senales[jugador2]] += 1 self.jugadores[jugador2].men_observadas[senales[jugador1]] += 1 self.jugadores[jugador1].mem_mostradas[senales[jugador1]] += 1 self.jugadores[jugador2].mem_mostradas[senales[jugador2]] += 1 class Jugador(): def __init__(self, senales): self.mem_mostradas = {senal: 0 for senal in senales} self.men_observadas = {senal: 0 for senal in senales} def main(): jugadores = [1, 2, 3, 4] senales = ['S1', 'S2', 'S3', 'S4'] emparejamientos = [[(1, 2), (3, 4)], [(1, 3), (2, 4)], [(1, 4), (2, 3)]] patron = 1 ####SIGMAS#### s1 = [1, 0, 0, 0] s2 = [0, 0, 0, 1] muestras = [{'b': 0.0, 'x': 0.0, 'm': 0.02}, {'b': 1.0, 'x': 0.0, 'm': 0.02}] muestras = [d for d in muestras for _ in range(1)] simulaciones = 10 estadisticas = {sim: {jugador: {muestra: {senal: [0 for ronda in range(1, len(emparejamientos) + 1)] for senal in senales} for muestra in range(len(muestras))} for jugador in jugadores} for sim in range(simulaciones)} for sim in range(simulaciones): for mu in range(len(muestras)): juego = Partida(jugadores, emparejamientos, senales, s1,s2, muestras[mu]['b'], muestras[mu]['x'], muestras[mu]['m']) juego.jugar() for n, ronda in enumerate(juego.memoria): for jugador, senal in ronda.items(): estadisticas[sim][jugador][mu][senal][n] += 1 with open('datos.csv','w', newline='') as csvfile: writer = csv.writer(csvfile, delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL) writer.writerow(['Sim','Muestra', 'Jugador', 'Ronda', 'Patron', 'b', 'x', 'm'] + senales + ['sumpop']) # Escribiendo las estadisticas para cada jugador, ronda y muestra for jugador in jugadores: for sim in range(simulaciones): for mu in range(len(muestras)): for ronda in range(1, len(emparejamientos) + 1): aux = [estadisticas[sim][jugador][mu][senal][ronda - 1] for senal in senales] aux1 = [estadisticas[sim][1][mu][senal][ronda - 1] for senal in senales] aux2 = [estadisticas[sim][2][mu][senal][ronda - 1] for senal in senales] aux3 = [estadisticas[sim][3][mu][senal][ronda - 1] for senal in senales] aux4 = [estadisticas[sim][4][mu][senal][ronda - 1] for senal in senales] print(aux) # Lista que contiene los sumatorios de cada tipo de senales producidas a nivel de la poblacion global en cada muestra y ronda summation_pop = [] for i in range(len(aux1)): summation_pop.append( aux1[i] + aux2[i] + aux3[i] + aux4[i]) writer.writerow([sim +1, mu + 1, jugador, ronda, patron, muestras[mu]['b'], muestras[mu]['x'], muestras[mu]['m']] + aux + [summation_pop]) if __name__ == '__main__': main()