【问题标题】:Dijkstra's Algorithm - Infinite LoopDijkstra 算法 - 无限循环
【发布时间】:2015-12-05 05:50:05
【问题描述】:

作为家庭作业,我将使用指向每个顶点的链表的指针数组来实现邻接表。每个链表都有一个元素<destination>,表示邻接表顶点的顶点邻居。

邻接列表是无向且未加权的,因此我将所有权重视为 1。

 /* Adjacency List Node data structure (edge)
 * Linked List data structure for storing linked vertices
 */
struct adjacencyListNode
{
    int destination;
    struct adjacencyListNode *next;
};

/* Adjacency List Vertex data structure (vertex)
 * <AdjacencyList> consists of pointers to <n> adjacencyListVertex
 */
struct adjacencyListVertex
{
    struct adjacencyListNode *head;
};

我正在尝试在邻接列表上执行 Dijkstra 算法以找到从 s 到 t 的最小路径。

现在我正在实现以下算法:

/* Prints the length and path taken of the shortest path in adjacency list between s and t.
 *  Uses Dijkstra’s algorithm to compute shortest path.
 *  S: source vertex
 *  V: destination vertex
 */
void shortestPath(int s, int t) {
    int known[size]; // shortest distance to vertex is know
    int cost[size]; // distance from source <s> to each vertex
    int path[size]; //path

    // Initialization: Set all distances to infinity (represented by -1), since arrays have not been visited and graph is positively weighted
    for (int index = 0; index<size; index++) {
        cost[index] = INFINITY;
        known[index] = 0;
    }

    // Set distance from source->source to 0
    cost[s-1] = 0;

    // Starting at s, traverse towards all reachable unvisited verticies, visit it and repeat
    while (isFinished(known, size) == false) {
        // Select a vertex from list of unvisited nodes which has the smallest cost
        int cheapestVertex, cheapestValue = INFINITY+1;
        for (int costCheck = 0; costCheck<size; costCheck++) {
            if ((known[costCheck] == 0) && (cost[costCheck] < cheapestValue)) {
                // We found a cheaper unvisited vertex
                //                  cout << "Cheapest vertex: " << costCheck << endl;
                cheapestVertex = costCheck;
                cheapestValue = cost[cheapestVertex];
            }
            //              cout << "found? " << cheapestVertex << " " << cheapestValue << endl;
        }


        //          cout << "Cheapest vertex: " << cheapestVertex << endl;
        // For each unvisited neighbor of our cheapest (unvisited) vertex
        adjacencyListNode* iterator = A[cheapestVertex].head; // iterator is our first neighbor
        while (iterator)
        {
            // Calculate the new cost from the current vertex <cheapestVertex>
            if (cost[cheapestVertex]+1 < cost[iterator->destination] && known[iterator->destination] == 0) {
                cost[iterator->destination] = cost[cheapestVertex]+1;
            }
            iterator = iterator->next; // move to next neighbor, repeat
        }

        //          cout << "Cheapest vertex: " << cheapestVertex  << " known." << endl;
        // Mark the current vertex <cheapestVertex> as visited
        known[cheapestVertex] = 1;

        // DEBUG: (REMOVE BEFORE SUBMISSION)
        for (int i = 0; i<size; i++) {
            cout << "Vertex " << i << " : known? " << known[i] << ", cost? " << cost[i] << endl;
        }
        cout << endl;

        if (cost[t-1] != INFINITY) break; // We already know shortest path, end.
    }

    // We know the shortest path cost to t
    cout << "Cost to t: " << cost[t] << endl;
}

bool isFinished(int array[], int arraySize) {
    bool finished = true;
    for (int iterator=0; iterator < arraySize; iterator++) {
        if (array[iterator] == 0) {
            // vertex not known, we're not done.
            finished = false;
        }
    }
    return finished;
}

我正在传递以下输入,它只是添加了指定的相关顶点并调用我的最短路径算法。

0 1
1 2
1 3
2 4
3 5
5 38
6 7
6 10
8 9
11 12
12 13
12 15
12 21
13 14
14 15 
16 17
17 18
18 19
19 20
20 39
21 22
22 23
22 31
23 24
23 32
24 25
24 33
25 26
26 27
27 28
28 29
29 30
31 40
34 35
34 37
35 36
36 37
1
shortest-path

我的代码从0->1->2->3->4->5->38遍历,然后无限重复38。

有人知道我的问题出在哪里吗?

【问题讨论】:

  • 看来这种情况正在发生,因为在我到达顶点 38 后,没有未访问的顶点有成本。如果发生这种情况我该怎么办?

标签: c++ algorithm dijkstra


【解决方案1】:

您有一些问题。由于这是作业,我不会给你完整的答案。

问题 1:如果存在无法从 s 到达的节点会发生什么?这就是您的示例中发生的情况。

提示:您需要确定何时停止循环(除了您已有的循环)。查看您最便宜的选择 - 您如何确定没有有效的选择?

提示 #2 - 如果所有剩余顶点的成本为 INFINITE,则当前循环不会为 cheapestVertex 设置值,因此您将使用未初始化的值。也许在继续之前检查一下您找到的最便宜的费用是多少。

问题2:cost[iterator-&gt;destination] = cost[cheapestVertex]+1;

提示:您确定每次都这样做是正确的吗?如果节点已经有更便宜的成本,或者已经被访问过怎么办?

问题 3:一旦知道 t,就可以停止查找。无需检查整个图表。注意:这是您不一定需要的更改,因为您的代码没有它也可以工作。

【讨论】:

  • 我已经更新了我的答案,修复了问题 2 和 3。在我的分级测试用例中,永远不应该有从 s 到 t 的路径无法到达的情况,所以我会为这个作业节省时间并忽略它。不过建议很好!还有什么显而易见的吗?感谢您的帮助!
  • 看你的输入,除非我看错了,如果你从节点0开始,你只能到达1、2、3、4、5和38。所以如果t不在这些节点中,则无法访问。此外,即使t 可以访问,您之前的代码也不会停止查找。我将更新我的 #1 提示
  • 实际上,您从我下面更改了代码 - 使 cheapestValue 的值从 INFINITY + 1 开始应该可以工作,只要 INFINITY + 1 是一个有效的无符号整数并且不会溢出.
  • 是的,无穷大只分配给 9999。我还更改了 cost[s-1] = 0;成本[s] = 0;它解决了一个问题,即所有成本为 9999。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-26
  • 2015-04-19
  • 2020-01-20
  • 2015-10-03
相关资源
最近更新 更多