Bug: fixed broken guided traversal. Discovered that guided traversal
rotates the dfs tree.
This commit is contained in:
parent
54b51b002d
commit
8ca09dbf9e
|
@ -56,8 +56,17 @@ 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 guided_DFS_visit(vector<node *> &dfsList,
|
||||||
void mutated_DFS_visit(vector<node*> &dfsList, vector<node*> &node_list, int &index, vector<int> rev_post_order, int &mutate_point);
|
vector<node *> &node_list,
|
||||||
|
int &return_index,
|
||||||
|
vector<int> rev_post_order,
|
||||||
|
int prev_node);
|
||||||
|
void mutated_DFS_visit(vector<node*> &dfsList,
|
||||||
|
vector<node*> &node_list,
|
||||||
|
int &index,
|
||||||
|
int &traversal_index,
|
||||||
|
vector<int> rev_post_order,
|
||||||
|
int mutate_point);
|
||||||
|
|
||||||
//PARENT-CHILDREN
|
//PARENT-CHILDREN
|
||||||
void set_parent(node* n) ;
|
void set_parent(node* n) ;
|
||||||
|
@ -150,6 +159,7 @@ public:
|
||||||
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_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);
|
||||||
|
vector<int> generate_guided_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();
|
||||||
|
|
|
@ -21,15 +21,31 @@ int compute_removed_edge_size(string input_file, vector<int> post_order);
|
||||||
|
|
||||||
vector<int> generate_post_order(string input_file);
|
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);
|
||||||
|
vector<int> generate_guided_post_order(string input_file, vector<int> post_order);
|
||||||
|
|
||||||
|
|
||||||
vector<int> repeated_mutation(string input_file, int k_max) {
|
vector<int> repeated_mutation(string input_file, int k_max) {
|
||||||
|
// 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(input_file);
|
||||||
vector<int> state_new;
|
vector<int> state_new;
|
||||||
int num_removed_edges;
|
int num_removed_edges;
|
||||||
for (int k = 0; k < k_max; ++k) {
|
for (int k = 0; k < k_max; ++k) {
|
||||||
state_new = generate_mutated_post_order(input_file, state_old);
|
// rotate it first
|
||||||
num_removed_edges = compute_removed_edge_size(input_file, state_new);
|
std::cout << "cycle:" << k << std::endl;
|
||||||
|
std::cout << "rotate the dfs tree" << std::endl;
|
||||||
|
state_new = generate_guided_post_order(input_file, state_old);
|
||||||
|
// then the next traversal will rotate it back
|
||||||
|
std::cout << "mutate the dfs tree" << std::endl;
|
||||||
|
state_new = generate_mutated_post_order(input_file, state_new);
|
||||||
|
// num_removed_edges = compute_removed_edge_size(input_file, state_new);
|
||||||
|
// first time will rotate the tree
|
||||||
|
std::cout << "rotate the dfs tree" << std::endl;
|
||||||
|
state_new = generate_guided_post_order(input_file, state_new);
|
||||||
|
// second time will rotate back the rotated tree
|
||||||
|
std::cout << "print the mutated tree again" << std::endl;
|
||||||
|
state_new = generate_guided_post_order(input_file, state_new);
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
return state_new;
|
return state_new;
|
||||||
}
|
}
|
||||||
|
@ -62,8 +78,8 @@ int main(int argc, char* argv[]) {
|
||||||
int k_max = std::stoi(argv[2]);
|
int k_max = std::stoi(argv[2]);
|
||||||
|
|
||||||
// generate order here
|
// generate order here
|
||||||
// vector<int> post_order = repeated_mutation(input_file, k_max);
|
vector<int> post_order = repeated_mutation(input_file, k_max);
|
||||||
test_correctness(input_file);
|
// test_correctness(input_file);
|
||||||
|
|
||||||
// // print final order and number of edges
|
// // print final order and number of edges
|
||||||
// // print post_order
|
// // print post_order
|
||||||
|
|
|
@ -61,19 +61,21 @@ maximal_planar_subgraph_finder::guidedPostOrderTraversal(vector<int> post_order)
|
||||||
int end_condition = _node_list.size();
|
int end_condition = _node_list.size();
|
||||||
int start = rev_post_order[0];
|
int start = rev_post_order[0];
|
||||||
int i = start;
|
int i = start;
|
||||||
|
|
||||||
|
int prev_node = INT_MAX;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (((start > 0) && (i == (start - 1))) || ((start == 0 ) && (i == end_condition - 1)))
|
if (((start > 0) && (i == (start - 1))) || ((start == 0 ) && (i == end_condition - 1)))
|
||||||
{
|
{
|
||||||
if (!_node_list[i]->is_marked())
|
if (!_node_list[i]->is_marked())
|
||||||
{
|
{
|
||||||
_node_list[i]->guided_DFS_visit(_post_order_list, _node_list, postOrderID, rev_post_order);
|
_node_list[i]->guided_DFS_visit(_post_order_list, _node_list, postOrderID, rev_post_order, prev_node);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!_node_list[i]->is_marked())
|
if (!_node_list[i]->is_marked())
|
||||||
{
|
{
|
||||||
_node_list[i]->guided_DFS_visit(_post_order_list, _node_list, postOrderID, rev_post_order);
|
_node_list[i]->guided_DFS_visit(_post_order_list, _node_list, postOrderID, rev_post_order, prev_node);
|
||||||
}
|
}
|
||||||
i = (i + 1) % end_condition;
|
i = (i + 1) % end_condition;
|
||||||
}
|
}
|
||||||
|
@ -91,6 +93,7 @@ maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector<int> post_order
|
||||||
rev_post_order.push_back(post_order[i]);
|
rev_post_order.push_back(post_order[i]);
|
||||||
}
|
}
|
||||||
int postOrderID = 0;
|
int postOrderID = 0;
|
||||||
|
int traversal_index = 0;
|
||||||
|
|
||||||
// introduce random selection
|
// introduce random selection
|
||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
|
@ -123,13 +126,13 @@ maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector<int> post_order
|
||||||
{
|
{
|
||||||
if (!_node_list[i]->is_marked())
|
if (!_node_list[i]->is_marked())
|
||||||
{
|
{
|
||||||
_node_list[i]->mutated_DFS_visit(_post_order_list, _node_list, postOrderID, rev_post_order, mutate_point);
|
_node_list[i]->mutated_DFS_visit(_post_order_list, _node_list, postOrderID, traversal_index, rev_post_order, mutate_point);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!_node_list[i]->is_marked())
|
if (!_node_list[i]->is_marked())
|
||||||
{
|
{
|
||||||
_node_list[i]->mutated_DFS_visit(_post_order_list, _node_list, postOrderID, rev_post_order, mutate_point);
|
_node_list[i]->mutated_DFS_visit(_post_order_list, _node_list, postOrderID, traversal_index, rev_post_order, mutate_point);
|
||||||
}
|
}
|
||||||
i = (i + 1) % end_condition;
|
i = (i + 1) % end_condition;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,11 @@ vector<int> generate_mutated_post_order(string input_file, vector<int> post_orde
|
||||||
return m.generate_mutated_post_order(input_file, post_order);
|
return m.generate_mutated_post_order(input_file, post_order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<int> generate_guided_post_order(string input_file, vector<int> post_order) {
|
||||||
|
maximal_planar_subgraph_finder m;
|
||||||
|
return m.generate_guided_post_order(input_file, post_order);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------
|
// ---------
|
||||||
|
|
||||||
|
@ -55,6 +60,7 @@ vector<int> maximal_planar_subgraph_finder::generate_post_order(string input_fil
|
||||||
postOrderTraversal();
|
postOrderTraversal();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
std::cout << "standard post order traversal" << std::endl;
|
||||||
print_post_order();
|
print_post_order();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -67,6 +73,20 @@ vector<int> maximal_planar_subgraph_finder::generate_mutated_post_order(string i
|
||||||
mutatedPostOrderTraversal(post_order);
|
mutatedPostOrderTraversal(post_order);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
std::cout << "mutated post order traversal" << std::endl;
|
||||||
|
print_post_order();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return return_post_order();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
guidedPostOrderTraversal(post_order);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::cout << "guided post order traversal" << std::endl;
|
||||||
print_post_order();
|
print_post_order();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -74,16 +94,13 @@ vector<int> maximal_planar_subgraph_finder::generate_mutated_post_order(string i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
guidedPostOrderTraversal(post_order);
|
guidedPostOrderTraversal(post_order);
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
std::cout << "guided post order traversal" << std::endl;
|
||||||
print_post_order();
|
print_post_order();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -69,50 +69,96 @@ void node::DFS_visit(vector<node*> &dfsList, int &index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void node::guided_DFS_visit(vector<node*> &dfsList, vector<node*> &node_list, int &index, vector<int> rev_post_order) {
|
void node::guided_DFS_visit(vector<node *> &dfsList,
|
||||||
|
vector<node *> &node_list,
|
||||||
|
int &return_index,
|
||||||
|
vector<int> rev_post_order,
|
||||||
|
int prev_node)
|
||||||
|
{
|
||||||
|
|
||||||
mark();
|
mark();
|
||||||
|
|
||||||
|
// purpose of this block: create list of neighbors ordered in the order they appear in rev_post_order
|
||||||
|
// we want to select neighbors that match the rev_post_order at the specific traversal_index
|
||||||
|
|
||||||
// purpose of this block: create list of neighbors
|
// create an unordered set to efficiently check for presence of an element
|
||||||
vector<node *> neighbor_list;
|
std::unordered_set<int> neighbor_set;
|
||||||
for (int i = 0; i < _adj_list.size(); ++i) {
|
for (int i = 0; i < _adj_list.size(); ++i) {
|
||||||
// we get the neighbors via _adj_list
|
neighbor_set.insert(_adj_list[i]->node_id());
|
||||||
// we get the id's of the neighbor nodes, then we use the id's to get the actual nodes via node_list
|
|
||||||
// node_list maps id to the actual node
|
|
||||||
neighbor_list.push_back(node_list[_adj_list[i]->node_id()]);
|
|
||||||
}
|
}
|
||||||
|
// when an element in rev_post_order is found in neighbor_set, we add that to neighbor_list
|
||||||
|
// this produces a neighbor_list that follows the order by which they occur in the rev_post_order
|
||||||
|
// it is ok if the neighbor was already visited before,
|
||||||
|
// it would've been marked and will be subsequently ignored
|
||||||
|
vector<node *> neighbor_list;
|
||||||
|
for (int i = 0; i < rev_post_order.size(); ++i) {
|
||||||
|
if (neighbor_set.find(rev_post_order[i]) != neighbor_set.end()) {
|
||||||
|
// only add if newly encountered
|
||||||
|
if (!node_list[rev_post_order[i]]->is_marked()) {
|
||||||
|
neighbor_list.push_back(node_list[rev_post_order[i]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::cout << "current node:" << this->node_id() << std::endl;
|
||||||
|
std::cout << "prev node:" << prev_node << std::endl;
|
||||||
|
for (int i = 0; i < neighbor_list.size(); ++i) {
|
||||||
|
std::cout << neighbor_list[i]->node_id() << "(" << neighbor_list[i]->is_marked() << ")" << ",";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < neighbor_list.size(); ++i) {
|
for (int i = 0; i < neighbor_list.size(); ++i) {
|
||||||
if (!neighbor_list[i]->is_marked()) {
|
if (!neighbor_list[i]->is_marked()) {
|
||||||
neighbor_list[i]->_parent = this;
|
neighbor_list[i]->_parent = this;
|
||||||
neighbor_list[i]->guided_DFS_visit(dfsList, node_list, index, rev_post_order);
|
neighbor_list[i]->guided_DFS_visit(dfsList, node_list, return_index, rev_post_order, this->node_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_post_order_index(index);
|
set_post_order_index(return_index);
|
||||||
dfsList.push_back(this);
|
dfsList.push_back(this);
|
||||||
++index;
|
++return_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 &return_index,
|
||||||
|
int &traversal_index,
|
||||||
|
vector<int> rev_post_order,
|
||||||
|
int mutate_point)
|
||||||
|
{
|
||||||
|
|
||||||
// mark current node
|
// mark current node
|
||||||
mark();
|
mark();
|
||||||
|
|
||||||
|
// purpose of this block: create list of neighbors ordered in the order they appear in rev_post_order
|
||||||
|
// we want to select neighbors that match the rev_post_order at the specific traversal_index
|
||||||
|
|
||||||
// purpose of this block: create list of neighbors
|
// create an unordered set to efficiently check for presence of an element
|
||||||
vector<node *> neighbor_list;
|
std::unordered_set<int> neighbor_set;
|
||||||
for (int i = 0; i < _adj_list.size(); ++i) {
|
for (int i = 0; i < _adj_list.size(); ++i) {
|
||||||
// we get the neighbors via _adj_list
|
neighbor_set.insert(_adj_list[i]->node_id());
|
||||||
// we get the id's of the neighbor nodes, then we use the id's to get the actual nodes via node_list
|
|
||||||
// node_list maps id to the actual node
|
|
||||||
neighbor_list.push_back(node_list[_adj_list[i]->node_id()]);
|
|
||||||
}
|
}
|
||||||
|
// when an element in rev_post_order is found in neighbor_set, we add that to neighbor_list
|
||||||
|
// this produces a neighbor_list that follows the order by which they occur in the rev_post_order
|
||||||
|
// it is ok if the neighbor was already visited before,
|
||||||
|
// it would've been marked and will be subsequently ignored
|
||||||
|
vector<node *> 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]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// since we increment the index before this line, the current index is "index - 1"
|
// since we increment the index before this line, the current index is "index - 1"
|
||||||
// if the current index matches the mutate_point, then we know this is the cycle to mutate
|
// if the current index matches the mutate_point, then we know this is the cycle to mutate
|
||||||
if (index - 1 == mutate_point) {
|
if (traversal_index == mutate_point) {
|
||||||
// Create a random number generator and seed it
|
// Create a random number generator and seed it
|
||||||
// std::cout << "mutated at index: " << index - 1<< "and at mutate point: " << mutate_point << std::endl;
|
// std::cout << "mutated at index: " << index - 1<< "and at mutate point: " << mutate_point << std::endl;
|
||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
|
@ -120,23 +166,25 @@ void node::mutated_DFS_visit(vector<node*> &dfsList, vector<node*> &node_list, i
|
||||||
// Use std::shuffle to shuffle the elements in the vector
|
// Use std::shuffle to shuffle the elements in the vector
|
||||||
std::shuffle(neighbor_list.begin(), neighbor_list.end(), rng);
|
std::shuffle(neighbor_list.begin(), neighbor_list.end(), rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// increment traversal index after checking
|
||||||
|
// next node will receive incremented index
|
||||||
|
traversal_index++;
|
||||||
|
|
||||||
for (int i = 0; i < neighbor_list.size(); ++i)
|
for (int i = 0; i < neighbor_list.size(); ++i)
|
||||||
{
|
{
|
||||||
if (!neighbor_list[i]->is_marked())
|
if (!neighbor_list[i]->is_marked())
|
||||||
{
|
{
|
||||||
neighbor_list[i]->_parent = this;
|
neighbor_list[i]->_parent = this;
|
||||||
neighbor_list[i]->mutated_DFS_visit(dfsList, node_list, index, rev_post_order, mutate_point);
|
neighbor_list[i]->mutated_DFS_visit(dfsList, node_list, return_index, traversal_index, rev_post_order, mutate_point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_post_order_index(index);
|
set_post_order_index(return_index);
|
||||||
dfsList.push_back(this);
|
dfsList.push_back(this);
|
||||||
++index;
|
++return_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
// PARENT-CHILDREN
|
// PARENT-CHILDREN
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue