From 1c50e1fe86fafcff5b906a911aa3fe0f7bda9e04 Mon Sep 17 00:00:00 2001 From: Richard Wong Date: Sun, 3 Mar 2024 23:53:21 +0900 Subject: [PATCH] Feat: optimized neighbor_list sorting --- deferred_planarity_test/include/mps.h | 9 ++-- deferred_planarity_test/src/main.cpp | 19 ++++---- deferred_planarity_test/src/mps_test.cpp | 3 +- deferred_planarity_test/src/node.cpp | 56 +++++++++++++++--------- 4 files changed, 55 insertions(+), 32 deletions(-) diff --git a/deferred_planarity_test/include/mps.h b/deferred_planarity_test/include/mps.h index 0d67053..b1f788c 100644 --- a/deferred_planarity_test/include/mps.h +++ b/deferred_planarity_test/include/mps.h @@ -58,9 +58,9 @@ public: void set_adj_list(vector vec); void DFS_visit(vector &dfsList, int &index); void guided_DFS_visit(vector &dfsList, - vector &node_list, + const vector &node_list, int &return_index, - vector rev_post_order, + const vector &rev_post_order, int prev_node); void mutated_DFS_visit(vector &dfsList, vector &node_list, @@ -68,6 +68,9 @@ public: int &traversal_index, vector rev_post_order, int mutate_point); + + // custom comparator function to sort nodes according to order in given vector + bool sortByOrder(const std::vector& vec_order, node* a, node* b); //PARENT-CHILDREN void set_parent(node* n) ; @@ -199,4 +202,4 @@ private: vector _new_node_list; //Newly added nodes. }; -#endif +#endif // for MPS_H diff --git a/deferred_planarity_test/src/main.cpp b/deferred_planarity_test/src/main.cpp index 35a5f89..82972c0 100644 --- a/deferred_planarity_test/src/main.cpp +++ b/deferred_planarity_test/src/main.cpp @@ -26,7 +26,7 @@ vector generate_post_order(const ogdf::Graph &G); vector generate_mutated_post_order(const ogdf::Graph &G, vector post_order, int mutate_point); vector generate_guided_post_order(const ogdf::Graph &G, vector post_order); -void vector_printer(vector state) { +void vector_printer(const vector& state) { for (int i = 0; i < state.size(); ++i) { std::cout << state[i] << ","; } @@ -36,8 +36,9 @@ void vector_printer(vector state) { vector 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 state_old = generate_post_order(G); + vector_printer(state_old); vector state_new; int old_edge_size = compute_removed_edge_size(G, state_old); @@ -46,7 +47,9 @@ vector 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 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 post_order = repeated_mutation(input_file, k_max, mutate_point); - // test_correctness(input_file); + vector 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(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; } diff --git a/deferred_planarity_test/src/mps_test.cpp b/deferred_planarity_test/src/mps_test.cpp index d72c4a9..437570d 100644 --- a/deferred_planarity_test/src/mps_test.cpp +++ b/deferred_planarity_test/src/mps_test.cpp @@ -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(end - start).count() << std::endl; diff --git a/deferred_planarity_test/src/node.cpp b/deferred_planarity_test/src/node.cpp index 6ce6378..412d6eb 100644 --- a/deferred_planarity_test/src/node.cpp +++ b/deferred_planarity_test/src/node.cpp @@ -70,10 +70,18 @@ void node::DFS_visit(vector &dfsList, int &index) { } +bool node::sortByOrder(const std::vector& 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 &dfsList, - vector &node_list, + const vector &node_list, int &return_index, - vector rev_post_order, + const vector &rev_post_order, int prev_node) { @@ -82,24 +90,32 @@ void node::guided_DFS_visit(vector &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 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 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 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 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 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;