【问题标题】:Dijkstra’s Algorithm problems with backtracing vertexes回溯顶点的 Dijkstra 算法问题
【发布时间】:2014-10-20 06:24:07
【问题描述】:

我正在尝试对访问的顶点进行回溯,以获取到顶点的成本最低的路线。我得到不正确的结果,不明白为什么。唯一正确的输出是图像中的最后一个。不正确的原因是什么

注意:driverMap 是一个 2D 14x14 整数向量,它保存到达每个顶点所需的距离,而 path 是一个 int 数组,用于保存过去路径顶点。开头是我的 Main 函数中的一段代码来帮忙。

这是不同的,因为我以前的问题不同,这一次我在尝试回溯时寻求有关我当前输出的帮助。

for(int i = 0; i < allCars.size(); i++) //allCars.size()

{

    int startInt = allCars[i].getStart(), loopEnder = 0;



    for(int k = 0; k < driverMap.size(); k++)
    {
        path[k] = 0;
        Distances[k] = 0;
    }


    for(int j = 0; j < driverMap.size(); j++) 

    {

        Distances[j] = driverMap[startInt][j];

    }

    cout << "\nSTART INTERSECTION: '" << startInt << "' END INTERSECTION: '" << allCars[i].getEnd() << "'" <<  endl;


    Dijkstra(driverMap, Distances, path, startInt);

    int endInt = allCars[i].getEnd(), atInt = path[endInt];

    cout << "END = " << endInt;

    //allCars[i].addPath(endInt);
    do
    {
        cout << "AT = " << atInt;
        allCars[i].addPath(atInt);
        atInt = path[atInt];
        loopEnder++;
    }while(atInt != endInt && loopEnder < 5);
    cout << endl;

    //allCars[i].addPath(startInt);


    allCars[i].displayCar();

}

void Dijkstra(const vector< vector<int> > & driverMap, int Distances[], int path[], int startInt) 
{
    int Intersections[driverMap.size()];
    for(int a = 0; a < driverMap.size(); a++)
    {
        Intersections[a] = a;
    }
    Intersections[startInt] = -1;

    for(int l = 0; l < driverMap.size(); l++)
    {
        int minValue = 99999;

        int minNode = 0;




        for (int i = 0; i < driverMap.size(); i++) 

        {

            if(Intersections[i] == -1) 

            {

                continue;

            }

            if(Distances[i] > 0 && Distances[i] < minValue)

            {

                minValue = Distances[i];

                minNode = i;

            }

        }


        Intersections[minNode] = -1;





        for(int i = 0; i < driverMap.size(); i++) 

        {

            if(driverMap[minNode][i] < 0)

            {

                continue;

            }

            if(Distances[i] < 0) 

            {

                Distances[i] = minValue + driverMap[minNode][i];
                path[i] = minNode;

                continue;

            }

            if((Distances[minNode] + driverMap[minNode][i]) < Distances[i]) 

            {

                Distances[i] = minValue + driverMap[minNode][i];
                path[i] = minNode;

            }

        }
    }

}

【问题讨论】:

  • 问题是……?
  • 在计算到顶点的最小距离时,我需要存储访问过的正确顶点。我试过了,但现在不知道该怎么做。

标签: c++ algorithm dijkstra backtracking


【解决方案1】:

在 djikstra 中进行回溯

  1. 记录更新当前节点值较小的节点

    // Every time you update distance value with a smaller value
    Distances[i] = minValue + driverMap[minNode][i];
    back[i] = minNode;  //Record the node with an int array, should be something like this
    
  2. 在完成所有 djikstra 循环之后。从起点以外的任何点回溯。 比如说,我们想在您的图中从 pt 5 跟踪到 pt 0,其中 pt 5 是起点。我们从0开始,取回[0](应该等于4),然后我们取回[4](应该等于8),然后我们取回[8](应该等于5),然后我们应该有一些各种机制在这里停止,因为 pt 5 是一个起点。结果,你得到 0-4-8-5 并且你颠倒了顺序。你得到路径 5-8-4-0。

在我的方法中,pathTaken[minNode].push_back(i); 没有使用。对于连接到起点的人,您可能需要使用起点值启动 int 数组 back[]。


编辑部分

您错过了重点:“对于连接到起点的人,您可能需要使用起点值启动 int 数组 back[]”。

path[k] = 0; 是错误的。您不应该在所有情况下都使用固定索引启动路径。 相反,您应该使用 startInt(对于直接连接到起始节点的那些)和不存在的节点索引 -1(对于那些不直接连接到起始节点的那些)启动

回溯是做什么的

  1. 记录哪个节点为当前节点提供了新的最小成本(并在 dijkstra 循环中不断更新)。最后,每个节点都会得到一个节点值(在我的例子中是back[i]),它指向一个节点,该节点为节点 i 提供了最小的成本。
  2. 基于带回溯的dijkstra算法的概念,back[i]是从起始节点到节点i的路径中的前一个节点。这意味着路径应该是这样的:

    (start node)->(path with zero or more nodes)->node point by back[i]-> node i
    

应用这个概念,我们可以用 back[i], back[back[i]], back[back[back[i]]],... 跟踪路径。

为什么path[k] = 0; 错了?在您的代码中,您的起始节点并不总是节点0,而是 startint。考虑像@​​987654328@ 这样的情况,您的目标目标节点是11。显然,路径是13-11。对于节点11,在您的编码中startint = 13 时永远不会遇到Distances[i] = minValue + driverMap[minNode][i];,因为这是第一个最小成本节点。你设置了什么?节点11 具有back[11]=0 (初始化),它表明路径节点1311 中的前一个节点是节点0,这在概念上显然是不正确的,并且返回[0]=0(最佳路径来自13 到 0 是 13-0,也没有更新),它将作为 0=back[back[0]]=back[back[back[0]]]=... 循环到自身。

【讨论】:

  • 谢谢,总是它访问的第一个节点总是在索引0处
  • @JacksonCollins 不,pt 0 仅作为示例。要访问的第一个点是您想要的终点。您可以从您想要的任何端点回溯,起点除外。例如,我想要从 pt 5 到 pt 8 的路径,我可以从 8 开始并收回 [8]。不必总是从 0 点开始。
  • 嘿,我遇到了逻辑错误。输出不正确,我应该只编辑帖子并显示我的问题吗?
  • @JacksonCollins 请在一篇文章中提出一个具体问题,除非该问题与答案相关。
  • @JacksonCollins 看看我的帖子。 “对于连接到起点的人,您可能需要使用起点值启动 int 数组 back[]”。 path[k] = 0; 是错误的。您不应该为所有情况启动具有固定索引的路径。相反,您应该使用 startInt(对于那些直接连接到起始节点的那些)和不存在的节点索引 -1(对于那些不直接连接到起始节点的那些)启动
【解决方案2】:

在 djikstra 中,如果您向后退(芬兰语 -> 开始),只需在每一步选择成本最低的节点即可到达起点。这在您解决了图表并且您对每个节点进行了评估/计算后才有效。

【讨论】:

  • 我不知道该怎么做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-09
  • 1970-01-01
  • 2014-06-20
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多