使用 Dijkstra 算法计算两个节点之间的最短路径

Posted

技术标签:

【中文标题】使用 Dijkstra 算法计算两个节点之间的最短路径【英文标题】:Using Dijkstra algorithm to compute shortest path between two nodes 【发布时间】:2017-03-20 02:46:39 【问题描述】:

我是 C++ 新手。我正在尝试使用 Dijkstra 算法计算从节点 start 到节点 end 的路径。我很确定我正在以正确的方式计算最短路径,但由于某种原因,我无法将其存储在我的 traceBack 向量中。如果有人能帮助我在这里指出我的错误,那将非常有帮助。 我的函数描述和计算最短路径的部分代码如下:

函数find_connected_nodes(int x) 仅返回连接到给定节点的节点。 函数find_travel_time(int x, int y) 返回从 x 到 y 的时间。

void dijkstra(int start, int end) 
    vector <unsigned> visited(getNumberOfNodes(), 0);
    vector <double> time_weight(getNumberOfNodes(), 99999); //99999 to represent not connected

    int inNode = start, pathNode = _end, nextnode = 0;
    double min; //will use min to compare time between edges
    vector<unsigned> traceBack(getNumberOfNodes(), inNode); //traceBack to contain the path from start to end



    time_weight[inNode] = 0;
    visited[inNode] = 1;


    vector<unsigned> x = find_connected_nodes(start);
    if (!x.empty()) 
        for (unsigned i = 0; i < x.size(); i++) 
            time_weight[x[i]] = find_travel_time(start, x[i]));
        
    

    for (int i = 0; i < getNumberOfNodes(); i++) 
        min = 99999;
        for (int j = 0; j < x.size(); j++) 
            if (min > time_weight[x[j]] && visited[x[j]] != 1) 
                min = time_weight[x[j]];
                nextnode = x[j];
            

        
        visited[nextnode] = 1;
        for (int j = 0; j < x.size(); j++) 
            if (visited[x[j]] != 1) 

                if (min + find_travel_time(nextnode, x[j]))<time_weight[x[j]]) 
                    time_weight[x[j]] = min + find_travel_time(nextnode, x[j]));
                        traceBack[x[j]] = nextnode;
                    
            
        
        x = find_connected_nodes(nextnode);
    

    int j;

    cout << "Path = " << pathNode;
    j = pathNode;
    do 
        j = traceBack[j];
        cout << "<-" << j;
     while (j != inNode);

【问题讨论】:

嗨!如果您发布 MCVE,我们将能够为您提供更好的答案:只需足够的代码来编译和重现问题。这可能意味着您的标题、您的库函数和最小的main()。但是,这里的一个主要问题是您永远不会返回任何计算!您将结果存储在一个临时对象中,当您的函数返回时该对象会被销毁。如果要返回visited,请将函数的返回类型从void 更改为vector&lt;int&gt;,并将return visited; 放在末尾。使用const vector&lt;int&gt; distances = dijkstra( start, end );调用函数。 【参考方案1】:

不是您问题的完整解决方案,因为这是家庭作业,您需要自己解决,但这里有一个示例说明如何解决您正在处理的同类设计问题:

#include <cstdlib>
#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::size_t;

std::vector<double> map_squares( const std::vector<double>& inputs )
/* Maps the square function onto the inputs.  That is, returns a vector whose
 * elements are the squares of the input elements.
 */

  const size_t size = inputs.size(); // The number of inputs, and outputs.
  std::vector<double> outputs(size); // We will return this.
 /* (Actually, we will return a copy of the vector, and then the compiler will
  * optimize the copy so it doesn't have to copy every element, just a single
  * reference to the data in the vector.  You'll learn more about how that
  * works, and how to write classes like that yourself, in due time.)
  */

  for ( size_t i = 0; i < size; ++i ) 
    outputs[i] = inputs[i]*inputs[i];
  

  outputs.shrink_to_fit(); // Maybe save a few bytes of memory.

  return outputs;


std::ostream& operator<<( std::ostream& os, const std::vector<double>& v )
// Boilerplate to serialize and print a vector to a stream.

  const size_t size = v.size();

  os << '[';
  if (size > 0)
    os << v[0];

  for ( size_t i = 1; i < size; ++i )
    os << ',' << v[i];

  os << ']';
  return os;


int main(void)

  // Out inputs:
  const std::vector<double> raw_numbers = 4,2,1,0.5,0.25;
  // Our results:
  const std::vector<double> squares = map_squares(raw_numbers);
  // Output: "[16,4,1,0.25,0.0625]"
  cout << squares << endl;
  return EXIT_SUCCESS;

【讨论】:

以上是关于使用 Dijkstra 算法计算两个节点之间的最短路径的主要内容,如果未能解决你的问题,请参考以下文章

四大算法解决最短路径问题(Dijkstra+Bellman-ford+SPFA+Floyd)

寻找包含两个节点的最短循环

最短路径算法:Dijkstra算法

最短路径算法:Dijkstra算法

Dijkstra算法求单源最短路径

迪杰斯特拉Dijkstra算法介绍