搜索与图论 - floyd 算法

简介: 搜索与图论 - floyd 算法

文章目录


一、floyd 算法

1. floyd 算法简介

2. floyd 算法核心思想

3. floyd 算法实现步骤

4. floyd 算法具体实现详见例题 floyd 求最短路。

二、floyd 算法与其他算法的总结复习(重点)

1. Dijkstra 算法-朴素 O(n*n)

2. Dijkstra 算法-堆优化 O(mlogm)

3. Bellman-ford 算法 O(nm)

4. spfa 算法 O(n)~O(nm)

5. floyd 算法 O(n*n*n)

三、floyd 算法例题—— floyd 求最短路

具体实现

1. 样例演示

2. 实现思路

3. 代码注解

4. 实现代码


一、floyd 算法

1. floyd 算法简介



floyd 算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与 Dijkstra 算法类似。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。

floyd 算法是一种在具有正或负边缘权重(但没有负周期)的加权图中找到最短路径的算法。

floyd 算法的单个执行将找到所有顶点对之间的最短路径的长度(加权)。 虽然它不返回路径本身的细节,但是可以通过对算法的简单修改来重建路径。

优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。

缺点:时间复杂度比较高,不适合计算大量数据。


2. floyd 算法核心思想


(1) 邻接矩阵(二维数组)dist 储存路径,数组中的值开始表示节点和节点之间初始直接路径,最终是节点和节点之间的最小路径,有两点需要注意的,第一是如果没有直接相连的两点那么默认为一个很大的值(不要因为计算溢出成负数),第二是自己和自己的距离要为 0。

(2) 从第 1 个到第 n 个点依次加入松弛计算,每个点加入进行试探枚举是否有路径长度被更改(自己能否更新路径)。顺序加入( k 枚举)松弛的点时候,需要遍历图中每一个点对( i , j )双重循环),判断每一个点对距离是否因为加入的点而发生最小距离变化,如果发生改变(变小),那么两点( i , j )距离就更改。

(3) 重复上述直到最后插点试探完成。

其中第 2 步的状态转移方程为:


dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);

其中 dp[a][b] 的意思可以理解为节点 a 到节点 b 的最短路径,所以 dp[i][k] 的意思可以理解为节点 i 到节点 k 的最短路径, dp[k][j] 的意思为节点 k 到节点 j 的最短路径。


3. floyd 算法实现步骤


  • (1) 在主函数中创建一个矩阵,存储输入的两点间的距离。
  • (2) 在 floyd 函数中,初始化记录最短距离的矩阵和记录中介点的矩阵。初始化之后将主函数的矩阵复制给记录最短距离的矩阵。
  • (3) 用三层循环不断更新最短距离。


4. floyd 算法具体实现详见例题 floyd 求最短路。

二、floyd 算法与其他算法的总结复习(重点)


8730e5065659486aa4289933e789ec91.png


1. Dijkstra 算法-朴素 O(n*n)


(1) 初始化距离数组, dist[1] = 0, dist[i] = 0x3f3f3f3f。

(2) for n 次循环 每次循环确定一个 min 加入 S 集合中,n 次之后就得出所有的最短距离。

(3) 将不在 S 中 dist_min 的点 ->t。

(4) t->S 加入最短路集合。

(5) 用 t 更新到其他点的距离


2. Dijkstra 算法-堆优化 O(mlogm)


  • (1) 利用邻接表,优先队列。
  • (2) 在 priority_queue<PII,vector,greater> heap; 中将返回堆顶。
  • (3) 利用堆顶来更新其他点,并加入堆中类似广度优先搜索。


3. Bellman-ford 算法 O(nm)


  • (1) 注意连锁想象需要备份,struct Edge{inta,b,c} Edge[M]。
  • (2) 初始化 dist, 松弛 dist[x.b] = min(dist[x.b], backup[x.a]+x.w)。
  • (3) 松弛 k 次,每次访问 m 条边。


4. spfa 算法 O(n)~O(nm)


  • (1) 利用队列优化仅加入修改过的地方。
  • (2) for k 次。
  • (3) for 所有边利用宽搜模型去优化 bellman-ford 算法。
  • (4) 更新队列中当前点的所有出边。


5. floyd 算法 O(nnn)

  • (1) 初始化 d 。
  • (2) k,i,j 去更新 d 。


三、floyd 算法例题—— floyd 求最短路

题目描述


给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,边权可能为负数。

再给定 k 个询问,每个询问包含两个整数 x 和 y,表示查询从点 x 到点 y 的最短距离,如果路径不存在,则输出 impossible

数据保证图中不存在负权回路。


输入格式

第一行包含三个整数 n,m,k。

接下来 m 行,每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。

接下来 k 行,每行包含两个整数 x,y,表示询问点 x 到点 y 的最短距离。

输出格式


共 k 行,每行输出一个整数,表示询问的结果,若询问两点间不存在路径,则输出 impossible

数据范围

1 ≤ n ≤ 200

1 ≤ k ≤ n2

1 ≤ m ≤ 20000

图中涉及边长绝对值均不超过 10000。


输入样例

3 3 2

1 2 1

2 3 2

1 3 1

2 1

1 3

输出样例

impossible

1


具体实现

1. 样例演示


首先,输入 n=3,m=3,k=2;表示图有 3 个点,3 条边,询问 2 次。

第一条边是从节点 1 到节点 2 ,边长为 1。

第二条边是从节点 2 到节点 3 ,边长为 2。

第三条边是从节点 1 到节点 3 ,边长为 1。

第一次询问,节点 2 到节点 1 是否存在路径?

第二次询问,节点 1 到节点 3 是否存在路径?

显然,第一次询问结果 impossible。

第二次询问结果 1。


2. 实现思路

  • 详见上文核心思想和实现步骤


3. 代码注解

  • floyd 本身是floyd 本身是个动态规划算法,在代码实现的时候省去了一维状态。

原状态是:f[i, j, k]表示从 i 走到 j 的路径上除了 i , j 以外不包含点 k 的所有路径的最短距离。那么f[i, j, k] = min(f[i, j, k - 1), f[i, k, k - 1] + f[k, j, k - 1]。

因此在计算第 k 层的 f[i, j] 的时候必须先将第 k - 1 层的所有状态计算出来,所以需要把 k 放在最外层。


4. 实现代码

#include <bits/stdc++.h>
using namespace std;
const int N = 210, INF = 1e9;
int n, m, Q;
int d[N][N];
void floyd()
{
    for (int k = 1; k <= n; k ++ )
    {
        for (int i = 1; i <= n; i ++ )
        {
            for (int j = 1; j <= n; j ++ )
            {
                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
            }
        }
    }
}
int main()
{
    cin >> n >> m >> Q;
    for (int i = 1; i <= n; i ++ )
    {
        for (int j = 1; j <= n; j ++ )
        {
            if (i == j) 
            {
                d[i][j] = 0;
            }
            else 
            {
                d[i][j] = INF;
            }
        }
    }
    while (m -- )
    {
        int a, b, c;
        cin >> a >> b >> c;
        d[a][b] = min(d[a][b], c);
    }
    floyd();
    while (Q -- )
    {
        int a, b;
        cin >> a >> b;
        int t = d[a][b];
        if (t > INF / 2) 
        {
            puts("impossible");
        }
        else 
        {
            cout << t << endl;
        }
    }
    system("pause");
    return 0;
}



























相关文章
|
3月前
|
机器学习/深度学习 算法 安全
【无人机三维路径规划】基于非支配排序的鲸鱼优化算法NSWOA与多目标螳螂搜索算法MOMSA求解无人机三维路径规划研究(Matlab代码实现)
【无人机三维路径规划】基于非支配排序的鲸鱼优化算法NSWOA与多目标螳螂搜索算法MOMSA求解无人机三维路径规划研究(Matlab代码实现)
199 5
|
3月前
|
机器学习/深度学习 算法 安全
【无人机三维路径规划】多目标螳螂搜索算法MOMSA与非支配排序的鲸鱼优化算法NSWOA求解无人机三维路径规划研究(Matlab代码实现)
【无人机三维路径规划】多目标螳螂搜索算法MOMSA与非支配排序的鲸鱼优化算法NSWOA求解无人机三维路径规划研究(Matlab代码实现)
159 0
|
2月前
|
算法 数据可视化 测试技术
HNSW算法实战:用分层图索引替换k-NN暴力搜索
HNSW是一种高效向量检索算法,通过分层图结构实现近似最近邻的对数时间搜索,显著降低查询延迟。相比暴力搜索,它在保持高召回率的同时,将性能提升数十倍,广泛应用于大规模RAG系统。
158 10
HNSW算法实战:用分层图索引替换k-NN暴力搜索
|
4月前
|
机器学习/深度学习 算法 文件存储
神经架构搜索NAS详解:三种核心算法原理与Python实战代码
神经架构搜索(NAS)正被广泛应用于大模型及语言/视觉模型设计,如LangVision-LoRA-NAS、Jet-Nemotron等。本文回顾NAS核心技术,解析其自动化设计原理,探讨强化学习、进化算法与梯度方法的应用与差异,揭示NAS在大模型时代的潜力与挑战。
926 6
神经架构搜索NAS详解:三种核心算法原理与Python实战代码
|
3月前
|
存储 算法 数据可视化
基于禁忌搜索算法的TSP问题最优路径搜索matlab仿真
本程序基于禁忌搜索算法解决旅行商问题(TSP),旨在寻找访问多个城市的最短路径。使用 MATLAB 2022A 编写,包含城市坐标生成、路径优化及结果可视化功能。通过禁忌列表、禁忌长度与藐视准则等机制,提升搜索效率与解的质量,适用于物流配送、路径规划等场景。
|
2月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
214 0
|
2月前
|
数据采集 分布式计算 并行计算
mRMR算法实现特征选择-MATLAB
mRMR算法实现特征选择-MATLAB
168 2
|
3月前
|
传感器 机器学习/深度学习 编解码
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
207 3
|
2月前
|
机器学习/深度学习 算法 机器人
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
149 8
|
2月前
|
机器学习/深度学习 算法 自动驾驶
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
159 8

热门文章

最新文章