当前位置: 首页 > 知识库问答 >
问题:

Dijkstra算法不起作用

隆长卿
2023-03-14

我正在为一个学校项目创建一个游戏,我想将Dijkstra的算法作为AI的一部分,用于玩家需要躲避的对象。

所以我有一个图(一个邻接矩阵),我想使用Dijkstra来获得从每个对象到玩家的路径,但是现在当我调用算法时,如果玩家在对象之后,它将不会找到玩家。

在我的理解中,Dijkstra的算法应该访问所有节点,直到它找到目的地,但在我的情况下没有。

到目前为止,我的算法是这样的:

Node* Graph::DijkstrasAlgorithm(Node* sNode, Node* dNode){
    std::cout<<"Hello Dijkstra!!"<<std::endl;
    for(unsigned int i = 0; i < this->nodeList.size(); ++i){
        nodeList.at(i)->setDistance(INT_MAX);
        nodeList.at(i)->setVisited(false);
    }
    std::cout<<"everything is set"<<std::endl;
    sNode->setDistance(0);
    int numberVisited = 0;
    Node* u = new Node();
    std::cout<<"before while lus"<<std::endl;
    while(numberVisited < numberOfNodes){
        u->setDistance(INT_MAX);
        for(unsigned int j = 0; j < this->nodeList.size(); ++j){
            if((u->getDistance() > this->nodeList.at(j)->getDistance()) && !this->nodeList.at(j)->isVisited() ){
                u = this->nodeList.at(j);
                u->setVisited(true);
                numberVisited++;
            }
        }

    std::cout<<u->getNodeName()<<"=="<<dNode->getNodeName()<<std::endl;
        if((u == dNode) || (u->getDistance() == INT_MAX)){
            std::cout<<"true"<<std::endl;
            break;
        }


        for(int k = 0; k < u->numberOfneighbors(); ++k){
            if(!u->getNeighbors(k)->isVisited())
            {
            //  std::cout<<u->getDistance()<<std::endl;
                int alt = u->getDistance() + 1;
                if( alt < u->getNeighbors(k)->getDistance()){
                     u->getNeighbors(k)->setDistance(alt);
                     u->getNeighbors(k)->setPrevious(u);
                }
            }
        }

    }
    std::vector<Node* > stack;
    u = dNode;
    while(u->getPrevious() != NULL){
        stack.insert(stack.begin(), u);
        u = u->getPrevious();
    }
    if(!stack.empty())
        return stack.at(0);
    else
        return sNode;


}

在这种情况下,dNode 是目标节点,sNode 是起始节点。

有谁知道我做错了什么?

共有2个答案

邵修诚
2023-03-14

它甚至不像Dijkstra算法。

要实现 Dijkstra 算法,您需要维护两个节点列表:

    < li >搜索到的节点列表 < li >边缘节点的排序列表。< br >此列表中的每个节点都有到达此位置的开销。

我在代码中看不到这两个列表。

您还将成本存储在节点中。这将不起作用,因为到达节点的成本将取决于路由(除非您可以存储与节点关联的多个成本)。

我希望代码看起来像这样:

 // pseudo code.
 // Note all features used are strictly available
 //
 Node* Graph::DijkstrasAlgorithm(Node* sNode, Node* dNode)
 {
     std::list<Node*>                    searchedNodes;
     std::list<std::pair<Node*, cost>>   edgeNodes;

     edgeNodes.push_sorted(sNode, 0);

     while(!edgeNodes.empty())
     {
          std::pair<Node*, cost>  next = edgeNodes.pop_front();
          searchedNodes.push_back(next.first);

          if (next.first == dnode)
          {   // We found the route
              return STUFF;
          }

          for(Edge* edge, next.first->getEdges())
          {
              if (searchedNodes.find(edge->dst) != searchedNodes.end())
              {   continue;
              }

              edgeNodes.push_sorted(dest.dst, next.second + edge->cost);
          }
     }
 }
许沛
2023-03-14

在Dijkstra算法中,您仅将最短增强路径指向的节点标记为已访问。我可以看到您在这里犯的一个错误:

u = this->nodeList.at(j);
u->setVisited(true);

不要立即将节点标记为已访问。

标记为仅访问了循环后指向的节点u

for(unsigned int j = 0; j < this->nodeList.size(); ++j){

否则,对于每个改进,您都会将节点标记为已访问,甚至不会处理所有节点。

 类似资料:
  • 我说的只是边缘,而不是负权重循环。

  • 我们将用于确定最短路径的算法称为“Dijkstra算法”。Dijkstra算法是一种迭代算法,它为我们提供从一个特定起始节点到图中所有其他节点的最短路径。这也类似于广度优先搜索的结果。 为了跟踪从开始节点到每个目的地的总成本,我们将使用顶点类中的 dist 实例变量。 dist实例变量将包含从开始到所讨论的顶点的最小权重路径的当前总权重。该算法对图中的每个顶点重复一次;然而,我们在顶点上迭代的顺序

  • 一、迪杰斯特拉算法介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。 基本思想 ​ 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算)。 ​ 此外,引进两个集合S和U。S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是

  • 问题内容: 我正在尝试编写Dijkstra的算法,但是我在努力如何在代码中“说”某些事情而苦苦挣扎。为了可视化,这是我要使用数组表示的列: 因此,将有几个数组,如下面的代码所示: 粗体部分是我要坚持的地方-我正在尝试实现算法的这一部分: 3.对于当前节点,请考虑其所有未访问的邻居并计算其暂定距离。 例如,如果当前节点(A)的距离为6,并且将其与另一个节点(B)相连的边为2,则通过A到B的距离将为6

  • 我试图使用邻接列表和PQ作为最小堆来实现单目标最短路径的Dijkstra算法。输出必须显示所有顶点到目标顶点的路径,如果路径存在,如果是,它的总和(最短),如果否,否路径。链接到整个代码 输入格式: 第一行是顶点数,n 第二行开始:(从1到n的顶点) 第一列是顶点 之后,多对, 根据GDB,它显示了在提取最小函数时发现的分段故障。 客户. c 从文本中提取输入。txt文件并创建一个有向图 服务器.

  • 据我所知,dijkstra无法处理负边权重。为此,我们必须使用贝尔曼福特。 Bellman fords在负边权重和负循环下运行良好,这是无法从源位置访问到的,否则,它将返回消息“负循环存在”。 但是,上面显示的图表与dijkstra运行良好,即使存在负边权重。那么,如何知道何时使用具有负边权重的dijkstra?? 我们想的是,dijkstra可以或不能使用负权重边。如果存在负循环,那么它将不起作