Dijsktra解决的问题
迪杰斯特拉算法主要用于求解单源最短路径问题。
实现思路
- 为每个节点设定检查标记、记录最短路径和记忆最短路径。
- 从源头节点开始到最后一个节点记录,按权重从小到大遍历每一条路,将当前节点最短路与权重之和跟路指向的节点的最短路径判断,更新路指向的节点的最短路径和记忆最短路径。
- 选定下一个节点的关键判断是,检查标记和最短路径大小。选择最短路径最小和未检查过的节点。
- 重复第2、3步骤,直至遍历完所有图节点。
代码实现
class graph{
vector<graphNode> nodes;
...
}
class route{
graphNode orgin;
graphNode dest;
int weight;
...
}
class graphNode{
string nodeName;
vector<route> routes;
...
}
void Dijkstra(const graph& G, const graphNode& orgin, const graphNode& dest)
{
//check null
if(!orgin || !dest){
....
return;
}
//1、为每个节点声明检查标记和最短路径
map<graphNode&, bool> checkNodes;
map<graphNode&, int> minVal;
map<graphNode&, string> minPath;
for(const auto& ele: G){
checkNodes.insert(ele, false);
minVal.insert(ele, INT_MAX);
minPath.insert(ele, ele.nodeName);
}
//2、遍历每个节点
auto checkNode = getNextCheckNode(G, minVal, checkNodes);
while(checkNode != nullptr){
//遍历当前节点所有路径
sortPath(G);
for(const auto& ele : checkNode.routes){
if(minVal[checkNode] + ele.weight < minVal[ele.dest]){
minVal[ele.dest] = minVal[checkNode] + weight;
minPath[ele.dest] = minPath[ele.checkNode] + ele.dest.nodeName;
}
}
}
checNodes[checkNode] = true;
checkNode = getNextCheckNode(G, minVal, checkNodes);
}
void sortPath(const graph& G)
{
for(const auto& ele : G){
int size = ele.routes.size();
for(int i = 0; i<size-1; i++){
for(int j = i+1; j<size; j++){
if(ele.routes[i].weight > ele.routes[j].weight){
swap(ele.routes[i], ele.routes[j]);
}
}
}
}
}
graphNode& getNextCheckNode(const graph& G, const& map<graphNode&, int> minVal, const mao<grapgNode, bool>& checkNodes){
int size = G.nodes.size();
for(int i=0; i<size-1; i++){
for(int j=0; j<size; j++){
if(minval[G.node[i]] > minVal[G.nodes[j]]){
swap(G.nodes[i], G.nodes[j]);
}
}
}
for(const auto& ele : G.nodes){
if(checkNodes[ele] == false)
continue;
return ele;
}
return nullptr;
}