dijkstra算法和floyd算法是常用的两种路径规划算法,其中
dijkstra算法主要用于求起始点到任意一点的最短路径,时间复杂度为O(N^2)
floyd算法 主要用于求任意两点之间的最短路径, 时间复杂度为O(N^3)
上代码
dijkstra算法
// dijistra_folyd.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include<vector>
#include<iomanip>
using namespace std;
vector <vector<int>> dijkstra(vector<vector<int>>& nums,int n) {
vector<bool>used(n, false);//查看是否遍历过
vector<vector<int>>dis(n, vector<int>(2, INT_MAX));
//n*2的二维数组,下角标为目标点,第一列为价值,第二列记录上一个点是谁
// 如下所示,0到0价值为0,上一个点为空记录为-1
// 0到1价值为1,上一个点为0
// 0到2价值为2,上一个点为1
//0 0 -1
//1 1 0
//2 2 1
//3 2 1
dis[0][0] = 0;
dis[0][1] = -1;
int k = 0;
while(1) {
k = -1;
for (int j = 0; j < n; j++) {
if(!used[j]&&(k==-1|| dis[j][0] < dis[k][0]))//找到一个未遍历的值最小的点作为起始点
k=j;
}
if (k == -1) //全遍历过了,退出循环条件
break;
used[k] = true; //当前点记录已遍历
for (int i = 0; i < nums.size(); i++) {//遍历路径,找到头为当前节点的路径,看未节点的值是否更大
int head = nums[i][0], tail = nums[i][1], val = nums[i][2];
if (head == k&&dis[tail][0]>(dis[k][0]+val)) {
dis[tail][0]= dis[k][0] + val;
dis[tail][1]=head;
}
}
}
return dis;
}
int main()
{
//1.dijkstra
//求起始点到任意一点的最短路径
//一般为无向图
vector<vector<int>>nums{ {0,1,1}, {1,2,1}, {1,4,4}, {1,3,5}, {2,3,3}, {3,4,3} };
int n = 5;
vector<vector<int>> ans = dijkstra(nums, n);
cout << setw(5) << "目标点" << setw(5) << "花费" << " " << "上一个点" << endl;
for (int i = 0; i < ans.size();i++) {
cout << setw(5) <<i<< setw(5) << ans[i][0]<<setw(5) << ans[i][1] << endl;
}
}
floyd算法
// dijistra_folyd.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include<vector>
#include<iomanip>
using namespace std;
vector <vector<int>> floyd(vector<vector<int>>& nums, int n) {
vector <vector<int>>dis(n, vector <int>( n, INT_MAX));
//初始化,自己到自己都是0,然后把路径放进去
for (int i = 0; i < n; i++) {
dis[i][i] = 0;
}
for (int i = 0; i < nums.size(); i++) {
int head = nums[i][0], tail = nums[i][1], val = nums[i][2];
dis[head][tail] = val;
}
//迭代一下,更新图
for (int i = 0; i < n; i++) {
//从i中转看看有没有更短路径
for (int j = 0; j < n; j++) {
if (i == j) //从i中转不用看i,直接跳过
continue;
for (int k = 0; k < n; k++) {
if (k == i || k == j) //j->j,也不看
continue;
//找原本 j->k 的路径和现在 j->i->k 的路径,看哪个短
//栗子,1->2 和 1->0->2 比
dis[j][k] = min(dis[j][k], dis[j][i] + dis[i][k]);
}
}
}
return dis;
}
int main()
{
//2.floyd
//求任意一点到其他点的最短路径
//一般为又向图
vector<vector<int>>nums{ {0,1,6}, {0,2,13}, {1,2,4}, {1,0,10}, {2,0,5}};
int n = 3;
vector <vector<int>> ans = floyd(nums, n);
cout << " 0 1 2" << endl;
for (int i = 0; i < n; i++) {
cout << i << " ";
for (int j = 0; j < n; j++) {
cout << ans[i][j] << " ";
}
cout << endl;
}
}