写在前面:
好久没有更新博客了,距离上一次更新已经过去了十一个月了,一是因为课业繁重,二是因为这一年中接了不少项目。其实早就想写写算法和数据结构相关的文章了,之前在Coders群里也说过17年要多写写算法和数据结构,奈何计划赶不上变化,实在是没有工夫写。现在到了18年了,最近刚放寒假,数据科学导论实验今天交上了最后一个,总算是有些闲工夫了,准备写些东西却又不知道应该写什么,算法那么多,从哪个写起呢?思来想去,想到了最短路径算法,因为博主今年开了计算机网络课程,在计算机网络中,有一个很重要的东西就是路由,即一个包怎么从某个节点发送到另外一个节点,在多条路径可供选择的时候,怎么选出来最佳路径,可以说,最短路算法是计算机网络的基石之一,本文就四种常规的最短路算法,及其原理,优化方法等进行了深入的介绍。
目录:
正文开始:
总述:
本文讲述的是求最短路的算法,首先就要定义最短路,严格的数学定义就不说了,我们用大白话说一说,在一个图G中,点u到点v有若干条路,那么定义u到v的最短路为这些路中最短的一条,这个是废话,显而易见。重要的是如果说边权中有负数怎么定义呢?如果有负边,就要分两种情况了。第一种情况:如果从某点出发,可以到达一个权值和为负数的环,那么这个点到其他点的最短距离就是负无穷了,很明显,如果有负环,且从某点可以到达这个负环,那么我可以无限得走这个负环,没走一次,距离就小一些,这种情况下,我们可以定义这个点到达其他点的最短距离为负无穷。第二种情况:如果说不存在一个这样的负环,那么就和没有负权边一样了,但是还不是完全一样,接下来我们介绍的四种算法中,有的是可以处理负权边不能处理负环的,有的是可以处理负环的,有的是既不能处理负权边也不能处理负环的。下面将会一一为您介绍。
约定:
文中的代码为部分代码,图为无向图,使用邻接矩阵a[][]存储, a[i][j]代表节点i到节点j的距离 若a[i][j]==Integer.MAX_VALUE>>1 则说明节点i和节点j不连通。文中算法以下面这个无向图为例说明。
初始化代码:
private void init() {
n = 5;
a = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = Integer.MAX_VALUE >> 1;
}
a[i][i] = 0;
}
a[0][1] = 10;
a[1][0] = 10;
a[0][3] = 30;
a[3][0] = 30;
a[0][4] = 100;
a[4][0] = 100;
a[1][2] = 50;
a[2][1] = 50;
a[2][3] = 20;
a[3][2] = 20;
a[2][4] = 10;
a[4][2] = 10;
a[3][4] = 60;
a[4][3] = 60;
}