diff --git a/deferred_planarity_test/include/mps.h b/deferred_planarity_test/include/mps.h index 3378441..4b40fa3 100644 --- a/deferred_planarity_test/include/mps.h +++ b/deferred_planarity_test/include/mps.h @@ -62,8 +62,16 @@ public: node* adj(int i); void set_adj_list(vector vec); void DFS_visit(vector &dfsList, int &index); - void guided_DFS_visit(vector &dfsList, vector &node_list, int &index, vector rev_post_order); - void mutated_DFS_visit(vector &dfsList, vector &node_list, int &index, vector rev_post_order, int mutate_point); + void guided_DFS_visit(vector &dfsList, + vector &node_list, + int &return_index, + vector rev_post_order); + void mutated_DFS_visit(vector &dfsList, + vector &node_list, + int &index, + int &traversal_index, + vector rev_post_order, + int mutate_point); //PARENT-CHILDREN void set_parent(node* n) ; @@ -163,8 +171,9 @@ public: void read_from_gml(string input_file); void output_print_removed_edge_size(); int output_int_removed_edge_size(); - vector postOrderTraversal(); - vector mutatedPostOrderTraversal(vector post_order, int mutate_point); + vector return_post_order(); + void postOrderTraversal(); + void mutatedPostOrderTraversal(vector post_order, int mutate_point); void guidedPostOrderTraversal(vector post_order); void set_post_order(vector post_order); void sort_adj_list(); diff --git a/deferred_planarity_test/src/main.cpp b/deferred_planarity_test/src/main.cpp index 138f407..807f24a 100644 --- a/deferred_planarity_test/src/main.cpp +++ b/deferred_planarity_test/src/main.cpp @@ -45,10 +45,11 @@ void measure_removed_edges(string input_file, int k_max, int mutate_point) { state_new = generate_mutated_post_order_at_x(input_file, state_old, mutate_point); removed_old = compute_removed_edge_size(input_file, state_old, mutate_point); removed_new = compute_removed_edge_size(input_file, state_new, mutate_point); - // for (int i = 0; i < state_new.size(); i++) { - // std::cout << state_new[i] << ", "; - // } - // std::cout << std::endl; + + for (int i = 0; i < state_new.size(); i++) { + std::cout << state_new[i] << ", "; + } + std::cout << std::endl; std::cout << "removed edges in old: " << removed_old << std::endl; std::cout << "removed edges in new: " << removed_new << std::endl; diff --git a/deferred_planarity_test/src/mps.cpp b/deferred_planarity_test/src/mps.cpp index 37ebdea..1612f88 100644 --- a/deferred_planarity_test/src/mps.cpp +++ b/deferred_planarity_test/src/mps.cpp @@ -31,9 +31,18 @@ maximal_planar_subgraph_finder::get_mutate_point() { return _mutate_point; } +vector +maximal_planar_subgraph_finder::return_post_order() { + vector post_order; + for (int i = 0; i < _post_order_list.size(); ++i) { + post_order.push_back(_post_order_list[i]->node_id()); + } + return post_order; +} + //Determine the post-order-list by a DFS-traversal. -vector +void maximal_planar_subgraph_finder::postOrderTraversal() { node::init_mark(); int postOrderID = 0; @@ -42,12 +51,6 @@ maximal_planar_subgraph_finder::postOrderTraversal() { _node_list[i]->DFS_visit(_post_order_list, postOrderID); } } - - vector post_order; - for (int i = 0; i < _post_order_list.size(); ++i) { - post_order.push_back(_post_order_list[i]->node_id()); - } - return post_order; } @@ -85,20 +88,22 @@ maximal_planar_subgraph_finder::guidedPostOrderTraversal(vector post_order) } //Determine the post-order-list by a DFS-traversal. -vector +void maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector post_order, int mutate_point) { node::init_mark(); + // reverse post_order because reversed post_order is the traversal of the DFS tree from the starting node vector rev_post_order; for (int i = post_order.size() - 1; i >= 0; --i) { rev_post_order.push_back(post_order[i]); } int postOrderID = 0; + int traversal_index = 0; // introduce random selection // Define the range [0, n] int n = _node_list.size() - 1; // Change 'n' to your desired upper bound - assert(mutate_point < n); + // assert(mutate_point < n); // set loop variables int start = rev_post_order[0]; @@ -112,27 +117,17 @@ maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector post_order { if (!_node_list[i]->is_marked()) { - _node_list[i]->mutated_DFS_visit(_post_order_list, _node_list, postOrderID, rev_post_order, mutate_point); + _node_list[i]->mutated_DFS_visit(_post_order_list, _node_list, postOrderID, traversal_index, rev_post_order, mutate_point); } break; } // std::cout << _node_list[i]->node_id() << ", " << !_node_list[i]->is_marked() << std::endl; if (!_node_list[i]->is_marked()) { - _node_list[i]->mutated_DFS_visit(_post_order_list, _node_list, postOrderID, rev_post_order, mutate_point); + _node_list[i]->mutated_DFS_visit(_post_order_list, _node_list, postOrderID, traversal_index, rev_post_order, mutate_point); } i = (i + 1) % end_condition; } - - vector return_order; - for (int i = 0; i < _post_order_list.size(); ++i) { - return_order.push_back(_post_order_list[i]->node_id()); - } - - // we have to reverse the order as we add to list in the forward direction of recursion - // unlike that of previous methods where we add to list in the return direction of recursion - std::reverse(return_order.begin(), return_order.end()); - return return_order; } @@ -187,9 +182,9 @@ void maximal_planar_subgraph_finder::back_edge_traversal() { node* i_node = 0; node* current_node = 0; - int dfs_mutate_point = get_mutate_point() + 1; + int dfs_mutate_point = get_mutate_point(); int node_list_last_index = _node_list.size() - 1; - int post_order_mutate_point = node_list_last_index - dfs_mutate_point; + int post_order_mutate_point = node_list_last_index - dfs_mutate_point - 1; std::cout << "post_order_mutate_point: " << post_order_mutate_point << std::endl; // back_edge first node is higher than the second for (int i = 0; i < _back_edge_list.size(); ++i) { @@ -200,7 +195,7 @@ maximal_planar_subgraph_finder::back_edge_traversal() { if (!back_edge_traversal(current_node, i_node->post_order_index())) { // if current_node is higher than post_order_mutate_point // then it is the preserved section - if (current_node->post_order_index() > post_order_mutate_point) { + if (current_node->post_order_index() >= post_order_mutate_point) { _is_back_edge_eliminate[i] = NON_MUTATED_REMOVE; } else { _is_back_edge_eliminate[i] = MUTATED_REMOVE; diff --git a/deferred_planarity_test/src/mps_test.cpp b/deferred_planarity_test/src/mps_test.cpp index ee1fbb2..c975e6d 100644 --- a/deferred_planarity_test/src/mps_test.cpp +++ b/deferred_planarity_test/src/mps_test.cpp @@ -54,13 +54,15 @@ int maximal_planar_subgraph_finder::find_mps(string input_file) { vector maximal_planar_subgraph_finder::generate_post_order(string input_file) { read_from_gml(input_file); set_mutate_point(INT_MAX); // essentially removed mutate_point - return postOrderTraversal(); + postOrderTraversal(); + return return_post_order(); } vector maximal_planar_subgraph_finder::generate_mutated_post_order(string input_file, vector post_order, int mutate_point) { read_from_gml(input_file); set_mutate_point(INT_MAX); - return mutatedPostOrderTraversal(post_order, mutate_point); + mutatedPostOrderTraversal(post_order, mutate_point); + return return_post_order(); } @@ -69,19 +71,6 @@ int maximal_planar_subgraph_finder::compute_removed_edge_size(string input_file, set_mutate_point(mutate_point); guidedPostOrderTraversal(post_order); - // let's reverse the order - std::reverse(_post_order_list.begin(), _post_order_list.end()); - // then set post_order_index - for (int i = 0; i < _post_order_list.size(); ++i) { - _node_list[_post_order_list[i]->node_id()]->set_post_order_index(i); - } - - // std::cout << "check order of duplicated traversal" << std::endl; - // for (int i = 0; i < _post_order_list.size(); ++i) { - // std::cout << _post_order_list[i]->node_id() << " "; - // } - // std::cout << std::endl; - sort_adj_list(); determine_edges(); back_edge_traversal(); @@ -93,19 +82,6 @@ void maximal_planar_subgraph_finder::print_removed_edge_size(string input_file, set_mutate_point(mutate_point); guidedPostOrderTraversal(post_order); - // let's reverse the order - std::reverse(_post_order_list.begin(), _post_order_list.end()); - // then set post_order_index - for (int i = 0; i < _post_order_list.size(); ++i) { - _node_list[_post_order_list[i]->node_id()]->set_post_order_index(i); - } - - // std::cout << "check order of duplicated traversal" << std::endl; - // for (int i = 0; i < _post_order_list.size(); ++i) { - // std::cout << _post_order_list[i]->node_id() << " "; - // } - // std::cout << std::endl; - sort_adj_list(); determine_edges(); back_edge_traversal(); diff --git a/deferred_planarity_test/src/node.cpp b/deferred_planarity_test/src/node.cpp index 5e7a20b..fd55f64 100644 --- a/deferred_planarity_test/src/node.cpp +++ b/deferred_planarity_test/src/node.cpp @@ -53,6 +53,8 @@ node* node::adj(int i) {return _adj_list[i];} void node::set_adj_list(vector vec) {_adj_list = vec;} +// original DFS visit implementation +// it just uses _adj_list directly as list of neighbors void node::DFS_visit(vector &dfsList, int &index) { mark(); for (int i = 0; i < _adj_list.size(); ++i) { @@ -61,83 +63,81 @@ void node::DFS_visit(vector &dfsList, int &index) { _adj_list[i]->DFS_visit(dfsList, index); } } + // head recursion: function call before returning result set_post_order_index(index); dfsList.push_back(this); ++index; } +void node::guided_DFS_visit(vector &dfsList, + vector &node_list, + int &return_index, + vector rev_post_order) +{ + mark(); + + // 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 -void node::guided_DFS_visit(vector &dfsList, vector &node_list, int &index, vector rev_post_order) { - mark(); - // you will want to sort the neighbor nodes by the order they appear in the rev_post_order - vector neighbor_list; - std::unordered_set neighbor_set; - // 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()) { neighbor_list.push_back(node_list[rev_post_order[i]]); } } - // print the neighbors - // std::cout << "current index: " << this->node_id() << std::endl; - // for (int i = 0; i < neighbor_list.size(); ++i) { - // std::cout << neighbor_list[i]->node_id() << " "; - // } - // std::cout << std::endl; - - set_post_order_index(index); - dfsList.push_back(this); - ++index; - for (int i = 0; i < neighbor_list.size(); ++i) { if (!neighbor_list[i]->is_marked()) { neighbor_list[i]->_parent = this; - neighbor_list[i]->guided_DFS_visit(dfsList, node_list, index, rev_post_order); + neighbor_list[i]->guided_DFS_visit(dfsList, node_list, return_index, rev_post_order); } } + + // head recursion + set_post_order_index(return_index); + dfsList.push_back(this); + ++return_index; } - -void node::mutated_DFS_visit(vector &dfsList, vector &node_list, int &index, vector rev_post_order, int mutate_point) { +void node::mutated_DFS_visit(vector &dfsList, + vector &node_list, + int &return_index, + int &traversal_index, + vector rev_post_order, + int mutate_point) { mark(); - // you will want to sort the neighbor nodes by the order they appear in the rev_post_order - vector neighbor_list; - std::unordered_set neighbor_set; - + + // 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()) { neighbor_list.push_back(node_list[rev_post_order[i]]); } } + - // print the neighbors - // std::cout << "current index: " << this->node_id() << std::endl; - // for (int i = 0; i < neighbor_list.size(); ++i) { - // std::cout << neighbor_list[i]->node_id() << " "; - // } - // std::cout << std::endl; - - set_post_order_index(index); - dfsList.push_back(this); - ++index; - - // we have reached the mutate point - // we change the order of the neighbor list just before the mutate point - // so that the mutation begins at the mutate point - if (index - 1 == mutate_point) { + // introduce mutation at mutate_point + if (traversal_index == mutate_point) { // Create a random number generator and seed it // std::cout << "mutated at index: " << index - 1<< "and at mutate point: " << mutate_point << std::endl; std::random_device rd; @@ -145,26 +145,25 @@ void node::mutated_DFS_visit(vector &dfsList, vector &node_list, i // Use std::shuffle to shuffle the elements in the vector std::shuffle(neighbor_list.begin(), neighbor_list.end(), rng); + } - // print the neighbors - // print the neighbors that are not yet marked - std::cout << "current index: " << index - 1 << std::endl; - std::cout << "order after mutation: "; - for (int i = 0; i < neighbor_list.size(); ++i) { - if (!neighbor_list[i]->is_marked()) - std::cout << neighbor_list[i]->node_id() << " "; - } - std::cout << std::endl; - } + // increment traversal index after checking + // next node will receive incremented index + traversal_index++; for (int i = 0; i < neighbor_list.size(); ++i) { if (!neighbor_list[i]->is_marked()) { neighbor_list[i]->_parent = this; - neighbor_list[i]->mutated_DFS_visit(dfsList, node_list, index, rev_post_order, mutate_point); + neighbor_list[i]->mutated_DFS_visit(dfsList, node_list, return_index, traversal_index, rev_post_order, mutate_point); } } + + // head recursion like the initial dfs visit implementation + set_post_order_index(return_index); + dfsList.push_back(this); + ++return_index; }