浅析计算机网络(5)-选路算法

LS和DV选路算法

问题??

  • 我们通过百度建立连接,搜索信息。我们发送的信息通过无数个路由器的转发才能够到达百度的服务器。那么这些分组(我们姑且这么叫它)是如何选择一条通往百度服务器的路呐?这就是这片文章要回答的问题。

选路算法的分类

  • 全局选路算法:这种算法必须知道网络中每条链路的费用,LS算法是全局选路算法的一种。
  • 分散式的选路算法:每个节点仅有与其直接连接的链路的费用知识就可以开始工作,DV算法就是分散式的选路算法的一种
  • 我们首先定义以下符号(如果现在不明白没有关系,我们通过后面的例子后再来看就清晰的多了:
    • D(V):从源节点到目的v的最低费用路径的费用
    • c(X,Y):表示X和Y间链路的费用
    • p(V):从源节点到v的最低路径的v的前一个节点
    • N’:节点子集;v在N’中,如果从源节点到目的节点的最低费用路径已经确定,也就是下面表格中的Travel Set
    • N:节点的集合
  • 源节点u的链路状态(LS)算法:如果看不懂也没关系,通过例子之后你会发现这样的表达很优雅。
  • 链路算法有很多种:下面我们给出的这种叫做Dijkstra算法
/* 伪代码摘自《计算机网络:自顶向下方法与Internet特色》*/

Initialization:
    N' = {A}
    for all nodes V
        if V is a neighbor of A
            then D(V) = c(A,V)
        else D(V) = ∞

    Loop
        find W not in N' such that D(W) is a minimun
        add W to N'
        update D(V) for each neighbor V of W and not in N':
            D(V) = min(D(V),D(W)+c(W,V))
        /* new cost to v is either old cost to v or known least path cost to w plus cost from w to v */
    until N' = N

我们以下面的一个抽象的计算机网络为例来解释LS算法


- 现在让我门对照我们的伪代码和下面的表格来分析LS算法(当然如果你直接就看懂了伪代码,就没有必要看下面的解释了。而如果你伪代码看不懂,又不想看解释,那么你可以去睡觉了)

  • 首先是初始化阶段:这时候的Travel Set只有A一个节点,这时候查看除A之外所有的节点(用V来表示特定的某个节点),如果V是A的邻节点,那么更新D(V)=c(A,V),同时更新p(V);如果V不是A的邻居节点那么D(V)= ∞(也就是infinity)。初始化的结果就是表格中的第0行写的那样。
  • 下面就进入到Loop循环中了,首先在0行的表格中找到D(W)的最小值为1,对应的W为D,所以我们吧D加入的N’中来,然后更新D(V) = min(D(V),D(W)+c(W,V)),我们需要注意到这里的V是有限制的,V只在N-N’中取值并且还必须是w的邻居节点。在表格的第一行中我们发现D(C)被更新为D(D)+c(D,C),因此p(C)也变成了D,同样变化的还有D(E)和P(E)。
  • 第二行中把D(V)最小的E放进来,然后再次更新直到N和N’相等。
  • 现在在回头去看看那些伪代码是不是觉得很优雅了呐!

LS算法的缺点

  • LS算法的复杂性为O(n*n)
  • 通过下面的图片我们可以看出初始选路之后,再一次运行选路算法的时候,B和C到A的流量都会逆时针流动。第三次运行选路算法的时候,流量会顺时针流向A。第四次运行选路算法之后,流量又会逆时针流向。这样的震荡是不是我们想要的。

  • 如何解决这种振荡呐?

    • 一种方法是强制链路费用不依赖于其承载的流量,可是这样是不可接受的,因为选路的目标之一就是避开高拥塞
    • 另外一种方法就是让不同的路由器在不同的时刻运行LS算法。可是有趣的是:有人发现即使一开始以不同的时刻执行选路算法,到最后路由器会自同步为相同时刻执行,并保持着这种同步。

距离向量(DV)选路算法

  • DV算法是一种迭代的、异步的和分布式的算法。现在让我们像学习LS算法一样学习DV算法。
  • 对于DV算法,每个节点X需要维护一下信息:
    • 对于每个邻居v,从X到直接相邻V的费用为c(x,y)
    • 节点x的距离向量:Dx=[Dx(y):y在N中],包括了X到在N中所有目的地费用的估计值
    • x的每个邻居的距离向量
  • 在DV算法中,每个节点不时地向它的每个邻居发送他的距离向量的拷贝。当节点X从它的任何一个邻居V接收到一个新的距离向量,它保存C的距离向量,然后通过BellmanFord方程dx(y)=min{c(x,v)+dv(y)}更新自己的距离向量。这里的v是指x的所有邻居节点。
  • 我们还是老规矩,不要着急,通过伪代码和一个例子之后,你对DV算法的了解就会深刻多了。
  • 代码
  • 例子
  • 我们以上图中只有三个路由器的简单网络来举例
    • 伪代码的1~8行是初始化过程。对于所有的在N中的目的地y,如果y是运行该算法的节点x的邻居,那么x到y的低费Dx(y)用路径的费用就是c(x,y);如果y不是节点x的邻居,那么Dx(y)=∞;
    • 对于x的邻居节点w来说,Dw(y)是未知的,所以就都是设为infinity,也就是∞
    • 然后运行该算法的节点x会把自己的距离向量发送给它的邻居。
    • 通过以上的运行,我们就看到了表格中的第一列的三个子表,同时还有志向第二列的所有箭头(表示把距离向量发送给邻居)
    • 然后算法运行到第9行进入了循环
    • 如果运行该算法的路由器x发现去往邻居节点的链路费用发生了变化,或者是x收到了来自邻居的距离向量,执行一下操作
    • 通过BellmanFord方程(我们上文写到过)来更新Dx(y)。我们这里以节点x为例,第一行第二列的表中Dx(z)由原来的7变成了现在的2,这是因为x(注意这里的x是这个例子网络中的x,而不是其他位置表示一个未知数,如果没有说明,我默认表示的是后者)收到了来自邻居的距离向量,然后通过BellmanFord方程计算的到Dx(z) = c(x,y)+Dy(z)
    • 然后如果运行该算法的路由器x更新了自己的距离向量,就将该向量发送到它的邻居节点。这里表现为表中第二列中,第一行和第三行向邻居节点发送了自己的距离向量,而第二行并没有,因为第二行的距离向量没有更新。
  • 难道DV算法不想LS算法,没有缺点?答案是否定的。如果你对这部分感兴趣,可以查找如何通过增加毒性逆转来避免选路环路等相关资料。

其他

  • 我们这里直介绍了LS和DV算法,可是他们趋势当前实践中使用的仅有的选路算法。当然还有其他选路算法,如电路交换选路算法,这是一个电话界的算法,每条链路资源都要保留给每一个经过该链路的连接。

你可能感兴趣的:(计算机网络)