当前位置: 首页 > news >正文

图论(二)之最短路问题

最短路

Dijkstra求最短路

文章目录

  • 最短路
    • Dijkstra求最短路
      • 栗题
      • 思想
      • 题目
      • 代码
      • 代码如下
      • bellman-ford
      • 算法分析
      • 只能用bellman-ford来解决的题型
      • 题目
      • 完整代码
    • spfa求最短路
      • spfa 算法思路
        • 明确一下松弛的概念。
        • spfa算法文字说明:
        • spfa 图解:
      • 题目
      • 完整代码
      • 总结tips
    • spfa判断负环
      • 算法分析
      • 代码如下
      • Floyd求最短路
      • 模拟过程
          • 链接:[https://www.acwing.com/problem/content/856/](https://www.acwing.com/problem/content/856/)
      • 题目
      • 代码如下

栗题

https://www.acwing.com/problem/content/851/

https://www.acwing.com/problem/content/852/

思想

迪杰斯特拉算法采用的是一种贪心的策略。

求源点到其余各点的最短距离步骤如下:

  1. 用一个 dist 数组保存源点到其余各个节点的距离,dist[i] 表示源点到节点 i 的距离。初始时,dist 数组的各个元素为无穷大。
    用一个状态数组 state 记录是否找到了源点到该节点的最短距离,state[i] 如果为真,则表示找到了源点到节点 i 的最短距离,state[i] 如果为假,则表示源点到节点 i 的最短距离还没有找到。初始时,state 各个元素为假。

03.png

  1. 源点到源点的距离为 0。即dist[1] = 0。

04.png

  1. 遍历 dist 数组,找到一个节点,这个节点是:没有确定最短路径的节点中距离源点最近的点。假设该节点编号为 i。此时就找到了源点到该节点的最短距离,state[i] 置为 1。

    05.png

  2. 遍历 i 所有可以到达的节点 j,如果 dist[j] 大于 dist[i] 加上 i -> j 的距离,即 dist[j] > dist[i] + w[i][j](w[i][j] 为 i -> j 的距离) ,则更新 dist[j] = dist[i] + w[i][j]。

    06.png

  3. 重复 3 4 步骤,直到所有节点的状态都被置为 1。

    071.png

  4. 此时 dist 数组中,就保存了源点到其余各个节点的最短距离。

    13.png

题目

在这里插入图片描述

代码

#include<iostream>
#include <cstring>
#include <algorithm>
using namespace std;const int N = 510, M = 100010;int h[N], e[M], ne[M], w[M], idx;//邻接表存储图
int state[N];//state 记录是否找到了源点到该节点的最短距离
int dist[N];//dist 数组保存源点到其余各个节点的距离
int n, m;//图的节点个数和边数void add(int a, int b, int c)//插入边
{e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}void Dijkstra()
{memset(dist, 0x3f, sizeof(dist));//dist 数组的各个元素为无穷大dist[1] = 0;//源点到源点的距离为置为 0for (int i = 0; i < n; i++){int t = -1;for (int j = 1; j <= n; j++)//遍历 dist 数组,找到没有确定最短路径的节点中距离源点最近的点t{if (!state[j] && (t == -1 || dist[j] < dist[t]))t = j;}state[t] = 1;//state[i] 置为 1。for (int j = h[t]; j != -1; j = ne[j])//遍历 t 所有可以到达的节点 i{int i = e[j];dist[i] = min(dist[i], dist[t] + w[j]);//更新 dist[j]}}
}int main()
{memset(h, -1, sizeof(h));//邻接表初始化cin >> n >> m;while (m--)//读入 m 条边{int a, b, w;cin >> a >> b >> w;add(a, b, w);}Dijkstra();if (dist[n] != 0x3f3f3f3f)//如果dist[n]被更新了,则存在路径cout << dist[n];elsecout << "-1";
}

优化

下面进行优化,可以看出上方时间复杂度为 O ( n 2 ) O(n^2) O(n2), 查找距离源点最近的点没有被确定的点t需要 O ( n ) O(n) O(n),遍历t所有可以到达的节点 i需要 O ( n ) O(n) O(n), 而这可以进行优化

  • 若是用小根堆(优先队列)进行存储, 那么每次找距离最近的那个点t只需要 O ( 1 ) O(1) O(1),而遍历t所有可以到达的需要 O ( m l o g n ) O(mlog_n) O(mlogn)因为堆的修改需要 O ( l o g n ) O(log_n) O(logn)

代码如下

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 150010;
//用邻接表的话重边可以不用考虑
typedef pair<int, int> PII;
int h[N], w[N], ne[N], idx, e[N];
int n, m;
bool st[N];
int dist[N];
void add(int a, int b, int c) {e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}int dijkstra() {memset(dist, 0x3f3f3f3f, sizeof dist);dist[1] = 0;priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, 1});  //{距离,编号}while(heap.size()) {auto t = heap.top();heap.pop();int no = t.second, distance = t.first;if(st[no])  continue;   //若此编号已经找到距离,那么跳过st[no] = true;for(int i = h[no]; i != -1; i = ne[i]) {int j = e[i];if(dist[j] > dist[no] + w[i]) {dist[j] = dist[no] + w[i];heap.push({dist[j], j});}}}if(dist[n] == 0x3f3f3f3f)   return -1;return dist[n];
}int main() {scanf("%d%d", &n, &m);//邻接表第一步的必备memset(h, -1, sizeof h);while(m --) {int a, b, c;scanf("%d%d%d", &a, &b, &c);add(a, b, c);}int t = dijkstra();cout << t;return 0;
}

bellman-ford

算法分析

1、问题:为什么Dijkstra不能使用在含负权的图中?
(这是以前错误的分析,若看完这个例子分析觉得正确的说明对最短路理解得还不够透彻,这里不做删除)
分析:如图所示:
若通过Dijkstra算法可以求出从1号点到达4号点所需的步数为3 (每次选择离源点最短距离的点更新其他点)
但实际上从 1 号点到达 4 号点所需步数为 1 (1 –> 2 –> 3),因此不能使用 Dijkstra 解决含负权图的问题

200fb33caef2d3ce435369aaa777f83.png

正确的分析
Dijkstra算法的3个步骤

1、找到当前未标识的且离源点最近的点t
2、对t号点点进行标识
3、用t号点更新其他点的距离
反例

8886031fd08869a6757d4c704c6f355.png

结果:

dijkstra算法在图中走出来的最短路径是1 -> 2 -> 4 -> 5,算出 1 号点到 5 号点的最短距离是2 + 2 + 1 = 5,然而还存在一条路径是1 -> 3 -> 4 -> 5,该路径的长度是5 + (-2) + 1 = 4,因此 dijkstra 算法失效

dijkstra详细步骤

  • 初始dist[1] = 0`

  • 找到了未标识且离源点1最近的结点1,标记1号点,用1号点更新其他所有点的距离,2号点被更新成dist[2] = 2,3号点被更新成

    dist[3] = 5

  • 找到了未标识且离源点1最近的结点2,标识2号点,用2号点更新其他所有点的距离,4号点被更新成dist[4] = 4

  • 找到了未标识且离源点1最近的结点4,标识4号点,用4号点更新其他所有点的距离,5号点被更新成dist[5] = 5

  • 找到了未标识且离源点1最近的结点3,标识3号点,用3号点更新其他所有点的距离,4号点被更新成dist[4] = 3
    结束

  • 得到1号点到5号点的最短距离是5,对应的路径是1 -> 2 -> 4 -> 5,并不是真正的最短距离

2、什么是bellman - ford算法?
Bellman - ford 算法是求含负权图的单源最短路径的一种算法,效率较低,代码难度较小。其原理为连续进行松弛,在每次松弛时把每条边都更新一下,若在 n-1 次松弛后还能更新,则说明图中有负环,因此无法得出结果,否则就完成。
(通俗的来讲就是:假设 1 号点到 n 号点是可达的,每一个点同时向指向的方向出发,更新相邻的点的最短距离,通过循环 n-1 次操作,若图中不存在负环,则 1 号点一定会到达 n 号点,若图中存在负环,则在 n-1 次松弛后一定还会更新)

3、bellman - ford算法的具体步骤

for n次for 所有边 a,b,w (松弛操作)dist[b] = min(dist[b],back[a] + w)

注意:back[] 数组是上一次迭代后 dist[] 数组的备份,由于是每个点同时向外出发,因此需要对 dist[] 数组进行备份,若不进行备份会因此发生串联效应,影响到下一个点

为什么需要back[a]数组
为了避免如下的串联情况, 在边数限制为一条的情况下,节点3的距离应该是3,但是由于串联情况,利用本轮更新的节点2更新了节点3的距离,所以现在节点3的距离是2。

2.PNG

正确做法是用上轮节点2更新的距离–无穷大,来更新节点3, 再取最小值,所以节点3离起点的距离是3。

3.PNG

for (int i = 0; i < k; i ++ )
{memcpy(backup, dist, sizeof dist);for (int j = 0; j < m ; j ++ ){int a = edges[j].a, b = edges[j].b, w = edges[j].w;dist[b] = min(dist[b], backup[a] + w);}
}

4、在下面代码中,是否能到达n号点的判断中需要进行if(dist[n] > INF/2)判断,而并非是if(dist[n] == INF)判断,原因是INF是一个确定的值,并非真正的无穷大,会随着其他数值而受到影响,dist[n]大于某个与INF相同数量级的数即可

5、bellman - ford算法擅长解决有边数限制的最短路问题
时间复杂度 O(nm)

其中n为点数,m为边数

作者:小呆呆
链接:https://www.acwing.com/solution/content/6320/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

只能用bellman-ford来解决的题型

有边数限制的最短路

这里题目说了可能为负权边或者负权回路,那么就不能用dijkstraspfa算法

dijkstra不能解决负权边是因为 dijkstra要求每个点被确定后st[j] = true,dist[j]就是最短距离了,之后就不能再被更新了(一锤子买卖),而如果有负权边的话,那已经确定的点的dist[j]不一定是最短了

题目

在这里插入图片描述

完整代码

```cpp
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 510, M = 10010;struct Edge
{int a, b, c;
}edges[M];int n, m, k;
int dist[N];
int last[N];void bellman_ford()
{memset(dist, 0x3f, sizeof dist);dist[1] = 0;for (int i = 0; i < k; i ++ ){memcpy(last, dist, sizeof dist);for (int j = 0; j < m; j ++ ){auto e = edges[j];dist[e.b] = min(dist[e.b], last[e.a] + e.c);}}
}int main()
{scanf("%d%d%d", &n, &m, &k);for (int i = 0; i < m; i ++ ){int a, b, c;scanf("%d%d%d", &a, &b, &c);edges[i] = {a, b, c};}bellman_ford();if (dist[n] > 0x3f3f3f3f / 2) puts("impossible");else printf("%d\n", dist[n]);return 0;
}```

spfa求最短路

spfa 算法思路

明确一下松弛的概念。
  • 考虑节点u以及它的邻居v,从起点跑到v有好多跑法,有的跑法经过u,有的不经过。

  • 经过u的跑法的距离就是dist[u]+u到v的距离。

  • 所谓松弛操作,就是看一看dist[v]和dist[u]+u到v的距离哪个大一点。

  • 如果前者大一点,就说明当前的不是最短路,就要赋值为后者,这就叫做松弛。

spfa算法文字说明:
  • 一个队列,初始时队列里只有起始点。

  • 再建立一个数组记录起始点到所有点的最短路径(该表格的初始值要赋为极大值,该点到他本身的路径赋为0)。

  • 再建立一个数组,标记点是否在队列中。

  • 队头不断出队,计算始点起点经过队头到其他点的距离是否变短,如果变短且被点不在队列中,则把该点加入到队尾。

  • 重复执行直到队列为空。

  • 在保存最短路径的数组中,就得到了最短路径。

spfa 图解:
  • 给定一个有向图,如下,求A~E的最短路。

1.png

  • 源点A首先入队,然后A出队,计算出到BC的距离会变短,更新距离数组,BC没在队列中,BC入队

2.png

  • B出队,计算出到D的距离变短,更新距离数组,D没在队列中,D入队。然后C出队,无点可更新。

3.png

  • D出队,计算出到E的距离变短,更新距离数组,E没在队列中,E入队。

  • 4.png

  • E出队,此时队列为空,源点到所有点的最短路已被找到,A->E的最短路即为8

    5.png

题目

https://www.acwing.com/problem/content/853/

在这里插入图片描述

完整代码

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 100010;
int w[N], h[N], idx, ne[N], e[N];
int n, m;
int dist[N];    //各点到源点的距离
bool st[N];
void add(int a, int b, int c) {e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}int spfa() {memset(dist, 0x3f3f3f3f, sizeof dist);dist[1] = 0;queue<int> q;    q.push(1);st[1] = true;   //代表在队列中了while(q.size()) {auto t = q.front();q.pop();st[t] = false;for(int i = h[t]; i != -1; i = ne[i]) {int j = e[i];if(dist[j] > dist[t] + w[i]) {dist[j] = dist[t] + w[i];if(!st[j]) {q.push(j);st[j] = true;   //在队列中了}}}}return dist[n];
}int main() {memset(h, -1, sizeof h);cin >> n >> m;while(m --) {int a, b, w;scanf("%d%d%d", &a, &b, &w);add(a, b, w);}int res = spfa();if(res == 0x3f3f3f3f)   cout << "impossible";else cout << res;return 0;
}

总结tips

在这里插入图片描述


spfa判断负环

https://www.acwing.com/problem/content/854/

算法分析

使用spfa算法解决是否存在负环问题

求负环的常用方法,基于SPFA,一般都用方法 2(该题也是用方法 2):

  • 方法 1:统计每个点入队的次数,如果某个点入队n次,则说明存在负环-
  • 方法 2:统计当前每个点的最短路中所包含的边数,如果某点的最短路所包含的边数大于等于n,则也说明存在环
  1. dist[x] 记录虚拟源点到x的最短距离

  2. cnt[x] 记录当前x点到虚拟源点最短路的边数,初始每个点到虚拟源点的距离为0,只要他能再走n步,即cnt[x] >= n,则表示该图中一定存在负环,由于从虚拟源点到x至少经过n条边时,则说明图中至少有n + 1个点,表示一定有点是重复使用

  3. dist[j] > dist[t] + w[i],则表示从t点走到j点能够让权值变少,因此进行对该点j进行更新,并且对应cnt[j] = cnt[t] + 1,往前走一步

注意:该题是判断是否存在负环,并非判断是否存在从1开始的负环,因此需要将所有的点都加入队列中,更新周围的点

故只需要对上方代码稍做改动即可:

代码如下

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 100010;
int w[N], h[N], idx, ne[N], e[N];
int n, m;
int dist[N];    //各点到源点的距离
int cnt[N]; //存储边的个数
bool st[N];
void add(int a, int b, int c) {e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}int spfa() {memset(dist, 0x3f3f3f3f, sizeof dist);	dist[1] = 0;			queue<int> q;    for(int i = 1; i <= n; i++) {st[i] = true;q.push(i);}while(q.size()) {auto t = q.front();q.pop();st[t] = false;for(int i = h[t]; i != -1; i = ne[i]) {int j = e[i];if(dist[j] > dist[t] + w[i]) {dist[j] = dist[t] + w[i];cnt[j] = cnt[t] + 1;if(cnt[j] > n)  return true;if(!st[j]) {q.push(j);st[j] = true;   //在队列中了}}}}return false;
}int main() {memset(h, -1, sizeof h);cin >> n >> m;while(m --) {int a, b, w;scanf("%d%d%d", &a, &b, &w);add(a, b, w);}bool res = spfa();if(res) cout << "Yes";else cout << "No";return 0;
}

Floyd求最短路

求多源最短路

通过中转动态规划来递推出最短路径距离

ij经过k,通过三重循环来实现

初始化自环为0,其他为INF

对于重边的情况下,我们初始化取最小距离

模拟过程

在这里插入图片描述

在这里插入图片描述

链接:https://www.acwing.com/problem/content/856/

题目

在这里插入图片描述

代码如下

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++)		//依次经过1~n中的n各点进行中转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 x, y, z;scanf("%d%d%d", &x, &y, &z);d[x][y] = min(d[x][y], z);}floyd();while(Q --) {int a, b;scanf("%d%d", &a, &b);int res = d[a][b];if(res > INF / 2) printf("impossible\n");else cout << res << '\n';}return 0;
}

相关文章:

图论(二)之最短路问题

最短路 Dijkstra求最短路 文章目录 最短路Dijkstra求最短路栗题思想题目代码代码如下bellman-ford算法分析只能用bellman-ford来解决的题型题目完整代码 spfa求最短路spfa 算法思路明确一下松弛的概念。spfa算法文字说明&#xff1a;spfa 图解&#xff1a; 题目完整代码总结ti…...

.NET Core 日志记录功能详解

在软件开发和运维过程中&#xff0c;日志记录是一个非常重要的功能。它可以帮助开发者跟踪应用程序的运行状况、诊断和监控问题。.NET Core 提供了一个灵活且易于使用的日志系统&#xff0c;本文将详细介绍.NET Core日志的相关概念、配置和使用方法。 1. 什么是日志记录以及它…...

docker——启动各种服务

1.Mysql 2.Redis 3.nginx 4.ES 注意&#xff1a;ES7之后环境为 -e ELASTICSEARCH_HOSTS http://ip地址:9200...

git远程仓库使用

赋值这个地址clone 克隆之后 cd slam_oncloud/ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/slam_oncloud.git 查看一下 linuxchenxiao:/media/linux/mydisk/cloud_slam/slam_oncloud$ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/sla…...

js导出的excel文件无法打开/打开乱码,excel无法打开xxx.xlsx因为文件格式或文件扩展无效

excel无法打开xxx.xlsx因为文件格式或文件扩展无效 使用 a 标签导出这里就不细说了&#xff0c;直接说上述问题解决方案 在调用导出接口的时候加上两个参数 responseType: “blob” responseEncoding: “utf8” export function test(data) {return util({url: /test,method: …...

透明多级分流系统(用户端缓存和负载均衡)

部件考虑 有些设备位于客户端或者网络边缘&#xff0c;能够迅速响应用户请求&#xff0c;避免给cpu和数据库带来压力&#xff0c;比如&#xff0c;本地缓存&#xff0c;内容分发网络&#xff0c;反向代理等。 有些设备处理能力能够线性扩展&#xff0c;易于伸缩&#xff0c;应…...

Python sort从大到小排序面试题

在Python中&#xff0c;你可以使用内置的sorted()函数或者列表的sort()方法来对列表中的元素进行从大到小的排序。 使用sorted()函数&#xff1a; numbers [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] sorted_numbers sorted(numbers, reverseTrue) # 设置reverseTrue实现从大到小排…...

【Stable Diffusion】入门:AI绘画提示词+参数设置攻略

目录 1 提示词1.1 分类和书写方式1.1.1 内容型提示词1.1.2 标准化提示词1.1.3 通用模板 1.2 权重1.2.1 套括号1.2.2 数字权重1.2.3 进阶语法 1.3 负面提示词 2 参数详解2.1 Sampling steps2.2 Sampling method2.3 Width, Height2.4 CFG Scale2.5 Seed2.6 Batch count, Batch si…...

Qt使用Q_DECLARE_INTERFACE Q_INTERFACES宏实现接口类使用qobject_cast进行类型转换

在写抽象类或者接口的时候&#xff0c;肯定是不能继承QObject的 但是又想使用qobject_cast进行类型转换&#xff0c;使用以下办法就能实现 #ifndef FACTORYINTERFACE_H__ #define FACTORYINTERFACE_H__ #include <QObject> class FactoryInterface{ public:FactoryInterf…...

docker离线搭建仓库

要在Docker中搭建本地仓库&#xff0c;可以按照以下步骤进行操作&#xff1a; 首先安装 Docker。根据不同的操作系统选择合适的版本并完成安装过程。打开命令行工具&#xff08;如Terminal或PowerShell&#xff09;&#xff0c;运行以下命令来创建一个新的容器并将其设置为本地…...

ABC344 A-E题解

文章目录 A题目AC Code&#xff1a; B题目AC Code&#xff1a; C题目AC Code&#xff1a; D题目AC Code&#xff1a; E题目AC Code&#xff1a; 不易不难&#xff0c;写到5题很简单&#xff0c;但是要有足够的思维能力。 A 题目 我们用一个 flag 变量记录我们是不是在两个竖…...

Jeecg-boot 初次启动项目失败

1.将IDEA的字符编码全部改成utf-8 2. 更改database的密码 3.换个jdk重新启动...

封装的echarts子组件使用watch监听option失效的问题

项目场景&#xff1a; 我在项目里面封装了一个echarts组件&#xff0c;组件接收一个来自外部的option,然后我用了一个watch函数去监听这个option的变化&#xff0c;option变化之后&#xff0c;销毁&#xff0c;然后再新建一个charts表 碎碎念 问题如标题所示&#xff0c;这篇…...

爬虫入门到精通_框架篇14(PySpider架构概述及用法详解)

官方文档 Sample Code&#xff1a; from pyspider.libs.base_handler import *class Handler(BaseHandler):crawl_config {}# minutes24 * 60&#xff1a;每隔一天重新爬取every(minutes24 * 60)def on_start(self):self.crawl(http://scrapy.org/, callbackself.index_page)…...

WPF DataGrid常用属性

AlternationCount属性&#xff1a;表示有几行不同的颜色来回替换&#xff0c;如果设置2则表示有两个颜色交替循环 AutoGenerateColumns属性&#xff1a;是否生成列 CanUserAddRows属性&#xff1a;用户是否可以添加行 CanUserDeleteRows属性&#xff1a;用户是否可以删除行 …...

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Stepper)

步骤导航器组件&#xff0c;适用于引导用户按照步骤完成任务的导航场景。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 仅能包含子组件StepperItem。 接口 Stepper(value?: { index?…...

Python基础语法:基本数据类型(列表)

现实世界中总是存在一组一组的事物。"组"的概念作为基本数据类型的一种&#xff0c;它也是来源于我们去解决现实生活中的一些问题而产生的。它需要有“组”这样的一个数据类型来丰富我们的基本数据类型。 那么在Python中如何来表示“组”的概念呢&#xff1f; 在Py…...

神经网络线性量化方法简介

可点此跳转看全篇 目录 神经网络量化量化的必要性量化方法简介线性对称量化线性非对称量化方法神经网络量化 量化的必要性 NetworkModel size (MB)GFLOPSAlexNet2330.7VGG-1652815.5VGG-1954819.6ResNet-50983.9ResNet-1011707.6ResNet-15223011.3GoogleNet271.6InceptionV38…...

阿里云k8s内OSS报错UnKnownHost。

这个问题就是链接不上oss属于网络问题&#xff1a; 1.排查服务器 在服务器&#xff08;ecs&#xff09;上直接ping oss地址看是否能够通。 不通就要修改dns和hosts&#xff08;这个不说&#xff0c;自己网上查&#xff09; 2.排查容器 进去ping一下你的容器是否能访问到oss…...

nginx的使用,homebrew安装及使用nginx。

Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;它提供了诸如 IMAP、POP3 和 SMTP 等邮件代理服务。以下是 Nginx 的主要作用&#xff1a;12345 作为 Web 服务器。Nginx 能够以较少的系统资源提供高效率的服务&#xff0c;尤其在高并发连接下表现出色。1…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...

云安全与网络安全:核心区别与协同作用解析

在数字化转型的浪潮中&#xff0c;云安全与网络安全作为信息安全的两大支柱&#xff0c;常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异&#xff0c;并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全&#xff1a;聚焦于保…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...