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

视觉中国网站建设公司口碑营销的名词解释

视觉中国网站建设公司,口碑营销的名词解释,苏州做企业网站公司,asp.net 做网站大家好,我们昨天是讲解了最短路算法,我先告诉大家一句,我们最近图论里面尤其是并查集之后讲解的这些算法,比如最小生成树和算法与最短路算法大家有初步了解就可以了,目前不需要自己手撕代码,因为大家可能多…

       大家好,我们昨天是讲解了最短路算法,我先告诉大家一句,我们最近图论里面尤其是并查集之后讲解的这些算法,比如最小生成树和算法与最短路算法大家有初步了解就可以了,目前不需要自己手撕代码,因为大家可能多是第一次接触这些算法,这些算法的逻辑有的比较难,而且代码量也比较大,大家就有一个初步了解即可,我们今天就继续我们昨天的内容继续讲,今天我们要讲的是SPFA算法其实就是队列优化算法和bellman_ford之判断负权回路,我们就开始今天的内容。

第一部分 Bellman_ford 队列优化算法(又名SPFA)

        我们先看到理论基础部分,大家对这个算法可能是不熟悉的,可能这个算法的名称还是第一次听说过,其实我也是第一次接触,我以前的基础也就到了Dijkstra算法和Floyd算法,这个算法我需要和大家一起学习,我们现在就开始。

      大家首先知道 SPFA 和 Bellman_ford 队列优化算法指的都是一个算法,大家可以发现 Bellman_ford 算法每次松弛 都是对所有边进行松弛。其实我们先看下面的这幅图:

       大家应该还记得我们的Bellman_ford算法是对所有的边进行松弛,我们起点是1,与起点有关联的两个节点就是只有2,3两个,因此我们只有松弛 边(节点1->节点2)和 边(节点1->节点3)才是有效的,我们的Bellman_ford算法是每一条边都松弛了其实无意间做了很多无用功,基于以上思路,如何记录 上次松弛的时候更新过的节点呢?这时候我们就应该使用队列,大家是否还记得我们前面使用广度优先搜索算法解决岛屿问题的时候是不是也是使用了队列存储我们目前访问的节点,这里也是使用队列,我们就看看我们是如何模拟出来的。

      我们依然使用minDist数组来表达 起点到各个节点的最短距离,例如minDist[3] = 5 表示起点到达节点3 的最小距离为5,首先进行初始化,起点为节点1, 起点到起点的最短距离为0,所以minDist[1] 为 0。 将节点1 加入队列 (下次松弛从节点1开始),

       我们其实目前的状态就是这样的,从队列里取出节点1,松弛节点1 作为出发点连接的边(节点1 -> 节点2)和边(节点1 -> 节点3),我们可以很轻易看出边:节点1 -> 节点2,权值为1 ,minDist[2] > minDist[1] + 1 ,更新 minDist[2] = minDist[1] + 1 = 0 + 1 = 1 。边:节点1 -> 节点3,权值为5 ,minDist[3] > minDist[1] + 5,更新 minDist[3] = minDist[1] + 5 = 0 + 5 = 5。这时候我们就把节点2与节点3加入队列,我就不再截图了,大家其实自己也是可以想出来的,随后从队列里取出节点2,松弛节点2 作为出发点连接的边(节点2 -> 节点4)和边(节点2 -> 节点5),边:节点2 -> 节点4,权值为1 ,minDist[4] > minDist[2] + (-3) ,更新 minDist[4] = minDist[2] + (-3) = 1 + (-3) = -2 。边:节点2 -> 节点5,权值为2 ,minDist[5] > minDist[2] + 2 ,更新 minDist[5] = minDist[2] + 2 = 1 + 2 = 3 。随后我们就将节点4与节点5加入队列,我们就重复上述过程即可。但是这里我们是从队列里出去节点3,松弛节点3 作为出发点连接的边。因为没有从节点3作为出发点的边,所以这里就从队列里取出节点3就好,不用做其他操作,其实往后都是一样的操作了,我们要使用一个visited数组来存储保证我当前的节点没有被访问过,这样我们就完成了基于队列优化bellman_ford的算法模拟过程。其实我们就可以发现SPFA算法可以省去很多不必要的操作。同时大家也可以发现 基于队列优化的算法,要比bellman_ford 算法 减少很多无用的松弛情况,特别是对于边数众多的大图 优化效果明显。

         这样我们就可以给出代码:

#include <iostream>
#include <vector>
#include <queue>
#include <list>
#include <climits>
using namespace std;struct Edge { //邻接表int to;  // 链接的节点int val; // 边的权重Edge(int t, int w): to(t), val(w) {}  // 构造函数
};int main() {int n, m, p1, p2, val;cin >> n >> m;vector<list<Edge>> grid(n + 1); vector<bool> isInQueue(n + 1); // 加入优化,已经在队里里的元素不用重复添加// 将所有边保存起来for(int i = 0; i < m; i++){cin >> p1 >> p2 >> val;// p1 指向 p2,权值为 valgrid[p1].push_back(Edge(p2, val));}int start = 1;  // 起点int end = n;    // 终点vector<int> minDist(n + 1 , INT_MAX);minDist[start] = 0;queue<int> que;que.push(start); while (!que.empty()) {int node = que.front(); que.pop();isInQueue[node] = false; // 从队列里取出的时候,要取消标记,我们只保证已经在队列里的元素不用重复加入for (Edge edge : grid[node]) {int from = node;int to = edge.to;int value = edge.val;if (minDist[to] > minDist[from] + value) { // 开始松弛minDist[to] = minDist[from] + value; if (isInQueue[to] == false) { // 已经在队列里的元素不用重复添加que.push(to);isInQueue[to] = true;}}}}if (minDist[end] == INT_MAX) cout << "unconnected" << endl; // 不能到达终点else cout << minDist[end] << endl; // 到达终点最短路径
}

          但是还队列优化版Bellman_ford 的时间复杂度 并不稳定,效率高低依赖于图的结构。如果是一个双向图,且每一个节点和所有其他节点都相连的话,那么该算法的时间复杂度就接近于 Bellman_ford 的 O(N * E) N 为节点数量,E为边的数量。大家目前了解这个算法就可以了。

第二部分 bellman_ford之判断负权回路

       我们来到今天的第二部分内容,我们通过以前的学习我们了解到几种最短路算法,比如Dijkstra算法和bellman_ford算法,我们知道Dijkstra算法是不能解决边权为负数的图中的最短路问题的,因此我们才有了bellman_ford算法,我们现在就要用bellman_ford判断负权回路,其实大家时候还记得我们前面的拓扑排序,我们是不是也是用拓扑排序来判断图中是否存在环,我们是利用入度来寻找起点的,如果出现了环就不存在入度为0的节点我们的拓扑排序就无法继续下去,我们一起来看看bellman_ford之判断负权回路的思路。

      我们首先需要先知道对于在有负权值的图中求最短路,都需要先看看这个图里有没有负权回路。因为 有负权回路 就是可以无限最短路径(一直绕圈,就可以一直得到无限小的最短距离)。因为是负权其实越走路径会越短,那么每松弛一次,都会更新最短路径,所以结果会一直有变化。因此我们在求解带负权的图中的最短路问题就需要先判断是否存在负权回路,

         大家可以先看到上面这幅图,这幅图是存在回路的,图中 节点1 到 节点4 的最短路径是多少(题目中的最低运输成本) (注意边可以为负数的)节点1 -> 节点2 -> 节点3 -> 节点4,这样的路径总成本为 -1 + 1 + 1 = 1,但是注意这里负权的回路,这就需要注意了,那么我们在负权回路中多绕一圈,我们的最短路径 是不是就更小了 (也就是更低的运输成本),我们多绕几圈路径就会更短,节点1 -> 节点2 -> 节点3 -> 节点1 -> 节点2 -> 节点3 -> 节点4,这样的路径总成本 (-1) + 1 + (-1) + (-1) + 1 + (-1) + 1 = -1,我们就会发现如果在负权回路多绕两圈,三圈,无穷圈,那么我们的总成本就会无限小, 如果要求最小成本的话,你会发现本题就无解了。这就是我们需要判断是否存在图中是否存在负权回路的原因,如果如果遇到这样的最短路问题就会出现无解的情况。

       在bellman_ford算法中,松弛 n-1 次所有的边 就可以求得 起点到任何节点的最短路径,松弛 n 次以上,minDist数组(记录起到到其他节点的最短距离)中的结果也不会有改变 。而在有负权回路的情况下,一直都会有更短的最短路,所以松弛 第n次,minDist数组也会发生改变。其实我们就可以再多松弛一次,看minDist数组 是否发生变化。我们对所有边松弛了n-1次后,在松弛一次,如果出现minDist出现变化就判断有负权回路。其实这就可以判断了,如果使用 SPFA 那么节点都是进队列的,那么节点进入队列几次后 足够判断该图是否有负权回路呢?其实也是可以的,那么如果节点加入队列的次数 超过了 n-1次 ,那么该图就一定有负权回路。大家目前理解这一些就可以了。

今日总结

       我们今天讲解了最短路算法的优化算法SPFA算法和判断负权回路的方法,大家理解好理论基础就可以了,无需深究,大家可以等到有了扎实的基础之后再去深究和手撕代码,我们今天就讲解到这里,我们明天再见!

http://www.dtcms.com/wzjs/519148.html

相关文章:

  • 青岛cms模板建站免费网站java源码大全
  • 深圳网站建设服务哪家专业全网推广外包公司
  • 企业网站维护合同如何做好口碑营销
  • id创建网站360搜索首页网址是多少
  • wordpress网站防伪查询模板2345网址大全设主页
  • 青岛公司建设网站跨境电商哪个平台比较好
  • wordpress内容关键字seo专业技术培训
  • 网站的现状辽源seo
  • 企业信息门户网站建设方案海外广告联盟平台推广
  • 服装 营销型网站案例seo优化包括什么
  • 焦作网站建设活动软文模板
  • 有什么网站专门做美食的吗个人网页制作成品欣赏
  • 网站开源系统bt kitty磁力猫
  • 文字logo免费设计在线生成优化关键词步骤
  • 江苏专业做网站的公司免费推广的预期效果
  • 中国最厉害的室内设计师seo做什么网站赚钱
  • 做常识的网站动态网站的制作与设计
  • 怎样自己做卖商品的网站自助建站网
  • 一流的网站建设搜索引擎外部优化有哪些渠道
  • 深圳企业网站建设制作网络公司外贸网站设计
  • 叮当快药网站谁做的网站建设推广服务
  • 在深圳做网站平台需要什么备案怎么查询最新网站
  • 万能进销存软件免费版seo网站怎么优化
  • 网店代运营收费标准佛山优化网站关键词
  • 2015年做那个网站能致富台州关键词优化平台
  • 饭店营销方案怎样快速引客南宁百度关键词优化
  • 官方网站建设银行泰安做网站公司
  • 做网站卖酒广州seo和网络推广
  • 临沂企业自助建站系统可以免费发广告的网站有哪些
  • 佛山 做网站公司有哪些网络营销成功案例介绍