具体介绍见:https://en.wikipedia.org/wiki/Yen%27s_algorithm
还有具体步骤见:https://blog.csdn.net/sharpdew/article/details/446510?tdsourcetag=s_pctim_aiomsg
我也不知道我对这个算法理解是否完全正确,但是大体的数据结构和逻辑是正确的,希望大家指点,后期我更理解了,会做相应修改。
在这个算法里需要改进的地方是:我没有用堆去插入,这个等有时间再做
#include<vector>
#include<string>
#include<math.h>
#include<algorithm>
#include <iostream>
#include<stack>
using namespace std;
static const unsigned int INF(std::numeric_limits<int>::max());
static const unsigned undefined = INF;
class K_Shortest_Path {
public:
vector<vector<unsigned int>> run(
const unsigned int kPath, // K Path
const vector<vector<unsigned int>>& NW, // network
const unsigned int src, // source node
const unsigned int dst); // destination node
};
//
//结构体用于保存两点之间的最短路径和长度
//
class DijPath
{
public:
vector<unsigned int> onePath;
int cost;
bool operator <(const DijPath &n2);
//判断两条路径是否相等
bool operator ==(const DijPath &n2);
};
bool DijPath::operator <(const DijPath &n2)
{
return cost < n2.cost;
}
//判断两条路径是否相等
bool DijPath::operator ==(const DijPath &n2)
{
if (onePath.size() == n2.onePath.size())
{
for (unsigned int i = 0; i < onePath.size(); i++)
{
if (onePath[i] != n2.onePath[i])
return false;
}
return true;
}
return false;
}
//
//最短路径算法,返回一个DijPath结构体
//
DijPath dijkstra(
const vector<vector<unsigned int>> &NW,
const int src,
const int dst
)
{
//图中节点个数
unsigned int sizeNW = NW.size();
//知道每一个节点都被访问过结束
vector<bool> visited(sizeNW);
//到达dst顶点的最短路径的前一个顶点
vector<unsigned int> prev(sizeNW);
//下一个距离当前访问过的最小的一个点
int minPos = 0;
//用于记录每个顶点到源节点的距离,如果最终len[dst]=INF,
//说明src和dst不可到达,讲cost设置为INF,用于ksp做判断舍弃这条路径
vector<unsigned int> len(sizeNW);
for (unsigned int i = 0; i < NW.size(); i++) //初始化
{
visited[i] = false; //一开始均被访问
len[i] = NW[src][i];
prev[i] = INF;
}
//初始节点被设置为访问过
visited[src] = true;
for (unsigned int i = 0; i < sizeNW; ++i)
{
unsigned int min = INF; //记录访问过的节点到没访问过的节点的最小路径长度
for (unsigned int j = 0; j < sizeNW; ++j)
{
if (!visited[j] && min > len[j])
{
minPos = j; //记录找到了下一个节点
min = len[j];
}
}
visited[minPos] = true;
for (unsigned int j = 0; j < sizeNW; ++j)
{
//如果j节点没有被访问过,且通过j节点发现到其他节点更短的len[j]值
if (!visited[j] && len[j] > (len[minPos] + NW[minPos][j]))
{
prev[j] = minPos;
len[j] = len[minPos] + NW[minPos][j];
}
}
}
unsigned int beforeVertex = dst;
//通过一个栈将prev[]中的节点给倒过去,实现正序排列
stack<unsigned int> st;
while (prev[beforeVertex] != IN