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

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实现

运行结果

 

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

posted on 2019-01-13 21:45  Dev_F  阅读(663)  评论(0编辑  收藏  举报

导航