博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Coursera algorithm II PA4
阅读量:6969 次
发布时间:2019-06-27

本文共 2851 字,大约阅读时间需要 9 分钟。

题意:

所给数据中是否有负环? 没有负环的图中所有路径中最短的值

思路:

1. bellmanford 判断负环

2. flodyWarshall 求所有定点的最短路径

细节:

1. bellmanford 算法时间复杂度为 o(n^3), 因为图的使用邻接矩阵存储的,  使用邻接表代码会容易理解些, 引用 wiki 的伪代码

123456
// 步骤2:重复对每一条边进行松弛操作   for i from 1 to size(vertices)-1:       for each edge (u, v) with weight w in edges:           if distance[u] + w < lt; distance[v]:               distance[v] := distance[u] + w               predecessor[v] := u

每次收缩至少能够使一个点达到其最小距离, 最差的情况就是 1 -> 2 ->…n, 需要 n-1 次才能收缩完毕

2. 负环判断. bellmanford 算法运行完毕后, 所得的结果应当是最终解, 除非有负环. 因此, 运行完 bellmanford 算法后, 再进行一次对所有收缩,若 dist 的值发生了变化(变小), 则说明出现了负环.
3. flodyWarshall算法:

设D_{i,j,k}为从i到j的只以(1..k)集合中的节点为中间节点的最短路径的长度。

若最短路径经过点k,则D_{i,j,k}=D_{i,k,k-1}+D_{k,j,k-1};
若最短路径不经过点k,则D_{i,j,k}=D_{i,j,k-1}。
因此,D_{i,j,k}=\mbox{min}(D_{i,k,k-1}+D_{k,j,k-1},D_{i,j,k-1})。
在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维

 

4. 动态规划算法第一件事就是要把最外层的循环变量确定, 确定的方式就是看状态转移方程的变化变量
5. 空间降维的方法. 先不考虑降维不降维的问题, 用笔画图模拟出矩阵或数组中的某一个值是由哪些导出的(在我后来做题中, 发现有新值是由通过request旧值更新, 如floydwarshell, 而也有一些dp的题目, 新值是通过旧值push更新的, 比如 poj 棋盘问题). 根据值的导出顺序来判断如何设置循环变量的遍历顺序(从大到小或从小到大)以使用滚动数组或滚动矩阵
6. 数学之美有一个小节讲到 google map 寻找城市之间的最短路径, 使用的就是 floydwarshell 算法

Submit original work, copying violates the class Honor Code

 

int bellmanford(int path[], int dist[], int verNum, int edge[][maxVertex], int src) {
// init array path and dist for(int i = 0; i < lt; verNum; i ++) {
path[i] = src; dist[i] = edge[src][i]; }  for(int i = 1; i < verNum; i ++) {
// 收缩 for(int j = 0; j < verNum; j++) {
if(j == src) continue; for(int k = 0; k < verNum; k ++) {
if(edge[k][j] < inf && dist[k] < inf && dist[k] + edge[k][j] < dist[j]) {
path[j] = k; dist[j] = edge[k][j] + dist[k]; } } } } for(int i = 0; i < verNum ; i++) {
cout << dist[i] << " "; } cout << endl; dist[src] = 0; // check if exists a negative cycle for(int i = 0; i < verNum; i++) {
for(int j = 0; j < verNum; j ++) {
if(edge[j][i] < inf && dist[j] < inf && dist[j] + edge[j][i] < dist[i]) return 0; } } return 1;}
int flodyWarshall(int dist[][maxSize], int path[][maxSize], int edge[][maxSize], int verNum) {
for(int i = 0; i < verNum; i++) {
for(int j = 0; j < verNum; j ++) {
if(i == j) {
dist[i][j] = 0; }else {
dist[i][j] = edge[i][j]; } } } for(int k = 0; k < verNum; k ++) {
for(int i = 0; i < verNum; i ++) {
for(int j = 0; j < verNum; j++) {
if(dist[i][j] > dist[i][k]+dist[k][j]) {
dist[i][j] =dist[i][k]+dist[k][j]; path[i][j] = k; } } } } int minDist = 9999999; for(int i = 0; i < verNum; i ++) {
for(int j = 0; j < verNum; j ++) {
if(dist[i][j] < minDist) minDist = dist[i][j]; } } return minDist;}

转载于:https://www.cnblogs.com/zhouzhuo/p/3758246.html

你可能感兴趣的文章
ijkplayer如何使用FFmpeg 4.0内核?
查看>>
HBase2.0中的Benchmark工具 — PerformanceEvaluation
查看>>
基于 Docker 打造前端持续集成开发环境
查看>>
[case1]记一次spring schedule异常
查看>>
五分钟了解微服务
查看>>
Android从零开始(第四篇)网络框架MVP+Retrofit+Rxjava
查看>>
Android逆向从未如此简单
查看>>
从Android Studio 开始的ARCore之旅
查看>>
Android轮播图控件CustomBanner的使用讲解
查看>>
让你在服务器上顺风顺水——linux常用命令
查看>>
[iOS] [OC] NSNotificationCenter 进阶及自定义(附源代码)
查看>>
Python logging 库的『完整教程』
查看>>
springboot -- 2.0版本自定义ReidsCacheManager的改变
查看>>
应用层,了解一下
查看>>
Failed to execute aapt
查看>>
创建个人cocopods集合(仅供参考)
查看>>
OAuth2.0认证授权workflow探究
查看>>
《Android Security Internals》第二章权限翻译
查看>>
笔者介绍
查看>>
spring-cloud Sleuth
查看>>