所以这是我当前的代码,我将发布下面的标题声明......
// Using Dijkstra's
int Graph::closeness(string v1, string v2){
int edgesTaken = 0;
unordered_map<string, bool> visited;
unordered_map<string, int> distances;
string source = v1; // Starting node
while(source != v2 && !visited[source]){
// The node has been visited
visited[source] = 1;
// Set all initial distances to infinity
for(auto i = vertices.begin(); i != vertices.end(); i++){
distances[i->first] = INT_MAX;
}
// Consider all neighbors and calculate distances from the current node
// & store them in the distances map
for(int i = 0; i < vertices[source].edges.size(); i++){
string neighbor = vertices[source].edges[i].name;
distances[neighbor] = vertices[source].edges[i].weight;
}
// Find the neighbor with the least distance
int minDistance = INT_MAX;
string nodeWithMin;
for(auto i = distances.begin(); i != distances.end(); i++){
int currDistance = i->second;
if(currDistance < minDistance){
minDistance = currDistance;
nodeWithMin = i->first;
}
}
// There are no neighbors and the node hasn't been found yet
// then terminate the function and return -1. The nodes aren't connected
if(minDistance == INT_MAX)
return -1;
// Set source to the neighbor that has the shortest distance
source = nodeWithMin;
// Increment edgesTaken
edgesTaken++;
// clear the distances map to prepare for the next iteration
distances.clear();
}
return edgesTaken;
}
声明(这是一个无向图):
class Graph{
private:
// This holds the connected name and the corresponding we
struct EdgeInfo{
std::string name;
int weight;
EdgeInfo() { }
EdgeInfo(std::string n, int w) : name(n), weight(
};
// This will hold the data members of the vertices, inclu
struct VertexInfo{
float value;
std::vector<EdgeInfo> edges;
VertexInfo() { }
VertexInfo(float v) : value(v) { }
};
// A map is used so that the name is used as the index
std::unordered_map<std::string, VertexInfo> vertices;
注意:请不要建议我更改标题声明,我正在为一个已经编写了8个其他函数的项目做出贡献,而且回过头来改变任何东西肯定为时已晚,因为其他所有函数都会必须重写
我目前得到的输出不正确。该函数正确处理0距离情况(如果两个顶点未连接,则函数应返回-1)。如果两个节点是相同的顶点(“波士顿”,“波士顿”),则该函数应返回0.
示例图
左侧的以下两个顶点的接近程度将在右侧:
Correct:
Trenton -> Philadelphia: 2
Binghamton -> San Francisco: -1
Boston -> Boston: 0
Palo Alto -> Boston: -1
Output of my function:
Trenton -> Philadelphia: 3
Binghamton -> San Francisco: -1
Boston -> Boston: 0
Palo Alto -> Boston: 3
我试图复制dijkstra的确切描述方式,但我得到的读数不正确,我一直试图解决这个问题 - &gt;有人能指出我正确的方向吗?
答案 0 :(得分:1)
这肯定不是问题的真正答案(因为我没有指出你关于你的实现的方向),但你是否考虑过只使用Boost Graph库? / p>
归结为为你的图形结构编写一个简短的Traits类(因此没有必要改变你的图形定义/标题),并且 - 至少对于这些基本算法 - 被证明是稳定且正确的。 / p>
我总是建议不要重新发明轮子,特别是在图形和数字方面......
答案 1 :(得分:0)
Palo Alto的问题 - &gt;波士顿似乎是算法采用路由Palo Alto -> San Fransisco -> Los Angeles -> San Fransisco
(edgesTaken = 3)然后失败,因为San Fransisco已经被访问了。
答案 2 :(得分:0)
您的实施是错误的,只有偶然的机会才能获得“正确”的结果。
让我们手工做一个例子。从特伦顿到费城。我使用城市的第一个字母作为标签。
First iteration
visited = [(T, 1), (N, 0), (W, 0), (P, 0), (B, 0)]
minDistance = 3;
nodeWithMin = N;
edgesTaken = 1
second iteration
visited = [(T, 1), (N, 1), (W, 0), (P, 0), (B, 0)]
minDistance = 2;
nodeWithMin = W;
edgesTaken = 2
third iteration
visited = [(T, 1), (N, 1), (W, 1), (P, 0), (B, 0)]
minDistance = 2;
nodeWithMin = N;
edgesTaken = 3;
fourth iteration
N is already 1 so we stop. Can you see the errors?
传统上Dijkstras最短路径算法是使用优先级队列
实现的dijkstra(graph, source)
weights is a map indexed by nodes with all weights = infinity
predecessor is a map indexed by nodes with all predecessors set to itself
unvisited is a priority queue containing all nodes
weights[source] = 0
unvisited.increase(source)
while unvisited is not empty
current = unvisited.pop();
for each neighbour to current
if weights[current] + edge_weight(current, neighbour) < weights[neighbour]
weights[neighbour] = weights[current] + + edge_weight(current, neighbour)
unvisited.increase(neighbour)
predecessors[neighbour] = current
return (weights, predecessors)
你可以通过跟随前辈来获得路径长度。