【问题标题】:dijkstra algorithm incorrect conditionaldijkstra 算法不正确的条件
【发布时间】:2017-11-26 09:22:52
【问题描述】:

我正在研究使用优先级队列的 dijkstra 算法。我一直在做很多研究,我认为我的代码遵循了算法,但是在比较最短路径时我无法进入条件

    void dijkstra( int startingID ) {

        priority_queue<Vertex*, vector<Vertex*>, PathWeightComparer> dijkstra_queue{};
        vector<Vertex*> vert;
        vert = _vertices;
        int n = vert.size();
        vector< double > dis(n);

        for (int i = 0; i < n; i++)
        {
            dis[i] = std::numeric_limits< double >::infinity();
        }
        vert[startingID]->setPathWeight(startingID);
        dis[startingID] = 0;
        Vertex* temp = vert[startingID];
        dijkstra_queue.push(temp);


        while (!dijkstra_queue.empty())
        {
            double dist = dijkstra_queue.top()->getPathWeight();
            double u = dijkstra_queue.top()->getId();
            dijkstra_queue.pop();

            for (auto i : vert)
            {
                double v = i->getId();
                double weight = i->getPathWeight();
                double distance_total = dist + weight;
                cout << "distance_total " << distance_total << " dis[v] " << dis[v] << endl;
                if (distance_total < dis[v]) //PROBLEM
                {
                    dis[v] = distance_total;
                    Vertex* temp2 = i;
                    temp2->setPathWeight(dis[v]);
                    dijkstra_queue.push(temp2);
                }
            }
        }
    }
};

这是图形类

class Graph
{
    vector<Vertex*> _vertices;      // All vertices in the graph (vertex id == index)
    int _last_startingID = -1;

这里是顶点类

class Vertex
{
private:
    int _id;                    // ID (key) of given vertice
    bool _known = false;        // Dijkstra's algorithm "known" flag
    Vertex* _path = nullptr;    // Dijkstra's algorithm parent vertex pointer
        // Weight of path through graph - starts at a true infinity (inf)
    double _path_weight = std::numeric_limits<double>::infinity();

我尝试只包含仅与 dijkstra 函数相关的代码,但如果有任何不清楚的地方,我可以添加更多。

【问题讨论】:

  • 你试过使用调试器吗?
  • 我在 linux 终端上工作,所以我尽我所能打印出值,但我没有把这些值放在@EdHeal 的问题中
  • 我的理解是gdb在终端工作
  • 我还没有掌握多个文件的 gdb,在我的代码中为了在终端中运行它,你必须使用命令“make test”(在文件位置)(有一个Makefile),我不知道如何让这些东西在 gbd 中工作。 @EdHeal
  • 您需要使用-g 标志进行编译(如果我没记错的话)。然后阅读 gdb。这将是您一生中的几个小时,并且是您编写代码能力的完美工具

标签: c++ algorithm conditional dijkstra


【解决方案1】:

您的算法实现不正确。

在您从队列中pop() 顶点u 之后(因为它与源的距离是最低的),您应该只检查从u 可直接到达的顶点(即存在从u 到那个的边顶点)。

您当前的实现似乎正在遍历所有顶点,无论它们是否可以从u 直接到达,也许因此,您对距离计算做了一些奇怪的事情,这没有任何意义。更具体地说,您的实现中的distance_total 似乎毫无意义。

Dijkstra 算法背后的关键思想是:

dis[u] = must be shortest path from source to u since u was popped.
dis[v] = current_known_distance_to_v

Then, for all v where edge exists from u to v:
IF dis[u] + weight(u, v) < dis[v]:
    // going via u is better than the current best known distance to v
    dis[v] = dis[u] + weight(u, v)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    相关资源
    最近更新 更多