diff --git a/deferred_planarity_test/include/mps.h b/deferred_planarity_test/include/mps.h index 42b2896..2844290 100644 --- a/deferred_planarity_test/include/mps.h +++ b/deferred_planarity_test/include/mps.h @@ -71,7 +71,7 @@ public: int mutate_point); // custom comparator function to sort nodes according to order in given vector - bool sortByOrder(const std::unordered_map& node_id_to_pos, node* a, node* b); + bool sortByOrder(const unordered_map& node_id_to_pos, node* a, node* b); //PARENT-CHILDREN void set_parent(node* n) ; @@ -160,18 +160,26 @@ class maximal_planar_subgraph_finder public: maximal_planar_subgraph_finder(); ~maximal_planar_subgraph_finder(); - int find_mps(const ogdf::Graph &G); - int compute_removed_edge_size(const ogdf::Graph &G, vector post_order); + + // functions that prepare state + void init_from_graph(const ogdf::Graph &G); 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); - node* get_new_node(node_type t); - void init_from_graph(const ogdf::Graph &G); - int output_removed_edge_size(); - vector return_post_order(); void postOrderTraversal(); void guidedPostOrderTraversal(vector post_order); void mutatedPostOrderTraversal(vector post_order, int mutate_point); + + // compute_mps combines functionality to reduce repeating object initialization + // the results are returned by modifying mutable reference + void compute_mps(const ogdf::Graph &G, int mutate_point, vector &post_order, int &return_edge_size); + + int find_mps(const ogdf::Graph &G); + int compute_removed_edge_size(const ogdf::Graph &G, vector post_order); + node* get_new_node(node_type t); + void reset_state(); + int output_removed_edge_size(); + vector return_post_order(); // void set_post_order(vector post_order); void print_post_order(); void sort_adj_list(); diff --git a/deferred_planarity_test/src/main.cpp b/deferred_planarity_test/src/main.cpp index d7d1276..aa3229b 100644 --- a/deferred_planarity_test/src/main.cpp +++ b/deferred_planarity_test/src/main.cpp @@ -25,6 +25,7 @@ ogdf::Graph read_from_gml(string input_file); 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 compute_mps(const ogdf::Graph &G, int mutate_point, vector &post_order, int &return_edge_size); void vector_printer(const vector& state) { for (size_t i = 0; i < state.size(); ++i) { @@ -34,53 +35,43 @@ void vector_printer(const vector& state) { } -vector repeated_mutation(const ogdf::Graph &G, int k_max, int mutate_point) { +vector repeated_mutation(const ogdf::Graph &G, int k_max) { // generate first post order // std::cout << "generate first post order" << std::endl; - vector state_old = generate_post_order(G); - vector_printer(state_old); - vector state_new; + vector old_order = generate_post_order(G); + vector_printer(old_order); + vector temp_order = old_order; + int new_removed_size; + int old_removed_size = INT_MAX; - int old_edge_size = compute_removed_edge_size(G, state_old); - - int new_edge_size = old_edge_size; + // prepare random selection + std::random_device rd; + std::mt19937 gen{rd()}; // seed the generator + int first_value = 0; + // we want the index of the third last value + // at a given traversal index, only the next iteration has the mutated value + int last_value = (old_order.size() - 1) - 2; + std::uniform_int_distribution<> dist{first_value, last_value}; // set min and max + int mutate_point = dist(gen); // generate number for (int k = 0; k < k_max; ++k) { - // mutation produces rotated view - // 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); - new_edge_size = compute_removed_edge_size(G, state_old); - - // if (new_edge_size < old_edge_size) { - // state_old = state_new; - // } - - + // function compute new post_order and new_removed_size + // temp_order and new_removed_size will be updated with new values + compute_mps(G, mutate_point, temp_order, new_removed_size); + // if there is an improvement + // 1. update the removed size to use the new smaller size + // 2. update the old_order to be the new_order + if (new_removed_size < old_removed_size) { + old_removed_size = new_removed_size; + old_order = temp_order; + // if there is no improvement, we revert the temp_order to the old_order + } else { + temp_order = old_order; + } } - // vector_printer(state_new); - return state_old; + return old_order; } -void test_correctness(const ogdf::Graph &G) { - vector state_old = generate_post_order(G); - compute_removed_edge_size(G, state_old); -} - - -int get_graph_size(string input_file) { - ogdf::Graph G; - - // utilize OGDF readGML - if (!ogdf::GraphIO::read(G, input_file, ogdf::GraphIO::readGML)) { - std::cerr << "Could not read " << input_file << ".gml" << std::endl; - } - - return G.numberOfNodes(); -} //----------------------------------------------------------------------------------- // Main function. @@ -90,20 +81,20 @@ int get_graph_size(string input_file) { int main(int argc, char* argv[]) { string input_file = argv[1]; int k_max = std::stoi(argv[2]); - int mutate_point = std::stoi(argv[3]); const ogdf::Graph G = read_from_gml(input_file); // generate order here - vector post_order = repeated_mutation(G, k_max, mutate_point); + vector post_order = repeated_mutation(G, k_max); // test timing of function // 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; + std::cout << "---" << std::endl; + std::cout << "final report" << std::endl; + std::copy(post_order.begin(), post_order.end(), std::ostream_iterator(std::cout, ",")); + std::cout << std::endl; int removed_edges = compute_removed_edge_size(G, post_order); std::cout << "Number of removed edges: " << removed_edges << std::endl; diff --git a/deferred_planarity_test/src/mps.cpp b/deferred_planarity_test/src/mps.cpp index 9561122..6f61c6e 100644 --- a/deferred_planarity_test/src/mps.cpp +++ b/deferred_planarity_test/src/mps.cpp @@ -99,7 +99,8 @@ maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector post_order node::init_mark(); vector rev_post_order; - for (size_t i = post_order.size() - 1; i >= 0; --i) { + + for (size_t i = post_order.size() - 1; i != std::numeric_limits::max(); --i) { rev_post_order.push_back(post_order[i]); } int postOrderID = 0; diff --git a/deferred_planarity_test/src/mps_test.cpp b/deferred_planarity_test/src/mps_test.cpp index c1625f2..b4ae576 100644 --- a/deferred_planarity_test/src/mps_test.cpp +++ b/deferred_planarity_test/src/mps_test.cpp @@ -8,6 +8,7 @@ #include // #define DEBUG +#define DEBUG_2 // #define TIME //----------------------------------------------------------------------------------- @@ -54,6 +55,12 @@ vector generate_guided_post_order(const ogdf::Graph &G, vector post_or } +void compute_mps(const ogdf::Graph &G, int mutate_point, vector &post_order, int &return_edge_size) { + maximal_planar_subgraph_finder m; + m.compute_mps(G, mutate_point, post_order, return_edge_size); +} + + // --------- int maximal_planar_subgraph_finder::find_mps(const ogdf::Graph &G) { @@ -85,6 +92,7 @@ vector maximal_planar_subgraph_finder::generate_post_order(const ogdf::Grap // result of this will be used as input to "compute_removed_edge_size" vector maximal_planar_subgraph_finder::generate_mutated_post_order(const ogdf::Graph &G, vector post_order, int mutate_point) { init_from_graph(G); + mutatedPostOrderTraversal(post_order, mutate_point); #ifdef DEBUG @@ -164,6 +172,36 @@ int maximal_planar_subgraph_finder::compute_removed_edge_size(const ogdf::Graph return output_removed_edge_size(); } +void maximal_planar_subgraph_finder::reset_state() { + _post_order_list.clear(); +} + +void maximal_planar_subgraph_finder::compute_mps(const ogdf::Graph &G, int mutate_point, vector &post_order, int &return_edge_size) { + init_from_graph(G); + mutatedPostOrderTraversal(post_order, mutate_point); + sort_adj_list(); + determine_edges(); + back_edge_traversal(); + return_edge_size = output_removed_edge_size(); + + // now we get the canonical representation of the post order + vector temp_post_order = return_post_order(); + #ifdef DEBUG_2 + std::cout << "post_order pre-flip" << std::endl; + print_post_order(); + #endif + + reset_state(); // clear the _post_order_list + // perform guided Post Order Traversal to flip the tree + guidedPostOrderTraversal(temp_post_order); + #ifdef DEBUG_2 + std::cout << "post order post_flip" << std::endl; + print_post_order(); + #endif + + post_order = return_post_order(); +} + //----------------------------------------------------------------------------------- // Input, output //----------------------------------------------------------------------------------- diff --git a/deferred_planarity_test/src/node.cpp b/deferred_planarity_test/src/node.cpp index 45c89d7..5eeb34c 100644 --- a/deferred_planarity_test/src/node.cpp +++ b/deferred_planarity_test/src/node.cpp @@ -119,7 +119,6 @@ void node::guided_DFS_visit(vector &dfsList, #ifdef DEBUG std::cout << "current node:" << this->node_id() << std::endl; - std::cout << "prev node:" << prev_node << std::endl; for (int i = 0; i < neighbor_list.size(); ++i) { std::cout << neighbor_list[i]->node_id() << "(" << neighbor_list[i]->is_marked() << ")" << ","; } @@ -171,7 +170,14 @@ void node::mutated_DFS_visit(vector &dfsList, } } - + #ifdef DEBUG_MUTATION + std::cout << "current node:" << this->node_id() << std::endl; + for (size_t i = 0; i < neighbor_list.size(); ++i) { + std::cout << neighbor_list[i]->node_id() << "(" << neighbor_list[i]->is_marked() << ")" << ","; + } + std::cout << std::endl; + #endif + // since we increment the index before this line, the current index is "index - 1" // if the current index matches the mutate_point, then we know this is the cycle to mutate @@ -183,13 +189,6 @@ void node::mutated_DFS_visit(vector &dfsList, // Use std::shuffle to shuffle the elements in the vector std::shuffle(neighbor_list.begin(), neighbor_list.end(), rng); - #ifdef DEBUG_MUTATION - std::cout << "current node:" << this->node_id() << std::endl; - for (size_t i = 0; i < neighbor_list.size(); ++i) { - std::cout << neighbor_list[i]->node_id() << "(" << neighbor_list[i]->is_marked() << ")" << ","; - } - std::cout << std::endl; - #endif } // increment traversal index after checking