Feat: optimized neighbor_list sorting
This commit is contained in:
parent
996222ab60
commit
1c50e1fe86
|
@ -58,9 +58,9 @@ public:
|
|||
void set_adj_list(vector<node*> vec);
|
||||
void DFS_visit(vector<node*> &dfsList, int &index);
|
||||
void guided_DFS_visit(vector<node *> &dfsList,
|
||||
vector<node *> &node_list,
|
||||
const vector<node *> &node_list,
|
||||
int &return_index,
|
||||
vector<int> rev_post_order,
|
||||
const vector<int> &rev_post_order,
|
||||
int prev_node);
|
||||
void mutated_DFS_visit(vector<node*> &dfsList,
|
||||
vector<node*> &node_list,
|
||||
|
@ -69,6 +69,9 @@ public:
|
|||
vector<int> rev_post_order,
|
||||
int mutate_point);
|
||||
|
||||
// custom comparator function to sort nodes according to order in given vector
|
||||
bool sortByOrder(const std::vector<int>& vec_order, node* a, node* b);
|
||||
|
||||
//PARENT-CHILDREN
|
||||
void set_parent(node* n) ;
|
||||
node* parent();
|
||||
|
@ -199,4 +202,4 @@ private:
|
|||
vector<node*> _new_node_list; //Newly added nodes.
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // for MPS_H
|
||||
|
|
|
@ -26,7 +26,7 @@ vector<int> generate_post_order(const ogdf::Graph &G);
|
|||
vector<int> generate_mutated_post_order(const ogdf::Graph &G, vector<int> post_order, int mutate_point);
|
||||
vector<int> generate_guided_post_order(const ogdf::Graph &G, vector<int> post_order);
|
||||
|
||||
void vector_printer(vector<int> state) {
|
||||
void vector_printer(const vector<int>& state) {
|
||||
for (int i = 0; i < state.size(); ++i) {
|
||||
std::cout << state[i] << ",";
|
||||
}
|
||||
|
@ -36,8 +36,9 @@ void vector_printer(vector<int> state) {
|
|||
|
||||
vector<int> repeated_mutation(const ogdf::Graph &G, int k_max, int mutate_point) {
|
||||
// generate first post order
|
||||
std::cout << "generate first post order" << std::endl;
|
||||
// std::cout << "generate first post order" << std::endl;
|
||||
vector<int> state_old = generate_post_order(G);
|
||||
vector_printer(state_old);
|
||||
vector<int> state_new;
|
||||
|
||||
int old_edge_size = compute_removed_edge_size(G, state_old);
|
||||
|
@ -46,7 +47,9 @@ vector<int> repeated_mutation(const ogdf::Graph &G, int k_max, int mutate_point)
|
|||
|
||||
for (int k = 0; k < k_max; ++k) {
|
||||
// mutation produces rotated view
|
||||
state_new = generate_mutated_post_order(G, state_old, mutate_point);
|
||||
// state_new = generate_mutated_post_order(G, state_old, mutate_point);
|
||||
// simulate a mutation
|
||||
state_new = generate_guided_post_order(G, state_old);
|
||||
|
||||
// another round of guided post order gives canonical representation
|
||||
state_new = generate_guided_post_order(G, state_new);
|
||||
|
@ -58,6 +61,7 @@ vector<int> repeated_mutation(const ogdf::Graph &G, int k_max, int mutate_point)
|
|||
|
||||
|
||||
}
|
||||
vector_printer(state_new);
|
||||
return state_new;
|
||||
}
|
||||
|
||||
|
@ -92,18 +96,17 @@ int main(int argc, char* argv[]) {
|
|||
const ogdf::Graph G = read_from_gml(input_file);
|
||||
|
||||
// generate order here
|
||||
// vector<int> post_order = repeated_mutation(input_file, k_max, mutate_point);
|
||||
// test_correctness(input_file);
|
||||
vector<int> post_order = repeated_mutation(G, k_max, mutate_point);
|
||||
|
||||
// test timing of function
|
||||
test_correctness(G);
|
||||
// test_correctness(G);
|
||||
|
||||
// // print final order and number of edges
|
||||
// // print post_order
|
||||
// std::copy(post_order.begin(), post_order.end(), std::ostream_iterator<int>(std::cout, ","));
|
||||
// std::cout << std::endl;
|
||||
// int removed_edges = compute_removed_edge_size(input_file, post_order);
|
||||
// std::cout << "Number of removed edges: " << removed_edges << std::endl;
|
||||
int removed_edges = compute_removed_edge_size(G, post_order);
|
||||
std::cout << "Number of removed edges: " << removed_edges << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
// #define DEBUG
|
||||
|
||||
#define TIME
|
||||
// #define TIME
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
// Finding MPS
|
||||
|
@ -127,6 +127,7 @@ int maximal_planar_subgraph_finder::compute_removed_edge_size(const ogdf::Graph
|
|||
start = std::chrono::high_resolution_clock::now();
|
||||
#endif
|
||||
guidedPostOrderTraversal(post_order);
|
||||
// postOrderTraversal();
|
||||
#ifdef TIME
|
||||
end = std::chrono::high_resolution_clock::now();
|
||||
std::cout << "guidedPostOrderTraversal: " << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << std::endl;
|
||||
|
|
|
@ -70,10 +70,18 @@ void node::DFS_visit(vector<node*> &dfsList, int &index) {
|
|||
}
|
||||
|
||||
|
||||
bool node::sortByOrder(const std::vector<int>& vec_order, node* a, node* b) {
|
||||
auto itA = std::find(vec_order.begin(), vec_order.end(), a->node_id());
|
||||
auto itB = std::find(vec_order.begin(), vec_order.end(), b->node_id());
|
||||
|
||||
return (std::distance(vec_order.begin(), itA) < std::distance(vec_order.begin(), itB));
|
||||
}
|
||||
|
||||
|
||||
void node::guided_DFS_visit(vector<node *> &dfsList,
|
||||
vector<node *> &node_list,
|
||||
const vector<node *> &node_list,
|
||||
int &return_index,
|
||||
vector<int> rev_post_order,
|
||||
const vector<int> &rev_post_order,
|
||||
int prev_node)
|
||||
{
|
||||
|
||||
|
@ -82,24 +90,32 @@ void node::guided_DFS_visit(vector<node *> &dfsList,
|
|||
// purpose of this block: create list of neighbors ordered in the order they appear in rev_post_order
|
||||
// we want to select neighbors that match the rev_post_order at the specific traversal_index
|
||||
|
||||
// create an unordered set to efficiently check for presence of an element
|
||||
std::unordered_set<int> neighbor_set;
|
||||
for (int i = 0; i < _adj_list.size(); ++i) {
|
||||
neighbor_set.insert(_adj_list[i]->node_id());
|
||||
}
|
||||
// when an element in rev_post_order is found in neighbor_set, we add that to neighbor_list
|
||||
// this produces a neighbor_list that follows the order by which they occur in the rev_post_order
|
||||
// it is ok if the neighbor was already visited before,
|
||||
// it would've been marked and will be subsequently ignored
|
||||
vector<node *> neighbor_list;
|
||||
for (int i = 0; i < rev_post_order.size(); ++i) {
|
||||
if (neighbor_set.find(rev_post_order[i]) != neighbor_set.end()) {
|
||||
// only add if newly encountered
|
||||
if (!node_list[rev_post_order[i]]->is_marked()) {
|
||||
neighbor_list.push_back(node_list[rev_post_order[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// implementation 1: loop through all elements
|
||||
// // create an unordered set to efficiently check for presence of an element
|
||||
// std::unordered_set<int> neighbor_set;
|
||||
// for (int i = 0; i < _adj_list.size(); ++i) {
|
||||
// neighbor_set.insert(_adj_list[i]->node_id());
|
||||
// }
|
||||
// // when an element in rev_post_order is found in neighbor_set, we add that to neighbor_list
|
||||
// // this produces a neighbor_list that follows the order by which they occur in the rev_post_order
|
||||
// // it is ok if the neighbor was already visited before,
|
||||
// // it would've been marked and will be subsequently ignored
|
||||
// vector<node *> neighbor_list;
|
||||
// for (int i = 0; i < rev_post_order.size(); ++i) {
|
||||
// if (neighbor_set.find(rev_post_order[i]) != neighbor_set.end()) {
|
||||
// // only add if newly encountered
|
||||
// if (!node_list[rev_post_order[i]]->is_marked()) {
|
||||
// neighbor_list.push_back(node_list[rev_post_order[i]]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// implementation 2: sort elements of _adj_list
|
||||
vector<node*> neighbor_list = _adj_list;
|
||||
std::sort(neighbor_list.begin(), neighbor_list.end(), [this, &rev_post_order](node* a, node* b) {
|
||||
return sortByOrder(rev_post_order, a, b);
|
||||
});
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cout << "current node:" << this->node_id() << std::endl;
|
||||
|
|
Loading…
Reference in New Issue