Dijkstra算法求解最短路径—— 从零开始的图论讲解(2)
前言
在本系列第一期:从零开始的图论讲解(1)——图的概念,图的存储,图的遍历与图的拓扑排序-CSDN博客
笔者给大家介绍了 图的概念,如何存图,如何简单遍历图,已经什么是图的拓扑排序
按照之前的学习规划,今天笔者将继续带大家深入了解图论中的一个核心问题:最短路径的求解。
博客将聚焦介绍Dijkstra 算法,这是解决单源最短路径问题中最经典、应用最广泛的算法之一。
博客中出现的参考图都是笔者手画的,代码示例也是笔者手敲的!影响虽小,但请勿抄袭
什么是最短路径问题
在具体介绍算法之前,我先给刚学习的读者简单科普一下什么是最短路径问题,简单来说,
最短路径问题的核心就是:
在一个图中,找到从起点出发,到达终点的路径,使路径的总权值最小。
这里的图可以是有向图,也可以是无向图,这里的权值也代表很多意思,抽象地说,就是代表达到两点之间的代价,比如路程、时间、费用等。
在地图导航中,寻找从出发地到目的地的最短行驶距离;
在网络通信中,找到数据包传输延迟最小的路径;
在项目管理中,计算最短的工期安排。
根据具体场景的不同,最短路径问题还可以细分为几种类型:
1. 单源最短路径:从一个指定节点出发,计算它到其他所有节点的最短路径。
2. 多源最短路径:计算任意两点之间的最短路径。
3. 单对最短路径:只关心从一个节点到另一个节点的最短路径。
在本篇博客中,我们将专注于介绍单源最短路径问题,并学习如何使用经典的Dijkstra 算法来高效解决这一问题。
什么是Dijkstra 算法
Dijkstra 算法是由荷兰计算机科学家艾兹赫尔·迪克斯特拉(Edsger W. Dijkstra)在1959年提出的。它是一种贪心思想的算法,专门用来计算从一个起点到图中其他所有节点的最短路径,前提是:
图的所有边权值必须是非负数,如果有权值是负数,那么有另外的算法去解决,我们以后再谈.
Dijkstra 算法的特点:
-
适用于无向图或有向图。
-
可以快速找到单源最短路径,效率优良,且思路简单。
-
常与优先队列(堆)配合,进一步优化性能,我们先介绍基础算法,然后再介绍用小根堆优化过的算法.
Dijkstra 算法的核心思想 :
Dijkstra 算法的核心思想就是:
1.先选择好起点.
2.每次访问距离起点最近的,且之前没有被访问过的点
3.更新它的邻居的最短路径,并将其标记为已访问。
具体的步骤是:
1.解决最短路径问题时,我们通常要记录从起点到各个节点的当前最短距离。
因此,可以创建一个dist[]
数组,长度为节点数量 + 1
。数组含义:
dist[i]
表示起点start
到第i
个节点的最短距离。起点
dist[start] = 0
,表示从起点到自己,距离为 0。其余节点初始值设置为
∞
(通常用Integer.MAX_VALUE
或自定义的INF
),表示“暂时不可达”。如果算法结束后,
dist[i]
仍然是∞
,则说明:起点无法到达节点i
。同时,还需要一个
vis[]
数组用于标记节点是否已经确定了最短路径:
vis[i] = false
:表示节点i
还未确定最短路径。
vis[i] = true
:表示节点i
的最短路径已确定,无需再次更新。2.在执行算法之前,必须先完成图的存储。
可以使用两种方式存储图:
邻接表:适合稀疏图,节省空间。
邻接矩阵:适合稠密图,查询方便。
构建完成后,图的结构应该已经完整地反映每个节点的所有出边。
3.构图完成后,开始进行 Dijkstra 算法:
private static void dijkstra(int start){Arrays.fill(dis,INF);dis[start] = 0;for(int i=1;i<=n;i++){int pd = -1;int minDist = INF;// 找到当前未访问的点中,距离最小的点for(int j=1;j<=n;j++){if(!vis[j] && dis[j] < minDist){pd = j;minDist = dis[j];}}// 如果 pd == -1,说明所有点都被访问完了if(pd==-1) break;vis[pd] = true;// 遍历 pd 的所有邻接点for(Edge edge : graph.get(pd)){int v = edge.v;int w = edge.w;if(dis[pd] + w < dis[v]){dis[v] = dis[pd] + w;}}}}
每次循环,都会从未访问的节点中,选择
距离起点最近
的节点pd
。如果
pd == -1
,说明所有节点都已被访问,或者剩下的节点无法从起点到达,算法提前结束。选中
pd
后,遍历它的邻接点,尝试通过pd
更新这些点的最短路径:
dis[v] = min(dis[v], dis[pd] + w);
这里
dis[pd] + w
代表:
“从起点先走到pd
,再从pd
走到v
” 的路径长度。如果这条路径更短,就用它更新
dis[v]
,确保每次记录的都是当前已知的最短路径。以上就是朴素版的Dijkstra 算法的具体步骤,接下来我们给一组例子,模拟一遍该算法,让您看的更明白
如图:
假设我们令 1 为源点strat,求 1 到其他点的最短路径,现在我们用Dijkstra 算法模拟一遍
初始状态:
点编号 | dist[] 数组值 | vis[] 状态 |
---|---|---|
1 | 0 | false |
2 | ∞ | false |
3 | ∞ | false |
4 | ∞ | false |
第一轮:距离源点最近的点且i
] = false
的节点 : 1
标记
vis[1] = true
。遍历邻接点:
到
2
的距离0 + 2 = 2
,更新dist[2] = 2
。到
3
的距离0 + 5 = 5
,更新dist[3] = 5
。
点编号 dist[] 数组值 vis[] 状态 1 0 true 2 2 false 3 5 false 4 ∞ false
第二轮: 距离源点最近的点且i
] = false
的节点 : 2
标记
vis[2] = true
。遍历邻接点:
到
3
的距离2 + 1 = 3
,比原来的5
小,更新dist[3] = 3
。到
4
的距离2 + 2 = 4
,更新dist[4] = 4
。此时我们可以看到,借节点2到达3所需要的权值更小,体现出了Dijkstra算法的作用
点编号 dist[] 数组值 vis[] 状态 1 0 true 2 2 true 3 3 false 4 4 false
第三轮: 距离源点最近的点且i
] = false
的节点 : 3
标记
vis[3] = true
。遍历邻接点:
到
4
的距离3 + 3 = 6
,但dist[4]
已经是4
,所以不更新。请注意,虽然节点2也和节点3邻接,但是此时的dist[2] 已经是最优解了
为什么?
因为在第二轮时:
首先:节点2被选中,
dist[2] = 2
,说明在所有未访问的点中,从源点出发,能到2的路径已经是全局最短。这时候就把vis[2]
设置成true
,表明节点2已经确定了最短路径。其次:Dijkstra 的算法核心原则就是
一旦某个节点
i
被选择,并且vis[i] = true
,说明dist[i]
的值已经是最终确定的最小值,不会再被改变。在第一轮时,选择1也不会改变也是同理
点编号 dist[] 数组值 vis[] 状态 1 0 true 2 2 true 3 3 true 4 4 false
第四轮:选出未访问且距离最小的点:节点4
标记
vis[4] = true
。由于前面的点都已经确定最短路径,因此没有可维护的节点
点编号 dist[] 数组值 vis[] 状态 1 0 true 2 2 true 3 3 true 4 4 true
最终结果:
点编号 | 最短距离 dist[] |
---|---|
1 | 0 |
2 | 2 |
3 | 3 |
4 | 4 |
完整代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;public class Dijkstra
{static int n,m;static int N = 505;final static int INF = Integer.MAX_VALUE-200000000;static List<List<Edge>> graph = new ArrayList<>();static boolean[] vis = new boolean[N];static int[] dis = new int[N];// 定义一个边的类 (u->v,权值w)static class Edge {int v, w;Edge(int v, int w) {this.v = v;this.w = w;}}// 添加一条 u -> v, 权值为 w 的边static void addEdge(int u, int v, int w){graph.get(u).add(new Edge(v,w));}// Dijkstra 算法private static void dijkstra(int start){Arrays.fill(dis,INF);dis[start] = 0;for(int i=1;i<=n;i++){int pd = -1;int minDist = INF;// 找到当前未访问的点中,距离最小的点for(int j=1;j<=n;j++){if(!vis[j] && dis[j] < minDist){pd = j;minDist = dis[j];}}// 如果 pd == -1,说明所有点都被访问完了if(pd==-1) break;vis[pd] = true;// 遍历 pd 的所有邻接点for(Edge edge : graph.get(pd)){int v = edge.v;int w = edge.w;if(dis[pd] + w < dis[v]){dis[v] = dis[pd] + w;}}}}public static void main(String[] args){Scanner scanner = new Scanner(System.in);n = scanner.nextInt();m = scanner.nextInt();// 提前创建 n+1 个 ArrayList,避免越界for(int i=0;i<=n;i++) {graph.add(new ArrayList<>());}for(int i=0;i<m;i++){int a = scanner.nextInt();int b = scanner.nextInt();int c = scanner.nextInt();addEdge(a,b,c);}dijkstra(1);if(dis[n]>=INF-100000000){System.out.println(-1);}else{System.out.println(dis[n]);}}
}
如何优化Dijkstra 算法?
我们可以看到
for(int i=1;i<=n;i++){int pd = -1;int minDist = INF;// 找到当前未访问的点中,距离最小的点for(int j=1;j<=n;j++){if(!vis[j] && dis[j] < minDist){pd = j;minDist = dis[j];}}// 如果 pd == -1,说明所有点都被访问完了if(pd==-1) break;vis[pd] = true;// 遍历 pd 的所有邻接点for(Edge edge : graph.get(pd)){int v = edge.v;int w = edge.w;if(dis[pd] + w < dis[v]){dis[v] = dis[pd] + w;}}}
内层寻找最小点的部分: O(n^2)
遍历边的部分:O(m),但这个通常远小于 O(n^2),所以主导复杂度是 O(n^2)。
如何优化呢?
在朴素版 Dijkstra 中,我们每次都需要从未访问过的点中,找到距离源点最近的节点,然后进行标记和松弛操作。这个寻找过程使用 O(n)
的循环,显然效率不高。
为了优化这一过程,我们可以使用小根堆来维护当前所有未访问的候选节点。每当我们遍历邻接点并更新 dist[]
时,就将这些点加入小根堆。堆顶的元素总是当前到源点距离最小的节点,因此每次从堆里取出的节点,正好就是下一个要访问的目标。
需要注意的是,由于同一个节点在更新路径时可能会多次入堆,实际取出时,可能会遇到这个节点已经被访问过的情况。因此,在正式处理之前,我们要加一个判断:
如果当前节点已经被访问过,直接
continue
,跳过它,继续从堆中取下一个节点。
代码如下:
import java.util.*;public class BetterperformanceDijkstra {static class Node{public int v;public int w;public Node(int v, int w) {this.v = v;this.w = w;}}static int n,m;static List<List<Node>> list = new ArrayList<>();public static void addEge(int u, int v, int w){list.get(u).add(new Node(v,w));}static boolean[] vis;static int[] dist;static final int INF = Integer.MAX_VALUE-20000000;
public static void dijkstra(int start)
{Arrays.fill(dist,INF);dist[start] = 0;PriorityQueue<Node> priorityQueue = new PriorityQueue<>(((o1, o2) -> o1.w-o2.w));Node cur = new Node(start,0);priorityQueue.offer(cur);while(!priorityQueue.isEmpty()){Node temp = priorityQueue.poll();int v = temp.v;int w = temp.w;if(vis[v]){continue;//已经访问过了}vis[v] = true;if(list.get(v)==null){continue;//没有联通的点}for(Node tep : list.get(v)){int vi = tep.v;int wi = tep.w;if(dist[vi]>dist[v]+wi)//维护最短路径{dist[vi] = dist[v]+wi;priorityQueue.offer(new Node(vi,dist[vi]));}}}
}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);n = scanner.nextInt();m = scanner.nextInt();for(int i=0;i<=n;i++){list.add(new ArrayList<>());}vis = new boolean[n+1];dist = new int[n+1];for(int i=0;i<m;i++){int a = scanner.nextInt();int b = scanner.nextInt();int c = scanner.nextInt();addEge(a,b,c);}dijkstra(1);System.out.println(dist[n]==INF?"-1":dist[n]);}
}
结尾
结尾笔者留几个题目给大家练手
3112. 访问消失节点的最少时间 - 力扣(LeetCode)
743. 网络延迟时间 - 力扣(LeetCode)
希望本博客对大家来说有收获,也不枉我分享出来!!!谢谢大家
相关文章:
Dijkstra算法求解最短路径—— 从零开始的图论讲解(2)
前言 在本系列第一期:从零开始的图论讲解(1)——图的概念,图的存储,图的遍历与图的拓扑排序-CSDN博客 笔者给大家介绍了 图的概念,如何存图,如何简单遍历图,已经什么是图的拓扑排序 按照之前的学习规划,今天笔者将继续带大家深入了解图论中的一个核心问题&#x…...
Spring AI 发布了它的 1.0.0 版本的第七个里程碑(M7)
Spring AI 发布了它的 1.0.0 版本的第七个里程碑(M7),下个月就是 RC1,紧接着就是 GA!,对于我们 Java 开发者来说,这绝对是个值得关注的好消息! 但是对于 Java 学习者来说,…...
如何从 GitHub 镜像仓库到极狐GitLab?
最近 GitHub 封禁中国用户的事情闹得沸沸扬扬,虽然官方发布的报道说中国用户被限制登录是因为配置错误导致,已经撤回了更新,中国用户已经可以正常使用。但是这就像横在国内开发者和企业头上的“达摩克利斯之剑”。为了避免 GitHub 不可用而带…...
大象机器人推出myCobot 280 RDK X5,携手地瓜机器人共建智能教育机
摘要 大象机器人全新推出轻量级高性能教育机械臂 myCobot 280 RDK X5,该产品集成地瓜机器人 RDK X5 开发者套件,深度整合双方在硬件研发与智能计算领域的技术优势,实现芯片架构、软件算法、硬件结构的全栈自主研发。作为国内教育机器人生态合…...
在Android Studio中,`Settings`里的Gradle路径、环境变量以及`gradle - wrapper.properties`文件关联
在Android Studio中,Settings里的Gradle路径、环境变量以及gradle - wrapper.properties文件关联 Android Studio中Settings里的Gradle路径 在Android Studio的Settings(Preferences ) -> Build, Execution, Deployment -> Build Tools -> Gradle 中: Use defau…...
用react 写一个可左右滑动的柱状图
效果图 目录 效果图 ✅ 项目结构 🚀 创建项目步骤 1️⃣ 打开终端或命令行,创建新项目: 2️⃣ 安装 recharts 图表库: 3️⃣ 替换默认代码: 4️⃣ 启动项目: ✅ 项目结构 scrollable-bar-chart/ ├…...
【正点原子STM32MP257连载】第四章 ATK-DLMP257B功能测试——MIPI LCD测试
1)实验平台:正点原子ATK-DLMP257B开发板 2)浏览产品:www.alientek.com 3)全套实验源码手册视频下载:正点原子资料下载中心 文章目录 第四章 ATK-DLMP257B功能测试——MIPI LCD测试4.3 MIPI LCD测试4.3.1 使…...
【正点原子STM32MP257连载】第四章 ATK-DLMP257B功能测试——RS485串口测试
1)实验平台:正点原子ATK-DLMP257B开发板 2)浏览产品:www.alientek.com 3)全套实验源码手册视频下载:正点原子资料下载中心 文章目录 第四章 ATK-DLMP257B功能测试——RS485串口测试 第四章 ATK-DLMP257B功能…...
Sui 的工具生态简化了游戏开发者的 Web3 集成流程
希望利用 Web3 独特协同效应的游戏开发者,常常在强大的区块链功能与流畅的游戏体验之间难以权衡。许多区块链方案要求大幅重构游戏基础架构,增加了开发难度,甚至需要学习全新的智能合约语言。而 Sui 通过直观的工具消除这一阻力,使…...
Vue 3 的组合式 API-hooks
Vue 3 的组合式 API 组合式 API 是 Vue 3 的核心特性之一,它允许开发者将组件的逻辑拆分为可复用的函数。组合式 API 的主要特点是 逻辑复用:将逻辑提取到独立的函数中,方便在多个组件中复用。组织清晰:将相关的逻辑分组&#x…...
AOSP Android14 Launcher3——底部任务栏Taskbar详解
前言:Launcher3中底部Taskbar和Navbar,或者说中文里面的术语导航栏,这几个词是很容易让人混淆的地方。本文要介绍的是Taskbar。从字面上意思来看,Taskbar就是任务栏,任务栏是Launcher3中一个重要的组件,尤其…...
QGraphicsView、QGraphicsScene和QGraphicsItem图形视图框架(五)QGraphicsView的缩放和移动
QGraphicsView自带滚动条的显示,但是大部分的需求样式都不需要滚动条,并且要通过鼠标来控制视图的缩放和移动。需要重写QGraphicsView实现。 一、相关函数 1.scale void QGraphicsView::scale(qreal sx, qreal sy) 按(sx,sy&…...
算法——果蝇算法
果蝇算法(Fruit Fly Optimization Algorithm,FOA)是一种受果蝇觅食行为启发而开发的群智能优化算法。以下从算法原理、算法流程、算法特点等方面为你详细讲述: 算法原理 果蝇本身具有优于其他物种的嗅觉和视觉。在觅食过程中&am…...
重返JAVA之路——图书管理系统
目录 一、功能介绍 二、设计模块 三、系统构建 1.book模块 2.operation模块 输入循环和验证 查找图书并处理借阅状态 未找到图书的处理 查找删除图书功能实现 未找到图书的处理 图书查找与归还 work方法实现图书信息输出 3. user模块实现 四、主菜单 一、功能介绍 …...
【16】数据结构之基于树的排序算法篇章
目录标题 选择排序简单选择排序树形选择排序 堆排序堆的定义Heap小跟堆大根堆堆的存储堆的代码设计堆排序的代码设计 排序算法综合比较 选择排序 基本思想:从待排序的序列中选出最大值或最小值,交换该元素与待排序序列的头部元素,对剩下的元…...
Uniapp:确认框
目录 一、 出现场景二、 效果展示三、具体使用 一、 出现场景 在项目的开发中,会经常出现删除数据的情况,如果直接删除的话,可能会存在误删,用户体验不好,所以需要增加一个消息提示,提醒用户是否删除。 二…...
pyswmm实现洪涝模拟
准备好.inp文件作为SWMM模型输入,调用pyswmm模块执行模拟,返回节点溢流量(flooding)作为积水量的初步表征。 代码: from pyswmm import Simulation, Nodes import pandas as pddef run_swmm_simulation(inp_file, ou…...
My Diary Pro:记录生活,珍藏回忆
我的日记My Diary Pro是一个非常好用的手机日记软件,可以使用它来记录每日生活日常,不少的用户可能都知道在生活之中可能会发生一些比较的重要的事情,实际上我们都可以将这些内容记录下来。包括个人观点,旅行游记,心情…...
CSRF(跨站请求伪造)漏洞概述
CSRF(跨站请求伪造)漏洞概述 一、什么是 CSRF 攻击者诱导已登录用户在不知情的情况下,对受信任网站执行未授权操作。 简单说:你登录着网站A,攻击者诱导你访问某个恶意链接,使网站A误以为是你自己发出的操作(比…...
[Java实战经验]对象拷贝
目录 谨慎重写clone方法重写clone()支持深拷贝带来的问题 合适的深拷贝 首先,对于不可变的类,我们不应该实现Cloneable接口,因为不可变类不需要拷贝,直接引用即可,实现Cloneable接口只会造成浪费。 对于Java可变类来说…...
WAF防火墙:构筑Web应用安全的“隐形护盾”
在数字化时代,Web应用已成为企业服务与用户交互的核心窗口。然而,随之而来的SQL注入、跨站脚本攻击(XSS)、DDoS攻击等威胁,时刻考验着网站的安全防线。Web应用防火墙(WAF)作为关键防护工具&…...
开源智慧巡检——无人机油田AI视频监控的未来之力
油田巡检,关乎能源命脉,却常受困于广袤地形、高危环境和人工效率瓶颈。管道泄漏、设备故障、非法闯入——这些隐患稍有疏忽,便可能酿成大患。传统巡检已无法满足现代油田对安全与效率的需求,而无人机油田巡检系统正以智能化之力重…...
【2025年泰迪杯数据挖掘挑战赛】B题 完整论文 模型建立与求解
目录 2025年泰迪杯数据挖掘挑战赛 B题完整论文:建模与求解 Matlab代码一、问题重述二、模型假设与符号说明2.1 模型基本假设2.2 符号说明 三、数据预处理**问题一:志愿者身体活动信息的统计分析****问题二:身体活动MET值的实时估计模型构建**…...
Chromium 134 编译指南 macOS篇:安装 Xcode(二)
1. 引言 在Chromium开发的征程中,为macOS平台构建正确的开发环境是成功编译的关键基础。继上一篇系统环境准备后,本文将重点介绍Xcode的安装与配置过程。作为macOS上不可或缺的集成开发环境(IDE),Xcode为Chromium 134的编译提供了必要的编译…...
软件定义网络(SDN):重塑未来网络的革命性架构
在当今数字化时代,网络已成为企业、云计算、5G通信和物联网(IoT)的核心基础设施。然而,传统网络架构由于其封闭、静态和分布式的特性,难以应对快速变化的业务需求。软件定义网络(Software-Defined Networki…...
Java虚拟机面试题:类加载机制
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…...
OCCT 入门(3)核心模块与架构
文章目录 一、核心模块与架构1、架构概述2、核心模块3、数据流转3.1、几何创建(Geometric Primitives)3.2、拓扑构建(Topology Construction)3.3、模型处理(Modeling Algorithms)3.4、可视化(Vi…...
MAC-需求:10万订单异步执行库存扣减、短信通知。
批量任务并行处理 实现,通过拆分任务、异步执行和线程池管理提升处理。 10万订单异步处理方案设计 基于图中代码的批量处理框架,结合订单业务需求,以下是 库存扣减与短信通知的异步实现: 1. 代码实现(基于原有框架改造) @Service public…...
ArrayList vs LinkedList,HashMap vs TreeMap:如何选择最适合的集合类?
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 在 Java 开发中,集合类的选择直接影响程序的性能和代码的可维护性。不同的数据结构适用于不同的场景,盲目使用可能导致内存浪费、性能…...
使用Form.List且有Select组件
当在使用Form.List组件,且组件中有Select选项时,针对每一次选择,都要过滤掉那些已经选择过的选项,可能遇到的问题: 直接过滤会将每一个Select中的options选项都过滤掉,无法正常展示选择的选项 解决办法&a…...
大数据学习笔记
文章目录 1. 大数据概述1.1 大数据的特性1.2 大数据技术生态1.2.1 Hadoop 的概念特性1.2.2 Hadoop生态圈 — 核心组件与技术栈1.2.3 Hadoop生态演进趋势 2. 数据处理流程与技术栈2.1 数据采集2.1.1 日志采集工具2.1.2 实时数据流2.1.3 数据迁移 2.2 数据预处理2.2.1 批处理2.2.…...
Obsidian 文件夹体系构建 -INKA
Obsidian 文件夹体系构建 -INKA 本篇文章主要分享一下自己折腾学习实践过的 INKA 框架方法。原地址:Obsidian文件夹体系构建–INKA。 文章目录 Obsidian 文件夹体系构建 -INKA前言INKA简介INKA 理论最佳实践实际应用 反思 前言 上文 Obsidian文件夹体系构建-ACCES…...
QML与C++:基于ListView调用外部模型进行增删改查(性能优化版)
目录 引言相关阅读工程结构数据模型设计DataModel 类ContactProxyModel 类 为什么使用QSortFilterProxyModel?应用初始化与模型连接UI实现 性能分析与优化运行效果扩展思考总结下载链接 引言 在上一篇中介绍了基于ListView调用外部模型进行增删改查,本文…...
集合常用Stream操作
1、中间操作 filter()过滤 将流中的元素筛选出满足条件的元素 List<String> list Arrays.asList("abc","test","demo","frse","fesfes"); list.stream().filter(s -> s.startsWith("f")).forEach(Sy…...
ReactNative中处理安全区域问题
RN原生方案不支持android系统,所以在此使用三方组件react-native-safe-area-context 1、安装插件 yarn add react-native-safe-area-context2、安装完成后直接yarn ios可能会失败,需要先 cd ios && pod install && cd ..出来再继…...
二、The Power of LLM Function Calling
一、Function Calling 的诞生背景 1. 传统LLM的局限性 静态文本生成的不足:早期的LLM(如早期版本的ChatGPT)主要依赖预训练的知识库生成文本,但无法直接与外部系统或API交互。这意味着它们只能基于历史数据回答问题,…...
贪心算法day10(无重叠区间)
1.无重叠区间 435. 无重叠区间 - 力扣(LeetCode) 思路: 代码: class Solution {public static int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals,(v1,v2)->{return v1[0]-v2[0];});int left interva…...
reactive 解构赋值给 ref
在 Vue 3 中,当你执行以下操作时: javascript const applyBasicInfo ref(); applyBasicInfo.value { ...props.applyBasicInfo }; 最终的 applyBasicInfo.value 是响应式对象,但与原对象 props.applyBasicInfo 的响应性完全独立…...
MongoDB简单用法
图片中 MongoDB Compass 中显示了默认的三个数据库: adminconfiglocal 如果在 .env 文件中配置的是: MONGODB_URImongodb://admin:passwordlocalhost:27017/ MONGODB_NAMERAGSAAS💡 一、为什么 Compass 里没有 RAGSAAS 数据库?…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(4): 可能形(かのうけい)
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(4): 可能形(かのうけい) 1、前言(1)情况说明(2)工程师的信仰2、知识点(1)~んです 復習(ふくしゅう)(2)いただけませんか 復習(ふくしゅう)(3)可能形(かのうけい)(1)1グループ:(2)2グループ…...
Windows 下 MongoDB ZIP 版本安装指南
在开发和生产环境中,MongoDB 是一种非常流行的 NoSQL 数据库,以其灵活性和高性能而受到开发者的青睐。对于 Windows 用户来说,MongoDB 提供了多种安装方式,其中 ZIP 版本因其灵活性和轻量级的特点,成为很多开发者的首选…...
万字长篇————C语言指针学习汇总
经过一段时间的学习,我们已经接触到了C语言的很多知识了。不过目前我们接下来我们要接触C语言中一个最大的“门槛”:指针。 什么是指针? 在介绍指针之前,我们首先要明白变量与地址之间的关系。 举一个生活中的案例:一…...
day29图像处理OpenCV
文章目录 一、图像预处理6 图像色彩空间转换6.3灰色/BGR/HSV相互转化 7 彩图转灰图方法7.1 最大值法7.2 平均值法7.3 加权均值法7.4 案例 8 图像二值化处理8.1 阈值法(typecv2.THRESH_BINARY)8.2 反阈值法(THRESH_BINARY_INV)8.3 截断阈值法(THRESH_TRUNC)8.4 低阈值零处理(THR…...
Spring Boot 项目三种打印日志的方法详解。Logger,log,logger 解读。
目录 一. 打印日志的常见三种方法? 1.1 手动创建 Logger 对象(基于SLF4J API) 1.2 使用 Lombok 插件的 Slf4j 注解 1.3 使用 Spring 的 Log 接口(使用频率较低) 二. 常见的 Logger,logger,…...
KrillinAI:视频跨语言传播的一站式AI解决方案
引言 在全球内容创作领域,跨语言传播一直是内容创作者面临的巨大挑战。传统的视频本地化流程繁琐,涉及多个环节和工具,不仅耗时耗力,还常常面临质量不稳定的问题。随着大语言模型(LLM)技术的迅猛发展,一款名为Krillin…...
PDF处理控件Aspose.PDF指南:使用 C# 从 PDF 文档中删除页面
需要从 PDF 文档中删除特定页面?本快速指南将向您展示如何仅用几行代码删除不需要的页面。无论您是清理报告、跳过空白页,还是在共享前自定义文档,C# 都能让 PDF 操作变得简单高效。学习如何以编程方式从 PDF 文档中选择和删除特定页面&#…...
在 IntelliJ IDEA 中开发 Java Web 项目时,遇到包内明明存在某个类但类名仍然爆红(显示红色错误提示)
在 IntelliJ IDEA 中开发 Java Web 项目时,遇到包内明明存在某个类但类名仍然爆红(显示红色错误提示),而项目却能正常运行,重启 IDEA 后问题依旧,这通常是由以下原因及解决方法导致的: 1. 缓存…...
【4】k8s集群管理系列--harbor镜像仓库本地化搭建
一、harbor基本概念 Harbor是一个由VMware开源的企业级Docker镜像仓库解决方案,旨在解决企业在容器化应用部署中的痛点,提供镜像存储、管理、安全和分发的全生命周期管理。Harbor扩展了Docker Registry,增加了企业级功能,如…...
Active Directory域服务管理与高级应用技术白皮书
目录 一、Active Directory核心架构解析 1.1 AD域服务核心组件 1.2 域功能级别演进 1.3 AD LDS应用场景 二、企业级域环境部署最佳实践 2.1 域控制器部署规划 2.2 高可用架构设计 2.3 客户端入域优化 三、高级域管理技术 3.1 精细化权限管理 3.2 组策略深度配置 3.3…...
OCP中的OCS operator介绍及应用示例
一、OCS operator介绍 在 Red Hat OpenShift Container Platform(OCP4.8版之前,包含4.8) 中,OCS Operator(OpenShift Container Storage Operator) 是用于在 OpenShift 集群中部署、配置和管理 OpenShift …...