我的Dijkstra算法没有选择短路径
My Dijkstra algorithm's not choosing the shortes path
我尝试使用两个自定义的顶点结构及其边缘编码Dijkstra算法,并在我的自定义图中编码算法编码,但该算法编译了,但错误的选择选择了最佳距离。代码如下。
class Graph {
struct Edge;
struct Vertex {
std::string _data; //name of vertex
std::list<Edge*> _ins;
std::list<Edge*> _outs;
bool visited;
int BestDist;//best distance from source to sink
};
struct Edge {
int _weight;
Vertex *_from;
Vertex *_to;
bool travelled; //if the edge has been travalled
};
//Graph of String as key to Values as vertexes
std::unordered_map<std::string, Vertex *> _mainData;
//Dijkstra Algo
int BestDistance(std::string source, std::string sink) {
//to save vertexes names
std::queue<std::string> q;
//for each vertex set dist and path to infinity
for (auto startItr : _mainData)
{
startItr.second->BestDist = Max;
startItr.second->visited = false;
for (auto kachal : startItr.second->_outs)
{
kachal->travelled = false;
}
}
//set source distacne to 0 sicen it is visiting itself
_mainData[source]->BestDist = 0;
q.push(source);
//while there is unknown distance vertex and we havent reach sink yet
while (!q.empty() )
{
//smallest unknow distance vertex
std::string currentVer = q.front(); q.pop();
//set that vertex to visited
_mainData[currentVer]->visited = true;
//for each vertex adj to current vertex
for (auto adjVer : _mainData[currentVer]->_outs) {
//if that vertex is not visted
if (!adjVer->travelled) {
int cvw = adjVer->_weight; //cost of edge from cuurent vertex to adj vertex
//if current vert.distance +cvw < adj vertex distance
if (_mainData[currentVer]->BestDist + cvw < _mainData[adjVer->_to->_data]->BestDist) {
//update adj vertex
q.push(adjVer->_to->_data);
//deacrease adj vertex distacne to current distacne + cvw
_mainData[adjVer->_to->_data]->BestDist = _mainData[currentVer]->BestDist + cvw;
//marked the travlled edge true
adjVer->travelled = true;
}
}
}
}
return _mainData[sink]->BestDist;
}
这是我的主要:
#include "stdafx.h"
#include "Graph.h"
#include <iostream>
int main()
{
Graph myGraph;
myGraph.Add("A");
myGraph.Add("B");
myGraph.Add("C");
myGraph.Add("D");
myGraph.Add("E");
myGraph.Add("F");
myGraph.Add("G");
myGraph.Connect("A", "B",20);
myGraph.Connect("A", "C",30);
myGraph.Connect("B", "D",200);
myGraph.Connect("C", "F",100);
myGraph.Connect("C", "G",200);
myGraph.Connect("D", "E",50);
myGraph.Connect("E", "F",1);
myGraph.Connect("F", "G",30);
std::cout << "best distacne example : " << myGraph.BestDistance("A", "G");
因此,当我运行代码时,从a到g shoudl的最佳距离返回为160(a-> c-> f-> g(,但是代码返回280,即(a-> c-> g(。我可以提供我的添加和连接功能,但我确定它们正常工作。
因此,在上述算法分析后,我意识到我的错误是将每个边缘都标记为行进是否被旅行,并基于此做出决定。我应该做的是标记每个顶点是否被访问。其余的还可以。因此,这是我实现Dijkstra算法的正确版本,找到了一个正加权图中的最短路径。希望它有帮助
//Dijkstra Algo
int BestDistance(std::string source, std::string sink) {
//to save vertexes names
std::queue<std::string> q;
//for each vertex set dist and path to infinity
for (auto startItr : _mainData)
{
startItr.second->BestDist = Max;
startItr.second->visited = false;
}
//set source distacne to 0 sicen it is visiting itself
_mainData[source]->BestDist = 0;
q.push(source);
//while there is unknown distance vertex and we havent reach sink yet
while (!q.empty() )
{
//smallest unknow distance vertex
std::string currentVer = q.front(); q.pop();
//set that vertex to visited
_mainData[currentVer]->visited = true;
//for each vertex adj to current vertex
for (auto adjVer : _mainData[currentVer]->_outs) {
//if that vertex is not visted
if (!adjVer->_to->visited) {
int cvw = adjVer->_weight; //cost of edge from cuurent
//vertex to adj vertex
//if current vert.distance +cvw < adj vertex distance
if (_mainData[currentVer]->BestDist + cvw <
_mainData[adjVer->_to->_data]->BestDist) {
q.push(adjVer->_to->_data);
//deacrease adj vertex distacne to current distacne + cvw
_mainData[adjVer->_to->_data]->BestDist = _mainData[currentVer]->BestDist + cvw;
//setting the path of adj vertext to his previous one
_mainData[adjVer->_to->_data]->path = _mainData[currentVer];
}
}
}
}
return _mainData[sink]->BestDist;
}
相关文章:
- 有选择地禁用第三方库的C++核心准则检查器
- 有选择地禁用库中的死代码消除
- C++,有选择地应用模板模式来发挥作用
- 使用 SFINAE 有选择地实例化模板的成员函数
- 有选择地隐藏类成员的成员
- 有选择地启用一个并行区域内的OpenMP进行循环
- 有选择地对向量 c++ 进行排序
- 有选择地替换 C++ 中 std::string 中的 (") 双引号
- 我可以在代码库中有选择地禁用RTTI以减少二进制尺寸
- 如何有选择地从缓冲区读取数据
- 有选择地覆盖模板化类的函数
- 有选择地编译框架C++的方法
- 运算符 = 重载C++有选择地工作
- 有选择地内联函数(用于调试目的)
- C++创建进程 - 系统错误#2找不到文件 - 我的文件路径有什么问题?
- 我可以使用 SFINAE 有选择地定义模板类中的成员变量吗?
- 在空格上有选择地分割字符串
- 如何*有选择地*修改由随机数生成的多维数组?
- 在Java中使用SWIG,我如何有选择地SWIG一个巨大的C/ c++头文件的某些部分
- Qt:有选择的项目出现在QGraphicsScene顶部