# PyTimetableCompression **Repository Path**: lzw37/py-timetable-compression ## Basic Information - **Project Name**: PyTimetableCompression - **Description**: 利用Python程序实现基于运行图压缩法的铁路区间通过能力计算 - **Primary Language**: Python - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 5 - **Forks**: 0 - **Created**: 2022-09-27 - **Last Updated**: 2025-03-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PyTimetableCompression ## 程序简介 本实验采用的是UIC 406手册推荐的列车运行图压缩法计算区间的通过能力利用率。与原生的UIC 406法不同的是,本实验中列车的追踪间隔保持是通过约束列车在车站的到达、出发间隔时间实现的,而UIC 406法中列车的追踪间隔保持是基于Blocking time理论,通过约束列车对闭塞分区的占用时间实现的。这是考虑到我国的铁路列车运行图编制工作中,列车的间隔是采用车站到发作业的间隔时间来保持的,并未考虑到微观层面的闭塞闭塞分区占用,因此采用列车在车站的作业间隔时间作为压缩列车运行图的约束更加符合我国列车运行图编制工作的实际,用于运行图压缩的参数也更加容易获得。 ## 程序算法原理 列车运行图压缩的具体要点为:保持列车运行图结构(各列车进入和离开区间的先后顺序)不变,列车运行图要素(区间运行时分、最小追踪间隔时间、列车在车站的最小停站时间等)符合约束条件的同时,使运行图上的列车到达和出发作业尽早地发生。由此可见,给定一张列车运行图,其可压缩的部分包括列车间隔(可压缩至最小间隔)、列车停站时间(可压缩至最小停站时间),其不可压缩的部分包括列车区间运行时分,其不可改变的部分为列车进入和离开区间的先后顺序。 基于此原则,可以将列车运行图压缩问题刻画为一个线性规划问题,其数学模型如下。模型的约束条件如下: 1. 列车的区间运行时分约束。该约束表示列车运行图在压缩时,不能压缩列车在区间的运行时分。由于压缩列车运行图不改变列车的停站方案(列车是否在某车站停站不改变,但列车在车站的停站时间可能改变),列车在区间的起停车附加时分是已知的。 2. 列车的最小停站时间约束。该约束表示列车运行图在压缩时,列车在车站的停站时间最多压缩至规定的列车最小停站时间为止,以满足列车在车站完成必要的客运和技术作业的需要。 4. 列车的最小追踪间隔约束。该约束根据列车是不停车通过车站还是在车站停留分为若干组,每组约束表示列车在车站的到达和出发追踪间隔时间约束。由于压缩列车运行图不改变列车进入区间的运行顺序,因此生成以下的列车最小追踪间隔约束前,需要先分析得到原列车运行图中各列车进入和离开区间的顺序,然后再根据列车进入区间的先后顺序以及列车在车站的通过方式,一一生成列车的最小追踪间隔约束。 以上的列车运行图压缩模型是一个线性规划模型,可以采用线性规划模型的求解器直接求解。常用的求解线性规划的商用求解器有CPLEX、Gurobi等,开源的求解器有SCIP、CBC等。本实验的程序借助Google OR-Tools工具包,调用的是工具包中内置的开源线性规划求解器(如SCIP、CBC)来求解以上的列车运行图压缩线性规划模型。 ## 程序运行环境 根据以上列车运行图压缩法的实验原理,铁路运输能力计算课程组利用Python语言开发了名为PyTimetableCompression的列车运行图压缩程序,该程序可以对给定的列车运行图进行压缩,进而计算线路的区间通过能力。 PyTimetableCompression程序是一个开源程序,其代码的托管主页为: https://gitee.com/lzw37/py-timetable-compression 程序采用的开源协议为MIT协议。简而言之,只要程序的开发者在修改后的源代码中保留原作者的许可信息即可,该程序的代码可以被用于各类软件中而不受限制。 运行PythonTimetableCompression程序需要安装以下的软件或程序包(Prerequisite)。 ### Python 3程序 下载地址为:https://www.python.org/downloads/,在该页面中选择与本机操作系统对应的Python3程序,下载后安装。 ### Python开发环境 可以按照个人的喜好选择一款合适的文本编辑器,作为Python的开发环境。推荐使用Visual Studio Code 或 PyCharm。安装好文本编辑器软件后,根据不同软件的要求配置好Python的开发环境。Visual Studio Code配置Python的开发环境的方法可以参考: ### Google OR-Tools 运筹学工具包 打开“终端(Terminal)”或“命令行(cmd)”,在终端中输入 ``` python -m pip install --user ortools ``` 即可安装Google OR-Tools工具包。 如果安装过程较慢,可以换用python的国内镜像,在终端中使用以下命令: python -m pip install --user ortools -i https://pypi.tuna.tsinghua.edu.cn/simple ### NET 6.0 如果需要采用程序输出绘制压缩后的列车运行图,可以安装.NET 6.0,以便运行列车运行图绘制程序。下载地址为(Windows 系统,64位,其他操作系统可以根据情况选择): ## PyTimetableCompression程序架构 程序包含以下几个源代码文件: ## Main.py PyTimetableCompression 的主程序。主程序的关键步骤包括: 1) 读入线路和原始列车运行图数据。 ```ptc.Data = ptcdata.LoadDataFromFiles("./InputFiles") # 从文件中读取数据``` 2) 初始化程序(根据原图生成列车进入区间顺序的集合),生成和求解列车运行图压缩线性规划模型。 ```ptc.Initialize() # 初始化``` ``` ptc.BuildModel() # 创建模型``` 3) 求解列车运行图压缩的线性规划模型。 ``` solutionStatus = ptc.Solve() # 求解模型``` 4) 压缩运行图成功后,输出文件和绘制列车运行图。 ``` if solutionStatus == True: # 如果模型求解成功,则输出运行图数据 ptc.Data.WriteTimetable() ptcdata.Plot(ptc.Data,"./OutputFiles/TimetableMetaData.xml") \# 绘制列车运行图 ``` ## PyTimetableCompressionData.py PyTimetableCompression 数据结构的定义。程序基于面向对象的程序设计思想,定义了线路基础数据的类,包括:车站、区间、运行时分标尺、追踪间隔。同时,程序还定义了列车运行图相关的类,包括:列车、列车运行图事件。 ## PyTimetableCompression.py PyTimetableCompression数学模型的构建及求解。具体的代码含义可见代码中的注释。 ## 数据输入 程序的所有数据输入均采用CSV格式的文件,在程序根目录下的./InputFile的目录中。CSV格式文件可以使用Excel打开、编辑和保存。 程序的数据输入包括以下文件: ### Station.csv 该文件描述的是车站的基础数据。 | 字段名 | 类型 | 说明 | 备注 | |----------|--------|----------------|--------------------------------------| | ID | String | 车站ID | | | Name | String | 车站名 | | | Position | Double | 车站中心线里程 | 用于决定绘制列车运行图时站名线的位置 | ### Segment.csv 该文件描述的是区间的基础数据。在本程序中,定义一个“区间”为一条区间的正线(双线铁路的区间包含2条正线,所以在本表中,一个双线铁路区间包括一个上行“区间”和一个下行“区间”)。 | 字段名 | 类型 | 说明 | 备注 | |---------------|--------|--------------|------| | ID | String | 区间ID | | | FromStationID | String | 区间出发站ID | | | ToStationID | String | 区间到达站ID | | | Name | String | 区间名称 | | ### Ruler.csv 该文件描述的是列车运行时分(标尺)。 | 字段名 | 类型 | 说明 | 备注 | |---------------------|--------|----------------------|----------------------| | SegmentID | String | 区间ID | | | TrainType | String | 采用该标尺的列车种类 | 可能的取值为‘G’和‘D’ | | FreeFlowRunningTime | Int | 纯运行时分 | | | AccelerateAdd | Int | 起动附加时分 | | | DecelerateAdd | Int | 停车附加时分 | | ### Headway.csv 该文件描述的是列车的追踪间隔时间。 | 字段名 | 类型 | 说明 | 备注 | |-----------|--------|------------|------| | ID | String | 追踪间隔ID | | | SegmentID | String | 区间ID | | | I_aa | Int | 到-到间隔 | | | I_dd | Int | 发-发间隔 | | | I_pd | Int | 通-发间隔 | | | I_ap | Int | 到-通间隔 | | | I_pp | Int | 通-通间隔 | | | I_pa | Int | 通-到间隔 | | | I_dp | Int | 发-通间隔 | | ### Train.csv 该文件描述的是列车的基本信息。 | 字段名 | 类型 | 说明 | 备注 | |--------|--------|--------------|--------------------------------------------------| | ID | String | 列车ID | 此数据集中的列车ID即为车次 | | Type | String | 列车种类 | 可能的取值为‘G’和‘D’,决定了列车采用何种运行标尺 | | Route | String | 列车运行径路 | 列车运行径路表示为采用“-”分隔的区间ID序列 | ### OrgTimetable.csv 该文件描述的是列车的原始时刻表。 | 字段名 | 类型 | 说明 | 备注 | |---------------|----------|----------|------| | TrainID | String | 列车ID | | | StationID | String | 车站ID | | | ArrivalTime | DateTime | 到达时刻 | | | DepartureTime | DateTime | 出发时刻 | | ## 数据输出 程序的所有数据输出也均采用CSV格式的文件,保存在程序根目录下的OutputFile的目录中。 程序的输出包括以下几个文件: ### CompressedTimetable.csv 该文件描述的是压缩后的列车时刻表。 | 字段名 | 类型 | 说明 | 备注 | |-------------|----------|------------------------|------------------------------------------------------------| | TrainID | String | 列车ID | | | StationName | String | 车站名 | | | EventType | String | 事件类型 | 可能的取值为“Arrival”(到达事件)和“Departure”(出发事件) | | Time | DateTime | 事件发生时刻(压缩后) | | ### GraphicalTimetable.svg 该文件是根据压缩后的列车时刻表绘制的列车运行图矢量图,可以通过浏览器打开。程序的运行环境中,需要安装.NET 6.0 Runtime才能实现该矢量图的绘制,如果没有安装则会在绘制运行图时弹出错误信息,但是不会影响程序其他部分的正常运行以及CompressedTimetable.csv文件的输出。 ## 程序的运行 程序可以在程序的根目录下,通过命令行: ``` python ./Main.py``` 运行,也可以在Visual Studio Code或其他文本编辑器、IDE下使用调试模式运行。