Feat: implemented mutate_point to measure separation of removed
back-edges based on mutated and preserved sections
This commit is contained in:
parent
00ce484c58
commit
446ba9ed1e
|
@ -0,0 +1,2 @@
|
|||
The objective of this branch is to measure the number of removed edges between
|
||||
preserved and mutated parts of the DFS tree.
|
|
@ -33,6 +33,12 @@ enum node_type {
|
|||
AE_VIRTUAL_ROOT = 3
|
||||
};
|
||||
|
||||
enum back_edge_type {
|
||||
RETAINED = 0,
|
||||
MUTATED_REMOVE = 1,
|
||||
NON_MUTATED_REMOVE = 2
|
||||
};
|
||||
|
||||
class node
|
||||
{
|
||||
public:
|
||||
|
@ -57,7 +63,7 @@ public:
|
|||
void set_adj_list(vector<node*> vec);
|
||||
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);
|
||||
void mutated_DFS_visit(vector<node*> &dfsList, vector<node*> &node_list, int &index, vector<int> rev_post_order, int mutate_point);
|
||||
|
||||
//PARENT-CHILDREN
|
||||
void set_parent(node* n) ;
|
||||
|
@ -147,14 +153,18 @@ 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);
|
||||
int compute_removed_edge_size(string input_file, vector<int> post_order, int mutate_point);
|
||||
void print_removed_edge_size(string input_file, vector<int> post_order, int mutate_point);
|
||||
vector<int> generate_post_order(string input_file);
|
||||
vector<int> generate_mutated_post_order(string input_file, vector<int> post_order);
|
||||
vector<int> generate_mutated_post_order(string input_file, vector<int> post_order, int mutate_point);
|
||||
void set_mutate_point(int mutate_point);
|
||||
int get_mutate_point();
|
||||
node* get_new_node(node_type t);
|
||||
void read_from_gml(string input_file);
|
||||
int output_removed_edge_size();
|
||||
void output_print_removed_edge_size();
|
||||
int output_int_removed_edge_size();
|
||||
vector<int> postOrderTraversal();
|
||||
vector<int> mutatedPostOrderTraversal(vector<int> post_order);
|
||||
vector<int> mutatedPostOrderTraversal(vector<int> post_order, int mutate_point);
|
||||
void guidedPostOrderTraversal(vector<int> post_order);
|
||||
void set_post_order(vector<int> post_order);
|
||||
void sort_adj_list();
|
||||
|
@ -182,8 +192,9 @@ private:
|
|||
vector<pair<node*, node*> > _edge_list; // Edges in DFS-tree. These edges must be contained in the maximal planar subgraph that we found.
|
||||
vector<node*> _post_order_list; //The sorted version (increasing with post-order-index) of _node_list.
|
||||
vector<pair<node*, node*> > _back_edge_list; // Edges other than that in DFS-tree. (The first node's index is higher than the second's.)
|
||||
vector<bool> _is_back_edge_eliminate; //Record that if the back-edge has been eliminated or not.
|
||||
vector<back_edge_type> _is_back_edge_eliminate; //Record that if the back-edge has been eliminated or not.
|
||||
vector<node*> _new_node_list; //Newly added nodes.
|
||||
int _mutate_point; // store the mutate_point
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,51 +11,51 @@
|
|||
#include <iterator>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#include <ogdf/fileformats/GraphIO.h>
|
||||
#define START_TEMP 100
|
||||
|
||||
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, int mutate_point);
|
||||
|
||||
void print_removed_edge_size(string input_file, vector<int> post_order, int mutate_point);
|
||||
|
||||
vector<int> generate_post_order(string input_file);
|
||||
vector<int> generate_mutated_post_order(string input_file, vector<int> post_order);
|
||||
|
||||
double temp_decay(int k, int k_max) {
|
||||
return 1.0 - ((k + 1.0) / (k_max));
|
||||
}
|
||||
vector<int> generate_mutated_post_order_at_x(string input_file, vector<int> post_order, int mutate_point);
|
||||
|
||||
vector<int> sa_solve(string input_file, int k_max) {
|
||||
|
||||
// create sampling function
|
||||
std::random_device rd;
|
||||
std::mt19937 rng(rd());
|
||||
std::uniform_real_distribution<> distribution(0.0, 1.0);
|
||||
|
||||
void measure_removed_edges(string input_file, int k_max, int mutate_point) {
|
||||
// generate first state
|
||||
vector<int> state_old = generate_post_order(input_file);
|
||||
vector<int> state_new;
|
||||
int e_old = compute_removed_edge_size(input_file, state_old);
|
||||
int e_new = 0;
|
||||
int delta = 0;
|
||||
// initialize terms
|
||||
double temp;
|
||||
|
||||
std::cout << "first generated order" << std::endl;
|
||||
for (int i = 0; i < state_old.size(); i++) {
|
||||
std::cout << state_old[i] << ", ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
int removed_old;
|
||||
int removed_new;
|
||||
|
||||
for (int k = 0; k < k_max; ++k) {
|
||||
temp = START_TEMP * temp_decay(k, k_max);
|
||||
std::cout << std::endl;
|
||||
std::cout << "new generated order" << std::endl;
|
||||
state_new = generate_mutated_post_order_at_x(input_file, state_old, mutate_point);
|
||||
removed_old = compute_removed_edge_size(input_file, state_old, mutate_point);
|
||||
removed_new = compute_removed_edge_size(input_file, state_new, mutate_point);
|
||||
// for (int i = 0; i < state_new.size(); i++) {
|
||||
// std::cout << state_new[i] << ", ";
|
||||
// }
|
||||
// std::cout << std::endl;
|
||||
|
||||
std::cout << "removed edges in old: " << removed_old << std::endl;
|
||||
std::cout << "removed edges in new: " << removed_new << std::endl;
|
||||
print_removed_edge_size(input_file, state_new, mutate_point);
|
||||
|
||||
state_new = generate_mutated_post_order(input_file, state_old);
|
||||
e_new = compute_removed_edge_size(input_file, state_new);
|
||||
delta = e_new - e_old;
|
||||
|
||||
if (std::exp( -(delta) / temp) > distribution(rng)) {
|
||||
state_old = state_new;
|
||||
e_old = e_new;
|
||||
}
|
||||
}
|
||||
|
||||
return state_old;
|
||||
|
||||
}
|
||||
|
||||
|
@ -78,16 +78,10 @@ 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]);
|
||||
|
||||
// generate order here
|
||||
vector<int> post_order = sa_solve(input_file, k_max);
|
||||
|
||||
// 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;
|
||||
measure_removed_edges(input_file, k_max, mutate_point);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
//-----------------------------------------------------------------------------------
|
||||
|
||||
#include "mps.h"
|
||||
#include <cassert>
|
||||
|
||||
// constructor can be made empty
|
||||
maximal_planar_subgraph_finder::maximal_planar_subgraph_finder() {}
|
||||
|
@ -19,6 +20,18 @@ maximal_planar_subgraph_finder::get_new_node(node_type t) {
|
|||
return _new_node_list[_new_node_list.size()-1];
|
||||
}
|
||||
|
||||
// setter and getter for mutate_point
|
||||
void
|
||||
maximal_planar_subgraph_finder::set_mutate_point(int mutate_point) {
|
||||
_mutate_point = mutate_point;
|
||||
}
|
||||
|
||||
int
|
||||
maximal_planar_subgraph_finder::get_mutate_point() {
|
||||
return _mutate_point;
|
||||
}
|
||||
|
||||
|
||||
//Determine the post-order-list by a DFS-traversal.
|
||||
vector<int>
|
||||
maximal_planar_subgraph_finder::postOrderTraversal() {
|
||||
|
@ -73,7 +86,7 @@ maximal_planar_subgraph_finder::guidedPostOrderTraversal(vector<int> post_order)
|
|||
|
||||
//Determine the post-order-list by a DFS-traversal.
|
||||
vector<int>
|
||||
maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector<int> post_order) {
|
||||
maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector<int> post_order, int mutate_point) {
|
||||
node::init_mark();
|
||||
|
||||
vector<int> rev_post_order;
|
||||
|
@ -83,26 +96,14 @@ maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector<int> post_order
|
|||
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;
|
||||
assert(mutate_point < n);
|
||||
|
||||
// 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)
|
||||
|
@ -173,7 +174,7 @@ maximal_planar_subgraph_finder::determine_edges() {
|
|||
if (_post_order_list[i]->adj(j)->post_order_index() > i) break;
|
||||
if (_post_order_list[i]->adj(j)->get_1st_label() == i) continue;
|
||||
_back_edge_list.push_back(pair<node*, node*> (_post_order_list[i], _post_order_list[i]->adj(j)));
|
||||
_is_back_edge_eliminate.push_back(false);
|
||||
_is_back_edge_eliminate.push_back(RETAINED);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < _post_order_list.size(); ++i) {
|
||||
|
@ -186,10 +187,25 @@ void
|
|||
maximal_planar_subgraph_finder::back_edge_traversal() {
|
||||
node* i_node = 0;
|
||||
node* current_node = 0;
|
||||
int dfs_mutate_point = get_mutate_point() + 1;
|
||||
int node_list_last_index = _node_list.size() - 1;
|
||||
int post_order_mutate_point = node_list_last_index - dfs_mutate_point;
|
||||
std::cout << "post_order_mutate_point: " << post_order_mutate_point << std::endl;
|
||||
// back_edge first node is higher than the second
|
||||
for (int i = 0; i < _back_edge_list.size(); ++i) {
|
||||
current_node = _back_edge_list[i].second;
|
||||
i_node = _back_edge_list[i].first;
|
||||
if (!back_edge_traversal(current_node, i_node->post_order_index())) _is_back_edge_eliminate[i] = true;
|
||||
// back_edge_traversal returns true if it should be included
|
||||
// false otherwise
|
||||
if (!back_edge_traversal(current_node, i_node->post_order_index())) {
|
||||
// if current_node is higher than post_order_mutate_point
|
||||
// then it is the preserved section
|
||||
if (current_node->post_order_index() > post_order_mutate_point) {
|
||||
_is_back_edge_eliminate[i] = NON_MUTATED_REMOVE;
|
||||
} else {
|
||||
_is_back_edge_eliminate[i] = MUTATED_REMOVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,21 +4,29 @@
|
|||
|
||||
#include "mps.h"
|
||||
#include <ogdf/fileformats/GraphIO.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
// Finding MPS
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
// programs to call from main:
|
||||
// functions to call from main:
|
||||
|
||||
int find_mps(string input_file) {
|
||||
maximal_planar_subgraph_finder m;
|
||||
return m.find_mps(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, int mutate_point) {
|
||||
maximal_planar_subgraph_finder m;
|
||||
return m.compute_removed_edge_size(input_file, post_order);
|
||||
return m.compute_removed_edge_size(input_file, post_order, mutate_point);
|
||||
}
|
||||
|
||||
void print_removed_edge_size(string input_file, vector<int> post_order, int mutate_point) {
|
||||
maximal_planar_subgraph_finder m;
|
||||
m.print_removed_edge_size(input_file, post_order, mutate_point);
|
||||
}
|
||||
|
||||
vector<int> generate_post_order(string input_file) {
|
||||
|
@ -26,13 +34,13 @@ vector<int> generate_post_order(string input_file) {
|
|||
return m.generate_post_order(input_file);
|
||||
}
|
||||
|
||||
vector<int> generate_mutated_post_order(string input_file, vector<int> post_order) {
|
||||
vector<int> generate_mutated_post_order_at_x(string input_file, vector<int> post_order, int mutate_point) {
|
||||
maximal_planar_subgraph_finder m;
|
||||
return m.generate_mutated_post_order(input_file, post_order);
|
||||
return m.generate_mutated_post_order(input_file, post_order, mutate_point);
|
||||
}
|
||||
|
||||
|
||||
// ---------
|
||||
// immediate functions called by functions called from main
|
||||
|
||||
int maximal_planar_subgraph_finder::find_mps(string input_file) {
|
||||
read_from_gml(input_file);
|
||||
|
@ -40,22 +48,25 @@ int maximal_planar_subgraph_finder::find_mps(string input_file) {
|
|||
sort_adj_list();
|
||||
determine_edges();
|
||||
back_edge_traversal();
|
||||
return output_removed_edge_size();
|
||||
return output_int_removed_edge_size();
|
||||
}
|
||||
|
||||
vector<int> maximal_planar_subgraph_finder::generate_post_order(string input_file) {
|
||||
read_from_gml(input_file);
|
||||
set_mutate_point(INT_MAX); // essentially removed mutate_point
|
||||
return postOrderTraversal();
|
||||
}
|
||||
|
||||
vector<int> maximal_planar_subgraph_finder::generate_mutated_post_order(string input_file, vector<int> post_order) {
|
||||
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);
|
||||
return mutatedPostOrderTraversal(post_order);
|
||||
set_mutate_point(INT_MAX);
|
||||
return mutatedPostOrderTraversal(post_order, mutate_point);
|
||||
}
|
||||
|
||||
|
||||
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, int mutate_point) {
|
||||
read_from_gml(input_file);
|
||||
set_mutate_point(mutate_point);
|
||||
guidedPostOrderTraversal(post_order);
|
||||
|
||||
// let's reverse the order
|
||||
|
@ -74,11 +85,38 @@ int maximal_planar_subgraph_finder::compute_removed_edge_size(string input_file,
|
|||
sort_adj_list();
|
||||
determine_edges();
|
||||
back_edge_traversal();
|
||||
return output_removed_edge_size();
|
||||
return output_int_removed_edge_size();
|
||||
}
|
||||
|
||||
void maximal_planar_subgraph_finder::print_removed_edge_size(string input_file, vector<int> post_order, int mutate_point) {
|
||||
read_from_gml(input_file);
|
||||
set_mutate_point(mutate_point);
|
||||
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();
|
||||
determine_edges();
|
||||
back_edge_traversal();
|
||||
output_print_removed_edge_size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
// Imput, output
|
||||
// Input, output
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
@ -97,6 +135,14 @@ void maximal_planar_subgraph_finder::read_from_gml(string input_file) {
|
|||
_node_list[i]->set_id(i);
|
||||
}
|
||||
|
||||
// vector<ogdf::edge> unique_edges;
|
||||
// // we want to get unique edge only
|
||||
// for (ogdf::edge e : G.edges) {
|
||||
// // Check if the edge is already in the array
|
||||
// if (std::find(unique_edges.begin(), unique_edges.end(), e) == unique_edges.end())
|
||||
// unique_edges.push_back(e);
|
||||
// }
|
||||
|
||||
// create edges
|
||||
for (ogdf::edge e : G.edges) {
|
||||
ogdf::node source = e->source();
|
||||
|
@ -109,10 +155,47 @@ void maximal_planar_subgraph_finder::read_from_gml(string input_file) {
|
|||
|
||||
|
||||
// count the number of removed edges
|
||||
int maximal_planar_subgraph_finder::output_removed_edge_size() {
|
||||
void maximal_planar_subgraph_finder::output_print_removed_edge_size() {
|
||||
int mutated_sum = 0;
|
||||
int preserved_sum = 0;
|
||||
|
||||
vector<pair<node*, node*>> mutated_removed_edges;
|
||||
vector<pair<node*, node*>> preserved_removed_edges;
|
||||
|
||||
for (int i = 0; i < _back_edge_list.size(); ++i) {
|
||||
if (_is_back_edge_eliminate[i] == MUTATED_REMOVE) {
|
||||
mutated_removed_edges.push_back(_back_edge_list[i]);
|
||||
++mutated_sum;
|
||||
}
|
||||
if (_is_back_edge_eliminate[i] == NON_MUTATED_REMOVE) {
|
||||
preserved_removed_edges.push_back(_back_edge_list[i]);
|
||||
++preserved_sum;
|
||||
}
|
||||
}
|
||||
|
||||
// print the edges
|
||||
// std::cout << "mutated removed edges: " << std::endl;
|
||||
// for (int i = 0; i < mutated_removed_edges.size(); ++i) {
|
||||
// std::cout << mutated_removed_edges[i].first->node_id() << ", " <<
|
||||
// mutated_removed_edges[i].second->node_id() << std::endl;
|
||||
// }
|
||||
|
||||
// std::cout << "preserved removed edges: " << std::endl;
|
||||
// for (int i = 0; i < preserved_removed_edges.size(); ++i) {
|
||||
// std::cout << preserved_removed_edges[i].first->node_id() << ", " <<
|
||||
// preserved_removed_edges[i].second->node_id() << std::endl;
|
||||
// }
|
||||
|
||||
std::cout << "<- sum of removed edges -> " << std::endl;
|
||||
std::cout << "mutated portion: " << mutated_sum << std::endl;
|
||||
std::cout << "preserved portion: " << preserved_sum << std::endl;
|
||||
}
|
||||
|
||||
int maximal_planar_subgraph_finder::output_int_removed_edge_size() {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < _back_edge_list.size(); ++i) {
|
||||
if (_is_back_edge_eliminate[i]) ++sum;
|
||||
if (_is_back_edge_eliminate[i] != RETAINED) ++sum;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
|
@ -105,7 +105,7 @@ void node::guided_DFS_visit(vector<node*> &dfsList, vector<node*> &node_list, in
|
|||
}
|
||||
|
||||
|
||||
void node::mutated_DFS_visit(vector<node*> &dfsList, vector<node*> &node_list, int &index, vector<int> rev_post_order, int &mutate_point) {
|
||||
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;
|
||||
|
@ -134,21 +134,27 @@ void node::mutated_DFS_visit(vector<node*> &dfsList, vector<node*> &node_list, i
|
|||
dfsList.push_back(this);
|
||||
++index;
|
||||
|
||||
// we have reached the mutate point
|
||||
// we change the order of the neighbor list just before the mutate point
|
||||
// so that the mutation begins at the mutate point
|
||||
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;
|
||||
|
||||
// print the neighbors
|
||||
// print the neighbors that are not yet marked
|
||||
std::cout << "current index: " << index - 1 << std::endl;
|
||||
std::cout << "order after mutation: ";
|
||||
for (int i = 0; i < neighbor_list.size(); ++i) {
|
||||
if (!neighbor_list[i]->is_marked())
|
||||
std::cout << neighbor_list[i]->node_id() << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
for (int i = 0; i < neighbor_list.size(); ++i)
|
||||
|
|
Loading…
Reference in New Issue