作者shter (飞梭之影)
看板Soft_Job
标题Re: [讨论] 软体业的感慨
时间Thu Jan 30 00:16:53 2020
来一篇纯兴趣者跟公司无关的个人作品演算法改进文了
不同於底子深、LeetCode 刷得勤的人,我是从兴趣与实作导向中遇到困难点才去做
演算法改进的人,而且也不是说效能改良,而是因为太麻烦才改良的
先谈一下作品背景
程式名称: 接轨时刻、公共运输整合资讯 library ROCPTX
超连结: https://melixyen.github.io/railtime
library: https://github.com/melixyen/rocptx
这个作品是参考日本的转乘案内网站後设计的
因为台北捷运环状线今年通车,今年过年刚好是我的作品很重要的一个改版
所以年假几乎都在写这两支程式,加入环状线的转乘资讯
这是目前版本所使用给予环状线转乘资料的一次 github commit
https://tinyurl.com/wwvvmn3
原网址
https://github.com/melixyen/railtime/commit/17a9fcb9762cbf82b5fde708aac57f8a81f4179e
其中 ttlib/data.js 是目前版本转乘路由规则的基础资料
当选择两个站点让程式自动查找转乘路线时所依据的就是这些资料连结起来的路由匹配
并透过一些 regexp 过滤掉不适合走该路线的起迄站 id
例如中和新芦线跟淡水信义线有两个转乘站东门与民权西路,中和到世贸可以跳过
先搭到民权西路才换淡水线去台北 101 方向重覆经过东门的走法
困难点
当台北的轨道运输路网越来越复杂後,像环状线加入後转乘路由暴增
以人工方式建立资料将来路网更多元後会更困难,要预想一个自动爬路径演算法
改进方式
不预先建立转乘资料,自起站开始往路线两端各开一个路由搜寻
碰到转乘站就再开分支路由递回搜寻,爬过每一个节点,如果遇到重复站就放弃路线
直到所有路线都被放弃或有爬到目标车站为止
将有爬到的路线全部纪录下来,并计算经过多少车站、耗时几分钟
效能调整
车站太多,要爬的次数太多,但有些情况可以直接跳过
例如板南线在忠孝敦化到南港间没有任何转乘站,我从市政府出发不需要每一次都先
爬永春跟国父纪念馆站,应该可以直接跳到忠孝复兴跟南港展览馆站
所以在爬之前先把路网 block 切出来,转乘站与转乘站间没有经过任何可以转车之
车站的路段就统一成一个 block,比如淡水开始一直到北投才切成第二个 block
不用爬红树林、竹围、关渡.....这样要爬的次数就少很多了
结果
https://github.com/melixyen/rocptx/blob/master/src/router.v2.js
新的演算法放在这个 library 内,如果从接轨时刻的网站打开 console
可以下 rocptx.router.v2.trtc.getAllLineRoute('BL10','R04')
就能找出龙山寺到信义安和所有不重复的转乘路由
也许搭到台北车站只转一趟,也许搭到西门就叫你转新店线到中正纪念堂接信义线
或者搭到忠孝复兴再爬上文湖线到大安再换信义线....都帮你列出来
把 BL10 和 R04 换成你要查的起迄捷运站代码即可
以这个为基础,当交通部更新路网资料後,让程式自动去爬就好
剩下的只是过滤掉所有不重复转乘路线,转太多次、经过车站太多的放弃掉
可能只取前三或前五给使用者参考就好
心得
我面试没刷 LeetCode 过,会跟我要 github 我就丢这个小作品
有些面试官会觉得有趣,就稍微讲解一下程式内容跟当初写演算法的想法
星星数很少,不过这本来就算满冷门的应用,纯粹是个人兴趣
没有公司是因为先看到 github 而找我去面试软体工程师的
但有几次是因为 github 被其他公司请去讲解原理或 library 需要技术支援而拿到钱的
不多,一次大概几千元到几万元之间,视需求跟时数
所以在 github 上除了面试能当作品外,想赚外快也还是有机会的
--
[LINE 台币汇率机器人] https://line.me/R/ti/p/sCsZnuBg5V
即时台银汇率,可计算退税价格,出国血拼直接输入货架金额查询退税後台币价。
打招呼会告诉你使用说明 讲日币就会将汇率切成日币模式 之後打数字就会自动转换
===============================================================
新增笔记本功能可纪录外币消费、比价用途,并利用所查价格开启团购功能
https://youtu.be/ttayJLYa7Oc
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 111.250.66.8 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Soft_Job/M.1580314623.A.49C.html
1F:推 k12795: 有点酷 01/30 02:42
2F:推 onegoman: 推。 01/30 06:43
3F:嘘 pig2014: 建议接馆长的case 01/30 07:06
4F:推 oopFoo: 不是都用dijkstra map来作path finding? 01/30 07:50
5F:推 yamakazi: 推 01/30 09:44
6F:推 AudiA4Avant: 看叙述是用dijkstra阿?,这case可以用Floyd-Warshall 01/30 10:20
7F:推 w2sw2sw2s: 推 01/30 19:36
8F:推 pig0038: 推 01/31 09:15
9F:推 MudHan: 优化的部分有点像DP, 去存已经爬过的sub route就可以省掉 01/31 16:27
10F:→ MudHan: 重复递回的时间 01/31 16:27
11F:推 oopFoo: 也许我理解错误。但从叙述看起来像是Depth First Search. 01/31 21:52
12F:→ oopFoo: Dijsktra是Breadth First Search + weight. 01/31 21:53
13F:→ oopFoo: A* search 是把weight变成Heuristic function. 01/31 21:53
14F:→ oopFoo: 台湾轨道运输应该只有几百个Nodes吧?现在JS一秒跑个百万 01/31 21:55
15F:→ oopFoo: Nodes的BFS应该都轻轻松松。应该完全不需要效能调整。 01/31 21:56
16F:→ oopFoo: 几百个Nodes,我连Priority Queue都懒的写。拿个Array当 01/31 21:57
17F:→ oopFoo: queue, deque前sort就够了。 01/31 21:59
18F:→ shter: 原来如此,那我不切 block 做搜寻看看,这样更简单 02/01 14:24
19F:→ shter: 其实就是爬遍所有路径再找最符合条件的几条出来而已 02/01 14:25
20F:→ shter: 只是符合条件不一定是最短、站最少、速度最快的单一条件 02/01 14:26
21F:→ shter: 毕竟捷运有平行转乘跟地下到地上的转乘,转车时间也差很多 02/01 14:26
22F:推 peter9s3b: 蛮有趣的 推一个 02/02 00:49
23F:推 jlhc: 蛮有趣的给个推 不过台北捷运node真的太少 其实一个Q就够 02/02 12:15
24F:推 oopFoo: 重点在你的weight(cost) function。你可以距离,时间,价 02/02 18:34
25F:→ oopFoo: 钱分开或组合。转乘的weight可以x2,x10的调整试试。你也可 02/02 18:36
26F:→ oopFoo: 好几种weight,显示不同路线。 02/02 18:36
27F:推 akito117: 推 02/18 13:52