mirror of
https://gitee.com/willfree/mlsr.git
synced 2026-06-15 19:24:47 +08:00
实现了迪克斯特拉算法基本计算逻辑
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
package Calculator
|
||||
|
||||
import (
|
||||
"math"
|
||||
"mlsr/common"
|
||||
"mlsr/lsa"
|
||||
"mlsr/lsdb"
|
||||
@@ -24,14 +25,21 @@ type LinkStateRoutingTableCalculator struct {
|
||||
NO_NEXT_HOP int
|
||||
|
||||
// 私有变量区
|
||||
// 表示源路由器想要到达某路由器,其最短路径上经过的上一个路由器。
|
||||
m_parent []int
|
||||
// 表示源路由器想要到达某路由器,其最短路径的距离
|
||||
m_distance []uint64
|
||||
|
||||
EMPTY_PARENT int
|
||||
INF_DISTANCE uint64
|
||||
NO_MAPPING_NUM int
|
||||
}
|
||||
|
||||
// 一些在最短路径计算时会用到的常量
|
||||
const (
|
||||
EMPTY_PARENT = -12345 // 没有父节点 -12345
|
||||
INF_DISTANCE = math.MaxUint64 // 无限距离 2147483647
|
||||
NO_MAPPING_NUM = -1 // 没有映射的点 -1
|
||||
// 公用常量
|
||||
NO_NEXT_HOP = -12345 // 没有下一跳 -12345
|
||||
)
|
||||
|
||||
//
|
||||
// CalculatePath
|
||||
// @Description: 计算可转发路径。路由计算里的唯一Public的接口
|
||||
@@ -49,25 +57,85 @@ func (c *LinkStateRoutingTableCalculator) CalculatePath(routerMap *RouterMap,
|
||||
//
|
||||
// doDijkstraPathCalculation
|
||||
// @Description: 在邻接矩阵基础上,针对源路由器,做迪吉斯特拉计算
|
||||
// 在注释中,“左集”表示已访问节点,“右集”表示未访问节点
|
||||
// @receiver c
|
||||
// @param sourceRouter
|
||||
//
|
||||
func (c *LinkStateRoutingTableCalculator) doDijkstraPathCalculation(sourceRouter int) {
|
||||
|
||||
// 尚未加入左集的最近元素(Q中右集最小元素)
|
||||
var u int
|
||||
// 每个单元代表具有该映射号的路由器。
|
||||
// Q是queue首字母,它按升序存储所有路由器
|
||||
Q := make([]int,c.m_nRouters)
|
||||
// 尚未加入左集的最近元素在Q中的索引值
|
||||
head := 0
|
||||
// 初始化parent
|
||||
for i := 0; i < c.m_nRouters; i++ {
|
||||
// 每个点的最短路径上一点都初始化为空,即无法到达源路由器
|
||||
c.m_parent[i] = EMPTY_PARENT
|
||||
// 数组中第i个元素存储的是:源路由器到映射号为i的路由器之间的距离。初始化为无穷大
|
||||
c.m_distance[i] = INF_DISTANCE
|
||||
// 路由器队列初始化为按映射号排列
|
||||
Q[i] = i
|
||||
}
|
||||
if sourceRouter != NO_MAPPING_NUM{
|
||||
// 源路由器到其本身的距离为0
|
||||
c.m_distance[sourceRouter] = 0
|
||||
// 排序完毕,Q中第一个节点必然为源路由器
|
||||
c.sortQueueByDistance(Q,c.m_distance,head,c.m_nRouters)
|
||||
// 当我们没有访问完每一个节点时,执行循环
|
||||
for head < c.m_nRouters {
|
||||
// 将u设置为head当前指向的节点。“u,你就是天选之子!”
|
||||
u = Q[head]
|
||||
if c.m_distance[u] == INF_DISTANCE {
|
||||
// 只有没有可访问的节点时,这里才会被执行。"天选之子是个废物,亡矣!"
|
||||
break
|
||||
}
|
||||
// 对u的相邻节点进行迭代遍历。“朕要以你为衡,重设天下!”
|
||||
for v := 0; v < c.m_nRouters; v++ {
|
||||
// 如果u->v是可达的,
|
||||
if c.adjMatrix[u][v] != route.NON_ADJACENT_COST{
|
||||
// 而且我们还没有访问过v,即v属于右集,
|
||||
if c.isNotExplored(Q,v,head+1,c.m_nRouters){
|
||||
// 如果到这个节点的距离+从这个节点到v的距离,
|
||||
// 小于我们在构建adj LSA时得到的从源节点到v的距离,
|
||||
// 就更新为新距离【算法中的松弛操作】
|
||||
if c.m_distance[u]+c.adjMatrix[u][v] < c.m_distance[v] {
|
||||
// 设置新距离
|
||||
c.m_distance[v]=c.m_distance[u]+c.adjMatrix[u][v]
|
||||
// 设置parent,即我们如何到达v的
|
||||
c.m_parent[v]=u
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 右移head位置,从我们所在的位置按距离重新排序列表。"苍天已死,黄天当立!"
|
||||
head++
|
||||
c.sortQueueByDistance(Q,c.m_distance,head,c.m_nRouters)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// sortQueueByDistance
|
||||
// @Description: 对列表中的元素进行简单排序
|
||||
// @Description: 对列表中的元素进行交换排序
|
||||
// @receiver c
|
||||
// @param Q 要排序元素的数组
|
||||
// @param dist 包含距离的数组
|
||||
// @param start 列表中要排序的第一个元素
|
||||
// @param element 列表中要排序的最后一个元素
|
||||
// @param element 列表元素数目
|
||||
//
|
||||
func (c *LinkStateRoutingTableCalculator) sortQueueByDistance(
|
||||
Q []int,dist []uint64,start int,element int) {
|
||||
|
||||
for i := start; i < element; i++ {
|
||||
for j := i+1; j < element; j++ {
|
||||
if dist[Q[j]] < dist[Q[i]]{
|
||||
temp := Q[j]
|
||||
Q[j] = Q[i]
|
||||
Q[i] = temp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -77,11 +145,16 @@ func (c *LinkStateRoutingTableCalculator) sortQueueByDistance(
|
||||
// @param Q 要查看的元素列表
|
||||
// @param u 要检查的元素
|
||||
// @param start 要查看的列表的开头
|
||||
// @param element 要查看的列表的结尾
|
||||
// @param element 列表元素数
|
||||
//
|
||||
func (c *LinkStateRoutingTableCalculator) isNotExplored(
|
||||
Q []int,u int,start int,element int) int {
|
||||
|
||||
Q []int,u int,start int,element int) bool {
|
||||
for i := start; i < element; i++ {
|
||||
if Q[i]==u {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *LinkStateRoutingTableCalculator) addAllLsNextHopsToRoutingTable(
|
||||
|
||||
Reference in New Issue
Block a user