Collect x samples of x simulations

1

The following code generates a CSV in which a series of columns are displayed (PLAYER, SIGNAL, ROUND1, ROUND2, ROUND3). In the columns "RONDAx" appear the times that each player has shown a determined signal in each round throughout 1000 simulations of the game (see for _ in range(1000) ). The code is configured for 3 rounds and 4 players.

from random import random, sample
from bisect import bisect
import csv

class Partida():
    def __init__(self, jugadores, emparejamientos, senales, s, b, x, m):
        self.emparejamientos = emparejamientos
        self.senales = senales
        self.s = s
        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()


    def generar_senales(self):

        def with_b(muestra, observa, s, r):
            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 * s) + ((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 * s) + ((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.s[indx], r)
                            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)]]
    s=[1,0,0,0]
    b=0.5
    x=0.5
    m=0.02

    rondas = ['RONDA' + str(n+1) for n in range(len(emparejamientos))]
    estadisticas = {jugador:{senal:[0 for ronda in rondas]
                        for senal in senales}
                            for jugador in jugadores}

    for _ in range(1000):
        juego = Partida(jugadores, emparejamientos, senales, s, b, x, m)
        juego.jugar()
        for n, ronda in enumerate(juego.memoria):
            for jugador, senal in ronda.items():
                estadisticas[jugador][senal][n] += 1

    with open('salida.csv', 'wb') as csvfile:
        writer =csv.writer(csvfile, delimiter=',',
                    quotechar='"', quoting=csv.QUOTE_MINIMAL)
        writer.writerow(['JUGADOR', 'SENAL'] + rondas)

        for jugador in jugadores:
            for senal in senales:
                writer.writerow([jugador, senal]+estadisticas[jugador][senal])



if __name__ == '__main__':
    main()

We now want to use this same code to generate x samples of x simulations and collect the data in a CSV as in the following example:

That is to say, as shown, it is intended that the code makes 3 times 1000 simulations of the complete game, and that the results of the 3 times (3 samples) are stored as shown in the image. Where in "sample" the number "1" refers to the first 1000 simulations, "2" refers to the second 1000 simulations and so on. Where "round" refers to the round number in the game. Where "player" refers to the player number.

Note that in this case the parameters b, x and m are included in the table, and that the numbers in the "Senalx" columns should refer to the times that each signal has been chosen in each round.

    
asked by pyring 12.01.2017 в 15:21
source

2 answers

1

Making some changes to the function main() you can get what you want (if I understand you well). We simply modify the structure of estadisticas so that it also stores the variable muestra and then we create the csv with the desired structure using this data:

from random import random, sample
from bisect import bisect
import csv

class Partida():
    def __init__(self, jugadores, emparejamientos, senales, s, b, x, m):
        self.emparejamientos = emparejamientos
        self.senales = senales
        self.s = s
        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()


    def generar_senales(self):

        def with_b(muestra, observa, s, r):
            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 * s) + ((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 * s) + ((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.s[indx], r)
                            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 = ['Senal 1', 'Senal 2', 'Senal 3', 'Senal 4']
    emparejamientos = [[(1,2),(3,4)],
                       [(1,3),(2,4)],
                       [(1,4),(2,3)]]
    s=[1,0,0,0]
    b=0.5
    x=0.5
    m=0.02

    muestras = 3
    simulaciones = 1000

    estadisticas = {jugador:{muestra:{senal:[0 for ronda in range(1, len(emparejamientos)+1)]
                        for senal in senales}
                            for muestra in range(1, muestras + 1)}
                                for jugador in jugadores}


    for muestra in range(1, muestras+1):
        for _ in range(simulaciones):
            juego = Partida(jugadores, emparejamientos, senales, s, b, x, m)
            juego.jugar()
            for n, ronda in enumerate(juego.memoria):
                for jugador, senal in ronda.items():
                    estadisticas[jugador][muestra][senal][n] += 1

        with open('salida.csv', 'wb') as csvfile:
            writer =csv.writer(csvfile, delimiter=',',
                        quotechar='"', quoting=csv.QUOTE_MINIMAL)
            writer.writerow(['Muestra' ,'Jugador', 'Ronda', 'b', 'x', 'm'] + senales)

            for jugador in jugadores:
                for muestra in range(1, muestras+1):
                    for ronda in range(1, len(emparejamientos)+1):
                        aux = [estadisticas[jugador][muestra][senal][ronda-1] for senal in senales]
                        writer.writerow([muestra, jugador, ronda, b, x, m]+aux)


if __name__ == '__main__':
    main()

This generates us a csv of the form:

Edit:

If you want to be able to pass to each sample different values of b , x and m you can create a list with the rounds and pass each set of parameters within a list, or better within a dictionary. For example, if we have three rounds, we can pass the values like this:

muestras = [{'b':0.2, 'x':0.5, 'm':0.02},
            {'b':0.4, 'x':0.6, 'm':0.02},
            {'b':0.5, 'x':0.7, 'm':0.02}]

If at any given time you want all the parameters to be the same you can do something like:

muestras = [{'b':0.2, 'x':0.5, 'm':0.02} for _ in range(3)]

Which would create 3 rounds and all have values of b , x and m 0.2,0.5 and 0.02 respectively.

The code could look like this:

from random import random, sample
from bisect import bisect
import csv

class Partida():
    def __init__(self, jugadores, emparejamientos, senales, s, b, x, m):
        self.emparejamientos = emparejamientos
        self.senales = senales
        self.s = s
        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()


    def generar_senales(self):

        def with_b(muestra, observa, s, r):
            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 * s) + ((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 * s) + ((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.s[indx], r)
                            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 = ['Senal 1', 'Senal 2', 'Senal 3', 'Senal 4']
    emparejamientos = [[(1,2),(3,4)],
                       [(1,3),(2,4)],
                       [(1,4),(2,3)]]
    s=[1,0,0,0]

    muestras = [{'b':0.2, 'x':0.5, 'm':0.02},
                {'b':0.4, 'x':0.6, 'm':0.02},
                {'b':0.5, 'x':0.7, 'm':0.02}]


    simulaciones = 1000
    estadisticas = {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 mu in range(len(muestras)):
        for _ in range(simulaciones):
            juego = Partida(jugadores, emparejamientos, senales, s, 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[jugador][mu][senal][n] += 1

        with open('salidav4.csv', 'wb') as csvfile:
            writer =csv.writer(csvfile, delimiter=',',
                        quotechar='"', quoting=csv.QUOTE_MINIMAL)
            writer.writerow(['Muestra' ,'Jugador', 'Ronda', 'b', 'x', 'm'] + senales)

            for jugador in jugadores:
                for mu in range(len(muestras)):
                    for ronda in range(1, len(emparejamientos)+1):
                        aux = [estadisticas[jugador][mu][senal][ronda-1] for senal in senales]
                        writer.writerow([mu+1, jugador, ronda, muestras[mu]['b'], muestras[mu]['x'], muestras[mu]['m']]+aux)


if __name__ == '__main__':
    main()

What generates something like:

I think that is what you want but check it just in case.

    
answered by 12.01.2017 / 17:16
source
0

Taking the latest version of the code, I have been implementing a new possibility. It will be observed that the variable s (which refers to something like the intrinsic value of each signal and that is taken into account in the equation when calculating the probability with which each signal will be chosen in the next generation), until now had been declaring itself as a fixed list:

s= [1,0,0,0] #El valor de la "señal 1" es 1, de la "señal 2" 0, de la "señal 3" 0 y de la "señal 4" 0.

Well, I have implemented the possibility that the values of the signals can be alternated and we can perform x simulations for each combination of intrinsic values of s. I have only touched the function _init_ and the function def main() , to obtain a CSV with the impression of the results.

Here is the code:

from random import random, sample
from bisect import bisect
import csv

class Partida():
    def __init__(self, jugadores, emparejamientos, senales, s1,s2,s3,s4, b, x, m):
        self.emparejamientos = emparejamientos
        self.senales = senales
        self.s = [s1,s2,s3,s4]
        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()


    def generar_senales(self):

        def with_b(muestra, observa, s, r):
            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 * s) + ((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 * s) + ((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.s[indx], r)
                            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 = ['Senal 1', 'Senal 2', 'Senal 3', 'Senal 4']
    emparejamientos = [[(1, 2), (3, 4)],
                       [(1, 3), (2, 4)],
                       [(1, 4), (2, 3)]]

    patron=1
    sm = [{'s1': 1, 's2': 0, 's3': 0, 's4': 0},
         {'s1': 0, 's2': 1, 's3': 0, 's4': 0},
         {'s1': 0, 's2': 0, 's3': 1, 's4': 0},
         {'s1': 0, 's2': 0, 's3': 0, 's4': 1}]
    sm = [d for d in sm for _ in range (10)]

    muestras = [{'b': 0.0, 'x': 0.0, 'm': 0.02},
                {'b': 0.5, 'x': 0.5, 'm': 0.02},
                {'b': 1.0, 'x': 1.0, 'm': 0.02}]
    muestras = [d for d in muestras for _ in range(10)]

    simulaciones = 10

    estadisticas = {jugador:{s:{muestra:{senal:[0 for ronda in range(1, len(emparejamientos)+1)]
                        for senal in senales}
                            for muestra in range(len(muestras))}
                                for s in range(len(sm))}
                                    for jugador in jugadores}


    for su in range(len(sm)):
        for mu in range(len(muestras)):
            for _ in range(simulaciones):
                juego = Partida(jugadores, emparejamientos, senales, sm[su]['s1'], sm[su]['s2'],sm[su]['s3'],sm[su]['s4'], 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[jugador][su][mu][senal][n] += 1

        with open('practica2.csv', 'wb') as csvfile:
            writer =csv.writer(csvfile, delimiter=';',
                        quotechar='"', quoting=csv.QUOTE_MINIMAL)
            writer.writerow(['Muestra', 'Jugador', 'Ronda', 'Patron','s1','s2','s3','s4', 'b', 'x', 'm'] + senales)

            for jugador in jugadores:
                for su in range(len(sm)):
                    for mu in range(len(muestras)):
                        for ronda in range(1, len(emparejamientos)+1):
                            aux = [estadisticas[jugador][su][mu][senal][ronda-1] for senal in senales]
                            writer.writerow([mu+1, jugador, ronda, patron, sm[su]['s1'], sm[su]['s2'],sm[su]['s3'],sm[su]['s4'], muestras[mu]['b'], muestras[mu]['x'], muestras[mu]['m']]+aux)


if __name__ == '__main__':
    main()

I would like to know if these implementations that I have made in the code are correct.

Edit:

Additionally, what is more complicated for me to think about how to solve, imagine that we want to obtain the results of the game (our game now allows to obtain x samples of x simulations for each desired combination of parameters) for two different patterns in the order of pairings For example, an A pattern of pairings with a B pattern of pairings:

patronA_emparejamientos =[[(1, 2), (3, 4)],
                         [(1, 3), (2, 4)],
                         [(1, 4), (2, 3)]]

patronB_emparejamientos =[[(1, 3), (2, 4)],
                         [(1, 4), (2, 3)],
                         [(1, 2), (3, 4)]]

This we can now do with our program by doing 2 simulations independently, one for the type of pairings A and one for the type of pairings B, and then combining the csv files. But it does not stop being cumbersome.

Any ideas for the program to give us the possibility of obtaining in the same csv file the results of both pairing patterns?

    
answered by 14.01.2017 в 17:26