Feat: optimized neighbor_list sorting

This commit is contained in:
Richard Wong 2024-03-03 23:53:21 +09:00
parent 996222ab60
commit 1c50e1fe86
Signed by: richard
GPG Key ID: 5BD36BA2E9EE33D0
4 changed files with 55 additions and 32 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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;