路由选择协议:
- 内网关选择协议:
- RIP(routing information protocol)路由信息协议:达到直连的 网络的距离是 1, 非直连的网络,没经过一个路由器,则距离加1。——方法简单,最多只能有15个路由。而且没有考虑带宽,可能选了距离最短但是带宽也最小的路线。
- OSPF(open shortest path first)开放最短路径优先:Dijsstra的最短路径算法。
- 外网选择协议:BGP
重点说说OSPF中使用的最短路径算法:
- 其实就是数据结构与算法里学的Dijstra算法:
Dijstra算法:计算图中一个点到其他点的最短路径。如下图就是计算从1点 到2,3,4,5,6点的最短路径。
图(带权重的图也称为网)可以用一个二维数组来存储:行用来表示出度的结点,列用来表示相应的入度点,值用来表示边上的代价。上面的图可以用下图e进行表示;用∞表示不可到达,对角线值为0,表示不可从自己到自己。
我们还可以用一个一维数组dis来标记1到其余各点的初始路径。
Dijstra算法干的事就是不断更新这个dis数组,使得每个元素表示从1到各个位置的最小值。
算法如下(以计算结点1到各个位置最短路径来讨论):
1. 首先取出二维数组e中的第一行赋值给dis,表示1可以到达的结点和相应的权重,并作为1到各位结点的最短的估计值。
2. 选出到1最近的结点,即为2;那么到2的最近距离就从“估计值”转为了“确定值”;
3. 选出上一个确定值之后,更新dis,表示1到可以到达的其他节点的距离的最短估计值;2的出度为3和4;更新到3和4的权重:
(1) 3:有1——>3 权重为12 和 2——>3 权重为1+9; 取小值:10
(2) 4: 无穷大和1->2->4 权重为4;取小值4
更新完毕后,dis为:
4. 接下来,在dis中3,4,5,6中选择最小的结点,即4结点,那么1到4结点的距离估计值也变为了确定值;并对4的出度3,5,6的值进行更新,如下
(1)3: 上一步已经更新为10 和 4——>3 权重为4+4 ;取小值8
(2)5: ∞ 和 4->5 权重为4+13; 取小值17
(3)6: ∞ 和 4——>6 权重为4+15; 取小值19
5. 接下来,在dis中3,,5,6,中选择一个最小值;即3结点;那么到3的距离就从估计值变为确定值,对3的出度5 进行更新。
(1)5: 已经更新的17 和 3——> 5 权重为8+5; 取小值13
更新dis如下:
6. 接下来对5,6中选择一个最小值,即5结点,那么5结点的距离就从估计值变为确定值了,更新5结点的出度6;
(1)6: 上次更新的19和 5->6的13+4; 取小值17
更新dis如下
7. 最后对剩余的6取最小值,取出度,没有出度,那么将6从估计值变为确定值。最终dis如下,这便是从1顶点到其余各个顶点的最短路径。
算法总结:
1. 每次都从未加入确定集中的结点中选择最小值,作为下一个确定值
2. 选好确定值后更新每个出度
3. 重复步骤1和步骤2
算法实现如下
#include<iostream>
#include<vector>
using namespace std;
int inf = 999999;
//网和要计算的开始结点
void Dijkstra(const vector<vector<int>> &vec, int index , vector<int> &dis) {
dis = vec[index]; //初始化dis数组,把它赋值给要计算的点和对应的出度之间的权重
vector<bool> used(n, false); //初始化used数组,用来判断是否已经确定
used[index] = true;//目标结点首选被确定
//循环m次;每次取出一个结点
for(int i = 0; i< m; i++) {
//找到dis矩阵中 未确定的结点中的最小值
int min = INT_MAX;
int u; //确定的结点
for(int j= 0; j<n; j++) {
if(used[j] == false && dis[j] < min) {
min = dis[j];
u = j;
}
}
used[u] = true;// 表示j已经被确定
//更新j的出度和对应的权重值
for(int k = 0; k< n; k++) {
if(k!=u && vec[u][k] < inf) { //找到不等于结点自身的出度并更新
if(dis[k] > dis[u] + vec[u][k]) {
dis[k] = dis[u] + vec[u][k];
}
}
}
}
}
int main() {
vector<vector<int>> vec = { {0,1,12,inf,inf,inf},
{inf,0, 9, 3, inf, inf},
{inf,inf , 0, inf, 5, inf},
{inf,inf,4,0,13,15},
{inf,inf,inf,inf, 0,4},
{inf, inf, inf, inf,inf, 0}};
vector<int> dis;
Dijstra(vec, 0, dis);
for(auto d:dis) cout<<d<<endl;
return 0;
}
0 1 8 4 13 17
999999 999999 0 999999 5 9 //999999 = inf,表示不可到达