Commit a3fc2648 authored by Jonas Seidel's avatar Jonas Seidel

Generalizing graph generator next to enable "wider" graphs

accomplished by iteratively generating edges for one batch of nodes by 
connecting it to the next fading many node batches.
parent 751b97db
......@@ -34,6 +34,16 @@ std::pair<std::pair<Node*, Node*>,Graph> random_graph_generator::next_acyclic_2_
return {tips, std::move(g)};
}
std::pair<std::pair<Node*, Node*>, Graph> random_graph_generator::next_acyclic_in_steps_2_tips(size_t steps, size_t fading){
Graph g (this->_template_edge_attributes, this->_template_node_attributes);
while(!random_graph_generator::grow_random_acyclic_in_steps(g, this->_number_of_nodes/steps, this->_number_of_edges/steps, steps, fading, this->_edge_generator, this->_node_generator).first){
std::cout << "generation failed; retrying!" << std::endl;
}
auto tips = g.tip_fringes(this->_edge_generator, this->_node_generator);
return {tips, std::move(g)};
}
std::pair<bool, Attribute> random_graph_generator::node_template(const std::string& attr) const{
auto search = this->_template_node_attributes.find(attr);
if(search == this->_template_node_attributes.end()){
......@@ -167,6 +177,81 @@ std::pair<bool, std::pair<std::vector<Node*>, std::vector<Edge*>>> random_graph_
}
return {true,{added_nodes, added_edges}};
failed:
/*
cleanup: restore state; due to failure: remove the already added components
*/
for(Edge* e : added_edges){
g.remove_edge(e);
}
for(Node* n : added_nodes){
g.remove_node(n);
}
return {false,{{},{}}};
}
//TODO: add generate_random_edge and random node to node, edge and use additional parameters to generate random attributes for edges, nodes
std::pair<bool, std::pair<std::vector<Node*>, std::vector<Edge*>>> random_graph_generator::grow_random_acyclic_in_steps(Graph& g, size_t number_of_nodes_per_step, size_t number_of_edges_per_step, size_t number_of_steps, size_t step_fading, random_attribute_generator& edge_attribute_generator, random_attribute_generator& node_attribute_generator){
std::vector<Node*> added_nodes;
std::vector<Edge*> added_edges;
added_nodes.reserve(number_of_nodes_per_step);
added_edges.reserve(number_of_edges_per_step);
std::vector<std::set<Node*>> step_nodes;
step_nodes.reserve(number_of_steps);
std::vector<random_set_element_generator<Node*>> rand_streams;
std::default_random_engine engine((std::random_device())());
for(int curr_step = 0; curr_step < number_of_steps; ++curr_step){
step_nodes.push_back(std::set<Node*>());
rand_streams.push_back(random_set_element_generator<Node*>(&step_nodes.back())); // random_set_element_generator does not copy the set
for(size_t i = 0; i < number_of_nodes_per_step; ++i){
std::stringstream name;
name << g.size().first;
Node* new_node = g.add_node(name.str(), node_attribute_generator.next());
added_nodes.push_back(new_node);
step_nodes[curr_step].insert(new_node);
}
}
for(int curr_step = 0; curr_step < number_of_steps; ++curr_step){
Node* n1;
Node* n2;
size_t edges_to_be_added = curr_step == number_of_steps-1 ? number_of_edges_per_step/step_fading : number_of_edges_per_step;
for(size_t i = 0; i < edges_to_be_added; ++i){ // the last step does not get any edges
size_t attempt = 0;
redo:
if(attempt > g.nodes().size()*g.nodes().size()*g.nodes().size()){
std::cout << "you might want to increase fading or decrease the number of generated edges" << std::endl;
goto failed;
};
std::uniform_int_distribution<int> fading_dist (0, std::min(step_fading, number_of_steps-1-curr_step));
try{
rand_streams[curr_step] >> n1;
rand_streams[curr_step + fading_dist(engine)] >> n2;
}catch (std::range_error& e){
goto failed;
}
if(n1 == n2 || g.directed_admissible_st_path(n2, n1).first || g.directed_admissible_st_path(n1, n2).second.number_of_edges() == 1) {
attempt++;
goto redo;
}
std::stringstream name;
name << n1->description() << "_" << n2->description();
added_edges.push_back(g.add_edge(n1, n2, name.str(), edge_attribute_generator.next()));
}
}
return {true,{added_nodes, added_edges}};
failed:
/*
cleanup: restore state; due to failure: remove the already added components
......
......@@ -27,6 +27,8 @@ public:
Graph next_acyclic();
Graph next();
std::pair<std::pair<Node*, Node*>, Graph> next_acyclic_2_tips();
std::pair<std::pair<Node*, Node*>, Graph> next_acyclic_in_steps_2_tips(size_t steps, size_t fading);
void operator>>(Graph& var);
std::pair<bool, Attribute> node_template(const std::string& attr) const;
......@@ -38,4 +40,5 @@ public:
public:
static std::pair<bool, std::pair<std::vector<Node*>, std::vector<Edge*>>> grow_random(Graph& g, size_t number_of_nodes, size_t number_of_edges, random_attribute_generator& edge_attribute_generator, random_attribute_generator& node_attribute_generator);
static std::pair<bool, std::pair<std::vector<Node*>, std::vector<Edge*>>> grow_random_acyclic(Graph& g, size_t number_of_nodes, size_t number_of_edges, random_attribute_generator& edge_attribute_generator, random_attribute_generator& node_attribute_generator);
static std::pair<bool, std::pair<std::vector<Node*>, std::vector<Edge*>>> grow_random_acyclic_in_steps(Graph& g, size_t number_of_nodes_per_step, size_t number_of_edges_per_step, size_t number_of_steps, size_t step_fading, random_attribute_generator& edge_attribute_generator, random_attribute_generator& node_attribute_generator);
};
......@@ -7,8 +7,8 @@ maintenance_problem_generator::maintenance_problem_generator(random_graph_genera
}
}
Maintenance_Problem maintenance_problem_generator::next(){
std::pair<std::pair<Node*,Node*>, Graph> stg = this->_graph_generator.next_acyclic_2_tips();
Maintenance_Problem maintenance_problem_generator::next(size_t steps, size_t fading){
std::pair<std::pair<Node*,Node*>, Graph> stg = this->_graph_generator.next_acyclic_in_steps_2_tips(steps, fading);
random_set_element_generator<Edge*> set_gen (&stg.second.edges());
for(size_t i = 0; i < this->_number_of_critical_edges; i++){
......@@ -25,6 +25,7 @@ Maintenance_Problem maintenance_problem_generator::next(){
return Maintenance_Problem(stg.second, stg.first.first, stg.first.second, this->_length_of_interval);
}
void maintenance_problem_generator::operator>>(Maintenance_Problem& mp){
mp = this->next();
}
......@@ -11,7 +11,7 @@ class maintenance_problem_generator{
public:
maintenance_problem_generator(random_graph_generator graph_generator, size_t number_of_critical_edges, size_t length_of_interval);
Maintenance_Problem next();
Maintenance_Problem next(size_t steps = 1, size_t fading = 0);
void operator>>(Maintenance_Problem& mp);
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment