首页 > 编程问答 >SimPy仿真:集装箱码头如何保证单个集装箱卸货和顺序运输?

SimPy仿真:集装箱码头如何保证单个集装箱卸货和顺序运输?

时间:2024-07-25 04:46:42浏览次数:13  
标签:python asynchronous simulation simpy

我正在对集装箱码头进行 SimPy 模拟,船舶到达、停泊并使用起重机卸载集装箱,然后使用卡车进行运输。 问题陈述_pt1 问题陈述_pt2

我需要确保:

  1. 每台起重机一次仅卸载一个集装箱。
  2. 在有空卡车可用之前,起重机应继续其卸载过程,无论之前的卡车是否已完成转运。
  3. 如果没有卡车如果可用,则起重机需要等待才能开始卸载集装箱。

simulation.py

import simpy
from vessel import Vessel
from config import *
import random

class Simulation:
    def __init__(self, simulation_time):
        self.env = simpy.Environment()
        self.simulation_time = simulation_time
        self.berth_resource = simpy.Resource(self.env, capacity=NUM_BERTHS)
        self.crane_resource = simpy.Resource(self.env, capacity=NUM_CRANES)
        self.truck_resource = simpy.Resource(self.env, capacity=NUM_TRUCKS)
        
    def generate_vessels(self):
        vessel_id = 1
        while True:
            yield self.env.timeout(random.expovariate(1 / (AVERAGE_INTERARRIVAL_TIME * 60)))  # time between arrivals
            vessel = Vessel(self.env, vessel_id, self.berth_resource, self.crane_resource, self.truck_resource)
            print(f"Time {self.env.now}: Vessel {vessel_id} arrives.")
            self.env.process(vessel.process())
            vessel_id += 1
            print(f"Time {self.env.now}: Number of vessels waiting for berths: {len(self.berth_resource.queue)}")
            print(f"Time {self.env.now}: Number of vessels currently being served at berths: {self.berth_resource.count}")
            print(f"Time {self.env.now}: Number of cranes currently being used: {self.crane_resource.count}")
            print(f"Time {self.env.now}: Number of trucks currently being used: {self.truck_resource.count}")
            
    def run(self):
        """Run the simulation"""
        self.env.process(self.generate_vessels())
        self.env.run(until=self.simulation_time)

vessel.py



import random
import simpy
from config import NUM_CONTAINERS, AVERAGE_INTERARRIVAL_TIME, CRANE_LIFT_TIME, TRUCK_CYCLE_TIME

class Vessel:
    def __init__(self, env, id, berth_resource, crane_resource, truck_resource):
        self.env = env
        self.id = id
        self.containers = NUM_CONTAINERS
        self.berth_resource = berth_resource
        self.crane_resource = crane_resource
        self.truck_resource = truck_resource
        self.container_queue = simpy.Store(env)  # Queue to hold unloaded containers

    def berth(self):
        """Simulate vessel berthing"""
        with self.berth_resource.request() as request:
            yield request
            print(f"Time {self.env.now}: Vessel {self.id} starts berthing.")
            print(f"Time {self.env.now}: Vessel {self.id} finished berthing.")
            yield self.env.process(self.unload())

    

    
    def unload_container(self, container_id):
        """Simulate unloading a single container"""
        print(f"Time {self.env.now}: Vessel {self.id} requests crane for container {container_id + 1}.")
        with self.crane_resource.request() as crane_request:
            yield crane_request
            print(f"Time {self.env.now}: Quay crane starts unloading container {container_id + 1} from vessel {self.id}.")
            yield self.env.timeout(CRANE_LIFT_TIME)  # Crane time to unload one container
            print(f"Time {self.env.now}: Quay crane finished unloading container {container_id + 1} from vessel {self.id}.")
            yield self.container_queue.put(container_id)  # Add the unloaded container to the queue
            # Start the transport process for this container after unloading
            self.env.process(self.transport_container(container_id))

    def transport_container(self, container_id):
        """Simulate the transport of a container by a truck"""
        print(f"Time {self.env.now}: Vessel {self.id} requests truck for container {container_id + 1}.")
        with self.truck_resource.request() as truck_request:
            yield truck_request
            print(f"Time {self.env.now}: Truck starts transporting container {container_id + 1} from vessel {self.id}.")
            yield self.env.timeout(TRUCK_CYCLE_TIME)  # Truck time to transport the container
            print(f"Time {self.env.now}: Truck finished transporting container {container_id + 1} from vessel {self.id}.")

    def unload(self):
        """Unload all containers from the vessel"""
        unload_processes = [self.env.process(self.unload_container(i)) for i in range(self.containers)]
        for process in unload_processes:
            yield process  # Wait for all unload processes to finish
        print(f"Time {self.env.now}: Vessel {self.id} has been fully unloaded and leaves the berth.")

    
    def process(self):
        """Process the entire sequence of arrival, berthing, and unloading"""
        yield self.env.process(self.berth())
        

输出:

Enter the number of hours to run the simulation: 3
Time 104.4311467616123: Vessel 1 arrives.
Time 104.4311467616123: Number of vessels waiting for berths: 0
Time 104.4311467616123: Number of vessels currently being served at berths: 0
Time 104.4311467616123: Number of cranes currently being used: 0
Time 104.4311467616123: Number of trucks currently being used: 0
Time 104.4311467616123: Vessel 1 starts berthing.
Time 104.4311467616123: Vessel 1 finished berthing.
Time 104.4311467616123: Vessel 1 requests crane for container 1.
Time 104.4311467616123: Vessel 1 requests crane for container 2.
Time 104.4311467616123: Vessel 1 requests crane for container 3.
Time 104.4311467616123: Vessel 1 requests crane for container 4.
Time 104.4311467616123: Vessel 1 requests crane for container 5.
Time 104.4311467616123: Vessel 1 requests crane for container 6.
Time 104.4311467616123: Vessel 1 requests crane for container 7.
Time 104.4311467616123: Vessel 1 requests crane for container 8.
Time 104.4311467616123: Vessel 1 requests crane for container 9.
Time 104.4311467616123: Vessel 1 requests crane for container 10.
Time 104.4311467616123: Quay crane starts unloading container 1 from vessel 1.
Time 104.4311467616123: Quay crane starts unloading container 2 from vessel 1.
Time 107.4311467616123: Quay crane finished unloading container 1 from vessel 1.
Time 107.4311467616123: Quay crane finished unloading container 2 from vessel 1.
Time 107.4311467616123: Vessel 1 requests truck for container 1.
Time 107.4311467616123: Vessel 1 requests truck for container 2.
Time 107.4311467616123: Truck starts transporting container 1 from vessel 1.
Time 107.4311467616123: Truck starts transporting container 2 from vessel 1.
Time 107.4311467616123: Quay crane starts unloading container 3 from vessel 1.
Time 107.4311467616123: Quay crane starts unloading container 4 from vessel 1.
Time 110.4311467616123: Quay crane finished unloading container 3 from vessel 1.
Time 110.4311467616123: Quay crane finished unloading container 4 from vessel 1.
Time 110.4311467616123: Vessel 1 requests truck for container 3.
Time 110.4311467616123: Vessel 1 requests truck for container 4.
Time 110.4311467616123: Truck starts transporting container 3 from vessel 1.
Time 110.4311467616123: Quay crane starts unloading container 5 from vessel 1.
Time 110.4311467616123: Quay crane starts unloading container 6 from vessel 1.
Time 113.4311467616123: Truck finished transporting container 1 from vessel 1.
Time 113.4311467616123: Truck finished transporting container 2 from vessel 1.
Time 113.4311467616123: Quay crane finished unloading container 5 from vessel 1.
Time 113.4311467616123: Quay crane finished unloading container 6 from vessel 1.
Time 113.4311467616123: Vessel 1 requests truck for container 5.
Time 113.4311467616123: Vessel 1 requests truck for container 6.
Time 113.4311467616123: Truck starts transporting container 4 from vessel 1.
Time 113.4311467616123: Truck starts transporting container 5 from vessel 1.
Time 113.4311467616123: Quay crane starts unloading container 7 from vessel 1.
Time 113.4311467616123: Quay crane starts unloading container 8 from vessel 1.
Time 116.4311467616123: Truck finished transporting container 3 from vessel 1.
Time 116.4311467616123: Quay crane finished unloading container 7 from vessel 1.
Time 116.4311467616123: Quay crane finished unloading container 8 from vessel 1.
Time 116.4311467616123: Vessel 1 requests truck for container 7.
Time 116.4311467616123: Vessel 1 requests truck for container 8.
Time 116.4311467616123: Truck starts transporting container 6 from vessel 1.
Time 116.4311467616123: Quay crane starts unloading container 9 from vessel 1.
Time 116.4311467616123: Quay crane starts unloading container 10 from vessel 1.
Time 119.4311467616123: Truck finished transporting container 4 from vessel 1.
Time 119.4311467616123: Truck finished transporting container 5 from vessel 1.
Time 119.4311467616123: Quay crane finished unloading container 9 from vessel 1.
Time 119.4311467616123: Quay crane finished unloading container 10 from vessel 1.
Time 119.4311467616123: Vessel 1 requests truck for container 9.
Time 119.4311467616123: Vessel 1 requests truck for container 10.
Time 119.4311467616123: Truck starts transporting container 7 from vessel 1.
Time 119.4311467616123: Truck starts transporting container 8 from vessel 1.
Time 119.4311467616123: Vessel 1 has been fully unloaded and leaves the berth.
Time 122.4311467616123: Truck finished transporting container 6 from vessel 1.
Time 122.4311467616123: Truck starts transporting container 9 from vessel 1.
Time 125.4311467616123: Truck finished transporting container 7 from vessel 1.
Time 125.4311467616123: Truck finished transporting container 8 from vessel 1.
Time 125.4311467616123: Truck starts transporting container 10 from vessel 1.
Time 128.4311467616123: Truck finished transporting container 9 from vessel 1.
Time 131.4311467616123: Truck finished transporting container 10 from vessel 1.

问题:

我无法同时满足要求 1 和2.最初我没有想到起重机在卡车转运时同时卸货,我能够在该限制下运行模拟。

提到的实现能够独立运行卸载和转运过程,但我无法解决两个集装箱能够同时使用起重机或卡车的问题(如输出中突出显示的)

我尝试过的:

顺序处理集装箱卸载和运输,但仍然面临同时卸载的问题。 任何有关如何纠正此问题的指导或建议将不胜感激。

所需的输出:

Enter the number of hours to run the simulation: 3
Time 1: Vessel 1 starts berthing.
Time 1: Vessel 1 finished berthing.
Time 1: Quay crane starts unloading container 1 from vessel 1.
Time 4: Quay crane finished unloading container 1 from vessel 1.
Time 4: Truck starts transporting container 1 from vessel 1.
Time 4: Quay crane starts unloading container 2 from vessel 1.
Time 7: Quay crane finished unloading container 2 from vessel 1.
Time 7: Quay crane starts unloading container 3 from vessel 1.
Time 7: Truck starts transporting container 2 from vessel 1.
Time 7: Quay crane finished unloading container 2 from vessel 1.
Time 7:Vessel 2 starts berthing.
Time 7: Vessel 2 finished berthing.
.
.
.

的问题在于,正在同时为所有集装箱请求起重机和卡车。这会导致起重机和卡车在它们实际可用之前就被“预订”,从而导致同时操作。

要解决此问题,需要按顺序请求每台起重机和卡车,在卸载一个集装箱并使用卡车将其运走后,再请求下一个集装箱的资源。

修改的 Vessel 类中的 unload 方法,如下所示:

def unload(self):
    """从船只上卸下所有集装箱"""
    for i in range(self.containers):
        # 请求起重机以卸载集装箱
        yield self.env.process(self.unload_container(i))
        # 请求卡车以运输集装箱
        yield self.env.process(self.transport_container(i))

    print(f"Time {self.env.now}: Vessel {self.id} has been fully unloaded and leaves the berth.")

在这个修改后的代码中:

  1. 我们循环遍历船只上的每个集装箱。
  2. yield self.env.process(self.unload_container(i)) 行确保在继续下一步之前完成一个集装箱的卸载过程。
  3. 卸下集装箱后, yield self.env.process(self.transport_container(i)) 行请求卡车并等待运输完成。

通过这种方式,强制执行以下顺序:

  1. 请求起重机
  2. 卸载集装箱
  3. 请求卡车
  4. 运输集装箱
  5. 对下一个集装箱重复步骤 1-4

这可以确保一次只使用一台起重机和一台卡车来处理一个集装箱,从而满足的要求。

标签:python,asynchronous,simulation,simpy
From: 78790520

相关文章

  • 如何使用 Python 创建新的 Azure 订阅?
    我正在尝试使用PythonSDK以编程方式创建新的Azure订阅。我发现的对AzurePythonSDK的唯一引用是这个这是我最终得到的结果:importazure.mgmt.billingimportazure.mgmt.subscriptioncreds=AzureCliCredential()client_name='test'defcreat......
  • 用于打印脚本输出的 Python 实用程序
    我可以发誓有一个实用程序可以打印一个python脚本,其输出交织在一起。例如,给定一个脚本:a=2b=3print(a+b)print(a*b)该实用程序将输出a=2b=3print(a+b)#>5print(a*b)#>6有人知道该实用程序的名称吗?我最难找到它。谢谢你!描述的实用程序没有标......
  • a method to make some handy tools with python
    Inmyworkingofcomputer,therearealotofsimplejobsthatarefrequentlyrepeated.Itriedtofindawaytomakethesejobbeenprocessedeasily.Method1:Themethodiswritingascripttodothejob,andexecutingthescriptbyutoolsextensionuto......
  • Python网络爬虫详解:实战豆瓣电影信息采集
    文章目录前言一、爬虫是什么?二、常用库及其作用1.Requests2.BeautifulSoup3.lxml4.Scrapy5.Selenium6.PyQuery7.Pandas8.JSON9.Time三、实现步骤步骤一:环境准备步骤二:数据采集步骤三:数据处理步骤四:数据存储总结前言随着互联网的迅猛发展和数据分析需求的不......
  • python学习之内置函数
    Python拥有许多内置函数,这些函数是Python的一部分,不需要额外导入即可直接使用。这些函数提供了对Python解释器功能的直接访问,涵盖了从数学计算到类型检查、从内存管理到异常处理等各个方面。下面是一些常用的Python内置函数及其简要说明:一、Printprint函数大家都不会......
  • Python中以函数为作用域
    点击查看代码#第一题foriteminrange(10):#不报错,没有函数,所有操作在全局作用域里面执行,item最后赋值为:9,此时item在缩进与全局都可以使用passprint(item)#第二题item=10deffunc():foriteminrange(10):#优先在本地查找,找不到在到全局查找p......
  • 掌握IPython宏:%%macro命令的高效使用指南
    掌握IPython宏:%%macro命令的高效使用指南在编程中,宏是一种允许你定义可重用代码片段的强大工具。IPython,这个增强版的Python交互式环境,提供了一个名为%%macro的魔术命令,允许用户创建宏,从而提高代码的可重用性和效率。本文将详细介绍如何在IPython中使用%%macro命令创建宏,并......
  • 7月24号python:库存管理
    7月24号python:库存管理题目:​ 仓库管理员以数组stock形式记录商品库存表。stock[i]表示商品id,可能存在重复。原库存表按商品id升序排列。现因突发情况需要进行商品紧急调拨,管理员将这批商品id提前依次整理至库存表最后。请你找到并返回库存表中编号的最小的元素以便及......
  • IPython的Bash之舞:%%bash命令全解析
    IPython的Bash之舞:%%bash命令全解析IPython的%%bash魔术命令为JupyterNotebook用户提供了一种在单元格中直接执行Bash脚本的能力。这个特性特别适用于需要在Notebook中运行系统命令或Bash特定功能的场景。本文将详细介绍如何在IPython中使用%%bash命令,并提供实际的代码示......
  • Python数据分析与可视化大作业项目说明(含免费代码)
    题目:对全球和中国互联网用户的数据分析与可视化代码下载链接:https://download.csdn.net/download/s44359487yad/89574688一、项目概述1.1.项目背景:互联网是当今时代最重要和最有影响力的技术之一,它已经深刻地改变了人们的生活、工作、学习等方面。互联网用户数据是反映......