Created
November 29, 2012 05:19
-
-
Save jcarlos7121/4166953 to your computer and use it in GitHub Desktop.
Simulacion Optima
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ Market.py | |
| Model of a supermarket. | |
| """ | |
| from SimPy.Simulation import * | |
| import random | |
| from math import sqrt | |
| import math | |
| ## Model components ------------------------ | |
| class Bolseo(Process): | |
| def __init__(self): | |
| Process.__init__(self) | |
| def bolseararticulos(self, x): | |
| yield request, self, bolseros_disponibles | |
| tiempoiniciobolseo = now() | |
| tiempobolseo = x * random.uniform(1/60,1.5/60) | |
| yield hold, self, tiempobolseo | |
| yield release, self, bolseros_disponibles | |
| bolseartime.tally(now() - tiempobolseo) | |
| class Customer(Process): | |
| def __init__(self): | |
| Process.__init__(self) | |
| # Randomly pick how many items this customer is buying | |
| #self.items = int(random.uniform(1,AVGITEMS)) | |
| self.items = int(random.normalvariate(AVGITEMS,ITEMSDEVIATION)) | |
| self.items = int(math.fabs(self.items)) | |
| articuloscomprados.tally(self.items) | |
| self.packeditems = 0 | |
| def tarticulo(self, tprom, vari): | |
| tvar = tprom * (vari / 100) | |
| return (random.uniform(tprom-tvar,tprom+tvar)) | |
| def checkoutitem(self): | |
| #generar pricecheck | |
| tiempopromedio = TPROM | |
| if (random.uniform(1,1000)<=13): #Si cae un numero entre 1 y 13 de 1000 osea 1.3% | |
| tiempopromedio = 2.2 #aumentar el tiempo ya que hubo un price check | |
| return tiempopromedio | |
| def checkout(self): | |
| #proceso de compra | |
| #Tiempo de espera por cada producto comprado en tienda | |
| if self.items<10: | |
| timeperitem = 42/60 | |
| else: | |
| timeperitem = 34/60 | |
| purchasetime = self.items*timeperitem | |
| #El tiempo minimo de compra de un cliente son 3 minutos | |
| if (purchasetime<=3): | |
| purchasetime=3 | |
| startpurchase = now() | |
| yield hold, self, purchasetime #Es el tiempo que se espera el cliente metiendo productos al carrito | |
| terminarcompra = now() | |
| tiempoentienda.tally(terminarcompra-startpurchase) | |
| largodefila.tally(len(checkout_aisle.waitQ)/AISLES) | |
| # Customer decides to check out | |
| startaisle = now() | |
| yield request, self, checkout_aisle | |
| # Customer gets to front of line | |
| at_checkout = now() | |
| waittime.tally(at_checkout-startaisle) #tiempo que el cliente estubo en la fila | |
| # Cliente hace su compra | |
| for x in range (0, self.items): | |
| tiempopromedio = self.checkoutitem() #Checa si hay una solicitud de precio, que toma tiempo | |
| variabilidad = 75 #Incrementa la variabilidad si es que hubo cambio de precio | |
| if (tiempopromedio == TPROM): #mantener variabilidad dentro del standard | |
| variabilidad = VARIAB | |
| start = now() | |
| yield hold, self, self.tarticulo(tiempopromedio, variabilidad) #Escanear codigo de barras | |
| tiempoporitem.tally(now()-start) | |
| b = Bolseo() | |
| lohizo = 0; | |
| #Empieza el bolseo | |
| if bolseros_disponibles.n > 0: | |
| lohizo = 1; | |
| activate(b, b.bolseararticulos(self.items)) | |
| # Cliente ahora hace el pago | |
| if (self.items <= 20): # Para compras de menos de 20 articulos, definir limites | |
| limiteinferiorcheque =45 | |
| limiteinferiorTC = 75 | |
| else: | |
| limiteinferiorcheque = 20 | |
| limiteinferiorTC = 65 | |
| tipodepago = random.uniform(1,100) #numero frente al que se verifica el limite | |
| # Default pago en efectivo | |
| tiempodepago = 0.95 | |
| desviacionpago = 0.17 | |
| if tipodepago>limiteinferiorcheque: # Pago con cheque | |
| tiempodepago = 1.45 | |
| desviacionpago = 0.35 | |
| #Si el pago es con cheque seleccionar 27% probabilidad de que requiera aprobacion | |
| if (random.uniform(1,100)<=27): | |
| tiempodepago = 1.45 + random.normalvariate(0.95, 0.15) #t. espera adicional 0.95 con dev std 0.15 | |
| if tipodepago>75: | |
| #25% paga con Tarjeta de credito | |
| tiempodepago = 1.24 | |
| desviacionpago = 0.21 | |
| yield hold, self, random.normalvariate(tiempodepago, desviacionpago) #Pagar con una tiempo y desviacion correspondiente | |
| if lohizo == 1: #Checamos si un bolsero guardo los articulos | |
| yield release, self, checkout_aisle #Ya se hizo el pago, liberar al atendiente de la caja | |
| else: | |
| if bolseros_disponibles.n > 0: #Se busca nuevamente si ya hay bolseros disponibles | |
| lohizo = 1; | |
| activate(b, b.bolseararticulos(self.items)) | |
| yield release, self, checkout_aisle | |
| else: | |
| if random.uniform(1,10) <= 3: #EL cliente es el que empaca los articulos | |
| yield release, self, checkout_aisle #Ya se hizo el pago, liberar al atendiente de la caja | |
| tiempobolseo = self.items * random.uniform(1/60,1.5/60) | |
| yield hold, self, tiempobolseo | |
| else: | |
| tiempobolseo = self.items * random.uniform(1/60,1.5/60) | |
| yield hold, self, tiempobolseo | |
| yield release, self, checkout_aisle #Ya se hizo el pago, liberar al atendiente de la caja | |
| # Cliente ya termino su compra | |
| checkouttime.tally(now()-at_checkout)#tiempo total para que le pasen todos los items por la caja | |
| class Customer_Factory(Process): | |
| def run(self): | |
| while 1: | |
| c = Customer() | |
| activate(c, c.checkout()) | |
| arrival = random.normalvariate(ARRIVALRATE,20) #Tiempo entre cada llegada de clientes | |
| yield hold, self, PERIOD/arrival | |
| class Monitor2(Monitor): | |
| def __init__(self): | |
| Monitor.__init__(self) | |
| self.min, self.max = (sys.maxsize,0) | |
| def tally(self, x): | |
| self.observe(x) | |
| self.min = min(self.min, x) | |
| self.max = max(self.max, x) | |
| ## Experiment data ------------------------- | |
| PERIOD = 30*16 # MINUTES OF SIMULATION | |
| ARRIVALRATE = 130*16 # Customers in period of time | |
| TPROM = 3/60 #Tiempo promedio para pasar un item por la caja | |
| VARIAB = 25 #Variabilidad asignada a cada item por la caja | |
| AISLES = 17 # Number of open aisles | |
| BOLSEROS = 9 # Cantidad de gente empacando en bolsas | |
| AVGITEMS = 88.93# Average number of items purchased | |
| ITEMSDEVIATION = 37.33 | |
| RUNS = 1 # Number of times to run the simulation | |
| SEED = 111333555 # seed value for random numbers | |
| ## Model/Experiment ------------------------------ | |
| random.seed(SEED) | |
| for run in range(RUNS): | |
| articuloscomprados = Monitor2() | |
| tiempoentienda = Monitor2() | |
| tiempoporitem = Monitor2() | |
| waittime = Monitor2() | |
| checkouttime = Monitor2() | |
| bolseartime = Monitor2() | |
| largodefila = Monitor2() | |
| bolseros_disponibles = Resource(BOLSEROS) | |
| checkout_aisle = Resource(AISLES) | |
| initialize() | |
| cf = Customer_Factory() | |
| activate(cf, cf.run(), 0.0) | |
| simulate(until=PERIOD) | |
| print ("Tiempo espera: " + str(waittime.mean())) | |
| print ("Tiempo espera maximo: " + str(waittime.max)) | |
| print ("Cola mas larga: " + str(largodefila.max)) | |
| print ("Gasto total: " + str((AISLES * 7.25) + (BOLSEROS * 5.50))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment