Skip to content

Instantly share code, notes, and snippets.

@jcarlos7121
Created November 29, 2012 05:19
Show Gist options
  • Select an option

  • Save jcarlos7121/4166953 to your computer and use it in GitHub Desktop.

Select an option

Save jcarlos7121/4166953 to your computer and use it in GitHub Desktop.
Simulacion Optima
""" 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