【发布时间】:2017-05-05 19:33:49
【问题描述】:
我尝试使用两个自定义顶点结构和它们的边为我的自定义图编写 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 的最佳距离应该返回为 160 (A->C->F->G),但代码返回 280,即 (A->C->G) .我可以提供我的添加和连接功能,但我确信它们工作正常。
【问题讨论】:
-
Dijkstra 的算法运行良好,并且总是做出正确的选择。是你的错误实现算法不起作用。
-
创建一个有两个节点的测试用例,看看它是否返回正确的值。然后 3...
-
@MikeNakis 是的,你是真的,对不起我的英语不好。目前我对 Dijkstra 的实现很糟糕。
-
@stark :大多数测试用例都可以正常工作,除非 Vertex 有两个或更多输入。在那种情况下,到达该顶点的任何方式都设置为最佳距离,我猜无论每条边的权重是多少
-
天哪!你找到了一些东西。现在使用调试器或添加打印语句来找出问题所在。
标签: c++ algorithm queue graph-algorithm dijkstra