Feat: introduced mutation and allow re-traversing of previous post-order
This commit is contained in:
parent
46a3810af5
commit
f2ba57b57f
|
@ -18,6 +18,9 @@ using namespace std;
|
||||||
|
|
||||||
int compute_removed_edge_size(string input_file, vector<int> post_order);
|
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 get_graph_size(string input_file) {
|
int get_graph_size(string input_file) {
|
||||||
ogdf::Graph G;
|
ogdf::Graph G;
|
||||||
|
|
||||||
|
@ -36,25 +39,23 @@ int get_graph_size(string input_file) {
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
string input_file = argv[1];
|
string input_file = argv[1];
|
||||||
int num_runs = stoi(argv[2]);
|
|
||||||
// find the size of the graph here
|
|
||||||
int node_size = get_graph_size(input_file);
|
|
||||||
// generate order here
|
// generate order here
|
||||||
vector<int> post_order;
|
vector<int> post_order = generate_post_order(input_file);
|
||||||
for (int i=0; i < node_size; ++i) {
|
std::copy(post_order.begin(), post_order.end(), std::ostream_iterator<int>(std::cout, " "));
|
||||||
post_order.push_back(i);
|
std::cout << std::endl;
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i< num_runs; ++i) {
|
// generate mutated order
|
||||||
std::random_device rd;
|
vector<int> mutated_order = generate_mutated_post_order(input_file, post_order);
|
||||||
std::mt19937 g(rd());
|
post_order = mutated_order;
|
||||||
|
std::copy(post_order.begin(), post_order.end(), std::ostream_iterator<int>(std::cout, " "));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
// print order
|
||||||
|
int removed_edges = compute_removed_edge_size(input_file, post_order);
|
||||||
|
std::cout << "Number of removed edges: " << removed_edges << std::endl;
|
||||||
|
|
||||||
std::shuffle(post_order.begin(), post_order.end(), g);
|
|
||||||
// print order
|
|
||||||
std::copy(post_order.begin(), post_order.end(), std::ostream_iterator<int>(std::cout, " "));
|
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout << "Number of removed edges: " << compute_removed_edge_size(input_file, post_order) << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ maximal_planar_subgraph_finder::get_new_node(node_type t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Determine the post-order-list by a DFS-traversal.
|
//Determine the post-order-list by a DFS-traversal.
|
||||||
void
|
vector<int>
|
||||||
maximal_planar_subgraph_finder::postOrderTraversal() {
|
maximal_planar_subgraph_finder::postOrderTraversal() {
|
||||||
node::init_mark();
|
node::init_mark();
|
||||||
int postOrderID = 0;
|
int postOrderID = 0;
|
||||||
|
@ -29,8 +29,113 @@ maximal_planar_subgraph_finder::postOrderTraversal() {
|
||||||
_node_list[i]->DFS_visit(_post_order_list, postOrderID);
|
_node_list[i]->DFS_visit(_post_order_list, postOrderID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<int> 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.
|
||||||
|
void
|
||||||
|
maximal_planar_subgraph_finder::guidedPostOrderTraversal(vector<int> post_order) {
|
||||||
|
node::init_mark();
|
||||||
|
|
||||||
|
vector<int> 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 end_condition = _node_list.size();
|
||||||
|
int start = rev_post_order[0];
|
||||||
|
int i = start;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (((start > 0) && (i == (start - 1))) || ((start == 0 ) && (i == end_condition - 1)))
|
||||||
|
{
|
||||||
|
if (!_node_list[i]->is_marked())
|
||||||
|
{
|
||||||
|
_node_list[i]->guided_DFS_visit(_post_order_list, _node_list, postOrderID, rev_post_order);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// std::cout << _node_list[i]->node_id() << ", " << !_node_list[i]->is_marked() << std::endl;
|
||||||
|
if (!_node_list[i]->is_marked())
|
||||||
|
{
|
||||||
|
_node_list[i]->guided_DFS_visit(_post_order_list, _node_list, postOrderID, rev_post_order);
|
||||||
|
}
|
||||||
|
i = (i + 1) % end_condition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Determine the post-order-list by a DFS-traversal.
|
||||||
|
vector<int>
|
||||||
|
maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector<int> post_order) {
|
||||||
|
node::init_mark();
|
||||||
|
|
||||||
|
vector<int> rev_post_order;
|
||||||
|
for (int i = post_order.size() - 1; i >= 0; --i) {
|
||||||
|
rev_post_order.push_back(post_order[i]);
|
||||||
|
}
|
||||||
|
int postOrderID = 0;
|
||||||
|
|
||||||
|
// introduce random selection
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937 rng(rd());
|
||||||
|
// Define the range [0, n]
|
||||||
|
int n = _node_list.size() - 1; // Change 'n' to your desired upper bound
|
||||||
|
// Create a uniform distribution for the range [0, n]
|
||||||
|
std::uniform_int_distribution<int> distribution(0, n);
|
||||||
|
// Generate a random number between 0 and n (inclusive)
|
||||||
|
int mutate_point = distribution(rng);
|
||||||
|
std::cout << "the mutate point: " << mutate_point << std::endl;
|
||||||
|
|
||||||
|
// set loop variables
|
||||||
|
int start = rev_post_order[0];
|
||||||
|
int i = start;
|
||||||
|
|
||||||
|
// if mutate_point = 0
|
||||||
|
if (mutate_point == 0) {
|
||||||
|
// generate another point
|
||||||
|
start = distribution(rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int end_condition = _node_list.size();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (((start > 0) && (i == (start - 1))) || ((start == 0 ) && (i == end_condition - 1)))
|
||||||
|
{
|
||||||
|
if (!_node_list[i]->is_marked())
|
||||||
|
{
|
||||||
|
_node_list[i]->mutated_DFS_visit(_post_order_list, _node_list, postOrderID, 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);
|
||||||
|
}
|
||||||
|
i = (i + 1) % end_condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<int> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Set the post-order-list via given list
|
//Set the post-order-list via given list
|
||||||
void
|
void
|
||||||
maximal_planar_subgraph_finder::set_post_order(vector<int> post_order) {
|
maximal_planar_subgraph_finder::set_post_order(vector<int> post_order) {
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
#include <random>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -53,6 +56,8 @@ public:
|
||||||
node* adj(int i);
|
node* adj(int i);
|
||||||
void set_adj_list(vector<node*> vec);
|
void set_adj_list(vector<node*> vec);
|
||||||
void DFS_visit(vector<node*> &dfsList, int &index);
|
void DFS_visit(vector<node*> &dfsList, int &index);
|
||||||
|
void guided_DFS_visit(vector<node*> &dfsList, vector<node*> &node_list, int &index, vector<int> rev_post_order);
|
||||||
|
void mutated_DFS_visit(vector<node*> &dfsList, vector<node*> &node_list, int &index, vector<int> rev_post_order, int &mutate_point);
|
||||||
|
|
||||||
//PARENT-CHILDREN
|
//PARENT-CHILDREN
|
||||||
void set_parent(node* n) ;
|
void set_parent(node* n) ;
|
||||||
|
@ -143,10 +148,14 @@ public:
|
||||||
~maximal_planar_subgraph_finder();
|
~maximal_planar_subgraph_finder();
|
||||||
int find_mps(string input_file);
|
int find_mps(string input_file);
|
||||||
int compute_removed_edge_size(string input_file, vector<int> post_order);
|
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);
|
||||||
node* get_new_node(node_type t);
|
node* get_new_node(node_type t);
|
||||||
void read_from_gml(string input_file);
|
void read_from_gml(string input_file);
|
||||||
int output_removed_edge_size();
|
int output_removed_edge_size();
|
||||||
void postOrderTraversal();
|
vector<int> postOrderTraversal();
|
||||||
|
vector<int> mutatedPostOrderTraversal(vector<int> post_order);
|
||||||
|
void guidedPostOrderTraversal(vector<int> post_order);
|
||||||
void set_post_order(vector<int> post_order);
|
void set_post_order(vector<int> post_order);
|
||||||
void sort_adj_list();
|
void sort_adj_list();
|
||||||
void determine_edges();
|
void determine_edges();
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
// Finding MPS
|
// Finding MPS
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// programs to call from main:
|
||||||
|
|
||||||
int find_mps(string input_file) {
|
int find_mps(string input_file) {
|
||||||
maximal_planar_subgraph_finder m;
|
maximal_planar_subgraph_finder m;
|
||||||
return m.find_mps(input_file);
|
return m.find_mps(input_file);
|
||||||
|
@ -18,6 +21,19 @@ int compute_removed_edge_size(string input_file, vector<int> post_order) {
|
||||||
return m.compute_removed_edge_size(input_file, post_order);
|
return m.compute_removed_edge_size(input_file, post_order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<int> generate_post_order(string input_file) {
|
||||||
|
maximal_planar_subgraph_finder m;
|
||||||
|
return m.generate_post_order(input_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<int> generate_mutated_post_order(string input_file, vector<int> post_order) {
|
||||||
|
maximal_planar_subgraph_finder m;
|
||||||
|
return m.generate_mutated_post_order(input_file, post_order);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------
|
||||||
|
|
||||||
int maximal_planar_subgraph_finder::find_mps(string input_file) {
|
int maximal_planar_subgraph_finder::find_mps(string input_file) {
|
||||||
read_from_gml(input_file);
|
read_from_gml(input_file);
|
||||||
postOrderTraversal();
|
postOrderTraversal();
|
||||||
|
@ -27,10 +43,34 @@ 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) {
|
||||||
|
read_from_gml(input_file);
|
||||||
|
return postOrderTraversal();
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<int> maximal_planar_subgraph_finder::generate_mutated_post_order(string input_file, vector<int> post_order) {
|
||||||
|
read_from_gml(input_file);
|
||||||
|
return mutatedPostOrderTraversal(post_order);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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(string input_file, vector<int> post_order) {
|
||||||
read_from_gml(input_file);
|
read_from_gml(input_file);
|
||||||
set_post_order(post_order);
|
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();
|
sort_adj_list();
|
||||||
determine_edges();
|
determine_edges();
|
||||||
back_edge_traversal();
|
back_edge_traversal();
|
||||||
|
|
|
@ -66,6 +66,103 @@ void node::DFS_visit(vector<node*> &dfsList, int &index) {
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void node::guided_DFS_visit(vector<node*> &dfsList, vector<node*> &node_list, int &index, vector<int> rev_post_order) {
|
||||||
|
mark();
|
||||||
|
// you will want to sort the neighbor nodes by the order they appear in the rev_post_order
|
||||||
|
vector<node *> neighbor_list;
|
||||||
|
std::unordered_set<int> neighbor_set;
|
||||||
|
|
||||||
|
// create an unordered set to efficiently check for presence of an element
|
||||||
|
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
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void node::mutated_DFS_visit(vector<node*> &dfsList, vector<node*> &node_list, int &index, vector<int> 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<node *> neighbor_list;
|
||||||
|
std::unordered_set<int> neighbor_set;
|
||||||
|
|
||||||
|
// create an unordered set to efficiently check for presence of an element
|
||||||
|
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
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (index - 1 == 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;
|
||||||
|
std::mt19937 rng(rd());
|
||||||
|
// Use std::shuffle to shuffle the elements in the vector
|
||||||
|
std::shuffle(neighbor_list.begin(), neighbor_list.end(), rng);
|
||||||
|
// print the neighbors
|
||||||
|
std::cout << "order after mutation: " << std::endl;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
// PARENT-CHILDREN
|
// PARENT-CHILDREN
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue