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 <algorithm>
#include <unordered_set>
#include <ogdf/fileformats/GraphIO.h>
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<int> post_order);
vector<int> generate_post_order(string input_file);
vector<int> generate_mutated_post_order(string input_file, vector<int> post_order, int mutate_point);
vector<int> generate_guided_post_order(string input_file, vector<int> post_order);
int find_mps(const ogdf::Graph &G);
int compute_removed_edge_size(const ogdf::Graph &G, vector<int> post_order);
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);
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<int> return_post_order();
void postOrderTraversal();

View File

@ -17,13 +17,14 @@
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
// but their signatures are not in mps.h, hence they are declared here
vector<int> generate_post_order(string input_file);
vector<int> generate_mutated_post_order(string input_file, vector<int> post_order, int mutate_point);
vector<int> generate_guided_post_order(string input_file, vector<int> post_order);
ogdf::Graph read_from_gml(string input_file);
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) {
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
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;
int old_edge_size = compute_removed_edge_size(G, state_old);
int new_edge_size = old_edge_size;
for (int k = 0; k < k_max; ++k) {
std::cout << "cycle:" << k << std::endl;
vector_printer(state_old);
// 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<int> state_old = generate_post_order(input_file);
void test_correctness(const ogdf::Graph &G) {
vector<int> 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<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 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<int>(std::cout, ","));

View File

@ -2,47 +2,63 @@
// Implementation of a MPS algorithm via PC-tree.
//-----------------------------------------------------------------------------------
#include <chrono>
#include "mps.h"
#include <ogdf/fileformats/GraphIO.h>
// #define DEBUG
#define TIME
//-----------------------------------------------------------------------------------
// Finding MPS
//-----------------------------------------------------------------------------------
// programs to call from main:
int find_mps(string input_file) {
maximal_planar_subgraph_finder m;
return m.find_mps(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 compute_removed_edge_size(string input_file, vector<int> post_order) {
int find_mps(const ogdf::Graph &G) {
maximal_planar_subgraph_finder m;
return m.compute_removed_edge_size(input_file, post_order);
return m.find_mps(G);
}
vector<int> generate_post_order(string input_file) {
int compute_removed_edge_size(const ogdf::Graph &G, vector<int> post_order) {
maximal_planar_subgraph_finder m;
return m.generate_post_order(input_file);
return m.compute_removed_edge_size(G, post_order);
}
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) {
maximal_planar_subgraph_finder m;
return m.generate_mutated_post_order(input_file, post_order, mutate_point);
return m.generate_post_order(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) {
maximal_planar_subgraph_finder m;
return m.generate_guided_post_order(input_file, post_order);
return m.generate_mutated_post_order(G, post_order, mutate_point);
}
vector<int> generate_guided_post_order(const ogdf::Graph &G, vector<int> post_order) {
maximal_planar_subgraph_finder m;
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<int> maximal_planar_subgraph_finder::generate_post_order(string input_file) {
read_from_gml(input_file);
vector<int> maximal_planar_subgraph_finder::generate_post_order(const ogdf::Graph &G) {
init_from_graph(G);
postOrderTraversal();
#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"
vector<int> maximal_planar_subgraph_finder::generate_mutated_post_order(string input_file, vector<int> post_order, int mutate_point) {
read_from_gml(input_file);
vector<int> maximal_planar_subgraph_finder::generate_mutated_post_order(const ogdf::Graph &G, vector<int> post_order, int mutate_point) {
init_from_graph(G);
mutatedPostOrderTraversal(post_order, mutate_point);
#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"
vector<int> maximal_planar_subgraph_finder::generate_guided_post_order(string input_file, vector<int> post_order) {
read_from_gml(input_file);
vector<int> maximal_planar_subgraph_finder::generate_guided_post_order(const ogdf::Graph &G, vector<int> post_order) {
init_from_graph(G);
guidedPostOrderTraversal(post_order);
// #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) {
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<int> 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<std::chrono::microseconds>(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<std::chrono::microseconds>(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<std::chrono::microseconds>(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));