首页 > 编程语言 >floyd-warshall算法

floyd-warshall算法

时间:2024-10-25 19:42:26浏览次数:5  
标签:Dijk matrix warshall range 算法 floyd adjacent vnum row

Floyd-warshall算法

问题描述

图的最短路径问题,多源最短路径问题求解

算法思路

  • 设Dijk为从i到j的只以(1...k)集合为中间节点的最短路径的长度,Dijk = min(Dijk-1, Dikk-1 + Dkjk-1)

    若最短路径经过点k,则Dijk = Dikk-1 + Dkjk-1;

    若最短路径不经过点k,则Dijk = Dijk-1

python代码如下:

graph = {'A':[(2, 'A', 'B')],
         'B':[(1, 'B', 'C'), (6, 'B', 'D')],
         'C':[(5, 'C', 'A'), (4, 'C', 'D')],
         'D':[(3, 'D', 'A')], 
        }
def graph2adjacent_matrix(graph):
    vertices = list(graph.keys())
    vnum = len(vertices)
    adjacent_matrix = [[0 if row == col else float('inf') for col in range(vnum)] for row in range(vnum)]
    for i in range(vnum):
        vertex = vertices[i]
        for edge in graph[vertex]:
            w, _, end_vertex = edge
            j = vertices.index(end_vertex)
            adjacent_matrix[i][j] = w
    return adjacent_matrix


def floyd(adjacent_matrix):
    vnum = len(adjacent_matrix)
    a = [[adjacent_matrix[row][col] for col in range(vnum)] for row in range(vnum)]
    nvertex = [[-1 if adjacent_matrix[row][col] == float('inf') else row for col in range(vnum)] for row in range(vnum)]
    for k in range(vnum):
        for i in range(vnum):
            for j in range(vnum):
                if a[i][j] > a[i][k] + a[k][j]:
                    a[i][j] = a[i][k] + a[k][j]
                    nvertex[i][j] = nvertex[k][j]
    return nvertex, a

adjacent_matrix = graph2adjacent_matrix(graph)
nvertex, a = floyd(adjacent_matrix)

for i in range(len(adjacent_matrix)):
    for j in range(len(adjacent_matrix[0])):
        print(adjacent_matrix[i][j], end='\t')
    print()
print('------------------------------------------------------------------------')
for i in range(len(nvertex)):
    for j in range (len(nvertex[0])):
        print(nvertex[i][j], end = '\t')
    print()
print('------------------------------------------------------------------------')
for i in range(len(a)):
    for j in range(len(a[0])):
        print(a[i][j], end='\t')
    print()
    

算法改进

  • 先比较再相加

    若Dikk-1 或Dkjk-1 > Dijk,则最短路径不经过点k,则Dijk = Dijk-1

    若Dikk-1 < Dijk且 Dkjk-1 < Dijk,则最短路径可能经过点k,则Dijk = min(Dijk-1, Dikk-1 + Dkjk-1)

  • 不难发现,对于每个点k,Dikk 以及Dkjk是不会更新的,故可以添加约束条件:

    if Dikk = 0,i++

    if Dkjk = 0,j++

  • 若点i与点k之间没有路径,那么点i到点j的最短路径一定不经过点k,故可添加约束条件:

    if Dikk-1 == inf, i++

    if Dkjk-1 == inf, j++

python代码如下:

def floyd(adjacent_matrix):
    vnum = len(adjacent_matrix)
    a = [[adjacent_matrix[row][col] for col in range(vnum)] for row in range(vnum)]
    nvertex = [[-1 if adjacent_matrix[row][col] == float('inf') else row for col in range(vnum)] for row in range(vnum)]
    for k in range(vnum):
        for i in range(vnum):
            if (a[i][k] == 'inf')| (i == k):
                continue
            for j in range(vnum):
                if (a[k][j] == 'inf')| (k == j):
                    continue
                elif (a[i][j] > a[i][k]) & (a[i][j] > a[k][j]):
                    if a[i][j] > a[i][k] + a[k][j]:
                        a[i][j] = a[i][k] + a[k][j]
                        nvertex[i][j] = nvertex[k][j]
    return nvertex, a
                

标签:Dijk,matrix,warshall,range,算法,floyd,adjacent,vnum,row
From: https://www.cnblogs.com/0214jx/p/18498949/floyd-warshall

相关文章

  • 算法刷题记录(day1)
     前言 之前在LeetCode上断断续续刷了几百道题,但是很多题可能过一段时间后又忘了,打算从今天开始尽量保持每天刷题,同时记录下自己的刷题过程和对题目的理解,方便自己进行总结和复习。LC15.三数之和题目描述:给你一个整数数组 nums ,判断是否存在三元组 [nums[i],nums[j]......
  • 【强化学习】—— Q-learning算法
    Q-Learning算法Q-learning是一种无模型的强化学习算法,用于寻找最优策略以最大化累积奖励。它通过学习一个状态-动作值函数Q(s,......
  • 程序员现在应该钻研算法还是prompt能力
    标题:程序员现在应该钻研算法还是prompt能力摘要:1、算法与prompt能力,两者在当今编程领域均占据了极为重要的地位。算法作为解决问题的基础,强调逻辑思维与高效实现;而prompt能力,则关乎于与先进AI系统的交互,强调理解与指令的准确传达。本文旨在探讨程序员应如何在算法与prompt能力间......
  • 蓝桥首场算法团队战2024.10.24 题解(1~5)
    蓝桥首场算法团队战2024.10.24题解1:不同角度【算法赛】题意:给定自然数S,需要找出一个自然数T。使得数字T>数字S并且S和T转化为字符串后,满足S的字典序>T的字典序。T一定存在,找出符合条件且字典序最小的T。输入:第一行一个整数t,表示t组测试用例。\((......
  • 算法题——执行操作可获得的最大总奖励
    3181.执行操作可获得的最大总奖励题干给你一个整数数组rewardValues,长度为n,代表奖励的值。最初,你的总奖励x为0,所有下标都是未标记的。你可以执行以下操作任意次:从区间[0,n-1]中选择一个未标记的下标i。如果rewardValues[i]大于你当前的总奖励x,则将rewar......
  • 全面了解 NGINX 的负载均衡算法
    NGINX提供多种负载均衡方法,以应对不同的流量分发需求。常用的算法包括:最少连接、最短时间、通用哈希、随机算法和IP哈希。这些负载均衡算法都通过独立指令来定义,每种算法都有其独特的应用场景。以下负载均衡方法(IP哈希除外)适用于HTTP、TCP和UDP上游池:轮询轮询(Ro......
  • K-近邻算法(KNN)
    """K-近邻算法用于分类和回归问题。比如,判断一款游戏是否受欢迎。KNN算法的基本思想是:如果一个样本在特征空间中的k个最邻近的样本中的大多数属于某个类别,则该样本也属于这个类别。KNN算法的实现方法有两种:1.基于欧氏距离的KNN算法2.基于余弦相似度的KNN算法KNN算法的优点:1.简......
  • 算法设计实验6
    p1249有一个8*8的棋盘,行号、列号均为0-7,一个特殊放个的位置是(5,6),给出采用L形骨牌覆盖其他全部方格的一种方案1#include<ostream>2#include<iostream>3#defineMAX_SIZE84usingnamespacestd;5intk;6intx,y;7intboard[MAX_SIZE][MAX_SIZE];8int......
  • 【数据结构和算法】一、算法复杂度:时间复杂度和空间复杂度)
    目录1、算法复杂度1.1概念1.2评价指标1.3时间复杂度1.3.1什么是时间复杂度1.3.2常数阶O(1)1.3.3  线性阶O(n)1.3.4 对数阶O(logN)1.3.5  线性对数阶O(nlogN)1.3.6 平方阶O(n²)1.3.7  立方阶O(n³)、K次方阶O(n^k)1.4 空间复杂度1.4.1 空间复......
  • 数据结构图的最短路径-弗洛伊德算法(有向图+数据结构课本C++代码一比一转C语言+邻接矩
    弗洛伊德算法有向图代码如下:#define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>#include<stdlib.h>#include<limits.h>#defineMaxInt32767#defineMVNum100intPath[MVNum][MVNum];//存放前驱索引的intD[MVNum][MVNum];//存放当前已知的权值//图的邻接......