城市轨道行车组织运行时刻表自动化生成与列车乘务员自动化排班---使用python代码实现

本文章基于作者先前的文章“城市轨道行车组织运行时刻表自动化生成---使用python代码实现”在基础上进行列车乘务员自动化排班的功能,使得代码更加智能。喜欢文章给作者点点赞把!


  •  一、客流量计算

   1.定义早高峰小时客流量:设定早高峰时段的小时客流量为43000人。

   2.时间段比例:根据不同时间段的比例,计算每个时间段的客流量。

  •  二、列车编组和容量

   1.列车编组:每列列车由6辆车组成。

   2.车辆定员:每辆车的定员为310人,因此每列列车的总定员为6 * 310人。

  • 三、 区间运行时间和停站时间

   2.上行方向运行时间:各区间的运行时间已定义。

   3.下行方向运行时间:各区间的运行时间已定义。

   4.停站时间:各站的停站时间分别定义了上行和下行方向的停站时间。

   5.折返时间:列车折返所需的时间。

   6.进场和出场时间:列车进场和出场所需的时间。

  • 四、满载率和列车数量计算

   7.满载率:通过随机函数为每个时间段生成一个满载率,特别是在高峰时段(如06:30和16:30),满载率较高。

   8.列车数量:根据每个时间段的客流量和满载率,计算所需的列车数量。

  •  五、列车循环时间计算

   上行时间:计算上行方向总运行时间和停站时间的总和。

   下行时间:计算下行方向总运行时间和停站时间的总和。

   循环时间:包括上行时间、下行时间、折返时间、进场时间和出场时间。

  •  六、列车运行图生成

   起始时间:设定列车的起始运行时间为05:00。

   列车池:记录每列车的下一次可用时间。

   列车运行时刻表:根据计算出的列车数量和运行间隔时间,为每个时间段生成列车的具体运行时刻表,包括各站的到达和出发时间,以及满载率。

  • 七、 乘务员排班表生成

   1.乘务员列表:定义50名乘务员。

   2.乘务员池:使用字典记录每名乘务员的下一次可用时间、累计工作时间和当天工作时间。

   3.乘务员分配:

     3.1. 每当一列列车需要分配乘务员时,从乘务员池中选择一名当前时间可用且当天工作时间未超过8小时的乘务员进行分配。

     3.2. 乘务员的工作时间分配有以下特点:

        3.2.1 每次工作时间不超过2小时。

        3.2.2每2小时工作时间后有30分钟的休息时间(如果连续工作达到2小时)。

   4.乘务员排班记录:记录乘务员的工作开始时间和结束时间。

 

代码部分:

import numpy as np
import pandas as pd
from datetime import datetime, timedelta
import random

# 定义早高峰小时客流量
peak_hour_passenger_flow = 43000

# 表1中的客流量比例
time_period_proportions = [
    0.08, 0.43, 1, 0.76, 0.51, 0.41, 0.47, 0.59, 0.64, 0.64, 
    0.69, 0.73, 0.88, 0.62, 0.39, 0.31, 0.26, 0.20, 0.08,
]

# 定义时间段(起始时间)
time_periods = [
    "05:00", "05:30", "06:30", "07:30", "08:30", "09:30", "10:30", "11:30", "12:30",
    "13:30", "14:30", "15:30", "16:30", "17:30", "18:30", "19:30", "20:30", "21:30", "22:30"
]

# 计算每个时间段的客流量
passenger_flow = [round(peak_hour_passenger_flow * proportion) for proportion in time_period_proportions]

# 列车编组和车辆定员
train_capacity = 6 * 310  # 6辆车,每辆车310人

# 定义区间运行时间和停站时间
section_times_up = [222, 250, 232, 175, 180, 210, 265]  # 上行方向停站时间(单位:秒)
section_times_down = [215, 245, 240, 182, 212, 300, 250]  # 下行方向停站时间(单位:秒)
stop_times_up = [40, 30, 50, 30, 30, 50, 30, 40]  # 各站停站时间(上行方向,单位:秒)
stop_times_down = [40, 30, 50, 30, 30, 50, 30, 40]  # 各站停站时间(下行方向,单位:秒)
turnaround_time = 200  # 折返时间(单位:秒)
entry_time = 260  # 进场时间(单位:秒)
exit_time = 270  # 出场时间(单位:秒)

stations = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']

# 满载率计算,加入随机性
def get_full_load_rate(period):
    if time_periods[period] in ["06:30", "16:30"]:
        return np.random.uniform(1.1, 1.2)
    else:
        return np.random.uniform(0.7, 0.9)

full_load_rates = [get_full_load_rate(i) for i in range(len(time_periods))]

# 计算各时间段的列车数量,加入随机性
train_numbers = [
    np.ceil((passenger_flow[i] * np.random.uniform(0.9, 1.1)) / (train_capacity * full_load_rates[i])).astype(int) 
    for i in range(len(passenger_flow))
]

# 计算列车运行间隔时间(单位:秒)
time_intervals = [1800 if i == 0 or i == len(time_periods) - 1 else 3600 for i in range(len(time_periods))]  # 修改后的每个时间段总时间
departure_intervals = [int(np.ceil(time_intervals[i] / train_numbers[i])) for i in range(len(train_numbers))]

# 计算一列列车的循环时间(包括上行、下行、折返和停站时间)
def calculate_cycle_time():
    up_time = sum(section_times_up) + sum(stop_times_up)
    down_time = sum(section_times_down) + sum(stop_times_down)
    return up_time + down_time + 2 * turnaround_time + entry_time + exit_time

cycle_time_seconds = calculate_cycle_time()
cycle_time = timedelta(seconds=cycle_time_seconds)  # 转换为timedelta对象

# 生成列车运行图和乘务员排班表
timetable = []
crew_schedule = []
train_id = 1

# 起始时间
start_time = datetime.strptime("05:00", "%H:%M")

# 列车池,记录每列车的下一次可用时间
train_pool = []

# 创建乘务员列表
crew_members = [f"乘{i+1}" for i in range(50)]

# 乘务员池,记录每个乘务员的下一次可用时间和累计工作时间
crew_pool = {member: (start_time, timedelta(0), timedelta(0)) for member in crew_members}  # (下一次可用时间, 累计工作时间, 当天工作时间)

for period in range(len(time_periods)):
    departure_time = start_time + timedelta(seconds=sum(time_intervals[:period]))
    current_train_numbers = train_numbers[period]
    active_trains = []

    for _ in range(current_train_numbers):
        # 检查列车池中是否有可用列车
        if train_pool and train_pool[0][1] <= departure_time:
            # 复用已有列车
            train_no, available_time = train_pool.pop(0)
        else:
            # 创建新列车
            train_no = f"01{train_id:03d}"
            train_id += 1
        
        active_trains.append(train_no)

    for train_no in active_trains:
        # 初始化时间
        current_time = departure_time
        
        # 分配乘务员
        for crew_member, (available_time, total_work_time, daily_work_time) in crew_pool.items():
            if available_time <= current_time and daily_work_time < timedelta(hours=8):
                work_time = min(cycle_time, timedelta(hours=2) - (total_work_time % timedelta(hours=2)))  # 每次工作时间不超过2小时
                rest_time = timedelta(minutes=30) if (total_work_time + work_time) % timedelta(hours=2) == timedelta(0) else timedelta(0)
                
                crew_pool[crew_member] = (current_time + work_time + rest_time, total_work_time + work_time, daily_work_time + work_time)
                break
        
        crew_schedule.append([crew_member, train_no, current_time.strftime("%H:%M:%S"), (current_time + work_time).strftime("%H:%M:%S")])
        
        # 上行方向运行
        for i, station in enumerate(stations):
            if i == 0:
                # 进场时间
                current_time += timedelta(seconds=entry_time)
            else:
                # 区间运行时间
                current_time += timedelta(seconds=section_times_up[i - 1])
            
            # 记录到达时间
            arrive_time = current_time
            
            # 停站时间
            current_time += timedelta(seconds=stop_times_up[i])
            
            # 记录出发时间
            depart_time = current_time
            
            # 添加到时刻表
            timetable.append([train_no, station, arrive_time.strftime("%H:%M:%S"), depart_time.strftime("%H:%M:%S"), round(full_load_rates[period], 2)])
        
        # 折返时间
        current_time += timedelta(seconds=turnaround_time)
        
        # 下行方向运行
        for i, station in enumerate(reversed(stations)):
            if i == 0:
                # 出发时间
                current_time += timedelta(seconds=0)
            else:
                # 区间运行时间
                current_time += timedelta(seconds=section_times_down[i - 1])
            
            # 记录到达时间
            arrive_time = current_time
            
            # 停站时间
            current_time += timedelta(seconds=stop_times_down[i])
            
            # 记录出发时间
            depart_time = current_time
            
            # 添加到时刻表
            timetable.append([train_no, station, arrive_time.strftime("%H:%M:%S"), depart_time.strftime("%H:%M:%S"), round(full_load_rates[period], 2)])
        
        # 出场时间
        current_time += timedelta(seconds=exit_time)
        
        # 更新列车池
        next_available_time = current_time + timedelta(seconds=turnaround_time)
        train_pool.append((train_no, next_available_time))
        train_pool.sort(key=lambda x: x[1])
        
        # 调整下一列车的发车时间,避免重叠
        departure_time += timedelta(seconds=departure_intervals[period])

# 创建DataFrame并保存到Excel文件
df_timetable = pd.DataFrame(timetable, columns=["列车号", "站点名称", "到达时间", "出发时间", "满载率"])
df_crew_schedule = pd.DataFrame(crew_schedule, columns=["乘务员", "列车号", "工作开始时间", "工作结束时间"])



# 保存为Excel文件到D盘
file_path_timetable = "D:/train_timetable_randomized.xlsx"
file_path_crew_schedule = "D:/crew_schedule.xlsx"
df_timetable.to_excel(file_path_timetable, index=False)
df_crew_schedule.to_excel(file_path_crew_schedule, index=False)

print(f"列车运行图已生成并保存为 {file_path_timetable} 文件。")
print(f"乘务员排班表已生成并保存为 {file_path_crew_schedule} 文件。")
 

 

 

 

  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值