I need to efficiently define an ordering on the std::set<Edge>. Edge represents an edge in a graph (not multigraph).
class Edge
{
friend class Graph;
string from;
string to;
EdgeInfo edge_length; //constructor is `EdgeInfo(int edge_length)`
public:
bool operator==(const Edge& rhs) {
return (from==rhs.from && to==rhs.to);
}
};
The problem is to efficiently find
- whether the
std::set<Edge>contains an edge with given “from” and “to” - edges that go from given “from” to some “to”, where “to” is not inside a given
set<string>
using std::set.count() and std::set.find(). I need to somehow define the appropriate ordering on the std::set. Is this possible?
EDIT: I figured I should have used map or multimap instead of set. Eventually I used map. The solution is inspired by @tom’s suggestion to use map of maps.
SOLUTION:
typedef int EdgeInfo; //just for the sake of this example (EdgeInfo can be length,price,...)
map< string, map<string, EdgeInfo> > edges;
whether the
std::set<Edge>contains an edge with given “from” and
“to”
if (edges.count(from)!=0 && edges[from].count(to)!=0) {
return true;
}
or in case the function is const
if (edges.count(from)!=0 && ((edges.find(top.second))->second).count(to)!=0) {
return true;
}
edges that go from given “from” to some “to”, where “to” is not inside
a given set
in case the function is const
//if there are any edges from "from"
if (edges.count(from)!=0) {
//iterate over all edges from "from"
for (map<string,EdgeInfo>::const_iterator
edge=((edges.find(from))->second).begin();
edge!=((edges.find(from))->second).end();
++edge) {
//if the edge goes to some vertex V that has not been discarded
if (discarded.count(edge->first)==0) { //edge->first means "to"
Adjacency List
Adjacency Matrix
One Ordered Set
This is more in line with the OP’s original request, but I feel it is much uglier than the other options.
I have included this only for the sake of completeness.
Explanation of
edgesExcept()Here is a pseudo code version:
Instead of actually removing edges that are no longer relevant from
exclude_edges, the C++ version uses an iterator to remember which edges inexclude_edgesare no longer relevant (those smaller than all the edges of interest that are yet to be examined). Once all the edges inexclude_edgesthat are smaller thanehave been removed / skipped over, checking ifeappears inexclude_edgescan be done simply by comparing it to the first (smallest) element ofexclude_edges.