Oct 23, 2013 at 5:19am UTC
Hello all,
I'm trying to use multiset with a user defined class "edge". I'm trying to use the multiset as a priority queue, and I've created a "less<edge>" via operator<() overloading.
For some reason, I cannot insert edges into the multiset.
I understand that I might also have to create an "allocator". I got some ideas for creating it at
http://stackoverflow.com/questions/8220032/how-to-use-remove-if-with-erase, but still don't know how to define size_type and difference_type.
Attached is my skeleton code, running on Windows 7 (32-bit), under Netbeans IDE, using Cygwin g++ 4.7.3.
How can I get this to work? What is important is that I get a priority queue working with my edges, prioritized by the weight.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#include <iostream>
#include <set> // for multiset
using namespace std; // assume std libraries (i.e. std::XXX)
class edge { // node, weight pair
public :
int get_node_value() { // returns the value associated with the node.
return id;
}
void set_node_value(const int &a) { // sets the value associated with the node to a.
id = a;
}
double get_edge_value() { // returns the value associated to the edge.
return weight;
}
void set_edge_value(const double &v) { // sets the value associated to the edge to v.
weight = v;
}
edge(void ):id(0),weight(1.0) {} // constructor
edge(const int a):id(a),weight(1.0) { // constructor
id = a;
weight = 1.0;
}
edge(const int a, const double v):id(a),weight(v) { // constructor
id = a;
weight = v;
}
edge(const edge &e) { // copy constructor
id = e.id;
weight = e.weight;
}
edge& operator =(const edge &e) { //assignment constructor
id = e.id;
weight = e.weight;
}
bool operator <(const edge &e) { // less operator
return weight < e.weight;
}
private :
int id; // destination node
double weight; // edge weight
};
int main() {
edge e(1, 5.0);
multiset<edge> pq; // priority queue
pq.insert(e);
}
Last edited on Oct 23, 2013 at 5:23am UTC
Oct 23, 2013 at 6:24am UTC
The predicate needs to be const correct.
1 2 3 4
// bool operator<(const edge &e) { // less operator
bool operator <(const edge &e) const { // const-correct less operator
return weight < e.weight;
}
Just write one user-defined constructor; and let the other foundation operations be implicit.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// edge(void):id(0),weight(1.0) {} // constructor
/*
edge(const int a):id(a),weight(1.0) { // constructor
id = a;
weight = 1.0;
}
*/
edge( /*const*/ int a = 0, /*const*/ double v = 1.0 ) : id(a), weight(v) { // constructor
id = a;
weight = v;
}
/*
edge(const edge &e) { // copy constructor
id = e.id;
weight = e.weight;
}
edge& operator=(const edge &e) { //assignment constructor
id = e.id;
weight = e.weight;
}
*/
If you really want a priority queue, use a priority queue.
1 2 3 4 5 6 7
#include <queue>
int main() {
edge e(1, 5.0);
std::priority_queue<edge> pq; // priority queue
pq.push(e);
}
Last edited on Oct 23, 2013 at 6:27am UTC
Oct 23, 2013 at 3:09pm UTC
Thanks! That did the trick!
I reduced my constructors down to only 1, and added the const
to the less operator.
Mine works fine now.
I used multiset over priority_queue based on a recommendation.
The reasoning might have been that the multiset was faster. They said that "its implementation is typically a red-black tree, so additional/removal/lookup is O(ln N)."
Since the priority_queue uses a vector container, it might be a little slower.