Feat: read file once, re-use ogdf Graph object

This commit is contained in:
Richard Wong 2024-03-03 22:28:42 +09:00
parent e35462ef2d
commit 996222ab60
Signed by: richard
GPG Key ID: 5BD36BA2E9EE33D0
3 changed files with 100 additions and 62 deletions

View File

@ -13,6 +13,7 @@
#include <random> #include <random>
#include <algorithm> #include <algorithm>
#include <unordered_set> #include <unordered_set>
#include <ogdf/fileformats/GraphIO.h>
using namespace std; using namespace std;
@ -155,13 +156,13 @@ class maximal_planar_subgraph_finder
public: public:
maximal_planar_subgraph_finder(); maximal_planar_subgraph_finder();
~maximal_planar_subgraph_finder(); ~maximal_planar_subgraph_finder();
int find_mps(string input_file); int find_mps(const ogdf::Graph &G);
int compute_removed_edge_size(string input_file, vector<int> post_order); int compute_removed_edge_size(const ogdf::Graph &G, vector<int> post_order);
vector<int> generate_post_order(string input_file); vector<int> generate_post_order(const ogdf::Graph &G);
vector<int> generate_mutated_post_order(string input_file, vector<int> post_order, int mutate_point); vector<int> generate_mutated_post_order(const ogdf::Graph &G, vector<int> post_order, int mutate_point);
vector<int> generate_guided_post_order(string input_file, vector<int> post_order); vector<int> generate_guided_post_order(const ogdf::Graph &G, vector<int> post_order);
node* get_new_node(node_type t); 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(); int output_removed_edge_size();
vector<int> return_post_order(); vector<int> return_post_order();
void postOrderTraversal(); void postOrderTraversal();

View File

@ -17,13 +17,14 @@
using namespace std; using namespace std;
int compute_removed_edge_size(string input_file, vector<int> post_order); int compute_removed_edge_size(const ogdf::Graph &G, vector<int> post_order);
// these functions are defined in mps_test.cpp // these functions are defined in mps_test.cpp
// but their signatures are not in mps.h, hence they are declared here // but their signatures are not in mps.h, hence they are declared here
vector<int> generate_post_order(string input_file); ogdf::Graph read_from_gml(string input_file);
vector<int> generate_mutated_post_order(string input_file, vector<int> post_order, int mutate_point); vector<int> generate_post_order(const ogdf::Graph &G);
vector<int> generate_guided_post_order(string input_file, vector<int> post_order); 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(vector<int> state) {
for (int i = 0; i < state.size(); ++i) { for (int i = 0; i < state.size(); ++i) {
@ -33,36 +34,37 @@ void vector_printer(vector<int> state) {
} }
vector<int> repeated_mutation(string input_file, int k_max, int mutate_point) { vector<int> repeated_mutation(const ogdf::Graph &G, int k_max, int mutate_point) {
// generate first post order // 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(input_file); vector<int> state_old = generate_post_order(G);
vector<int> state_new; vector<int> state_new;
for (int k = 0; k < k_max; ++k) { int old_edge_size = compute_removed_edge_size(G, state_old);
std::cout << "cycle:" << k << std::endl;
vector_printer(state_old); int new_edge_size = old_edge_size;
for (int k = 0; k < k_max; ++k) {
// mutation produces rotated view // mutation produces rotated view
state_new = generate_mutated_post_order(input_file, state_old, mutate_point); state_new = generate_mutated_post_order(G, state_old, mutate_point);
vector_printer(state_new);
// another round of guided post order gives canonical representation // another round of guided post order gives canonical representation
state_new = generate_guided_post_order(input_file, state_new); state_new = generate_guided_post_order(G, state_new);
vector_printer(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; return state_new;
} }
void test_correctness(string input_file) { void test_correctness(const ogdf::Graph &G) {
vector<int> state_old = generate_post_order(input_file); vector<int> state_old = generate_post_order(G);
int num_removed_edges; 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 k_max = std::stoi(argv[2]);
int mutate_point = std::stoi(argv[3]); int mutate_point = std::stoi(argv[3]);
const ogdf::Graph G = read_from_gml(input_file);
// generate order here // generate order here
vector<int> post_order = repeated_mutation(input_file, k_max, mutate_point); // vector<int> post_order = repeated_mutation(input_file, k_max, mutate_point);
// test_correctness(input_file); // test_correctness(input_file);
// test timing of function
test_correctness(G);
// // print final order and number of edges // // print final order and number of edges
// // print post_order // // print post_order
// std::copy(post_order.begin(), post_order.end(), std::ostream_iterator<int>(std::cout, ",")); // std::copy(post_order.begin(), post_order.end(), std::ostream_iterator<int>(std::cout, ","));

View File

@ -2,47 +2,63 @@
// Implementation of a MPS algorithm via PC-tree. // Implementation of a MPS algorithm via PC-tree.
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
#include <chrono>
#include "mps.h" #include "mps.h"
#include <ogdf/fileformats/GraphIO.h> #include <ogdf/fileformats/GraphIO.h>
// #define DEBUG // #define DEBUG
#define TIME
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
// Finding MPS // Finding MPS
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
// programs to call from main: // 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; 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<int> post_order) { int compute_removed_edge_size(const ogdf::Graph &G, vector<int> post_order) {
maximal_planar_subgraph_finder m; 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<int> generate_post_order(string input_file) { vector<int> generate_post_order(const ogdf::Graph &G) {
maximal_planar_subgraph_finder m; maximal_planar_subgraph_finder m;
return m.generate_post_order(input_file); return m.generate_post_order(G);
} }
vector<int> generate_mutated_post_order(string input_file, vector<int> post_order, int mutate_point) { vector<int> generate_mutated_post_order(const ogdf::Graph &G, vector<int> post_order, int mutate_point) {
maximal_planar_subgraph_finder m; 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<int> generate_guided_post_order(string input_file, vector<int> post_order) { vector<int> generate_guided_post_order(const ogdf::Graph &G, vector<int> post_order) {
maximal_planar_subgraph_finder m; 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) { int maximal_planar_subgraph_finder::find_mps(const ogdf::Graph &G) {
read_from_gml(input_file); init_from_graph(G);
postOrderTraversal(); postOrderTraversal();
#ifdef DEBUG #ifdef DEBUG
@ -55,8 +71,8 @@ int maximal_planar_subgraph_finder::find_mps(string input_file) {
return output_removed_edge_size(); return output_removed_edge_size();
} }
vector<int> maximal_planar_subgraph_finder::generate_post_order(string input_file) { vector<int> maximal_planar_subgraph_finder::generate_post_order(const ogdf::Graph &G) {
read_from_gml(input_file); init_from_graph(G);
postOrderTraversal(); postOrderTraversal();
#ifdef DEBUG #ifdef DEBUG
@ -68,8 +84,8 @@ vector<int> maximal_planar_subgraph_finder::generate_post_order(string input_fil
} }
// result of this will be used as input to "compute_removed_edge_size" // result of this will be used as input to "compute_removed_edge_size"
vector<int> maximal_planar_subgraph_finder::generate_mutated_post_order(string input_file, vector<int> post_order, int mutate_point) { vector<int> maximal_planar_subgraph_finder::generate_mutated_post_order(const ogdf::Graph &G, vector<int> post_order, int mutate_point) {
read_from_gml(input_file); init_from_graph(G);
mutatedPostOrderTraversal(post_order, mutate_point); mutatedPostOrderTraversal(post_order, mutate_point);
#ifdef DEBUG #ifdef DEBUG
@ -81,8 +97,8 @@ vector<int> maximal_planar_subgraph_finder::generate_mutated_post_order(string i
} }
// result of this will be used as input to "compute_removed_edge_size" // result of this will be used as input to "compute_removed_edge_size"
vector<int> maximal_planar_subgraph_finder::generate_guided_post_order(string input_file, vector<int> post_order) { vector<int> maximal_planar_subgraph_finder::generate_guided_post_order(const ogdf::Graph &G, vector<int> post_order) {
read_from_gml(input_file); init_from_graph(G);
guidedPostOrderTraversal(post_order); guidedPostOrderTraversal(post_order);
// #ifdef DEBUG // #ifdef DEBUG
@ -95,35 +111,49 @@ vector<int> maximal_planar_subgraph_finder::generate_guided_post_order(string in
int maximal_planar_subgraph_finder::compute_removed_edge_size(string input_file, vector<int> post_order) { int maximal_planar_subgraph_finder::compute_removed_edge_size(const ogdf::Graph &G, vector<int> post_order) {
read_from_gml(input_file); // read_from_gml
guidedPostOrderTraversal(post_order); #ifdef TIME
auto start = std::chrono::high_resolution_clock::now();
#ifdef DEBUG #endif
std::cout << "guided post order traversal" << std::endl; init_from_graph(G);
print_post_order(); #ifdef TIME
auto end = std::chrono::high_resolution_clock::now();
std::cout << "init from G: " << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << std::endl;
#endif #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<std::chrono::microseconds>(end - start).count() << std::endl;
#endif
// remaining procedure
#ifdef TIME
start = std::chrono::high_resolution_clock::now();
#endif
sort_adj_list(); sort_adj_list();
determine_edges(); determine_edges();
back_edge_traversal(); back_edge_traversal();
#ifdef TIME
end = std::chrono::high_resolution_clock::now();
std::cout << "remaining procedures: " << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << std::endl;
#endif
return output_removed_edge_size(); return output_removed_edge_size();
} }
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
// Imput, output // Input, output
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
void maximal_planar_subgraph_finder::init_from_graph(const ogdf::Graph &G) {
// 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;
}
// create nodes // create nodes
for (int i = 0; i < G.numberOfNodes(); ++i) { for (int i = 0; i < G.numberOfNodes(); ++i) {
_node_list.push_back(new node(P_NODE)); _node_list.push_back(new node(P_NODE));