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

图解

链路状态路由选择算法 —— Dijkstra算法(Golang)_第1张图片

代码

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

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