Dijkstra-Algorithmを実装しようとしています。そのために、私はクラス 'Node'のオブジェクトへのポインタを格納する優先度キューを使用しています。これは開始ノードまでの距離が最も短いノードを返します。開始ノードと現在のノードの間の距離を手動で編集し、優先度キューから要素を抽出するようにコードを減らしました。通常、ダイクストラがそれを行います。次のコードは正しく動作しません:C++:オブジェクトへのポインタを持つ優先キューが正しく動作しない
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();
}
をそれが返されます。
extracted: Node -1 , distance 0
extracted: Node 0 , distance 0.5
extracted: Node 1 , distance 0.5
extracted: Node 5 , distance 2.14748e+09
三回pqが正常に動作しますが、最後にそれは距離2.5で、ノード2を返す必要があります。
どうすればいいですか?答え
pqのサイズは縮小されますが、要素はsNode、nodes [0]、nodes [1]の順にポップアウトされます。ノード[2] - ノード[5]はまだpqに含まれています。ノード[3] - >距離= 3.5ノード[1]を設定すると、すでにpqからポップされています。 –
はい、そうです。 sNode要素を挿入すると、priority_queueの順序が変更されるため、ノード内の参照が正しくありません。 IMAXではなく、距離値が設定されたpqのすべての要素を挿入するか、ヒープなどの別のSTLコンテナを使用することをおすすめします。 Look here here [http://stackoverflow.com/a/18493336/6535516] –