最短路径算法

算法思想 

 从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。 每次选择距离起始点最近的节点, 然后以此不断向外扩展, 直至达到终点

 算法描述(步骤) 

1: 定义集合, S = {u}, Q= v - S, 定义dist: 起始点距离其他节点的距离 

2: 在Q中找出距离起点最近的节点加入 S中, 然后更新dist

 3: 重复2, 直接Q集合为空, dist就是所求的内容 比较难理解的算法需要演练下 

算法伪代码实现

 1: 定义visit数组: 为1代表已经被访问过 

find u-> minQ(u) && visit[u] == 0 

update dist[i]: if dist[i] > dist[u]+cost[i][u] 

2: 使用最小堆做优化 

get minQ(u) in minheap 

update dist[i]: if dist[i] > dist[u]+cost[i][u]

 有兴趣写下具体实现

```

type nodeinfo struct {

    targetNode int

    distance int

    index int

}

type nodeinfos []*nodeinfo

const Inf = 1e9

func (nodes *nodeinfos) Len() int {

    return len(*nodes)

}

func (nodes *nodeinfos) Less(i, j int) bool {

    return (*nodes)[i].distance < (*nodes)[j].distance

}

func (nodes *nodeinfos) Swap(i, j int) {

    (*nodes)[i], (*nodes)[j] = (*nodes)[j], (*nodes)[i]

    (*nodes)[i].index = i

    (*nodes)[j].index = j

}

func (nodes *nodeinfos) Push(x interface{}) {

    n := len(*nodes)

    item := x.(*nodeinfo)

    item.index = n

    *nodes = append(*nodes, item)

}

func (nodes *nodeinfos) Pop() interface{} {

    if len((*nodes)) <= 0 {

        return nil

    }

    x := (*nodes)[len((*nodes))-1]

    (*nodes) = (*nodes)[:len((*nodes))-1]

    return x

}

//n个节点, k为起始节点, cost为邻接矩阵

func Dijkstra(cost [][]int, N int, start int, end int) (res [][]int) {

    dist := make([]int, N)

    for i := 0; i < N; i++ {

        dist[i] = Inf

    }

    dist[start] = 0

    nodemap := map[int]*nodeinfo{}

    heapElement := make(nodeinfos, 0)

    heap.Init(&heapElement)

    nodeptr := &nodeinfo{

        targetNode: start,

        distance: 0,

    }

    heap.Push(&heapElement, nodeptr)

    nodemap[start] = nodeptr

    relayNodes := make([][]int, N)//源节点到各节点的最后一个中转节点

    for i := 0; i < N; i++ {

        relayNodes[i] = make([]int, 0)

    }

    relayNodes[start] = append(relayNodes[start], start)

    for len(heapElement) > 0 {

        minNode := heap.Pop(&heapElement).(*nodeinfo)

        delete(nodemap, minNode.targetNode)

        if minNode.targetNode == end {

            res = getAllTreePaths(relayNodes, start, end)

            return

        }

        for i := 0; i < N; i++ {

            if cost[minNode.targetNode][i] == Inf {

                continue

            }

            distance := dist[minNode.targetNode] + cost[minNode.targetNode][i]

            if distance < dist[i] {

                relayNodes[i] = make([]int, 0)

            }

            if distance <= dist[i] && i != minNode.targetNode {

                relayNodes[i] = append(relayNodes[i], minNode.targetNode)

            }

            if distance < dist[i] {

                dist[i] = distance

                if value, ok := nodemap[i]; ok {

                    value.distance = distance

                    heap.Fix(&heapElement, value.index)

                } else {

                    heap.Push(&heapElement, &nodeinfo{

                        targetNode: i,

                        distance: distance,

                    })

                }

            }

        }

    }

    return

}

func getAllTreePaths(relayNodes [][]int, start int, end int) [][]int {

    path := make([]int, 0)

    allpath := [][]int{}

    getAllResults(relayNodes, start, end, path, &allpath)

    length := len(allpath) - 1

    for i := 0; i <= length; i++ {

        length2 := len(allpath[i])

        for j := 0; j < length2 / 2; j++ {

            allpath[i][j], allpath[i][length2-j-1] = allpath[i][length2-j-1], allpath[i][j]

        }

    }

    return allpath

}

func getAllResults(relayNodes [][]int, start int, end int, path []int, allpath *[][]int)  {

    if (start == end || len(relayNodes[end]) == 0) {

        path = append(path, end)

        *allpath = append(*allpath, path)

        return

    }

    path = append(path, end)

    nodes := relayNodes[end]

    for i := 0; i < len(nodes); i++ {

        getAllResults(relayNodes, start, nodes[i], path, allpath)

    }

}


注意: 有关堆的使用可以看:  go自带的test用例, 写的比较好, 特别是fix使用方法值得学习

```

应用场景 

  1: 从地点a达到地点b, 如何走最短?

  2: 有关求最短路径或者最短步骤的, 都可以试着把问题抽象成图, 然后解之

扩展算法

    Floyd算法等

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容