Beispiel #1
0
def prueba_poisson(random):
    gen = Generador(x=12, c=40, k=27, g=14, decimals=4, random=random)
    datos = gen.poisson(lam=1, n=1000)
    tabla = Poisson(datos=datos, decimals=4)
    tabla.prueba_de_bondad()
    print(tabla)
    tabla.histogram()
Beispiel #2
0
def prueba_normal(random, box=True):
    gen = Generador(x=12, c=40, k=27, g=14, decimals=4, random=random)
    datos = gen.normal(media=0, desviacion=1, n=1000, box=box)
    tabla = Normal(num_intervalos=10, datos=datos, decimals=4)
    tabla.prueba_de_bondad()
    print(tabla)
    tabla.histogram()
Beispiel #3
0
def prueba_exponencial(random):
    gen = Generador(x=12, c=40, k=27, g=14, decimals=4, random=random)
    datos = gen.exponencial(lam=10, n=1000)
    tabla = Exponencial(num_intervalos=10, datos=datos, decimals=4)
    tabla.prueba_de_bondad()
    print(tabla)
    tabla.histogram()
Beispiel #4
0
    def test_rnd(self):
        gen = Generador(x=6, c=7, k=3, g=3)
        self.assertEqual(13, gen.a)
        self.assertEqual(8, gen.m)

        self.assertEqual(0.625, estadistica.truncate(gen.rnd(), 4))
        self.assertEqual(5, gen.x)
        self.assertNotEqual(gen.rnd(), gen.rnd())
Beispiel #5
0
def prueba_uniforme(random):
    gen = Generador(x=12, c=40, k=27, g=14, decimals=4, random=random)
    datos = gen.uniforme(a=0, b=10, n=25)
    tabla = Uniforme(num_intervalos=5, datos=datos, decimals=4)
    # tabla.chi_uniforme()
    tabla.prueba_de_bondad()
    print(tabla)
    tabla.histogram()
Beispiel #6
0
 def __init__(self):
     self.nombre = "Grupo"
     self.generador_ocupacion = Generador(decimals=4, random=True)
     self.generador_llegada = Generador(decimals=4, random=True)
     self.cola = False
     self.acondicionando = False
     self.fin_ocupacion = 0
     self.cancha = None
     self.tipo = ""
     self.finalizado = False
Beispiel #7
0
    def __init__(self,
                 capcacidades,
                 desde=0,
                 hasta=30,
                 ultimas_filas=10,
                 decimales=4):
        self.tabla = []
        self.tabla_final = []
        self.pos_ultimo_elemento = 0
        self.generador = Generador(decimals=decimales, random=True)
        self.decimales = decimales
        self.cantidad_iteraciones = 1

        # Inicializacion
        self.numero = 0
        self.evento = 'Inicializacion'
        self.reloj = 0
        self.set_proxima_llegada()

        self.lote_actual = None

        # Resultados
        self.cantidad_visitas = 0
        self.maximo_cola = 0

        # Parametros de visualizacion
        self.desde = desde
        self.hasta = hasta
        self.ultimas_filas = ultimas_filas

        # Salas
        self.sala_a = SalaNormal("A",
                                 capacidad=capcacidades[0],
                                 media=30,
                                 desviacion=5)
        self.sala_b = SalaNormal("B",
                                 capacidad=capcacidades[1],
                                 media=25,
                                 desviacion=4)
        self.sala_c = SalaUniforme("C",
                                   capacidad=capcacidades[2],
                                   minimo=12,
                                   maximo=18)
        self.sala_d = SalaUniforme("D",
                                   capacidad=capcacidades[3],
                                   minimo=14,
                                   maximo=18)

        # TP6
        self.estado_servidor = 'libre'
        self.porc_inestable = 0
        self.tiempo_inestable = 0
        self.fin_purga = 0
        self.inicio_purga = 0
        self.k = 20
Beispiel #8
0
 def __init__(self):
     self.generador = Generador(decimals=4, random=True)
     self.grupo_actual = None
     self.en_cancha = []
     self.en_cola_FutbolHandball = []
     self.en_colaBasquet = []
     self.acondicionando = False
     self.tiempo_acondicionado = 0
Beispiel #9
0
    def __init__(self, desde=0, hasta=30, ultimas_filas=10, medias_llegada=[10, 12, 8], medias_ocupacion=[1.30, 1.33, 1.67], desviaciones_llegada=[0, 2, 2], desviaciones_ocupacion=[0.167, 0.33, 0.5]):
        self.tabla = []
        self.tabla_final = []
        self.cantidad_iteraciones = 1
        self.decimales = 4
        #Paso arrays para poder config los tiempos de llegada  ocup
        self.medias_llegada = medias_llegada
        self.medias_ocupacion = medias_ocupacion
        self.desviaciones_llegada = desviaciones_llegada
        self.desviaciones_ocupacion = desviaciones_ocupacion

        self.generadorFutbol = Generador(decimals=4, random=True)
        self.generadorHandball = Generador(decimals=4, random=True)
        self.generadorBasquet = Generador(decimals=4, random=True)

        self.numero = 0
        self.evento = "Inicializacion"
        self.reloj = 0

        self.desde = desde
        self.hasta = hasta
        self.ultimas_filas = ultimas_filas

        self.cancha = Cancha()
        self.acondicionando = False

        #En_todo momento van a haber 3 grupos concurrentes cada uno con su tiempo de ocupacion
        self.grupo_actual = None
        self.grupo_actual_futbol = GrupoFutbol(media=self.medias_ocupacion[0], desviacion=self.desviaciones_ocupacion[0])
        self.grupo_actual_handball = GrupoHandball(media=self.medias_ocupacion[1], desviacion=self.desviaciones_ocupacion[1])
        self.grupo_actual_basquet = GrupoBasquet(media=self.medias_ocupacion[2], desviacion=self.desviaciones_ocupacion[2])

        self.grupos_futbol = []
        self.grupos_handball = []
        self.grupos_basquet = []

        #Determino las primeras llegadas de cada grupo
        self.proxima_llegada_futbol = self.generadorFutbol.exponencial_next(media=self.medias_llegada[0])
        self.proxima_llegada_handball = self.generadorHandball.box_muller_next(media=self.medias_llegada[1], desviacion=self.desviaciones_llegada[1])
        self.proxima_llegada_basquet = self.generadorHandball.box_muller_next(media=self.medias_llegada[2], desviacion=self.desviaciones_llegada[2])
        """"#Las meto en un array y lo ordeno cada vez que se modifica un valor
        self.proximas_llegadas = []
        self.proximas_llegadas.append(self.proxima_llegada_futbol)
        self.proximas_llegadas.append(self.proxima_llegada_handball)
        self.proximas_llegadas.append(self.proxima_llegada_basquet)
        self.ordenar_llegadas()"""
        #Determino cual es la prox llegada
        self.set_proxima_llegada()
Beispiel #10
0
 def test_truncate(self):
     gen = Generador(decimals=5)
     self.assertEqual(gen.truncate(0.1234567), 0.12345)
     gen.decimals = 2
     self.assertEqual(gen.truncate(0.1234567), 0.12)
Beispiel #11
0
class Iteracion:

    def __init__(self, desde=0, hasta=30, ultimas_filas=10, medias_llegada=[10, 12, 8], medias_ocupacion=[1.30, 1.33, 1.67], desviaciones_llegada=[0, 2, 2], desviaciones_ocupacion=[0.167, 0.33, 0.5]):
        self.tabla = []
        self.tabla_final = []
        self.cantidad_iteraciones = 1
        self.decimales = 4
        #Paso arrays para poder config los tiempos de llegada  ocup
        self.medias_llegada = medias_llegada
        self.medias_ocupacion = medias_ocupacion
        self.desviaciones_llegada = desviaciones_llegada
        self.desviaciones_ocupacion = desviaciones_ocupacion

        self.generadorFutbol = Generador(decimals=4, random=True)
        self.generadorHandball = Generador(decimals=4, random=True)
        self.generadorBasquet = Generador(decimals=4, random=True)

        self.numero = 0
        self.evento = "Inicializacion"
        self.reloj = 0

        self.desde = desde
        self.hasta = hasta
        self.ultimas_filas = ultimas_filas

        self.cancha = Cancha()
        self.acondicionando = False

        #En_todo momento van a haber 3 grupos concurrentes cada uno con su tiempo de ocupacion
        self.grupo_actual = None
        self.grupo_actual_futbol = GrupoFutbol(media=self.medias_ocupacion[0], desviacion=self.desviaciones_ocupacion[0])
        self.grupo_actual_handball = GrupoHandball(media=self.medias_ocupacion[1], desviacion=self.desviaciones_ocupacion[1])
        self.grupo_actual_basquet = GrupoBasquet(media=self.medias_ocupacion[2], desviacion=self.desviaciones_ocupacion[2])

        self.grupos_futbol = []
        self.grupos_handball = []
        self.grupos_basquet = []

        #Determino las primeras llegadas de cada grupo
        self.proxima_llegada_futbol = self.generadorFutbol.exponencial_next(media=self.medias_llegada[0])
        self.proxima_llegada_handball = self.generadorHandball.box_muller_next(media=self.medias_llegada[1], desviacion=self.desviaciones_llegada[1])
        self.proxima_llegada_basquet = self.generadorHandball.box_muller_next(media=self.medias_llegada[2], desviacion=self.desviaciones_llegada[2])
        """"#Las meto en un array y lo ordeno cada vez que se modifica un valor
        self.proximas_llegadas = []
        self.proximas_llegadas.append(self.proxima_llegada_futbol)
        self.proximas_llegadas.append(self.proxima_llegada_handball)
        self.proximas_llegadas.append(self.proxima_llegada_basquet)
        self.ordenar_llegadas()"""
        #Determino cual es la prox llegada
        self.set_proxima_llegada()

    #No entiendo como funciona este diccionario
    def __str__(self):
        dic = self.as_dict
        dic.pop('cancha')
        dic.pop('grupos')
        cancha = self.as_dict['cancha']
        grupos = self.as_dict['grupos']
        grupos = '\t' + '\n\t'.join([str(grupo) for grupo in grupos])
        return f"{dic}\n{cancha}\n{grupos}\n"

    #Este tampoco
    def print_tabla(self, tabla):
        print("Tabla")
        for linea in tabla:
            dic = linea.copy()
            cancha = dic.pop('cancha')
            grupos = dic.pop('grupos')
            grupos = '\t' + '\n\t'.join([str(grupo) for grupo in grupos.items()])
            print(f"{dic}\n{cancha}\n{grupos}")
            print("-" * 20)

    def show_evento(self):
        if self.evento == "fin_ocupacion" or self.evento == "llegada":
            if self.grupo_actual:
                return self.evento + '_' + str(self.grupo_actual.nombre)
        return self.evento

    # Devuelve un diccionario con los valores actuales del objeto
    @property
    def as_dict(self):
        # Creo un diccionario con todos los atributos del objeto
        dic = {
            'numero': self.numero,
            'evento': self.show_evento(),
            'reloj': round(self.reloj, self.decimales),
            'proxima_llegada': self.proxima_llegada,
            'prox llegada futbol': self.proxima_llegada_futbol,
            'prox llegada handball': self.proxima_llegada_handball,
            'prox llegada basquet': self.proxima_llegada_basquet,
            #Cancha
            'cancha': self.cancha.as_dict(),
            'grupos': {grupo.numero : grupo.as_dict() for grupo in self.get_grupos()}
        }
        return dic

    #Igual que en otros TPs
    def guardar_iteracion(self):
        "Guarda el estado de una iteracion"
        if self.desde <= self.numero <= self.hasta:
            self.tabla.append(self.as_dict)
        else:
            self.tabla_final.append(self.as_dict)
            if len(self.tabla_final) > self.ultimas_filas:
                self.tabla_final.pop(0)
            # Actualizo el proximo elemnto a reemplazar cuidando de que se mantenga en el rango de las ultimas filas
            # self.pos_ultimo_elemento = (self.pos_ultimo_elemento + 1) % self.ultimas_filas

    def get_grupos_full(self):
        return self.get_grupos_futbol() + self.get_grupos_handball() + self.get_grupos_basquet()

    def get_grupos(self):
        return self.get_grupos_en_sala() + self.get_grupos_en_cola_futbolhandball() + self.get_grupos_en_cola_basquet()

    def get_grupos_en_sala(self):
        return self.cancha.en_cancha

    def get_grupos_en_cola_futbolhandball(self):
        return self.cancha.en_cola_FutbolHandball

    def get_grupos_en_cola_basquet(self):
        return self.cancha.en_colaBasquet

    def get_grupos_futbol(self):
        return self.grupos_futbol

    def get_grupos_handball(self):
        return self.grupos_handball

    def get_grupos_basquet(self):
        return self.grupos_basquet

    def ordenar_tabla_final(self):
        "Ordena la tabla final"
        self.tabla_final = self.tabla_final[self.pos_ultimo_elemento:] + self.tabla_final[:self.pos_ultimo_elemento]

    def set_proxima_llegada(self):
        self.proxima_llegada = min(self.proxima_llegada_futbol, self.proxima_llegada_handball, self.proxima_llegada_basquet)

    def add_proxima_llegada(self, grupo_proximo):
        if grupo_proximo.tipo == "Futbol":
            self.grupo_actual_futbol = GrupoFutbol(media=self.medias_ocupacion[0],desviacion=self.desviaciones_ocupacion[0])
            self.grupos_futbol.append(self.grupo_actual_futbol)
            self.proxima_llegada_futbol = round(self.reloj + self.generadorFutbol.box_muller_next(media=self.medias_llegada[0]), 4)
        elif grupo_proximo.tipo == "Handball":
            self.grupo_actual_handball = GrupoHandball(media=self.medias_ocupacion[1],desviacion=self.desviaciones_ocupacion[1])
            self.grupos_handball.append(self.grupo_actual_handball)
            self.proxima_llegada_handball = round(self.reloj + self.generadorHandball.box_muller_next(media=self.medias_llegada[1],desviacion=self.desviaciones_llegada[1]), 4)
        else:
            self.grupo_actual_basquet = GrupoBasquet(media=self.medias_ocupacion[2],desviacion=self.desviaciones_ocupacion[2])
            self.grupos_basquet.append(self.grupo_actual_basquet)
            self.proxima_llegada_basquet = round(self.reloj + self.generadorBasquet.box_muller_next(media=self.medias_llegada[2],desviacion=self.desviaciones_llegada[2]), 4)
        self.set_proxima_llegada()

    """"#Ordenar array de llegadas para ver cual es la siguiente
    def ordenar_llegadas(self):
        proxima_llegada = self.proximas_llegadas[0]
        for llegada in self.proximas_llegadas[1:3]:
            if llegada < proxima_llegada:
                proxima_llegada = llegada
        return proxima_llegada
"""
    #Determina cual es el siguiente evento (falta acondicionamiento)
    def proximo_evento(self):
        grupo_proximo = self.grupo_actual
        if grupo_proximo:
            if self.cancha.acondicionando and self.cancha.tiempo_acondicionado < self.proxima_llegada:
                self.acondicionando = False
                self.evento = "fin_acondicionamiento"
                self.reloj = round( self.reloj + self.cancha.tiempo_acondicionado, 4)
            elif self.proxima_llegada < grupo_proximo.fin_ocupacion or self.grupo_actual.finalizado:
                self.evento = "llegada"
                self.reloj = self.proxima_llegada
            else:
                self.evento = "fin_ocupacion"
                #self.evento = self.show_evento()
                self.reloj = grupo_proximo.fin_ocupacion
        else:
            self.evento = "llegada"
            self.reloj = self.proxima_llegada

    #Diferenciar entre llegada de 3 grupos
    def llegada(self):
        if self.proxima_llegada_futbol == self.proxima_llegada:
            grupo_proximo = self.grupo_actual_futbol
        elif self.proxima_llegada_handball == self.proxima_llegada:
            grupo_proximo = self.grupo_actual_handball
        else:
            grupo_proximo = self.grupo_actual_basquet
        if not self.grupo_actual:
            self.grupo_actual = grupo_proximo
        self.cancha.agregar_grupo(grupo_proximo, self.reloj)
        #self.reloj = round(self.reloj + self.cancha.tiempo_acondicionado, 4)
        self.acondicionando = self.cancha.acondicionando
        self.add_proxima_llegada(grupo_proximo)
        self.guardar_iteracion()

    def fin_acondicionamiento(self):
        self.cancha.agregar_grupo(self.grupo_actual, self.reloj)
        #self.reloj = self.grupo_actual.fin_ocupacion
        self.guardar_iteracion()

    def fin_ocupacion(self):
        self.cancha.agregar_grupo(self.grupo_actual, self.reloj)
        self.grupo_actual = None
        self.guardar_iteracion()
        if len(self.cancha.en_cancha) > 0 :
            self.reloj = self.cancha.en_cancha[0].fin_ocupacion
        else:
            self.reloj = self.proxima_llegada

    def calcular_iteracion(self, tiempo):
        while True:
            self.numero += 1
            self.proximo_evento()
            if self.reloj > tiempo:
                break
            if self.evento == "llegada":
                self.llegada()
            elif self.evento == "fin_ocupacion":
            #elif self.fin_ocupacion:
                self.fin_ocupacion()
            elif self.evento == "fin_acondicionamiento":
                self.fin_acondicionamiento()
            else:
                raise Exception("Evento inexistente")
Beispiel #12
0
class Iteracion:
    def __init__(self,
                 capcacidades,
                 desde=0,
                 hasta=30,
                 ultimas_filas=10,
                 decimales=4):
        self.tabla = []
        self.tabla_final = []
        self.pos_ultimo_elemento = 0
        self.generador = Generador(decimals=decimales, random=True)
        self.decimales = decimales
        self.cantidad_iteraciones = 1

        # Inicializacion
        self.numero = 0
        self.evento = 'Inicializacion'
        self.reloj = 0
        self.set_proxima_llegada()

        self.lote_actual = None

        # Resultados
        self.cantidad_visitas = 0
        self.maximo_cola = 0

        # Parametros de visualizacion
        self.desde = desde
        self.hasta = hasta
        self.ultimas_filas = ultimas_filas

        # Salas
        self.sala_a = SalaNormal("A",
                                 capacidad=capcacidades[0],
                                 media=30,
                                 desviacion=5)
        self.sala_b = SalaNormal("B",
                                 capacidad=capcacidades[1],
                                 media=25,
                                 desviacion=4)
        self.sala_c = SalaUniforme("C",
                                   capacidad=capcacidades[2],
                                   minimo=12,
                                   maximo=18)
        self.sala_d = SalaUniforme("D",
                                   capacidad=capcacidades[3],
                                   minimo=14,
                                   maximo=18)

        # TP6
        self.estado_servidor = 'libre'
        self.porc_inestable = 0
        self.tiempo_inestable = 0
        self.fin_purga = 0
        self.inicio_purga = 0
        self.k = 20

    def __str__(self):
        dic = self.as_dict
        dic.pop('salas')
        dic.pop('lotes')
        salas = self.as_dict['salas']
        lotes = self.as_dict['lotes']
        lotes = '\t' + '\n\t'.join([lote for lote in lotes])
        return f"{dic}\n{salas}\n{lotes}\n"

    def print_tabla(self, tabla):
        print("Tabla")
        for linea in tabla:
            dic = linea.copy()
            salas = dic.pop('salas')
            lotes = dic.pop('lotes')
            lotes = '\t' + '\n\t'.join([str(lote) for lote in lotes.items()])
            print(f"{dic}\n{salas}\n{lotes}")
            print("-" * 20)

    def show_evento(self):
        if self.evento == "fin_recorrido" or self.evento == "llegada":
            return self.evento + '(' + str(self.lote_actual.numero) + ')'
        return self.evento

    # Devuelve un diccionario con los valores actuales del objeto
    @property
    def as_dict(self):
        # Creo un diccionario con todos los atributos del objeto
        dic = {
            'numero': self.numero,
            'evento': self.show_evento(),
            'reloj': round(self.reloj, self.decimales),
            'proxima_llegada': self.proxima_llegada,
            # 'lote_actual': self.lote_actual,
            'cantidad_visitas': self.cantidad_visitas,
            'maximo_cola': self.maximo_cola,
            # Bloqueo
            'estado_servidor': self.estado_servidor,
            'porcentaje_inestable': self.porc_inestable,
            'inestable': self.tiempo_inestable,
            'inicio_purga': self.inicio_purga,
            'fin_purga': self.fin_purga,
            # Salas
            'salas': {
                'sala_a': self.sala_a.as_dict(),
                'sala_b': self.sala_b.as_dict(),
                'sala_c': self.sala_c.as_dict(),
                'sala_d': self.sala_d.as_dict(),
            },
            'lotes':
            {lote.numero: lote.as_dict()
             for lote in self.get_lotes()}
        }
        return dic

    def guardar_iteracion(self):
        "Guarda el estado de una iteracion"
        if self.desde <= self.numero <= self.hasta:
            self.tabla.append(self.as_dict)
        else:
            self.tabla_final.append(self.as_dict)
            if len(self.tabla_final) > self.ultimas_filas:
                self.tabla_final.pop(0)
            # Actualizo el proximo elemnto a reemplazar cuidando de que se mantenga en el rango de las ultimas filas
            # self.pos_ultimo_elemento = (self.pos_ultimo_elemento + 1) % self.ultimas_filas

    def ordenar_tabla_final(self):
        "Ordena la tabla final"
        self.tabla_final = self.tabla_final[
            self.pos_ultimo_elemento:] + self.tabla_final[:self.
                                                          pos_ultimo_elemento]

    def set_proxima_llegada(self):
        self.rnd_proxima_llegada = self.generador.exponencial_next(lam=1 / 5)
        self.proxima_llegada = round(self.reloj + self.rnd_proxima_llegada,
                                     self.decimales)
        return self.proxima_llegada

    def get_lotes(self):
        """Obtiene todos los lotes activos en un sistema"""
        return self.get_lotes_en_sala() + self.get_lotes_en_cola()

    def get_lotes_en_sala(self):
        """Devuelve una lista con los lotes en sala de todas las salas"""
        return self.sala_a.en_sala + self.sala_b.en_sala + self.sala_c.en_sala + self.sala_d.en_sala

    def get_lotes_en_cola(self):
        """Devuelve una lista con los lotes en sala de todas las colas"""
        return self.sala_a.en_cola + self.sala_b.en_cola + self.sala_c.en_cola + self.sala_d.en_cola

    #ESTADISTICAS
    def get_numero_lotes_encolados(self):
        colaA = self.sala_a.contador_cola
        colaB = self.sala_b.contador_cola
        colaC = self.sala_c.contador_cola
        colaD = self.sala_d.contador_cola
        return colaA, colaB, colaC, colaD

    def get_numero_lotes(self):
        lotesA = self.sala_a.contador_lotes
        lotesB = self.sala_b.contador_lotes
        lotesC = self.sala_c.contador_lotes
        lotesD = self.sala_d.contador_lotes
        return lotesA, lotesB, lotesC, lotesD

    def get_numero_lotes_sala(self):
        lotesA_sala = self.sala_a.contador_sala
        lotesB_sala = self.sala_b.contador_sala
        lotesC_sala = self.sala_c.contador_sala
        lotesD_sala = self.sala_d.contador_sala
        return lotesA_sala, lotesB_sala, lotesC_sala, lotesD_sala

    def calcular_porcentaje_lotes_cola(self):
        lotesA, lotesB, lotesC, lotesD = self.get_numero_lotes()
        colasA, colasB, colasC, colasD = self.get_numero_lotes_encolados()

        if lotesA == 0:
            porcentajeA = 0
        else:
            porcentajeA = self.generador.truncate((colasA * 100) / lotesA, 2)

        if lotesB == 0:
            porcentajeB = 0
        else:
            porcentajeB = self.generador.truncate((colasB * 100) / lotesB, 2)

        if lotesC == 0:
            porcentajeC = 0
        else:
            porcentajeC = self.generador.truncate((colasC * 100) / lotesC, 2)

        if lotesD == 0:
            porcentajeD = 0
        else:
            porcentajeD = self.generador.truncate((colasD * 100) / lotesD, 2)

        return porcentajeA, porcentajeB, porcentajeC, porcentajeD

    def get_tiempo_medio_recorrido(self):
        tiempoA = self.sala_a.tiempo_recorrido_medio
        tiempoB = self.sala_b.tiempo_recorrido_medio
        tiempoC = self.sala_c.tiempo_recorrido_medio
        tiempoD = self.sala_d.tiempo_recorrido_medio

        if self.sala_a.contador_lotes == 0:
            mediaA = 0
        else:
            mediaA = tiempoA / self.sala_a.contador_sala

        if self.sala_b.contador_lotes == 0:
            mediaB = 0
        else:
            mediaB = tiempoB / self.sala_b.contador_sala

        if self.sala_c.contador_lotes == 0:
            mediaC = 0
        else:
            mediaC = tiempoC / self.sala_c.contador_sala

        if self.sala_d.contador_lotes == 0:
            mediaD = 0
        else:
            mediaD = tiempoD / self.sala_d.contador_sala

        return mediaA, mediaB, mediaC, mediaD

    def get_tiempo_espera_cola(self):
        tiempoA = self.sala_a.tiempo_espera_medio
        tiempoB = self.sala_b.tiempo_espera_medio
        tiempoC = self.sala_c.tiempo_espera_medio
        tiempoD = self.sala_d.tiempo_espera_medio

        if self.sala_a.contador_cola_a_sala == 0:
            mediaA = 0
        else:
            mediaA = self.generador.truncate(
                tiempoA / self.sala_a.contador_cola_a_sala, 2)

        if self.sala_b.contador_cola_a_sala == 0:
            mediaB = 0
        else:
            mediaB = self.generador.truncate(
                tiempoB / self.sala_b.contador_cola_a_sala, 2)

        if self.sala_c.contador_cola_a_sala == 0:
            mediaC = 0
        else:
            mediaC = self.generador.truncate(
                tiempoC / self.sala_c.contador_cola_a_sala, 2)

        if self.sala_d.contador_cola_a_sala == 0:
            mediaD = 0
        else:
            mediaD = self.generador.truncate(
                tiempoD / self.sala_d.contador_cola_a_sala, 2)

        return mediaA, mediaB, mediaC, mediaD

    def get_visitantes_por_sala(self):
        visitantesA = self.sala_a.contador_visitantes
        visitantesB = self.sala_b.contador_visitantes
        visitantesC = self.sala_c.contador_visitantes
        visitantesD = self.sala_d.contador_visitantes
        return visitantesA, visitantesB, visitantesC, visitantesD

    # Proximos eventos
    def proximo_lote(self):
        """Devuelve el proximo lote que finalizara el recorrido"""
        # Elimino los lotes bloqueados
        lotes = [
            lote for lote in self.get_lotes_en_sala() if not lote.bloqueado
        ]
        if len(lotes) > 0:
            lote_proximo = lotes[0]
            for lote in lotes[1:]:
                if lote.fin_recorrido < lote_proximo.fin_recorrido:
                    lote_proximo = lote
            return lote_proximo
        else:
            return None

    def proximo_evento(self):
        lote_proximo = self.proximo_lote()
        if lote_proximo:
            # Bloquear servidor
            if 0 < self.inicio_purga < self.proxima_llegada and self.inicio_purga < lote_proximo.fin_recorrido \
                    and self.estado_servidor != 'bloqueado':
                self.estado_servidor = 'bloqueado'

                self.evento = "bloqueo"
                self.reloj = self.inicio_purga
            # Desbloquear servidor
            elif 0 < self.fin_purga <= self.proxima_llegada and self.fin_purga <= lote_proximo.fin_recorrido \
                    and self.estado_servidor != 'libre':
                self.estado_servidor = 'libre'
                self.evento = "desbloqueo"
                self.reloj = self.fin_purga
            # Llegada
            elif self.proxima_llegada < lote_proximo.fin_recorrido and self.estado_servidor != 'bloqueado':
                self.evento = "llegada"
                self.reloj = self.proxima_llegada
            # Fin de recorrido
            else:
                self.evento = "fin_recorrido"
                self.lote_actual = lote_proximo
                self.reloj = lote_proximo.fin_recorrido
        else:
            self.evento = "llegada"
            self.reloj = self.proxima_llegada

    #         todo no se tendria que registrar el tiempo de proxima llegada

    # Eventos
    def llegada(self):
        """Setea los campos para el caso de una llegada nueva"""
        # Se agrega el lote a la sala C, se calculan todos los atributos
        # necesarios incluyendo el fin de recorrido si correspondiera
        self.lote_actual = Lote(self.sala_a, self.sala_b, self.sala_c,
                                self.sala_d)
        self.sala_c.add_lote(self.lote_actual, self.reloj)
        # Se actualiza la cantidad total de visitas
        self.cantidad_visitas += self.lote_actual.visitantes
        # Se calcula la proxima llegada
        self.set_proxima_llegada()
        acu = 0
        for i in range(len(self.sala_c.en_cola)):
            acu += self.sala_c.en_cola[i].visitantes
        if acu > self.maximo_cola:
            self.maximo_cola = acu
        self.guardar_iteracion()

    def fin_recorrido_sala(self):
        lote = self.lote_actual
        sala = lote.sala_actual

        lote_en_cola = None

        # Verifica si el lote se encuente en la ultima sala del recorrido
        if lote.ultima_sala():
            # Acciones si un lote llega al final del recorrido
            lote.fin_recorrido = '-'
            # Actualizo la cantidad total de visitas
            #self.cantidad_visitas += lote.visitantes

            # Se verifica si la sala tenia algun lote en cola y este puede entrar en la sala
            for i in range(len(sala.en_cola)):
                if sala.puede_entrar_a_sala_desde_cola():
                    lote_en_cola = sala.en_cola[0]
                    self.entrar_a_sala_desde_cola(sala, lote_en_cola)
                    sala.en_cola.pop(0)
                    # Guardo la iteracion despues de haber cambiado al lote a su nueva sala

            # Guarda la iteracion con todos los cambios realizados
            self.guardar_iteracion()

            # Elimino el lote anterior
            lote.sala_actual.salir_de_sala(lote)

        # El lote no se encuentra en la ultima sala
        else:
            # Me salgo de la sala actual
            lote.sala_actual.salir_de_sala(lote)
            # Paso a la proxima sala
            lote.proxima_sala()
            # Asigno el lote a la proxima sala
            lote.sala_actual.add_lote(lote, self.reloj)

            # Se verifica si la sala tenia algun lote en cola y este puede entrar en la sala
            for i in range(len(sala.en_cola)):
                if sala.puede_entrar_a_sala_desde_cola():
                    lote_en_cola = sala.en_cola[0]
                    self.entrar_a_sala_desde_cola(sala, lote_en_cola)
                    sala.en_cola.pop(0)
                    # Guardo la iteracion despues de haber cambiado al lote a su nueva sala
                # Guarda la iteracion con todos los cambios realizados
            self.guardar_iteracion()

    def entrar_a_sala_desde_cola(self, sala, lote):
        """Se ingresa un objeto desde la cola hasta sus sala calculando su fin de recorrido"""
        # Esta funcion cuenta como una iteracion adicional en caso de que pueda ingresar un lote a la sala
        # No se si corresponde sumar una iteracion
        sala.en_sala.append(lote)

        # Hago la diferencia del momento en el que entro en la cola y el momento que lo agrregamos a la sala
        lote.tiempo_espera_cola = self.reloj - lote.tiempo_espera_cola
        sala.tiempo_espera_medio += lote.tiempo_espera_cola
        #sala.contador_cola += 1
        sala.contador_cola_a_sala += 1

        lote.cola = False
        sala.contador_visitantes += lote.visitantes
        lote.set_fin_recorrido(self.reloj)

    def bloquear_servidor(self):
        """Se marca el servidor como bloqueado. se guardan las llegadas en una nueva cola para procesarlas cuando
        se libere el servidor"""
        self.estado_servidor = 'bloqueado'
        # Obtengo los lotes de la sala c
        lotes = self.sala_c.en_sala + self.sala_c.en_cola
        for lote in lotes:
            lote.bloquear_recorrido(self.reloj)
        # Se ajusta la proxima llegada
        self.proxima_llegada = round(
            self.fin_purga + (self.proxima_llegada - self.reloj), 4)
        self.guardar_iteracion()

    def desbloquear_servidor(self):
        """Se marca el servidor como desbloqueado y se procesan todas las salidas anteriores a este tiempo"""
        self.estado_servidor = 'libre'
        lotes = self.sala_c.en_sala + self.sala_c.en_cola
        for lote in lotes:
            lote.desbloquear_recorrido(self.reloj)
        self.set_inestable()
        self.guardar_iteracion()

    def set_inestable(self):
        rnd = self.generador.rnd()
        if rnd < .5:
            self.porc_inestable = 100
            self.tiempo_inestable = 250
        elif rnd < .8:
            self.porc_inestable = 70
            self.tiempo_inestable = 220.2347
        else:
            self.porc_inestable = 50
            self.tiempo_inestable = 192.1554

        self.inicio_purga = round(self.tiempo_inestable + self.reloj, 4)
        self.fin_purga = round(self.inicio_purga + self.k, 4)

    def calcular_iteracion(self, tiempo):
        """Metodo que realiza el calculo completo tomando los datos de la iteracion anterior"""
        # Setear bloqueo del servidor
        self.set_inestable()

        while True:
            self.numero += 1
            self.proximo_evento()
            if self.reloj >= tiempo:
                break
            if self.evento == "llegada":
                self.llegada()
            elif self.evento == "fin_recorrido":
                self.fin_recorrido_sala()
            elif self.evento == 'bloqueo':
                self.bloquear_servidor()
            elif self.evento == 'desbloqueo':
                self.desbloquear_servidor()
            else:
                raise Exception("Evento inexistente")

    # Mostrar los lotes de un intervalo en una matriz
    def get_matrix(self, tabla):
        lotes = set()
        # Obtengo los numeros de todos los lotes en todas las iteraciones y elimino los duplicados
        for linea in tabla:
            lotes.update(list(linea["lotes"].keys()))

        lotes = list(lotes)
        # Creo una matriz llena de diccionarios vacios
        # matriz = [[None] * numero_columnas] * numero_filas
        # {'numero': '', 'estado': '', 'visitantes': '', 'recorrido': '' , 'fin_recorrido': ''}
        matriz = [[{
            'numero': '',
            'estado': '',
            'visitantes': '',
            'recorrido': '',
            'fin_recorrido': ''
        }] * len(lotes) for i in range(len(tabla))]

        for i in range(len(tabla)):
            linea = tabla[i]
            # print(i, list)
            for j in range(len(lotes)):
                numero = lotes[j]
                # print("Lineas:", list(linea['lotes'].keys()))
                # print("Numeros:", numero)
                # print("en: ", numero in list(linea['lotes'].keys()))
                # Si el lote existe en esta linea
                if numero in list(linea['lotes'].keys()):
                    matriz[i][j] = linea['lotes'][numero]
                    # print(linea['lotes'][numero])

        # Agrego los lotes a la tabla
        for i in range(len(tabla)):
            tabla[i]['lotes_arreglados'] = matriz[i]

        return tabla, lotes

        # Ver tabla
        # for i in range(len(tabla)):
        #     for j in range(len(lotes)):
        #         print(matriz[i][j], end="\n\t")
        #     print()
        #     print("-" * 20)
        #
        # Ver que matrices se registraron en cada fila
        # for i in range(len(tabla)):
        #     for j in range(len(lotes)):
        #         print(matriz[i][j]["numero"], end=" | ")
        #     print()
        #     print("-" * 20)

    def limpiar_salas(self):
        """Limpia todas las salas para una nueva simulacion"""
        self.sala_a.limpiar_sala()
        self.sala_b.limpiar_sala()
        self.sala_c.limpiar_sala()
        self.sala_d.limpiar_sala()
        Lote.resetear_lote()
Beispiel #13
0
from generador_pseudoaliatorio.generador import Generador

generador = Generador(decimals=4, random=True)


class Lote:
    nro = 0
    instances = set()

    @classmethod
    def get_nro(cls):
        """Devuelve para cada nuevo objeto un valor unico"""
        cls.nro += 1
        return cls.nro

    # @classmethod
    # def fin_recorrido_proximo(cls):
    #     lotes = cls.
    #
    # @classmethod
    # def get_instances(cls):
    #     dead = set()
    #     for ref in cls.instances:
    #         obj = ref()
    #         if obj is not None:
    #             yield obj
    #         else:
    #             dead.add(ref)
    #     cls.instances -= dead

    def __init__(self, sala_a, sala_b, sala_c, sala_d):