图的应用——最短路径

简介: 图的应用——最短路径

最短路径

  • 典型用途:交通问题。如:城市A到城市B有多条线路,但每条线路的交通费(或所需时间)不同,那么,如何选择一条线路,使总费用(或总时间)最少?
  • 问题抽象:在带权有向图中A点(源点)到达B点(终点)的多条路径中,寻找一条各边权值之和最小的路径,即最短路径。
最短路径与最小生成树不同,路径上不一定包含n个顶点

两种常见最短路径问题


Dijkstra(迪杰斯特拉)算法 —— 单源最短路径

在这里插入图片描述

算法思想

把图中顶点集合分成两组:
第一组为已求出其最短路径的顶点集合S
第二组为尚未确定最短路径的顶点集合U
  1. 初始时,S只包含源点,S={v},U包含除v外的其他顶点;
  2. 从U中选取一个距离最小的顶点k,把k加入到S中;
  3. 以k作为新考虑的中间点,修改U中各顶点的距离;
  4. 重复步骤 2、3 直到所有顶点都包含在S中

算法实现

算法流程图
在这里插入图片描述
C++代码实现

void ShortestPath_DIJ(AMGraph G, int v0){
    // 用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径 
    n = G.vexnum;  // G 中顶点个数
    for(v = 0; v < n; v++){
        // n 个顶点依次初始化
        S[v] = false;  // S 初始为空集
        D[v] = G.arcs[v0][v];  // 将v0到各个终点的最短路径长度初始化  
        if(D[v] < MaxInt) Path[v] = v0;  // v0和v之间有弧,将v的前驱置为v0
        else Path[v] = -1;  // 如果v0和v之间无弧,则将v的前驱置为-1
    }
    S[v0] = true;  // 将v0加入S
    D[v0] = 0;  // 源点到源点的距离为0

    /*―开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集―*/
    for(i = 1; i < n; i++){
        // 对其余n-1个顶点,依次进行计算
        min = MaxInt;
        for(w = 0; w < n; w++)
            if(!S[w] && (D[w] < min)){
                v = w;
                min = D[w];  // 选择一条当前的最短路径,终点为v
            }
        S[v] = true;  // 将v加入S
        for(w = 0; w < n; w++)  // 更新从v0出发到集合V−S上所有顶点的最短路径长度
            if(!S[w] && ((D[v] + G.arcs[v][w]) < D[w])){
                D[w] = D[v] + G.arcs[v][w];  // 更新D[w]
                Path[w] = v;  // 更新w的前驱为v
            }
    }
}

Floyd(弗洛伊德)算法 —— 所有顶点间的最短路径

每一对顶点之间的最短路径
方法一:每次以一个顶点为源点,重复执行Dijkstra算法n次—— T(n)=O(n³)
方法二:弗洛伊德(Floyd)算法
算法思想:逐个顶点试探法

算法思想

  • 初始时设置一个n阶方阵,令其对角线元素为0,若存在弧<Vi,Vj>,则对应元素为权值;否则为∞
  • 逐步试着在原直接路径中增加中间顶点,若加入中间点后路径变短,则修改之;否则,维持原值。
  • 所有顶点试探完毕,算法结结束

在这里插入图片描述

算法实现

typedef int Pathmatirx[MAXVEX][MAXVEX]
typedef int ShortPathTable[MAXVEX][MAXVEX]

/*- Floyd算法,求网图G中各顶点v到其余顶点w最短路径P[v][w]及带权长度D[v][w] -*/
void ShrotestPath_Floyd(MGraph G, Pathmatirx* P, ShortPathTable* D){
    int v, w, k;
    for(v = 0; v < G.numVertexes; ++v){
        // 初始化D与P
        for(w = 0; w < G.numVertexes; ++w){
            (*D)[v][w] = G.matirx[v][w];  // D[v][w]值即为对应点间的权值
            (*P)[v][w] = w;  // 初始化P

        }
    }

    for(k = 0; k < G.numVertexes; ++k)
        for(v = 0; v < G.numVertexes; ++v)
            for(w = 0; w < G.numVertexes; ++w)
                if((*D)[v][w] > (*D)[v][k] + (*D)[k][w]){
                    // 如果经过下标为k顶点路径比原两点间路径更短
                    // 将当前两点间权值设为更小的一个
                    (*D)[v][w] = (*D)[v][k] + (*D)[k][w];
                    (*P)[v][w] = (*P)[v][k];  // 路径设置为经过下标为k的顶点
                }
}
目录
相关文章
|
索引 Python
华为、阿里巴巴、字节跳动 100+ Python 面试问题总结(五)(2)
华为、阿里巴巴、字节跳动 100+ Python 面试问题总结(五)(2)
|
存储 SQL Prometheus
【TiDB原理与实战详解】1、原理与基础优化~学不会? 不存在的!
TiDB 是一款开源的分布式关系型数据库,具备水平扩展、高可用性和强一致性等特点,适用于高并发、低延迟的大规模数据处理场景。其架构设计灵感源自 Google 的 Spanner 和 F1,并兼容 MySQL。TiDB 集群由 TiDB Server(无状态 SQL 层)、PD(元数据管理模块)和 TiKV Server(分布式存储层)组成,还包含 TiFlash(列存储引擎)以加速分析型查询。TiDB 支持分布式事务和多种事务模式,适用于 OLTP 和 HTAP 场景,如电商平台和金融系统。此外,TiDB 的部署要求包括高性能硬件配置和特定网络设置,以确保系统的稳定性和高效运行。
|
4天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
14天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
8天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
561 210
|
3天前
|
编解码 Linux 数据安全/隐私保护
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
226 138
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
787 59
|
6天前
|
人工智能 移动开发 自然语言处理
2025最新HTML静态网页制作工具推荐:10款免费在线生成器小白也能5分钟上手
晓猛团队精选2025年10款真正免费、无需编程的在线HTML建站工具,涵盖AI生成、拖拽编辑、设计稿转代码等多种类型,均支持浏览器直接使用、快速出图与文件导出,特别适合零基础用户快速搭建个人网站、落地页或企业官网。
1105 157