简体   繁体   English

C ++:具有对象指针的优先级队列无法正常工作

[英]C++: priority queue with pointer to object does not work correctly

I am trying to implement Dijkstra-Algorithm. 我正在尝试实现Dijkstra-Algorithm。 For that i am using a priority queue storing pointers to objects of the class 'Node' which shall return the node with the lowest distance to the start node. 为此,我正在使用优先级队列来存储指向“节点”类的对象的指针,该指针将返回距离起始节点距离最短的节点。 I reduced my code so that it manually edits the distance between start node and current node and extracts element from the priority queue. 我减少了代码,以便它手动编辑起始节点和当前节点之间的距离,并从优先级队列中提取元素。 Normally Dijkstra would do that. 通常Dijkstra会这样做。 The following code does not work correctly: 以下代码无法正常工作:

using namespace std;

#include <iostream>
#include <limits>
#include <vector>
#include <queue>

const int numberNodes = 6;
int IMAX = numeric_limits<int>::max();

class Node{
public:
    Node(float pdistance, int pid){distance = pdistance;    id = pid;}
    float distance;
    int id;     //only for debug
};

Node** nodes;       //in int main() Array of Node*

class Compare{  //Compare pointer to nodes based on distance to start node (Dijkstra)
public:
    bool operator() (Node *n1, Node *n2) const {
        return n1->distance>n2->distance;
    }
};

priority_queue<Node*, vector<Node*>, Compare> pq;

int main(){
    nodes = new Node*[numberNodes];
    for(int i=0; i<numberNodes; i++){       //create new objects and store them in pq
        nodes[i] = new Node(IMAX, i);
        pq.push(nodes[i]);
    }
    Node* sNode;        //Start node. not contained in nodes[]
    sNode = new Node(0, -1);        //distance 0, id -1
    pq.push(sNode);

    cout << "extracted: Node " << (pq.top())->id << " , distance " << (pq.top())->distance << endl;
    pq.pop();

    nodes[0]->distance = 0.5;
    nodes[1]->distance = 0.5;
    cout << "extracted: Node " << (pq.top())->id << " , distance " << (pq.top())->distance << endl;
    pq.pop();       

    cout << "extracted: Node " << (pq.top())->id << " , distance " << (pq.top())->distance << endl;
    pq.pop();   

    nodes[2]->distance = 2.5;
    nodes[3]->distance = 3.5;
    cout << "extracted: Node " << (pq.top())->id << " , distance " << (pq.top())->distance << endl;
    pq.pop();   
}

It returns: 它返回:

extracted: Node -1 , distance 0
extracted: Node 0 , distance 0.5
extracted: Node 1 , distance 0.5
extracted: Node 5 , distance 2.14748e+09

Three times the pq works correctly, but at the end it should return Node 2 with distance 2.5. pq可以正常工作三倍,但最后应该返回距离2.5的节点2。

So how can i make it work? 那么我该如何运作呢?

Thanks for answers 谢谢答案

Since you are popping out the elements of your priority_queue its size is beeing reduced, since the line: 由于您正在弹出您的priority_queue的元素,因此其大小正在减小,因为该行:

nodes[2]->distance = 2.5; 节点[2]->距离= 2.5; nodes[3]->distance = 3.5; 节点[3]->距离= 3.5;

Should be changed to: 应更改为:

nodes[0]->distance = 2.5; 节点[0]->距离= 2.5; nodes[1]->distance = 3.5; 节点[1]->距离= 3.5;

At the top the variable numberNodes is set equal to 6. Reduce it to a smaller number since it is initializing 6 nodes in your main function. 在顶部,变量numberNodes设置为等于6。将其减小为较小的数字,因为它将在您的main函数中初始化6个节点。

The huge number is the default garbage that the compiler will initialize the float to since you declared it but didn't assign anything to it. 巨大的数字是自从您声明float以来,编译器将float初始化为的默认垃圾,但没有为其分配任何内容。

To avoid this problem just make sure that you initialize all your variables before you use them. 为避免此问题,只需确保在使用它们之前初始化所有变量。

for(int i=0; i<numberNodes; i++){       //create new objects and store them in pq
    nodes[i] = new Node(IMAX, i);
    nodes[i].distance = 0.0f; //<--set a default value
    pq.push(nodes[i]);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM