diff --git a/README.md b/README.md new file mode 100644 index 0000000..9ead933 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +This branch tests the idea of using fuzzing to choose the direction of mutation diff --git a/deferred_planarity_test/include/mps.h b/deferred_planarity_test/include/mps.h index d70fc1d..3003163 100644 --- a/deferred_planarity_test/include/mps.h +++ b/deferred_planarity_test/include/mps.h @@ -153,10 +153,12 @@ public: node* get_new_node(node_type t); void read_from_gml(string input_file); int output_removed_edge_size(); - vector postOrderTraversal(); - vector mutatedPostOrderTraversal(vector post_order); + vector return_post_order(); + void postOrderTraversal(); void guidedPostOrderTraversal(vector post_order); - void set_post_order(vector post_order); + void mutatedPostOrderTraversal(vector post_order); + // void set_post_order(vector post_order); + void print_post_order(); void sort_adj_list(); void determine_edges(); void back_edge_traversal(); diff --git a/deferred_planarity_test/src/main.cpp b/deferred_planarity_test/src/main.cpp index cce7b9d..88cb85a 100644 --- a/deferred_planarity_test/src/main.cpp +++ b/deferred_planarity_test/src/main.cpp @@ -22,43 +22,25 @@ int compute_removed_edge_size(string input_file, vector post_order); vector generate_post_order(string input_file); vector generate_mutated_post_order(string input_file, vector post_order); -double temp_decay(int k, int k_max) { - return 1.0 - ((k + 1.0) / (k_max)); -} -vector 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); - - // generate first state +vector repeated_mutation(string input_file, int k_max) { vector state_old = generate_post_order(input_file); vector state_new; - int e_old = compute_removed_edge_size(input_file, state_old); - int e_new = 0; - int delta = 0; - // initialize terms - double temp; - + int num_removed_edges; for (int k = 0; k < k_max; ++k) { - temp = START_TEMP * temp_decay(k, k_max); - 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; - } + num_removed_edges = compute_removed_edge_size(input_file, state_new); } - - return state_old; - + return state_new; } +void test_correctness(string input_file) { + vector state_old = generate_post_order(input_file); + int num_removed_edges; + num_removed_edges = compute_removed_edge_size(input_file, state_old); +} + + int get_graph_size(string input_file) { ogdf::Graph G; @@ -80,14 +62,15 @@ int main(int argc, char* argv[]) { int k_max = std::stoi(argv[2]); // generate order here - vector post_order = sa_solve(input_file, k_max); + // vector post_order = repeated_mutation(input_file, k_max); + test_correctness(input_file); - // std::copy(post_order.begin(), post_order.end(), std::ostream_iterator(std::cout, " ")); + // // print final order and number of edges + // // print post_order + // std::copy(post_order.begin(), post_order.end(), std::ostream_iterator(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; + // int removed_edges = compute_removed_edge_size(input_file, post_order); + // std::cout << "Number of removed edges: " << removed_edges << std::endl; return 0; } diff --git a/deferred_planarity_test/src/mps.cpp b/deferred_planarity_test/src/mps.cpp index ab5a1ce..82c1bad 100644 --- a/deferred_planarity_test/src/mps.cpp +++ b/deferred_planarity_test/src/mps.cpp @@ -3,6 +3,9 @@ //----------------------------------------------------------------------------------- #include "mps.h" +#include + +// #define DEBUG // constructor can be made empty maximal_planar_subgraph_finder::maximal_planar_subgraph_finder() {} @@ -19,17 +22,8 @@ maximal_planar_subgraph_finder::get_new_node(node_type t) { return _new_node_list[_new_node_list.size()-1]; } -//Determine the post-order-list by a DFS-traversal. -vector -maximal_planar_subgraph_finder::postOrderTraversal() { - node::init_mark(); - int postOrderID = 0; - for (int i = 0; i < _node_list.size(); ++i) { - if (!_node_list[i]->is_marked()) { - _node_list[i]->DFS_visit(_post_order_list, postOrderID); - } - } - +vector +maximal_planar_subgraph_finder::return_post_order() { vector post_order; for (int i = 0; i < _post_order_list.size(); ++i) { post_order.push_back(_post_order_list[i]->node_id()); @@ -37,8 +31,23 @@ maximal_planar_subgraph_finder::postOrderTraversal() { return post_order; } - //Determine the post-order-list by a DFS-traversal. +void +maximal_planar_subgraph_finder::postOrderTraversal() { + node::init_mark(); + // always start with node 0 + int postOrderID = 0; + for (int i = 0; i < _node_list.size(); ++i) { + if (!_node_list[i]->is_marked()) { + _node_list[i]->DFS_visit(_post_order_list, postOrderID); + } + } +} + + +// Determine the post-order-list by a DFS-traversal. +// take in a post-order argument then traces the graph in the same order +// return is by reference via _post_order_list void maximal_planar_subgraph_finder::guidedPostOrderTraversal(vector post_order) { node::init_mark(); @@ -62,7 +71,6 @@ maximal_planar_subgraph_finder::guidedPostOrderTraversal(vector 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); @@ -72,7 +80,9 @@ maximal_planar_subgraph_finder::guidedPostOrderTraversal(vector post_order) } //Determine the post-order-list by a DFS-traversal. -vector +// take in a post-order argument then traces the graph in the same order +// return is by reference via _post_order_list +void maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector post_order) { node::init_mark(); @@ -105,6 +115,8 @@ maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector post_order int end_condition = _node_list.size(); + // this loop assumes start is not from 0 + // if starting index is not 0, it just increments and loops around until it encounters the element before it while (true) { if (((start > 0) && (i == (start - 1))) || ((start == 0 ) && (i == end_condition - 1))) @@ -115,35 +127,34 @@ maximal_planar_subgraph_finder::mutatedPostOrderTraversal(vector 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]->mutated_DFS_visit(_post_order_list, _node_list, postOrderID, rev_post_order, mutate_point); } i = (i + 1) % end_condition; } - - vector 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 void -maximal_planar_subgraph_finder::set_post_order(vector post_order) { - for (int i = 0; i < _node_list.size(); ++i) { - _node_list[i]->set_post_order_index(post_order[i]); +maximal_planar_subgraph_finder::print_post_order() { + int current_index; + for (int i = 0; i < _post_order_list.size(); ++i) { + current_index = _post_order_list[i]->node_id(); + std::cout << current_index << ","; } + std::cout << std::endl; } + +// this function is not used anywhere +//Set the post-order-list via given list +// void +// maximal_planar_subgraph_finder::set_post_order(vector post_order) { +// for (int i = 0; i < _node_list.size(); ++i) { +// _node_list[i]->set_post_order_index(post_order[i]); +// } +// } + //Sort the adj-list of every node increasingly according to post-order-index. void maximal_planar_subgraph_finder::sort_adj_list() { diff --git a/deferred_planarity_test/src/mps_test.cpp b/deferred_planarity_test/src/mps_test.cpp index fec6000..9693983 100644 --- a/deferred_planarity_test/src/mps_test.cpp +++ b/deferred_planarity_test/src/mps_test.cpp @@ -5,6 +5,8 @@ #include "mps.h" #include +#define DEBUG + //----------------------------------------------------------------------------------- // Finding MPS //----------------------------------------------------------------------------------- @@ -37,6 +39,11 @@ vector generate_mutated_post_order(string input_file, vector post_orde int maximal_planar_subgraph_finder::find_mps(string input_file) { read_from_gml(input_file); postOrderTraversal(); + + #ifdef DEBUG + print_post_order(); + #endif + sort_adj_list(); determine_edges(); back_edge_traversal(); @@ -45,12 +52,25 @@ int maximal_planar_subgraph_finder::find_mps(string input_file) { vector maximal_planar_subgraph_finder::generate_post_order(string input_file) { read_from_gml(input_file); - return postOrderTraversal(); + postOrderTraversal(); + + #ifdef DEBUG + print_post_order(); + #endif + + return return_post_order(); } +// result of this will be used as input to "compute_removed_edge_size" vector maximal_planar_subgraph_finder::generate_mutated_post_order(string input_file, vector post_order) { read_from_gml(input_file); - return mutatedPostOrderTraversal(post_order); + mutatedPostOrderTraversal(post_order); + + #ifdef DEBUG + print_post_order(); + #endif + + return return_post_order(); } @@ -58,18 +78,14 @@ int maximal_planar_subgraph_finder::compute_removed_edge_size(string input_file, read_from_gml(input_file); guidedPostOrderTraversal(post_order); - // let's reverse the order - std::reverse(_post_order_list.begin(), _post_order_list.end()); - // then set post_order_index + // 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; + + #ifdef DEBUG + print_post_order(); + #endif sort_adj_list(); determine_edges(); diff --git a/deferred_planarity_test/src/node.cpp b/deferred_planarity_test/src/node.cpp index e134d0d..380b814 100644 --- a/deferred_planarity_test/src/node.cpp +++ b/deferred_planarity_test/src/node.cpp @@ -4,6 +4,8 @@ #include "mps.h" +// #define DEBUG + //----------------------------------------------------------------------------------- // CONSTRUCTOR //----------------------------------------------------------------------------------- @@ -69,71 +71,47 @@ void node::DFS_visit(vector &dfsList, int &index) { void node::guided_DFS_visit(vector &dfsList, vector &node_list, int &index, vector rev_post_order) { mark(); - // you will want to sort the neighbor nodes by the order they appear in the rev_post_order + + + // purpose of this block: create list of neighbors vector neighbor_list; - std::unordered_set 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()); + // we get the neighbors via _adj_list + // 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 - 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); } } + + set_post_order_index(index); + dfsList.push_back(this); + ++index; } void node::mutated_DFS_visit(vector &dfsList, vector &node_list, int &index, vector rev_post_order, int &mutate_point) { + // mark current node mark(); - // you will want to sort the neighbor nodes by the order they appear in the rev_post_order + + // purpose of this block: create list of neighbors vector neighbor_list; - std::unordered_set 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()); + // we get the neighbors via _adj_list + // 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 - 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; - + // 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 (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; @@ -141,14 +119,6 @@ void node::mutated_DFS_visit(vector &dfsList, vector &node_list, i 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) @@ -159,6 +129,10 @@ void node::mutated_DFS_visit(vector &dfsList, vector &node_list, i neighbor_list[i]->mutated_DFS_visit(dfsList, node_list, index, rev_post_order, mutate_point); } } + + set_post_order_index(index); + dfsList.push_back(this); + ++index; }