Visualización de los resultados de la simulación de estacionamiento de SimPy.

Recientemente compartí un ejemplo de modelado de simulación de Python usando SimPy en Python. Usando SimPy, una biblioteca de simulación de eventos discretos disponible en Python, modelé un estacionamiento con una cantidad definida de espacios y un proceso de llegada de automóviles definido. En este tutorial de seguimiento sobre visualización de modelos de simulación SimPy , muestro cómo, utilizando el mismo ejemplo de referencia, se pueden recopilar y visualizar datos sobre la utilización de espacios de estacionamiento . En próximos artículos mostraré además cómo se puede animar el estacionamiento usando Python y SimPy.

Por qué SimPy es relevante para los gerentes de operaciones y logística

SimPy, la biblioteca de simulación de eventos discretos de código abierto para Python, ofrece una herramienta valiosa para los administradores de la cadena de suministro. No se trata de características aisladas, sino de cómo SimPy permite a estos profesionales abordar las complejidades de la gestión de la cadena de suministro.

Una de las ventajas más destacadas de SimPy es su capacidad para crear modelos realistas de operaciones de la cadena de suministro. Estos modelos se parecen mucho a los procesos reales dentro de una cadena de suministro, lo que facilita a los gerentes analizar y comprender sus operaciones. En un campo donde las operaciones del mundo real pueden ser increíblemente complejas, es indispensable tener una herramienta de simulación que refleje con precisión estas complejidades.

Lo que hace que SimPy sea aún más atractivo es su flexibilidad. Es una biblioteca de simulación de propósito general, lo que significa que los gerentes de la cadena de suministro pueden adaptarla para modelar diversos aspectos de sus operaciones. Ya sea gestión de inventario, procesamiento de pedidos, previsión de la demanda, transporte o cualquier otro elemento crítico de la cadena de suministro, SimPy puede adaptarse para abordar desafíos específicos.

La fortaleza de SimPy también radica en su capacidad para facilitar el análisis de «qué pasaría si». Los gerentes de la cadena de suministro pueden usar SimPy para probar diferentes escenarios y estrategias. Pueden explorar el impacto de los cambios en sus operaciones, ayudándolos a tomar decisiones informadas sobre la optimización de los procesos de la cadena de suministro. Esta capacidad de modelar diferentes escenarios y predecir resultados es invaluable para la planificación estratégica.

En un mundo donde la eficiencia es primordial, SimPy ayuda a optimizar el rendimiento. Los gerentes de la cadena de suministro pueden simular sus procesos, identificar cuellos de botella e ineficiencias y trabajar en estrategias para mejorar el desempeño general. Esta optimización puede conducir a una reducción de costos y un mejor servicio al cliente.

La resiliencia de la cadena de suministro es fundamental y SimPy es una herramienta valiosa para la gestión de riesgos. Al modelar varios escenarios de riesgo, los gerentes pueden evaluar las vulnerabilidades en sus cadenas de suministro y desarrollar planes de contingencia para mitigar posibles interrupciones. Esto es esencial en el panorama actual de la cadena de suministro globalizado y a menudo impredecible.

La asignación de recursos es otra área donde SimPy demuestra su valía. Puede simular cómo se asignan recursos como mano de obra, máquinas y espacio de almacenamiento en diferentes escenarios. Esta información ayuda a los gerentes a tomar decisiones informadas sobre la planificación de recursos, garantizando que los recursos se utilicen de manera eficiente y efectiva.

La reducción de costos es un beneficio significativo de usar SimPy. Al identificar ineficiencias y optimizar procesos, los gerentes pueden reducir potencialmente los costos asociados con el inventario, el transporte y otros aspectos operativos. Esta reducción de costos impacta directamente en el resultado final de una empresa.

Adiciones de modelos para visualización del modelo de estacionamiento de SimPy

En mi ejemplo anterior de modelo de estacionamiento de SimPy , ya tenía el código del modelo de referencia del estacionamiento . Puede encontrar el ejemplo de codificación aquí: Ejemplo de modelado de simulación de estacionamiento de SimPy

En el modelo de referencia no hubo visualización. Las llegadas y salidas de vehículos desde y hacia el estacionamiento se imprimían simplemente en la consola. Ahora implementaremos una visualización de los resultados de la simulación SimPy.

Para poder visualizar los resultados de la simulación, debemos recopilar datos de simulación relevantes y debemos monitorear los valores relevantes durante toda la simulación. Después de ejecutar la simulación, los datos recopilados se visualizan con matplotlib .pyplot.

Hay varias formas de monitorear los valores en un modelo de simulación SimPy, pero la forma más fácil (para principiantes de SimPy) de comenzar a monitorear la cantidad de espacios de estacionamiento ocupados y disponibles es implementar un proceso de monitoreo SimPy personalizado:

def monitor_parkingspot(self) -> None:

 
        while self.env.now <= self.simdata.duration:

            self.simdata.data_timeseries[self.env.now, 0] = self.env.now
            self.simdata.data_timeseries[self.env.now, 1] = self.spots_occupied
            self.simdata.data_timeseries[self.env.now, 2] = self.spots_available

            yield self.env.timeout(1)

Agregué un método a la clase ParkingLot para implementar un proceso de monitoreo personalizado. Este proceso verifica el tiempo de simulación, la cantidad de puntos disponibles y la cantidad de puntos disponibles, y escribe estos valores en un ndarray numpy . Puede ver en el ejemplo anterior que la clase ParkingLot tiene algunos atributos y variables adicionales: .data_timeseries (: numpy .ndarray), .spots_occupied (: int) y .spots_available (: int). Así es como se ven ahora el encabezado y el constructor de la clase:

class ParkingLot:

    env             :simpy.Environment
    capacity        :int
    spots           :simpy.resources.container.Container
    spots_occupied  :int
    spots_available :int
    simdata         :Simdata

    def __init__(self, 
        env      :simpy.Environment, 
        capacity :int,
        duration :int
        ):
        
        """ constructor """
        
        self.env = env
        self.capacity = capacity
        self.spots = simpy.resources.container.Container(env, capacity, init=capacity)
        self.spots_occupied = 0
        self.spots_available = capacity
        self.simdata = Simdata(duration= duration)
        self.simdata.data_timeseries = np.zeros([duration+1, 3], dtype = int)

Para el atributo .simdata, escribí una pequeña clase, Simdata. Escribiré más métodos y atributos en esta clase en futuros tutoriales, así que quería presentarlos en este punto.

class Simdata:

    duration         :int
    data_timeseries  :np.ndarray

    def __init__(self, 
        duration :int,
        ):
    
        """ constructor """

        self.duration = duration
        self.data_timeseries = np.zeros(duration+1, dtype = float)

El número de plazas ocupadas y disponibles, ahora variables de la clase ParkingLot, se actualizan durante todo el proceso de llegada del coche:

def car_arrival(self,
        car_id          :int, 
        dwelltime_min   :float,
        dwelltime_max   :float
        )               -> None:
        """ 
    
        implement simpy process; 
        models car arrivals in the parking lot, occupying a slot for a randomly distributed duration
    
        """
    
        #print(f"Car {car_id} arrives at {self.env.now}")
    
        yield self.spots.get(1)

        self.spots_occupied += 1
        self.spots_available -= 1
        
        #print(f"Car {car_id} parks at {self.env.now}")
        
        yield self.env.timeout(random.uniform(dwelltime_min, dwelltime_max))
        
        #print(f"Car {car_id} leaves at {self.env.now}")
        
        self.spots_occupied -= 1
        self.spots_available += 1

        yield self.spots.put(1)

Esto facilita la recopilación de resultados durante la simulación. Ahora puedo trazar los resultados una vez completada la ejecución de la simulación.

Visualización de espacios ocupados y disponibles, utilizando los resultados generados por SimPy

El último paso es simple: uso matplotlib .pyplot para crear un lote lineal que muestra la cantidad de espacios de estacionamiento ocupados y disponibles en el estacionamiento durante el tiempo de simulación.

env.process(parking_lot.monitor_parkingspot())

# run the model
env.run()

# plot simulation results
plt.plot(parking_lot.simdata.data_timeseries[:,1], linestyle = 'dotted', color = "red", label = "occupied")
plt.plot(parking_lot.simdata.data_timeseries[:,2], linestyle = 'dotted', color = "green", label = "available")
plt.legend()
plt.xlabel("sim time")
plt.ylabel("# of spots")
plt.title("parking lot utilization over time")
plt.show()

Puedes ver que agregué otro proceso SimPy al configurar el modelo de simulación antes de su ejecución. Este es el proceso de seguimiento. Recopila resultados de simulación en cada incremento de simulación y almacena estos valores en un ndarray numpy .

Así es como se ven los resultados.

El estacionamiento , en este escenario, está infrautilizado. 2 plazas de aparcamiento habrían sido suficientes para este escenario específico de llegada de coches.

Comentarios finales y contenido relacionado.

En este tutorial, mostré cómo puede monitorear los valores relevantes del modelo SimPy durante el tiempo de simulación y cómo puede implementar la visualización de los resultados de la simulación SimPy usando matplotlib .pyplot en Python.

Aquí hay algunos artículos relacionados que también podrían interesarle:

You May Also Like

Leave a Reply

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.