事前申明:博主就是个臭拉网线的,意在通过简单的描述分享对于路由方式(寻路算法)的理解。
零、假设环节
各位设想一下,假如今天各位需要出门买东西,我们都想找到一个“最省成本、最省时间、最省力气”的出行方案,举例如下(可见图示):
- 走路去地铁站需要10分钟,等待地铁需要5分钟,地铁站A到地铁站B需要5分钟(成本5元),地铁站B走路去超市需要10分钟。
- 等出租车5分钟,打车去超市需要20分钟(成本15元)。
- 前往共享单车停放点1分钟,扫共享单车骑去地铁站3分钟(成本1元),等地铁5分钟,地铁站A到地铁站B需要5分钟(成本5元),地铁站B骑共享单车去停放点需要3分钟(成本1元),停放点走路去超市需要2分钟。
tip:假设地铁站就是共享单车还车点
OK,咱们现在假设咱们1分钟相当于1块钱的成本,将上面图示全部转为以“元”为单位,可以想象成以下图示:
这样我们成功地将多种成本统一单位,并表现在图例上,现在先不着急找所谓的“最佳出行方式”,而是思考一个问题:我想知道从家里为起点,到达图上各个位置的最佳方式与我想知道从家里为起点到超市的最佳方式的区别,不难看出,到各个位置的最佳方式包含到超市的最佳方式。所以我们通过找到前者的解决方案的同时也是解决后者的方案了。
在最短路径优先的理解中,有一个比较有意思的思维:长的路径有可能可以从短的路径“抄近路”变得更短,也可能长的路径本身就是最短路径,但是最短的路径一定就是最短路径,不存在“抄近路”让最短路径被更短路径优化。
这个思维很有趣,上图举例:
- 从家出发,下一行动到共享单车停车点成本为1;
- 从家出发,下一行动到地铁站的成本为15;
- 从家出发,下一行动到“打到车”出发的成本为5。
一、第一轮思考
此时能发现,在只知道下一行动的情况下,坐在家里的我有可能去地铁站可以通过骑车去更优,也有可能骑车到某个地方再绕到出租车上车点更优,有可能打出租车到地铁站更优(我不知道全局路径)
但是有一点是确定的:到单车停车点的最优方式一定开销是1,且就是走路去,因为只要我下一个动作选择坐出租还是去地铁站,成本就已经高于走路去骑单车了。
我们得出结论:从家到单车停车点(家附近)的最短路径就是“家—单车停车点(家附近)”
第一轮思考后,出门的下一个动作结果如下表所示:
节点 | 到达成本 | 路径 |
---|---|---|
(已确认最短路径)家 | 0 | 躺着就行 |
(已确认最短路径)单车停车点(家附近) | 1 | 家—单车停车点(家附近) |
地铁站A(家附近) | 15 | 家—地铁站A(家附近) |
打到出租车 | 5 | 家—打到出租车 |
地铁站B(超市附近) | 无穷大 | 到不了 |
单车停车点(超市附近) | 无穷大 | 到不了 |
超市 | 无穷大 | 到不了 |
二、第二轮思考
好,接下来上强度了,既然我们已经得出来到单车停车点(家附近)的最短路径,这个节点我们就能只保留走上面的路径成本,把单车停车点(家附近)这个位置删掉了,如下图所示:。
各位再次假设,咱们坐在家里,在只知道下一个行动的情况下,所有下个行动的较长路径依然有可能通过最短路径的后续行动被“抄近路”,但是最短路径就是最短路径。
如上图中,坐在家中的我只知道下一行动成本,所以去往“打到车”的上车点成本最低的方式就是直接等车,既不是走上面去地铁站再怎么去上车点,也不是走中间再怎么去上车点,因为只要出了门,去地铁站的成本就一定比直接打车的成本要高。而在不知道全局情况下,去地铁站有可能打车优于走上面的10,也可能走上面的10优于打车
此时,我们的第二轮思考后,出门的下一个动作结果如下表所示(保留之前咱们第一轮思考的结论):
节点 | 到达成本 | 路径 |
---|---|---|
(已确认最短路径)家 | 0 | 躺着就行 |
(已确认最短路径)单车停车点(家附近) | 1 | 家—单车停车点(家附近) |
地铁站A(家附近) | 15 | 家—地铁站A(家附近) |
(已确认最短路径)打到出租车 | 5 | 家—打到出租车 |
地铁站B(超市附近) | 无穷大 | 到不了 |
单车停车点(超市附近) | 无穷大 | 到不了 |
超市 | 无穷大 | 到不了 |
三、第三轮思考
接下来咱们加快速度,一样的规律,因为我们找到了打到出租车的最短路径,所以我们保留打出租车出行的路径,删除“打到出租车”的节点,变成下面图示:
此时按照上面的思考一样,坐家中的我能唯一确定的是:去往家附近地铁站A最短的路径就是走上面成本为10的路径,因为我只知道下一行动,所以我无法确定下面坐出租车的方式是否为最短路径,此时我们把成本为10的路径替换原有到达地铁站成本为15的路径
第三轮的思考结果如下:
节点 | 到达成本 | 路径 |
---|---|---|
(已确认最短路径)家 | 0 | 躺着就行 |
(已确认最短路径)单车停车点(家附近) | 1 | 家—单车停车点(家附近) |
(已确认最短路径)地铁站A(家附近) | 10 | 家—单车停车点(家附近)—地铁站A(家附近) |
(已确认最短路径)打到出租车 | 5 | 家—打到出租车 |
地铁站B(超市附近) | 无穷大 | 到不了 |
单车停车点(超市附近) | 无穷大 | 到不了 |
超市 | 40 | 家—打到出租车—超市 |
四、第四轮思考
删除地铁站A(家附近)的节点
此时按照上面的思考一样,坐家中的我能唯一确定的是:此时有办法去往超市附近地铁站B,并且最短的路径就是走上面成本为20的路径,而上面成本为20的路径是“家—单车停车点(家附近)—地铁站A(家附近)—地铁站B(超市附近)”的路径。
第四轮的思考结果如下:
节点 | 到达成本 | 路径 |
---|---|---|
(已确认最短路径)家 | 0 | 躺着就行 |
(已确认最短路径)单车停车点(家附近) | 1 | 家—单车停车点(家附近) |
(已确认最短路径)地铁站A(家附近) | 10 | 家—单车停车点(家附近)—地铁站A(家附近) |
(已确认最短路径)打到出租车 | 5 | 家—打到出租车 |
(已确认最短路径)地铁站B(超市附近) | 20 | 家—单车停车点(家附近)—地铁站A(家附近)—地铁站B(超市附近) |
单车停车点(超市附近) | 无穷大 | 到不了 |
超市 | 40 | 家—打到出租车—超市 |
五、第五轮思考
删除地铁站B(超市附近)的节点
此时,坐在家里的我已经人麻了,但是一眼就看出来,去往单车停车点(超市附近)的最短路径一定是上面那条,而且成本为24,其余的我还是无法保证。
第五轮的思考结果如下:
节点 | 到达成本 | 路径 |
---|---|---|
(已确认最短路径)家 | 0 | 躺着就行 |
(已确认最短路径)单车停车点(家附近) | 1 | 家—单车停车点(家附近) |
(已确认最短路径)地铁站A(家附近) | 10 | 家—单车停车点(家附近)—地铁站A(家附近) |
(已确认最短路径)打到出租车 | 5 | 家—打到出租车 |
(已确认最短路径)地铁站B(超市附近) | 20 | 家—单车停车点(家附近)—地铁站A(家附近)—地铁站B(超市附近) |
(已确认最短路径)单车停车点(超市附近) | 24 | 家—单车停车点(家附近)—地铁站A(家附近)—地铁站B(超市附近)—单车停车点(超市附近) |
超市 | 40 | 家—打到出租车—超市 |
六、第六轮思考
删除单车停车点(超市附近)的节点
此时一眼能看出结果,最短的就是最上面那条路径,第六轮思考结果如下:
节点 | 到达成本 | 路径 |
---|---|---|
(已确认最短路径)家 | 0 | 躺着就行 |
(已确认最短路径)单车停车点(家附近) | 1 | 家—单车停车点(家附近) |
(已确认最短路径)地铁站A(家附近) | 10 | 家—单车停车点(家附近)—地铁站A(家附近) |
(已确认最短路径)打到出租车 | 5 | 家—打到出租车 |
(已确认最短路径)地铁站B(超市附近) | 20 | 家—单车停车点(家附近)—地铁站A(家附近)—地铁站B(超市附近) |
(已确认最短路径)单车停车点(超市附近) | 24 | 家—单车停车点(家附近)—地铁站A(家附近)—地铁站B(超市附近)—单车停车点(超市附近) |
(已确认最短路径)超市 | 26 | 家—单车停车点(家附近)—地铁站A(家附近)—地铁站B(超市附近)—单车停车点(超市附近)—超市 |
七、还原初始图
当所有思考结束后,从家出发,前往各节点,都找到了对应的最优路径,我们来还原初始图最短路径,呈现下图所示:
tip:因文章太长,一日三问的后两问“链路状态为什么需要某些字段”与“上述算法怎么用链路状态协议当中”将放在下一篇文章,随后会讲到上述路由方式的作用,并从设计人的角度思考链路状态路由协议