From 996222ab60c411a63cb19b9208b2d2a9eab84e41 Mon Sep 17 00:00:00 2001 From: Richard Wong Date: Sun, 3 Mar 2024 22:28:42 +0900 Subject: [PATCH] Feat: read file once, re-use ogdf Graph object --- deferred_planarity_test/include/mps.h | 13 +-- deferred_planarity_test/src/main.cpp | 47 ++++++----- deferred_planarity_test/src/mps_test.cpp | 102 +++++++++++++++-------- 3 files changed, 100 insertions(+), 62 deletions(-) diff --git a/deferred_planarity_test/include/mps.h b/deferred_planarity_test/include/mps.h index 4a99594..0d67053 100644 --- a/deferred_planarity_test/include/mps.h +++ b/deferred_planarity_test/include/mps.h @@ -13,6 +13,7 @@ #include #include #include +#include using namespace std; @@ -155,13 +156,13 @@ class maximal_planar_subgraph_finder public: maximal_planar_subgraph_finder(); ~maximal_planar_subgraph_finder(); - int find_mps(string input_file); - int compute_removed_edge_size(string input_file, vector post_order); - vector generate_post_order(string input_file); - vector generate_mutated_post_order(string input_file, vector post_order, int mutate_point); - vector generate_guided_post_order(string input_file, vector post_order); + int find_mps(const ogdf::Graph &G); + int compute_removed_edge_size(const ogdf::Graph &G, vector post_order); + 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 read_from_gml(string input_file); + void init_from_graph(const ogdf::Graph &G); int output_removed_edge_size(); vector return_post_order(); void postOrderTraversal(); diff --git a/deferred_planarity_test/src/main.cpp b/deferred_planarity_test/src/main.cpp index acb33a7..35a5f89 100644 --- a/deferred_planarity_test/src/main.cpp +++ b/deferred_planarity_test/src/main.cpp @@ -17,13 +17,14 @@ using namespace std; -int compute_removed_edge_size(string input_file, vector post_order); +int compute_removed_edge_size(const ogdf::Graph &G, vector post_order); // these functions are defined in mps_test.cpp // but their signatures are not in mps.h, hence they are declared here -vector generate_post_order(string input_file); -vector generate_mutated_post_order(string input_file, vector post_order, int mutate_point); -vector generate_guided_post_order(string input_file, vector post_order); +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 vector_printer(vector state) { for (int i = 0; i < state.size(); ++i) { @@ -33,36 +34,37 @@ void vector_printer(vector state) { } -vector repeated_mutation(string input_file, int k_max, int mutate_point) { +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; - vector state_old = generate_post_order(input_file); + vector state_old = generate_post_order(G); vector state_new; - for (int k = 0; k < k_max; ++k) { - std::cout << "cycle:" << k << std::endl; + int old_edge_size = compute_removed_edge_size(G, state_old); - vector_printer(state_old); - - + int new_edge_size = old_edge_size; + + for (int k = 0; k < k_max; ++k) { // mutation produces rotated view - state_new = generate_mutated_post_order(input_file, state_old, mutate_point); - vector_printer(state_new); + state_new = generate_mutated_post_order(G, state_old, mutate_point); // another round of guided post order gives canonical representation - state_new = generate_guided_post_order(input_file, state_new); - vector_printer(state_new); + state_new = generate_guided_post_order(G, state_new); + new_edge_size = compute_removed_edge_size(G, state_new); + + if (new_edge_size < old_edge_size) { + state_old = state_new; + } - std::cout << std::endl; } return state_new; } -void test_correctness(string input_file) { - vector state_old = generate_post_order(input_file); +void test_correctness(const ogdf::Graph &G) { + vector state_old = generate_post_order(G); int num_removed_edges; - num_removed_edges = compute_removed_edge_size(input_file, state_old); + num_removed_edges = compute_removed_edge_size(G, state_old); } @@ -87,10 +89,15 @@ int main(int argc, char* argv[]) { 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(input_file, k_max, mutate_point); + // vector post_order = repeated_mutation(input_file, k_max, mutate_point); // test_correctness(input_file); + // 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, ",")); diff --git a/deferred_planarity_test/src/mps_test.cpp b/deferred_planarity_test/src/mps_test.cpp index 47b4259..d72c4a9 100644 --- a/deferred_planarity_test/src/mps_test.cpp +++ b/deferred_planarity_test/src/mps_test.cpp @@ -2,47 +2,63 @@ // Implementation of a MPS algorithm via PC-tree. //----------------------------------------------------------------------------------- +#include #include "mps.h" + #include // #define DEBUG +#define TIME + //----------------------------------------------------------------------------------- // Finding MPS //----------------------------------------------------------------------------------- // programs to call from main: -int find_mps(string input_file) { +// read input file of gml format +ogdf::Graph read_from_gml(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; +} + + +int find_mps(const ogdf::Graph &G) { maximal_planar_subgraph_finder m; - return m.find_mps(input_file); + return m.find_mps(G); } -int compute_removed_edge_size(string input_file, vector post_order) { +int compute_removed_edge_size(const ogdf::Graph &G, vector post_order) { maximal_planar_subgraph_finder m; - return m.compute_removed_edge_size(input_file, post_order); + return m.compute_removed_edge_size(G, post_order); } -vector generate_post_order(string input_file) { +vector generate_post_order(const ogdf::Graph &G) { maximal_planar_subgraph_finder m; - return m.generate_post_order(input_file); + return m.generate_post_order(G); } -vector generate_mutated_post_order(string input_file, vector post_order, int mutate_point) { +vector generate_mutated_post_order(const ogdf::Graph &G, vector post_order, int mutate_point) { maximal_planar_subgraph_finder m; - return m.generate_mutated_post_order(input_file, post_order, mutate_point); + return m.generate_mutated_post_order(G, post_order, mutate_point); } -vector generate_guided_post_order(string input_file, vector post_order) { +vector generate_guided_post_order(const ogdf::Graph &G, vector post_order) { maximal_planar_subgraph_finder m; - return m.generate_guided_post_order(input_file, post_order); + return m.generate_guided_post_order(G, post_order); } // --------- -int maximal_planar_subgraph_finder::find_mps(string input_file) { - read_from_gml(input_file); +int maximal_planar_subgraph_finder::find_mps(const ogdf::Graph &G) { + init_from_graph(G); postOrderTraversal(); #ifdef DEBUG @@ -55,8 +71,8 @@ int maximal_planar_subgraph_finder::find_mps(string input_file) { return output_removed_edge_size(); } -vector maximal_planar_subgraph_finder::generate_post_order(string input_file) { - read_from_gml(input_file); +vector maximal_planar_subgraph_finder::generate_post_order(const ogdf::Graph &G) { + init_from_graph(G); postOrderTraversal(); #ifdef DEBUG @@ -68,8 +84,8 @@ vector maximal_planar_subgraph_finder::generate_post_order(string input_fil } // result of this will be used as input to "compute_removed_edge_size" -vector maximal_planar_subgraph_finder::generate_mutated_post_order(string input_file, vector post_order, int mutate_point) { - read_from_gml(input_file); +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 @@ -81,8 +97,8 @@ vector maximal_planar_subgraph_finder::generate_mutated_post_order(string i } // result of this will be used as input to "compute_removed_edge_size" -vector maximal_planar_subgraph_finder::generate_guided_post_order(string input_file, vector post_order) { - read_from_gml(input_file); +vector maximal_planar_subgraph_finder::generate_guided_post_order(const ogdf::Graph &G, vector post_order) { + init_from_graph(G); guidedPostOrderTraversal(post_order); // #ifdef DEBUG @@ -95,35 +111,49 @@ vector maximal_planar_subgraph_finder::generate_guided_post_order(string in -int maximal_planar_subgraph_finder::compute_removed_edge_size(string input_file, vector post_order) { - read_from_gml(input_file); - guidedPostOrderTraversal(post_order); - - #ifdef DEBUG - std::cout << "guided post order traversal" << std::endl; - print_post_order(); +int maximal_planar_subgraph_finder::compute_removed_edge_size(const ogdf::Graph &G, vector post_order) { + // read_from_gml + #ifdef TIME + auto start = std::chrono::high_resolution_clock::now(); + #endif + init_from_graph(G); + #ifdef TIME + auto end = std::chrono::high_resolution_clock::now(); + std::cout << "init from G: " << std::chrono::duration_cast(end - start).count() << std::endl; #endif + // guidedPostOrderTraversal + #ifdef TIME + start = std::chrono::high_resolution_clock::now(); + #endif + guidedPostOrderTraversal(post_order); + #ifdef TIME + end = std::chrono::high_resolution_clock::now(); + std::cout << "guidedPostOrderTraversal: " << std::chrono::duration_cast(end - start).count() << std::endl; + #endif + + // remaining procedure + #ifdef TIME + start = std::chrono::high_resolution_clock::now(); + #endif sort_adj_list(); determine_edges(); back_edge_traversal(); + #ifdef TIME + end = std::chrono::high_resolution_clock::now(); + std::cout << "remaining procedures: " << std::chrono::duration_cast(end - start).count() << std::endl; + #endif + + + return output_removed_edge_size(); } //----------------------------------------------------------------------------------- -// Imput, output +// Input, output //----------------------------------------------------------------------------------- - -// read input file of gml format -void maximal_planar_subgraph_finder::read_from_gml(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; - } - +void maximal_planar_subgraph_finder::init_from_graph(const ogdf::Graph &G) { // create nodes for (int i = 0; i < G.numberOfNodes(); ++i) { _node_list.push_back(new node(P_NODE));