算法之狄克斯特拉算法 --《图解算法》

2019你好!好好生活,好好工作!

狄克斯特拉算法

狄克斯特拉算法(Dijkstra )用于计算出不存在非负权重的情况下,起点到各个节点的最短距离

可用于解决2类问题:

从A出发是否存在到达B的路径;
从A出发到达B的最短路径(时间最少、或者路径最少等),事实上最后计算完成后,已经得到了A到各个节点的最短路径了;
其思路为:

(1) 找出“最便宜”的节点,即可在最短时间内到达的节点。

(2) 更新该节点对应的邻居节点的开销,其含义将稍后介绍。

(3) 重复这个过程,直到对图中的每个节点都这样做了。

(4) 计算最终路径。

我们根据书中的例子给出相关的具体实现

因为个人最经常使用的是OC语言,所以先用OC简单实现了一下,有不对之处还请告知,谢谢!

- (void)installDijkstra
{
    //用来记录已经被便利过该节点所有邻居的节点
    NSMutableArray *processed= [NSMutableArray array];
   //描述图的
    NSMutableDictionary *origianldic = [NSMutableDictionary dictionary];
    [origianldic setObject:@{@"a":@6,@"b":@2} forKey:@"start"];
    [origianldic setObject:@{@"fin":@1} forKey:@"a"];
    [origianldic setObject:@{@"a":@3,@"fin":@5} forKey:@"b"];
    //创建开销
    NSMutableDictionary *costDic = [NSMutableDictionary dictionary];
    costDic[@"a"] = @6;
    costDic[@"b"] = @2;
    costDic[@"fin"] = @(NSIntegerMax);
    //记录该节点的父节点的
    NSMutableDictionary *parentDic = [NSMutableDictionary dictionary];
    parentDic[@"a"] = @"start";
    parentDic[@"b"] = @"start";
    parentDic[@"fin"] = @"";

    NSString *node = [self findLowerCostNode:costDic array:processed];
    while (![node isEqualToString:@""]) {
        NSDictionary *tempDic = origianldic[node];
        for (NSString *key in tempDic.allKeys) {
            NSInteger newCount = [costDic[node]integerValue] + [tempDic[key]integerValue];
            if ([costDic[key] integerValue] > newCount) {
                costDic[key] = @(newCount);
                parentDic[key] = node;
            }
        }
        [processed addObject:node];
        node = [self findLowerCostNode:costDic array:processed];
    }
    NSLog(@"origianldic = %@,\ncostDic = %@,\nparentDic = %@,\n processed = %@,\n NSIntegerMax = %ld",origianldic,costDic,parentDic,processed,NSIntegerMax);
    NSLog(@"--end --costDic = %@",costDic);
    NSLog(@"--end --parentDic = %@",parentDic);
}

/**
 找到开销最小的节点

 @param dic dic
 @param processArray 记录节点
 @return 为空说明已经查找完毕
 */
- (NSString *)findLowerCostNode:(NSDictionary *)dic array:(NSMutableArray *)processArray
{
    NSInteger lowerCost = [dic[@"fin"]integerValue];
    NSString *lowedNode = @"";
    for (NSString *key in dic.allKeys) {
        NSInteger costNum = [dic[key]integerValue];
        if (costNum < lowerCost && (![processArray containsObject:key]) ) {
            lowerCost = costNum;
            lowedNode = key;

        }

    }
    return lowedNode;
}

OC语言简单实现

2019-01-13 21:24:14.382432+0800 HaiFeiTestProject[29763:1130947] --end --costDic = {
    a = 5;
    b = 2;
    fin = 6;
}

python实现

infinity = float(‘inf‘)
graph = {‘start‘: {‘a‘: 6, ‘b‘: 2}, ‘a‘: {‘fin‘: 1}, ‘b‘: {‘a‘: 3, ‘fin‘: 5}, ‘fin‘: {}}
costs = {‘a‘: 6, ‘b‘: 2, ‘fin‘: infinity}
parents = {‘a‘: ‘start‘, ‘b‘: ‘start‘, ‘fin‘: None}
processed = []

def main(graph, costs, parents, processed, infinity):
    node = find_lowest_cost_node(costs, processed)
    while node is not None:
        for n in graph[node].keys():
            new_cost = costs[node] + graph[node][n]
            if costs[n] > new_cost:
                costs[n] = new_cost
                parents[n] = node
        processed.append(node)
        node = find_lowest_cost_node(costs, processed)

def find_lowest_cost_node(costs, processed):
    lowest_cost = float(‘inf‘)
    lowest_cost_node = None
    for node in costs:
        if lowest_cost > costs[node] and node not in processed:
            lowest_cost = costs[node]
            lowest_cost_node = node
    return lowest_cost_node

main(graph, costs, parents, processed, infinity)
print(costs)
print(parents)

Python实现

运行结果

算法图解之狄克斯特拉算法 和书中描述基本一致,可参考!

原文地址:https://www.cnblogs.com/lisaloveyou1900/p/10264170.html

时间: 2024-10-11 00:31:52

算法之狄克斯特拉算法 --《图解算法》的相关文章

最短路径--Dijkstra(狄克斯特拉)算法

最短路径 路径的概念:       在一个无权的图中,若从一顶点到另一顶点存在着一条路径,则称该路径长度为该路径上所经过的边的数目,它等于该路径上的顶点数减1.       由于从一顶点到另一顶点可能存在着多条路径,每条路径上所经过的边数可能不同,即路径长度不同,我们把路径长度最短(即经过的边数最少)的那条路径叫做最短路径,其路径长度叫做最短路径长度或最短距离.       对于带权的图,考虑路径上各边上的权值,则通常把一条路径上所经边的权值之和定义为该路径的路径长度或称带权路径长度.     

图算法——狄克斯特拉算法

这里有一些定义及代码取自CodeInfo的简书,链接:https://www.jianshu.com/p/b805e9d1eb5c,和heroacool的CSDN,链接:https://blog.csdn.net/heroacool/article/details/51014824,感谢两位大佬. 狄克斯特拉算法(Dijkstra )用于计算出不存在非负权重的情况下,起点到各个节点的最短距离(单源最短路问题),如果要得到整个图各个顶点之间的最短距离,则需要对整个图的每个顶点都遍历一遍狄克斯特拉算

狄克斯特拉算法

狄克斯特拉算法用于在加权图中查找最短路径. 仅当权重为时算法才管用,如果图中包含负权边,请使用贝尔曼-福得算法. # 有向无环图 graph = {} graph["start"] = {} graph["start"]["a"] = 6 graph["start"]["b"] = 2 graph["a"] = {} graph["a"]["fin"

狄克斯特拉算法(图的最短路问题)

该算法思想就是   1)首先找离起点最近的点 2)然后对该点进行标记,并且对与该点相邻的点进行松弛(也就是更新周围点离起点的距离最小值) 3)继续找更新之后的图中离起点最近的未被标记的点 具体的实现方式有两种: 方式一时间复杂度是O(n^2),具体实现方式是通过两个for循环实现(其中内层循环负责找最近点以及遍历更新最近点附近的点,外层循环负责维持内层遍历的持续进行) 方式二时间复杂度是O(m*logn),具体实现是利用bfs结合优先队列来实现(优先队列代替了内层循环,bfs代替了外层for循环

单源最短路 狄克斯特拉算法

一般形式的用邻接矩阵来实现dijkstra效率比较低,我这里直接记录的是用邻接表的方法以及用优先队列加以应用. 首先解释什么是dijkstra算法 dijkstra算法 dijkstra算法适用于求单源最短路,即可以求出起点到其余各点之间的最短路.它的算法实现是一个不断更新的过程. 举一个最简单的例子,假设有这么一个图,红色表示权值,黑色表示4个点以及路径,我们假设起点为1,用d[i]来表示1到i的最短路,那么在第一轮的时候,d[2]=1,d[3]=1,d[4]=5,再下一轮的时候会对这个情况进

最短路径之迪杰斯特拉(Dijkstra)算法

对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点为源点,最后一个顶点为终点.最短路径的算法主要有迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd)算法.本文先来讲第一种,从某个源点到其余各顶点的最短路径问题. 这是一个按路径长度递增的次序产生最短路径的算法,它的大致思路是这样的. 初始时,S中仅含有源.设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度.D

十大基础实用算法之迪杰斯特拉算法、最小生成树和搜索算法

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离). 初始时,S中只有起点s:U中是除s之外的顶点,并且U中顶点的路径是"起点s

普里姆算法,克鲁斯卡尔算法,迪杰斯特拉算法,弗洛里德算法

做数据结构的课程设计顺便总结一下这四大算法,本人小白学生一枚, 如果总结的有什么错误,希望能够告知指正 普里姆算法如图所示prim 找出最短的边,再以这条边构成的整体去寻找与之相邻的边,直至连接所有顶点,生成最小生成树,时间复杂度为O(n2) 克鲁斯卡尔算法如图所示kruskal 克鲁斯卡尔算法,假设连通网N=(N,{E}),则令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),图中每个顶点 自成一个连通分量.在E中选择代价最小的边,若该边依附的定顶点落在T中不同的连通分量上,

dijkstra(迪杰斯特拉)最短路算法的堆优化

dijkstra(迪杰斯特拉)最短路算法是一种时间复杂度经过严格证明的最短路算法. 优化在于每次取最小值的时候采用堆优化,但是在最短路松弛过程中,dist是不断修改的,所以,为了能使复杂度降到O(nlogn),dist修改的同时,在堆中也要修改. 注意dijkstra(迪杰斯特拉)最短路算法只能用于正权边. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algo