Dijkstra的回溯顶点算法问题

时间:2014-10-20 06:24:08

标签: c++ algorithm dijkstra backtracking

我正在尝试实现为最低成本路线到达顶点所访问的顶点的回溯。我得到的结果不正确,不明白为什么。唯一正确的输出是图像中的最后一个。导致错误的原因是什么

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

不同之处在于我以前的问题不同,这次我在寻求帮助时对我的当前输出求助,而不是在尝试回溯时。

enter image description here

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;

            }

        }
    }

}

Output result

2 个答案:

答案 0 :(得分:2)

在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),那么我们应该有一些在这里停止的各种机制,因为第5页是一个起点。结果,您得到0-4-8-5并且您撤销订单。你得到了路径5-8-4-0。

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


    修改零件

    你忽略了这一点:“对于那些连接到起点的人来说,你可能需要使用起始点的值来启动int数组[。]

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

    后退跟踪正在做什么

    1. 记录哪个节点为当前节点提供新的最小成本(并在dijkstra循环中继续更新)。最后,每个节点都会获得一个节点值(在我的情况下为back[i]),该节点值指向为节点i提供最小化Cost的节点。
    2. 基于具有反向跟踪的dijkstra算法的概念,back [i]是从起始节点到节点i的路径中的前一节点。这意味着路径应该是:

      (start node)->(path with zero or more nodes)->node point by back[i]-> node i
      
    3. 应用这个概念,我们可以用back [i],back [back [i]],back [back [back [i]]],......跟踪路径。

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

答案 1 :(得分:0)

在djikstra,如果你倒退(芬兰 - >开始),只需在每一步选择最低成本节点,以达到凝视点。在解决了图形并且每个节点都已评估/计算成本后,这将有效。