首页 > 编程语言 >python 利用simpy工具包设计一个仿真应用

python 利用simpy工具包设计一个仿真应用

时间:2024-07-17 18:42:08浏览次数:12  
标签:python simpy self 工具包 len env time now speed

这里仿真了一个直行红绿灯路口。

假设有一条红绿灯路口的直行车道(假设只有一条,一条和多条相似),现在有一些车要过红绿灯,绿灯20s,黄灯5s,路口40m
这里采用网上五菱宏光s的加速度和刹车数据,零百14.3s左右,100码刹车42m,仪器显示加速度数值约为40km/h
我们假设均匀加减速,启动加速度取2m/s^2,刹车加速度取10m/s^2,设最大速度10m/s(36km/h),车长4.4m,这样最大刹车距离为5m
SimPy 是 Python 中一个流行的离散事件模拟框架。它允许用户使用 Python 编程语言进行事件驱动的模拟。SimPy 可以用于构建复杂的离散事件系统,如排队系统、库存系统等

详情请看代码如下:

import simpy
import random
import matplotlib.pyplot as plt
 
 
# 有一条红绿灯路口的直行车道(假设只有一条,一条和多条相似),现在有一些车要过红绿灯,绿灯20s,黄灯5s,路口40m
# 这里采用网上五菱宏光s的加速度和刹车数据,零百14.3s左右,100码刹车42m,仪器显示加速度数值约为40km/h
# 我们假设均匀加减速,启动加速度取2m/s^2,刹车加速度取10m/s^2,设最大速度10m/s(36km/h),车长4.4m,这样最大刹车距离为5m
# 最开始采用 每辆车只会在前面车启动1~3s后 启动,但是感觉像是一个一个上,慢慢改成现在的样子
 
class Traffic_Light(object):
    def __init__(self, traffic_light_time, ):
        # 0红1绿2黄
        self.state = 0  # 开始红灯
        self.time = 5  # 五秒后再变灯
        self.traffic_light_time = traffic_light_time  # 红绿灯时间
 
    def change_light(self):
        # 变灯过程
        if self.state == 0:
            self.state = 1
        elif self.state == 1:
            self.state = 2
        else:
            self.state = 0
        self.time = self.traffic_light_time[self.state]
 
    def getState(self):  # 返回当前灯
        return self.state
 
    def run(self, env):  # 开启红绿灯
        self.env = env
        while True:
            yield env.timeout(self.time)
            self.change_light()  # 变灯
            if self.state == 0:
                print("红灯,==========时间:", env.now, "======================================")
            elif self.state == 1:
                print("绿灯,==========时间:", env.now, "======================================")
            else:
                print("黄灯,==========时间:", env.now, "======================================")
 
 
class Vehicle(object):
    def __init__(self, env, delay, id, position_len, max_speed, acceleration):  # 构造函数,
        self.env = env  # 车辆所处的环境
        self.delay = delay  # 比前车晚的启动时间
        self.id = id
        self.position_len = position_len  # 到路口的距离,归零就结束
        self.speed = max_speed  # 当前速度
        self.acceleration = acceleration  # 加速度
        self.ultimate_braking_distance = max_speed ** 2 / 2 / -acceleration[1]  # 极限刹车距离
        self.maximum_error = max_speed * time_particles  # 最大误差,一个时间颗粒能跑最远距离
 
    def run(self):
        while True:
            vi = vehicle.index(self)
            now_a = 0
            if vi > 0:
                s = (self.position_len - vehicle[
                    vi - 1].position_len - self.ultimate_braking_distance - self.maximum_error)
                if self.speed > vehicle[vi - 1].speed or s < 0:  # 比前车快或者有点近了
                    # 通过与前车距离和速度差减速,留下最短刹车距离和误差做缓冲
                    if not s <= 0:
                        now_a = -(self.speed - vehicle[vi - 1].speed) ** 2 / 2 / s  # 慢慢刹车
                    else:
                        now_a = -10
                else:
                    now_a = self.acceleration[0]
            else:  # 是第一辆车
                if traffic_light.getState() == 1:  # 绿灯
                    now_a = self.acceleration[0]  # 直接往前开
                else:  # 黄灯或者红灯 s = v^2/2a
                    if self.speed ** 2 / 2 / -acceleration[1] > self.position_len:  # 刹不住的
                        now_a = self.acceleration[0]  # 直接往前开
                    else:
                        if not self.position_len == 0:
                            now_a = -self.speed ** 2 / 2 / self.position_len  # 慢慢刹车
                        else:
                            now_a = 0
            if now_a > self.acceleration[0]:
                now_a = self.acceleration[0]
            if now_a < self.acceleration[1]:
                print(self.id, "正在用脸停车,脸刹也止不住")
                now_a = self.acceleration[1]
            self.speed += now_a * time_particles  # 微分思想,在短短时间内变速
            if self.speed > max_speed:  # 不允许超过最大速度
                self.speed = max_speed
            if self.speed <= 0:
                self.speed = 0  # 负数减速到0
            self.position_len -= self.speed * time_particles  # 减少当前距离
            print(self.id, "当前速度:", self.speed, "加速度:", now_a, "距离:", self.position_len, "时间:", env.now)
            yield env.timeout(time_particles)  # 等待一下再看看
            if self.position_len <= -0.5:  # 开过去了
                self.firing = True
                print(self.id, "已通过,时间:", env.now)
                vehicle.remove(self)
                break
 
 
def Vehicle_Appears(env, appears_time):  # 随机时间出现车辆
    all_vehicle = 0
    while True:
        yield env.timeout(random.uniform(appears_time[0], appears_time[1]))  # 每隔随机时间出现一辆车
        if len(vehicle) >= max_wait_len:  # 车太多了,就不进来了
            continue
        vehicle.append(Vehicle(env, random.uniform(delay_time[0], delay_time[1]), all_vehicle, position_len, max_speed,
                               acceleration))  # 添加一个车辆
        print("新车辆", all_vehicle, "到了,\t时间:", env.now)  # 车辆启动
        all_vehicle += 1
        env.process(vehicle[-1].run())  # 车辆进入道路
 
 
def plt_Refresh(env):
    while True:
        plt.clf()  # 清屏
        plt.xlim(-2, position_len + 2)
        plt.ylim(-1, 6)
        # 绘图
        plt.scatter(0, -0.5, 1000,
                    "r" if traffic_light.state == 0 else ("g" if traffic_light.state == 1 else "y"))  # 红绿灯
        for i in vehicle:
            plt.scatter(i.position_len, i.id % 6, 50, coler[i.id % 6])
            plt.text(i.position_len, i.id % 6 + 0.2, i.id, fontsize=12)
        # 刷新图形
        plt.draw()
        plt.pause(time_particles / 10)# 不想真等几分钟
        yield env.timeout(time_particles)
 
 
time_particles = 0.1  # 时间颗粒,车辆操作最小时间,大了不够细致,太小了运行太慢
delay_time = [0.5, 1.2]  # 开车延时 后面通过各种实验和修改,废弃了这个方法
traffic_light_time = [10, 20, 5]  # 红绿灯时间
appears_time = [1, 2]  # 来车时间
run_time = 120  # 运行时间
position_len = 40  # 路口长度
max_speed = 10  # 最大速度
acceleration = [2, -10]  # 加速度
max_wait_len = 5  # 最多5辆车排队
spacing = 6  # 等待中距离前车车头的距离
# 参数设置完毕
traffic_light = Traffic_Light(traffic_light_time)  # 红绿灯
vehicle = []  # 汽车列表
# 绘图
plt.figure()
coler = ["r", "m", "y", "g", "c", "b", "k"]  # 颜色
env = simpy.Environment()  # 设置环境并启动模拟
env.process(traffic_light.run(env))  # 启动红绿灯
env.process(plt_Refresh(env))
env.process(Vehicle_Appears(env, appears_time))  # 开始来车
env.run(until=run_time)  # 运行模拟
 
plt.show()

 

 

标签:python,simpy,self,工具包,len,env,time,now,speed
From: https://www.cnblogs.com/kn-zheng/p/18308089

相关文章

  • 第二课堂笔记:python入门
    数据类型和操作python的常见数据类型标准数据类型不可变数据Number(数字)String(字符串)Tuple(元组)可变数据List(列表)Set(集合)Dictionary(字典)其他Type(类型)Numberint(整数)离散的数据类型float(浮点数)浮点数误差:​ 精确计算浮点数importdecimala=decimal.......
  • [oeasy]python0025_ 顺序执行过程_流水_流程_执行次序
    顺序执行过程_流水_流程_执行次序......
  • python 中深浅拷贝
    #等号赋值#l0=[1,3,5]#l2=[1,3,5]#l0.append(7)#print(l0,l2)#print(l0==l2,l0isl2,id(l0),id(l2))#等号赋值:直接赋予内存地址两个变量最终还是同一个内存地址#修改一个另一个同步更改#l0=[1,3,5]#l2=l0#l0.append(7)#pri......
  • Clarke-Wright节约算法详解与Python代码示例
    Clarke-Wright节约算法详解与Python代码示例一、算法详解Clarke-Wright节约算法(简称C-W算法),也称为节约里程法或节约算法,是由Clarke和Wright于1964年提出的一种启发式算法。该算法主要用于解决车辆路径问题(VehicleRoutingProblem,VRP),特别是在运输车辆数目不确定的情况下......
  • 小一保姆级 Python 文件操作与管理详解
    Python文件操作与管理在Python编程中,文件操作是日常任务中不可或缺的一部分。本文将介绍Python中三个重要的文件相关模块和功能:open函数、json与pickle库、以及os模块的使用。1. open 函数的使用Python中的open函数是用来打开文件的核心函数。它提供了多种......
  • 【Python】从基础到进阶(四):深入了解Python中的控制流
    ......
  • 【Python】CSS与选择器
        ......
  • python gradio 页面控件
    1、textbox的使用importgradioasgrimportrequestsdefmobile(mobilephone):url='https://api.oioweb.cn/api/common/teladress?mobile='+str(mobilephone)headers={}payload={}response=requests.request("GET",url,......
  • 从零开始学Python第一天:基础知识
    前言在这个信息爆炸的时代,编程技能已经成为我们生活和工作中不可或缺的一部分。而Python,作为一门简洁易读、功能强大的编程语言,正逐渐受到越来越多人的青睐。作为初学者,你可能会对编程充满好奇与期待,同时也有一些担忧和困惑。但是请相信,只要你愿意付出努力和时间,Python的......
  • 为什么都提倡学Python?这10大特性你一定要清楚!
    前言在了解Python的特性之前,我们首先要了解Python编程语言是什么。Python编程语言是世界上发展最快的编程语言。这一高级通用编程语言提供了广泛的实际应用,并且是一种非常流行的认证。Python可以让程序员更加高效地工作和集成系统。Python的语法优先考虑了可读性,同......