基于堆优化的dijkstra算法,求出任意两个火车站之间的最快换乘方案
本系统基于Dijkstra单源最短路算法,对于给定的出发时间,可以给出从任意一个火车站出发,到达任意一个火车站的最快方案。虽然与携程、飞猪、去哪儿等成熟的OTA平台相比,少了很多的功能,但也多了很少但很实用的功能,在某些特定应用场景下有着独特的优势。
- 可查询12306任意两座火车站之间的最快交通方案
- 支持设置出发时间,早中晚出发方案各不相同
- 支持同城车站查询
- 支持筛选高铁/动车
- 支持绕开特定车站
- 支持设置换乘间隔
- 理论上可扩展更多功能(最短路程、最少花费、飞机)
本系统暂时只支持命令行和桌面应用,Web端和移动端以后可能会开发。下面以桌面应用介绍本程序的使用方法。
出发、到达车站请填写车站的中文汉字全程,要与12306网站的站名一致,最后面不要加“站”字,也不要写成“XX省XX市”,“XX县”(除非该火车站的站名后面自带“市”、“县”等后缀)。
正确示范:北京、北京南、北京大兴、上海虹桥
错误示范:上海市,广州南站,山东济南,辽宁省朝阳市
请尽量填写离您最近的车站名,例如如果您填写“北京”,早上7点出发,同城换乘间隔为120分钟,系统会认为您可以赶上07:01分从北京站开出的火车,而赶不上08:59分北京西站的火车(详见同城车站换乘部分)。
表示您到达出发站的时间,也是旅途总耗时的计算起点。例如您选择15:00出发,如果有一列15:01分出发的火车,您只需要等待1分钟就可以坐上火车了,而如果有一列14:59分的火车,您需要等待23小时59分钟(如果赶不上今天的车,就需要再等一天)
旅行历时指的是从您设置的出发时间开始计算,到您抵达目的地车站为止,所经历的总时间。例如,从A地到B地,A地的出发时间是15:00,有一列16:00从A地出发,18:00到达B地,从A到B的旅行历时是3小时而不是2小时。本系统寻找的是旅行历时最短的方案(将等车的时间也计算在内),而非单纯的乘车时间最短。
最小同站换乘间隔指的是当在同一个火车站换乘时,需要预留出来的最小转车时间。最小同城异站换乘间隔指的是当在同一座城市的两座不同的火车站之间换乘时,需要预留的时间。换乘间隔需要综合考虑各种因素,包括前序列车是否晚点,车站有无便捷换乘通道,出站后再安检进站的时间,不同车站之间的距离以及城市内部的交通状况,以及您对换乘地的熟悉程度。请确保预留足够的换乘间隔,以免在旅行途中赶不上车而影响行程。
您可以选择只考虑高铁/动车或不考虑高铁/动车,本系统认为车次以G/D/C开头的列车为高铁/动车,否则为非高铁/动车。
当您出于某种原因,而不愿或不能途径某些地区时,您可以选择绕行某个车站。请注意,绕行车站不包括同城车站,如果您想避开某个城市,您需要分别输入该城市境内的所有车站的名称。另外,绕行车站只是说您不会在该地上下车中转换乘,您乘坐的列车仍有可能在您绕行的车站停靠。
在开始使用前,别忘了先设置好数据文件的路径。如果您使用的是命令行操作,您可能需要修改源代码中的文件路径,如果您使用的是桌面版应用,点击设置按钮,选择文件路径。本系统附带了一些数据文件,这些数据文件是2021年1月份从12306网站上获取的,您也可以使用自己的数据文件,文件格式如下:
站名字典应当是一个csv文件,下面给出了一个例子,表头的内容不影响程序工作,但您需要保证每一列的顺序与下表中的一致,三位首字母、站点代号、全拼、缩写不是必需的。编号必须从0开始连续编号。
| 站点名 | 三位首字母 | 站点代号 | 全拼 | 缩写 | 编号 |
|---|---|---|---|---|---|
| 北京北 | bjb | VAP | beijingbei | bjb | 0 |
| 北京东 | bjd | BOP | beijingdong | bjd | 1 |
| 北京 | bji | BJP | beijing | bj | 2 |
| 北京南 | bjn | VNP | beijingnan | bjn | 3 |
同城车站文件与站名字典文件比较类似,也是csv文件,下面截取文件的一部分
| 车站ID | 车站名 | 站点代号 | 同城车站 | ||||||
|---|---|---|---|---|---|---|---|---|---|
| 0 | 北京北 | VAP | 北京 | 北京东 | 北京南 | 北京朝阳 | 北京西 | 昌平北 | 清河 |
| 1 | 北京东 | BOP | 北京 | 北京北 | 北京南 | 北京朝阳 | 北京西 | 昌平北 | 清河 |
| 2 | 北京 | BJP | 北京东 | 北京北 | 北京南 | 北京朝阳 | 北京西 | 昌平北 | 清河 |
| 3 | 北京南 | VNP | 北京 | 北京东 | 北京北 | 北京朝阳 | 北京西 | 昌平北 | 清河 |
| 4 | 北京西 | BXP | 北京 | 北京东 | 北京北 | 北京南 | 北京朝阳 | 昌平北 | 清河 |
| 5 | 广州南 | IZQ | 广州 | 广州东 | 广州北 |
车站名,车站ID必须与站名字典文件中的车站名,id一一对应,从第4列开始(列标从1开始)表示该车站的同城车站,同城车站不包括该车站本身,每个车站占一个独立的单元格(在csv文件里以逗号分割)
车次文件是一个txt文件,文件的第一行为一个整数$n$,表示一共有$n$个车次,不同车次之间用1行一个独立的英文分号表示间隔。接下来$n$组数据,每组数据的第一行为一个整数$m$,表示该列车有$m$站,接下来$m$行,每行以制表符'\t'分割,从左到右依次是站点序号、车次、车站、到达时间、出发时间、到达日期,下面给出了一个例子。
7856 1 01 K101 北京 ---- 23:20 0 02 K101 沧州 02:13 02:31 1 03 K101 德州 03:47 03:49 1 …… 24 K101 缙云 02:04 02:07 2 25 K101 温州 05:49 05:49 2 ; 2 01 K102 温州 11:03 11:03 0 02 K102 青田 12:08 12:16 0 03 K102 缙云 14:15 14:17 0 …… 24 K102 廊坊北 14:35 14:45 1 25 K102 北京 15:45 15:45 1 ; 3 01 K105 北京西 23:18 23:18 0 02 K105 霸州 00:17 00:26 1 03 K105 任丘 01:01 01:03 1 …… 23 K105 东莞东 03:05 03:15 2 24 K105 深圳 04:20 04:20 2 ;
……(下略)
下面给出几个查询样例
漠河 -> 哈尔滨 K7040(始:漠河,终:哈尔滨) 12 :51 ~05 :50 (+1) (共7站) 哈尔滨 站 --市内交通--> 哈尔滨西 站 哈尔滨西 -> 石家庄 G1276(始:哈尔滨西,终:武汉) 08 :57 ~17 :30 (共16站) 石家庄 -> 三亚 Z201(始:北京西,终:三亚) 20 :25 ~08 :12 (+2) (共12站) 70 时12 分
山海关 -> 西安北 G1284(始:沈阳北,终:成都东) 09 :40 ~17 :31 (共17站) 西安北 -> 兰州西 D2663(始:西安北,终:兰州西) 18 :39 ~21 :58 (共6站) 兰州西 -> 嘉峪关南 D2741(始:兰州西,终:嘉峪关南) 07 :04 ~11 :44 (共6站) 嘉峪关南 站 --市内交通--> 嘉峪关 站 26 时44 分
丹东 -> 沈阳北 G8102(始:东港北,终:吉林) 07 :19 ~09 :05 (共6站) 沈阳北 -> 武汉 G1276(始:哈尔滨西,终:武汉) 11 :32 ~21 :49 (共19站) 武汉 站 --市内交通--> 武昌 站 武昌 -> 桂林北 Z5(始:北京西,终:南宁) 03 :01 ~11 :25 (共4站) 桂林北 -> 防城港北 D8493(始:三江南,终:防城港北) 12 :58 ~17 :10 (共7站) 32 时40 分