链路状态路由选择算法 —— Dijkstra算法(Golang)

图解

在这里插入图片描述

代码

dijkstra.go
/*
入参
p 图
from 源
to 目的
算法目的:计算出 from-to 的带权最短路径
*/
func dijkstra(p [][]int, from, to int) {
	{
		// 相关变量的初始化
		D = make([]int, len(p))
		P = make([]int, len(p))
		F = make([]bool, len(p))
		j := 0
		for j < len(p) {
			D[j] = math.MaxInt32
			P[j] = -1
			j++
		}
	}
	for i, v := range p[from] {
		if from == i { // 是当前结点 置距离为0,无前面点P
			D[i] = 0
			P[i] = from
		} else if v > 0 { // 如果是邻居结点,则标志距离大小
			D[i] = v
			P[i] = from // 记录索引
		} else { // 不是邻居结点,则距离无穷大:math.MaxInt32
			D[i] = math.MaxInt32
		}
	}
	F[from] = true

	for shouldContinue() {
		i := nextNode() // 下一个遍历结点
		for key, val := range p[i] {
			if val > 0 && D[i]+val < D[key] { //
				D[key] = D[i] + val
				P[key] = i
			}
		}
		F[i] = true
	}
	fmt.Println("D:", D)
	fmt.Println("P:", P)
}

// 源到结点i的长度 distance
// math.MaxInt32 表示无穷大
var D []int

// D 对应的结点i的前一个结点的索引 pre
var P []int

// 结点是否已标记,表示已经搜索过
var F []bool

// 是否还有没有遍历的结点
func shouldContinue() bool {
	for _, b := range F {
		if b == false {
			return true
		}
	}
	return false
}

// 下一个遍历结点
// 需要遍历结点的优先级:谁的D小谁就可以优先遍历
func nextNode() int {
	// 对D进行排序:小到大
	unFlagIndex, minVal := 0, math.MaxInt32
	for k, v := range D {
		// 如果k未遍历并且v值更小
		if !F[k] && v < minVal {
			unFlagIndex = k
			minVal = v
		}
	}
	fmt.Println(unFlagIndex)
	return unFlagIndex
}
dijkstra_test.go
func TestDijkstra(t *testing.T) {
	var p [][]int
	p = [][]int{
		//a b  c  d  e  f
		{0, 3, 0, 1, 2, 0}, // a 0
		{3, 0, 0, 0, 0, 2}, // b 1
		{0, 0, 0, 3, 1, 0}, // c 2
		{1, 0, 3, 0, 0, 2}, // d 3
		{2, 0, 1, 0, 0, 0}, // e 4
		{0, 2, 0, 2, 0, 0}, // f 5
	}
	dijkstra(p, 4, 5)
}
测试结果
=== RUN   TestDijkstra
// 第一个默认是 E
2 		// C
0		// A
3		// D
1		// B
5		// F
D: [2 5 1 3 0 5]
P: [4 0 4 0 4 3]		// E A E A E D
--- PASS: TestDijkstra (0.00s)
PASS
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值