Commit c5afe07d authored by jonasseidel's avatar jonasseidel
Browse files

adding support for simulation of more than two terminal generation; fixed some errors along the way

- adding orphaning to fringe operations
- adding exposing tipping options through graph generator/maintenance 
problem generator
  - exclusive tipping of nodes without incoming/outcoming edges
  - exclusive tipping of nodes generated in start and end steps of 
grow_acyclic_from_graph_in_steps
parent 98cc8d24
......@@ -40,16 +40,59 @@ std::tuple<std::pair<Node*, Node*>, std::set<Edge*>, Graph> random_graph_generat
return {std::pair{source, target}, std::move(core_network), std::move(g)};
}
std::tuple<std::pair<Node*, Node*>, std::set<Edge*>, Graph> random_graph_generator::next_acyclic_in_steps_2_tips(size_t steps, size_t fading, random_attribute_generator* connector_generator, random_attribute_generator* terminal_generator){
std::tuple<std::pair<Node*, Node*>, std::set<Edge*>, Graph> random_graph_generator::next_acyclic_in_steps_2_tips(size_t steps, size_t fuzzing, bool only_tip_fringes, bool only_tip_extreme_layer, bool shelter_orphans, random_attribute_generator* connector_generator, random_attribute_generator* terminal_generator){
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::tuple<bool, std::vector<std::set<Node*>>, std::pair<std::vector<Node*>, std::vector<Edge*>>> tpl;
while( !std::get<0>(tpl = std::move(random_graph_generator::grow_random_acyclic_in_steps(g, this->_number_of_nodes/steps, this->_number_of_edges/steps, steps, fuzzing, this->_edge_generator, this->_node_generator))) ){
std::cout << "generation failed; retrying!" << std::endl;
}
std::set<Edge*> core_network = g.edges();
if(connector_generator == nullptr) connector_generator = &this->_edge_generator;
if(terminal_generator == nullptr) terminal_generator = &this->_node_generator;
auto [source, target] = g.tip_fringes(*connector_generator, *terminal_generator);
Node* source;
Node* target;
if(only_tip_fringes){
// connect those nodes to start that have no incoming edges / connect those nodes to target that have no outgoing edges
if(only_tip_extreme_layer){
// tips first and last layer
auto [source_, target_] = g.tip_fringes(std::get<1>(tpl).front(), std::get<1>(tpl).back(), *connector_generator, *terminal_generator, shelter_orphans);
source = source_;
target = target_;
}else{
// tips all fringes
auto [source_, target_] = g.tip_fringes(*connector_generator, *terminal_generator, shelter_orphans);
source = source_;
target = target_;
}
}else{
// tips nodes regardless of if they have incoming or outgoing edges
assert(only_tip_extreme_layer);
// only those nodes of the first and last generated layers (tipping just everything doesn't make sense)
Node* s = g.add_node(std::to_string(g.size().first), terminal_generator->next());
for(Node* n : std::get<1>(tpl).front()){
if(!shelter_orphans && n->incident().size() == 0) continue;
std::stringstream name;
name << s->description() << "_" << n->description();
g.add_edge(s, n, name.str(), connector_generator->next());
}
Node* t = g.add_node(std::to_string(g.size().first), terminal_generator->next());
for(Node* n : std::get<1>(tpl).back()){
if(!shelter_orphans && n->incident().size() == 0) continue;
std::stringstream name;
name << n->description() << "_" << t->description();
g.add_edge(n, t, name.str(), connector_generator->next());
}
source = s;
target = t;
}
source->add_attribute("Source", Attribute({fix, 1, Integral}) );
target->add_attribute("Target", Attribute({fix, 1, Integral}) );
......@@ -214,7 +257,7 @@ std::pair<bool, std::pair<std::vector<Node*>, std::vector<Edge*>>> random_graph_
}
//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::tuple<bool, std::vector<std::set<Node*>>, 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_fuzzing, 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);
......@@ -223,6 +266,7 @@ std::pair<bool, std::pair<std::vector<Node*>, std::vector<Edge*>>> random_graph_
std::vector<std::set<Node*>> step_nodes;
step_nodes.reserve(number_of_steps);
std::vector<random_set_element_generator<Node*>> rand_streams;
rand_streams.reserve(number_of_steps);
std::default_random_engine engine((std::random_device())());
......@@ -239,29 +283,30 @@ std::pair<bool, std::pair<std::vector<Node*>, std::vector<Edge*>>> random_graph_
step_nodes[curr_step].insert(new_node);
}
}
for(int curr_step = 0; curr_step < number_of_steps; ++curr_step){
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+1) : number_of_edges_per_step;
size_t edges_to_be_added = (curr_step == number_of_steps-1) ? number_of_edges_per_step/(step_fuzzing+1) : 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;
std::cout << "you might want to increase fuzzing 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));
std::uniform_int_distribution<int> fuzzing_dist (0, std::min(step_fuzzing, (number_of_steps-1)-curr_step));
try{
rand_streams[curr_step] >> n1;
rand_streams[curr_step + fading_dist(engine)] >> n2;
rand_streams[curr_step + fuzzing_dist(engine)] >> n2;
}catch (std::range_error& e){
goto failed;
}
// ensure acyclic ensure simple
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;
......@@ -272,10 +317,12 @@ std::pair<bool, std::pair<std::vector<Node*>, std::vector<Edge*>>> random_graph_
added_edges.push_back(g.add_edge(n1, n2, name.str(), edge_attribute_generator.next()));
}
}
return {true,{added_nodes, added_edges}};
return {true,step_nodes,{added_nodes, added_edges}};
failed:
std::cerr << "graph generation failed; partial result given by:" << std::endl;
std::cerr << g << std::endl;
/*
cleanup: restore state; due to failure: remove the already added components
*/
......@@ -285,5 +332,5 @@ std::pair<bool, std::pair<std::vector<Node*>, std::vector<Edge*>>> random_graph_
for(Node* n : added_nodes){
g.remove_node(n);
}
return {false,{{},{}}};
return {false,{},{{},{}}};
}
......@@ -30,7 +30,7 @@ public:
Graph next_acyclic();
Graph next();
std::tuple<std::pair<Node*, Node*>, std::set<Edge*>, Graph> next_acyclic_2_tips();
std::tuple<std::pair<Node*, Node*>, std::set<Edge*>, Graph> next_acyclic_in_steps_2_tips(size_t steps, size_t fading, random_attribute_generator* connector_generator = nullptr, random_attribute_generator* terminal_generator = nullptr);
std::tuple<std::pair<Node*, Node*>, std::set<Edge*>, Graph> next_acyclic_in_steps_2_tips(size_t steps, size_t fading, bool only_tip_extreme_layer, bool only_tip_fringes, bool shelter_orphans, random_attribute_generator* connector_generator = nullptr, random_attribute_generator* terminal_generator = nullptr);
void operator>>(Graph& var);
......@@ -46,7 +46,7 @@ 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);
static std::tuple<bool, std::vector<std::set<Node*>>, 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);
};
#endif
......@@ -152,19 +152,37 @@ public:
// fringe_operations
std::vector<Node*> select_sources();
std::vector<const Node*> select_sources() const ;
static std::vector<Node*> select_sources(std::set<Node*>& candidates_source);
std::vector<Node*> select_targets();
std::vector<const Node*> select_targets() const ;
static std::vector<Node*> select_targets(std::set<Node*>& candidates_target);
Node* tip_targets(
std::set<Node*>& candidates_target,
random_attribute_generator edge_attribute_generator = {{}},
random_attribute_generator node_attribute_generator = {{}},
bool shelter_orphans = true
);
Node* tip_targets(
random_attribute_generator edge_attribute_generator = {{}},
random_attribute_generator node_attribute_generator = {{}}
);
std::vector<Node*> select_sources();
std::vector<const Node*> select_sources() const ;
Node* tip_sources(
std::set<Node*>& candidates_source,
random_attribute_generator edge_attribute_generator = {{}},
random_attribute_generator node_attribute_generator = {{}},
bool shelter_orphans = true
);
Node* tip_sources(
random_attribute_generator edge_attribute_generator = {{}},
random_attribute_generator node_attribute_generator = {{}}
);
std::pair<Node*, Node*> tip_fringes(random_attribute_generator edge_attribute_generator = {{}}, random_attribute_generator node_attribute_generator = {{}});
std::pair<Node*, Node*> tip_fringes(random_attribute_generator edge_attribute_generator = {{}}, random_attribute_generator node_attribute_generator = {{}}, bool shelter_orphans = true);
std::pair<Node*, Node*> tip_fringes(std::set<Node*>& candidates_source, std::set<Node*>& candidates_target, random_attribute_generator edge_attribute_generator = {{}}, random_attribute_generator node_attribute_generator = {{}}, bool shelter_orphans = true);
// _advanced.cpp:
Graph(std::istream& is);
......
......@@ -30,8 +30,30 @@ std::vector<const Node*> Graph::select_targets() const {
return targets;
}
std::vector<Node*> Graph::select_targets(std::set<Node*>& candidates_target){
std::vector<Node*> targets;
for(Node* n : candidates_target){
bool is_terminal_target = true;
for(Edge* e : n->incident()){
if(n == e->from()) is_terminal_target = false;
}
if(is_terminal_target){
targets.push_back(n);
}
}
return targets;
}
Node* Graph::tip_targets(random_attribute_generator edge_attribute_generator, random_attribute_generator node_attribute_generator){
std::vector<Node*> targets = this->select_targets();
return this->tip_targets(this->_nodes, edge_attribute_generator, node_attribute_generator, true);
}
Node* Graph::tip_targets(std::set<Node*>& tip_candidates_target, random_attribute_generator edge_attribute_generator, random_attribute_generator node_attribute_generator, bool shelter_orphans){
// nodes must be part of graph
for(Node* n : tip_candidates_target) {assert(this->_nodes.find(n) != this->_nodes.end());}
std::vector<Node*> targets = Graph::select_targets(tip_candidates_target);
std::stringstream name;
name << this->size().first;
......@@ -39,6 +61,7 @@ Node* Graph::tip_targets(random_attribute_generator edge_attribute_generator, ra
if(targets.size() > 1){
t = this->add_node(name.str(), node_attribute_generator.next());
for(Node* n : targets){
if(!shelter_orphans && n->incident().size() == 0) continue;
std::stringstream name;
name << n->description() << "_" << t->description();
this->add_edge(n, t, name.str(), edge_attribute_generator.next());
......@@ -72,6 +95,20 @@ std::vector<Node*> Graph::select_sources(){
return sources;
}
std::vector<Node*> Graph::select_sources(std::set<Node*>& candidates_source){
std::vector<Node*> sources;
for(Node* n : candidates_source){
bool is_terminal_source = true;
for(Edge* e : n->incident()){
if(n == e->to()) is_terminal_source = false;
}
if(is_terminal_source){
sources.push_back(n);
}
}
return sources;
}
std::vector<const Node*> Graph::select_sources() const {
std::vector<const Node*> sources;
for(Node* n : this->_nodes){
......@@ -87,7 +124,15 @@ std::vector<const Node*> Graph::select_sources() const {
}
Node* Graph::tip_sources(random_attribute_generator edge_attribute_generator, random_attribute_generator node_attribute_generator){
std::vector<Node*> sources = this->select_sources();
return this->tip_sources(this->_nodes, edge_attribute_generator, node_attribute_generator, true);
}
Node* Graph::tip_sources(std::set<Node*>& tip_candidates_source, random_attribute_generator edge_attribute_generator, random_attribute_generator node_attribute_generator, bool shelter_orphans){
// nodes must be part of graph
for(Node* n : tip_candidates_source) {assert(this->_nodes.find(n) != this->_nodes.end());}
std::vector<Node*> sources = Graph::select_sources(tip_candidates_source);
std::stringstream name;
name << this->size().first;
......@@ -95,6 +140,7 @@ Node* Graph::tip_sources(random_attribute_generator edge_attribute_generator, ra
if(sources.size() > 1){
s = this->add_node(name.str(), node_attribute_generator.next());
for(Node* n : sources){
if(!shelter_orphans && n->incident().size() == 0) continue;
std::stringstream name;
name << s->description() << "_" << n->description();
this->add_edge(s, n, name.str(), edge_attribute_generator.next());
......@@ -112,9 +158,12 @@ Node* Graph::tip_sources(random_attribute_generator edge_attribute_generator, ra
tandem
*/
std::pair<Node*, Node*> Graph::tip_fringes(random_attribute_generator edge_attribute_generator, random_attribute_generator node_attribute_generator){
std::pair<Node*, Node*> tips;
tips.first = this->tip_sources(edge_attribute_generator, node_attribute_generator);
tips.second = this->tip_targets(edge_attribute_generator, node_attribute_generator);
return tips;
std::pair<Node*, Node*> Graph::tip_fringes(random_attribute_generator edge_attribute_generator, random_attribute_generator node_attribute_generator, bool shelter_orphans){
return this->tip_fringes(this->_nodes, this->_nodes, edge_attribute_generator, node_attribute_generator);
}
std::pair<Node*, Node*> Graph::tip_fringes(std::set<Node*>& tip_candidates_source, std::set<Node*>& tip_candidates_target, random_attribute_generator edge_attribute_generator, random_attribute_generator node_attribute_generator, bool shelter_orphans){
Node* source = this->tip_sources(tip_candidates_source, edge_attribute_generator, node_attribute_generator, shelter_orphans);
Node* target = this->tip_targets(tip_candidates_target, edge_attribute_generator, node_attribute_generator, shelter_orphans);
return {source, target};
}
......@@ -28,7 +28,7 @@ bool generate_tests_data(std::filesystem::path path, int number_of_instances){
{{"Flow", Attribute(max, 0)},{"Upper", Attribute(fix, 1)}, {"Selected", Attribute(fix, 0)}, {"Edgepotential", Attribute(min, 0)}},
{{"Nodepotential", Attribute(min, 0)}}
),
test_parameters.share_of_critical, test_parameters.number_of_epochs, test_parameters.core_network_problem
test_parameters.share_of_critical, test_parameters.number_of_epochs, test_parameters.number_of_nodes/test_parameters.nodes_per_step, test_parameters.fuzzing, test_parameters.simulate_multiple_sources, test_parameters.only_tip_fringes, test_parameters.only_tip_extreme_layer
);
......@@ -69,7 +69,7 @@ bool generate_tests_data(std::filesystem::path path, int number_of_instances){
new_data.gen_data = test_parameters;
std::cout << " [problem]" << std::flush;
new_data.mp = std::move(mpg.next(test_parameters.number_of_nodes/test_parameters.nodes_per_step, test_parameters.fuzzing));
new_data.mp = std::move(mpg.next());
std::cout << " [empty derived data]" << std::endl;
new_data.derived_problem = Derived_Problem_Data{
......
......@@ -14,29 +14,32 @@
std::ostream& operator<<(std::ostream& os, const Generation_Parameters& gen_param){
os << "Generation_Parameters {\n"
<< "graph_type: " << gen_param.graph_type << "\n"
<< "core_network_problem: " << gen_param.core_network_problem
<< "number_of_nodes: " << gen_param.number_of_nodes << "\n"
<< "avg_incid_per_node: " << gen_param.avg_incid_per_node << "\n"
<< "share_of_critical: " << gen_param.share_of_critical << "\n"
<< "nodes_per_step: " << gen_param.nodes_per_step << "\n"
<< "fuzzing: " << gen_param.fuzzing << "\n"
<< "number_of_epochs: " << gen_param.number_of_epochs << "\n"
<< "graph_type: " << gen_param.graph_type << "\n"
<< "number_of_nodes: " << gen_param.number_of_nodes << "\n"
<< "avg_incid_per_node: " << gen_param.avg_incid_per_node << "\n"
<< "share_of_critical: " << gen_param.share_of_critical << "\n"
<< "nodes_per_step: " << gen_param.nodes_per_step << "\n"
<< "fuzzing: " << gen_param.fuzzing << "\n"
<< "number_of_epochs: " << gen_param.number_of_epochs << "\n"
<< "simulate_multiple_sources: " << gen_param.simulate_multiple_sources << "\n"
<< "only_tip_fringes: " << gen_param.only_tip_fringes << "\n"
<< "only_tip_extreme_layer: " << gen_param.only_tip_extreme_layer << "\n"
<< "}";
return os;
}
std::string csv(const Generation_Parameters& gen_param){
std::stringstream csv_string;
csv_string << gen_param.graph_type << ","
<< gen_param.core_network_problem << ","
<< gen_param.number_of_nodes << ","
<< gen_param.avg_incid_per_node << ","
<< gen_param.share_of_critical << ","
<< gen_param.nodes_per_step << ","
<< gen_param.fuzzing << ","
<< gen_param.number_of_epochs;
csv_string << gen_param.graph_type << ","
<< gen_param.number_of_nodes << ","
<< gen_param.avg_incid_per_node << ","
<< gen_param.share_of_critical << ","
<< gen_param.nodes_per_step << ","
<< gen_param.fuzzing << ","
<< gen_param.number_of_epochs << ","
<< gen_param.simulate_multiple_sources << ","
<< gen_param.only_tip_fringes << ","
<< gen_param.only_tip_extreme_layer;
return csv_string.str();
}
......@@ -51,15 +54,16 @@ std::istream& operator>>(std::istream& is, Generation_Parameters& gen_param){
if(gen_param.graph_type.size() > 0 && gen_param.graph_type.c_str()[0] == ' '){
gen_param.graph_type = gen_param.graph_type.substr(1, std::string::npos);
}
IF_READ_VAR_SET_VAR_DIRECT(is, gen_param, core_network_problem, curr);
IF_READ_VAR_SET_VAR_DIRECT(is, gen_param, number_of_nodes, curr);
IF_READ_VAR_SET_VAR_DIRECT(is, gen_param, avg_incid_per_node, curr);
IF_READ_VAR_SET_VAR_DIRECT(is, gen_param, share_of_critical, curr);
IF_READ_VAR_SET_VAR_DIRECT(is, gen_param, nodes_per_step, curr);
IF_READ_VAR_SET_VAR_DIRECT(is, gen_param, fuzzing, curr);
IF_READ_VAR_SET_VAR_DIRECT(is, gen_param, number_of_epochs, curr);
IF_READ_VAR_SET_VAR_DIRECT(is, gen_param, simulate_multiple_sources, curr);
IF_READ_VAR_SET_VAR_DIRECT(is, gen_param, only_tip_fringes, curr);
IF_READ_VAR_SET_VAR_DIRECT(is, gen_param, only_tip_extreme_layer, curr);
}
return is;
}
......@@ -414,13 +418,16 @@ std::istream& operator>>(std::istream& is, Data& data){
bool operator==(Generation_Parameters& a, Generation_Parameters& b){
if(a.graph_type != b.graph_type) return false;
if(a.core_network_problem != b.core_network_problem) return false;
if(a.number_of_nodes != b.number_of_nodes) return false;
if(std::abs(a.avg_incid_per_node - b.avg_incid_per_node) > CMP_EPS) return false;
if(std::abs(a.share_of_critical - b.share_of_critical) > CMP_EPS) return false;
if(a.nodes_per_step != b.nodes_per_step) return false;
if(a.fuzzing != b.fuzzing) return false;
if(a.number_of_epochs != b.number_of_epochs) return false;
if(a.simulate_multiple_sources != b.simulate_multiple_sources) return false;
if(a.only_tip_fringes != b.only_tip_fringes) return false;
if(a.only_tip_extreme_layer != b.only_tip_extreme_layer) return false;
return true;
}
......
......@@ -60,13 +60,15 @@ attribute /= vector.size();
// define a struct of data we wish to use in our execution function
struct Generation_Parameters{
std::string graph_type;
bool core_network_problem;
size_t number_of_nodes;
double avg_incid_per_node;
double share_of_critical;
size_t nodes_per_step;
size_t fuzzing;
size_t number_of_epochs;
size_t number_of_nodes;
double avg_incid_per_node;
double share_of_critical;
size_t nodes_per_step;
size_t fuzzing;
size_t number_of_epochs;
bool simulate_multiple_sources;
bool only_tip_fringes;
bool only_tip_extreme_layer;
};
struct Derived_Problem_Data{
std::pair<bool, size_t> number_of_edges;
......@@ -89,20 +91,20 @@ struct Derived_Performance_Data{
std::pair<bool, int> number_of_primal_sols;
};
struct Data{
bool marked_for_inspection;
std::string path;
std::string name;
Generation_Parameters gen_data;
Maintenance_Problem mp;
Derived_Problem_Data derived_problem;
bool marked_for_inspection;
std::string path;
std::string name;
Generation_Parameters gen_data;
Maintenance_Problem mp;
Derived_Problem_Data derived_problem;
std::map<std::string, std::vector<Derived_Performance_Data> > derived_performance;
};
struct axis_data{
std::string name;
size_t resolution;
double lower_bound;
double upper_bound;
size_t resolution;
double lower_bound;
double upper_bound;
};
std::ostream& operator<<(std::ostream& os, const Generation_Parameters& gen_param);
......
......@@ -2,23 +2,23 @@
#include <climits>
maintenance_problem_generator::maintenance_problem_generator(random_graph_generator graph_generator, double share_of_critical, size_t length_of_interval, bool generate_core_network_problem)
: _graph_generator(graph_generator), _share_of_critical(share_of_critical), _generate_core_network_problem(generate_core_network_problem), _length_of_interval(length_of_interval) {
maintenance_problem_generator::maintenance_problem_generator(random_graph_generator graph_generator, double share_of_critical, size_t number_of_epochs, size_t steps, size_t fuzzing, bool simulate_multiple_sources, bool only_tip_fringes, bool only_tip_extreme_layer)
: _graph_generator(graph_generator), _share_of_critical(share_of_critical), _number_of_epochs(number_of_epochs), _steps(steps), _fuzzing(fuzzing), _simulate_multiple_sources(simulate_multiple_sources), _only_tip_fringes(only_tip_fringes), _only_tip_extreme_layer(only_tip_extreme_layer) {
// by core_network_problem we mean those where the tip connections are part of a reduction. In these tip connections have infinite capacity and can not be critical
for(std::string attr : std::vector({"Selected", "Upper", "Flow"})){
if(!this->_graph_generator.edge_template(attr).first) throw std::invalid_argument("Maintenance_Problem needs Graph with predetermined attributes present");
}
}
Maintenance_Problem maintenance_problem_generator::next(size_t steps, size_t fading){
Maintenance_Problem maintenance_problem_generator::next(){
random_attribute_generator* connector_generator = &this->_graph_generator.edge_generator();
random_attribute_generator* terminal_generator = &this->_graph_generator.node_generator();
if(this->_generate_core_network_problem){
std::cout << "replaced" << std::endl;
if(this->_simulate_multiple_sources){
connector_generator = new random_attribute_generator({ {"Upper", {fix, Integral, INT_MAX, INT_MAX}} });
}
auto [st, core_network, g] = this->_graph_generator.next_acyclic_in_steps_2_tips(steps, fading, connector_generator, terminal_generator);
if(this->_generate_core_network_problem){
auto [st, core_network, g] = this->_graph_generator.next_acyclic_in_steps_2_tips(this->_steps, this->_fuzzing, this->_only_tip_fringes, this->_only_tip_extreme_layer, connector_generator, terminal_generator);
if(this->_simulate_multiple_sources){
delete connector_generator;
}
......@@ -27,14 +27,14 @@ Maintenance_Problem maintenance_problem_generator::next(size_t steps, size_t fad
random_set_element_generator_capture<Edge*>* set_gen = nullptr;
if(this->_generate_core_network_problem){
if(this->_simulate_multiple_sources){
set_gen = new random_set_element_generator_capture<Edge*>(core_network, true);
}else{
set_gen = new random_set_element_generator_capture<Edge*>(g.edges(), true);
}
int number_of_critical_edges = round((1-this->_generate_core_network_problem)*this->_share_of_critical*g.edges().size() + this->_generate_core_network_problem*this->_share_of_critical*core_network.size());
assert(number_of_critical_edges <= (1-this->_generate_core_network_problem)*g.edges().size()+this->_generate_core_network_problem*core_network.size());
int number_of_critical_edges = round((1-this->_simulate_multiple_sources)*this->_share_of_critical*g.edges().size() + this->_simulate_multiple_sources*this->_share_of_critical*core_network.size());
assert(number_of_critical_edges <= (1-this->_simulate_multiple_sources)*g.edges().size()+this->_simulate_multiple_sources*core_network.size());
for(size_t i = 0; i < number_of_critical_edges; i++){
Edge* curr = set_gen->next();
Attribute* attribute_search = &curr->attribute_throwing("Selected");
......@@ -45,7 +45,7 @@ Maintenance_Problem maintenance_problem_generator::next(size_t steps, size_t fad
delete set_gen;
return Maintenance_Problem(g, st.first, st.second, this->_length_of_interval);
return Maintenance_Problem(g, st.first, st.second, this->_number_of_epochs);
}
......
......@@ -7,12 +7,16 @@
class maintenance_problem_generator{
random_graph_generator _graph_generator;
double _share_of_critical;
size_t _length_of_interval;
bool _generate_core_network_problem;
size_t _number_of_epochs;
size_t _steps;
size_t _fuzzing;
bool _simulate_multiple_sources;
bool _only_tip_fringes;
bool _only_tip_extreme_layer;
public:
maintenance_problem_generator(random_graph_generator graph_generator, double share_of_critical, size_t length_of_interval, bool generate_core_network_problem);
maintenance_problem_generator(random_graph_generator graph_generator, double share_of_critical, size_t number_of_epochs, size_t steps, size_t fuzzing, bool simulate_multiple_sources, bool only_tip_fringes, bool only_tip_extreme_layer);
Maintenance_Problem next(size_t steps = 1, size_t fading = 0);
void operator>>(Maintenance_Problem& mp);
Maintenance_Problem next();
void operator>>(Maintenance_Problem& mp);
};
......@@ -12,11 +12,11 @@ int main(int argc, char** argv){
Maintenance_Problem mp;
size_t number_of_nodes = 100;
size_t number_of_nodes = 15;
double avg_incid_per_node = 6;
double share_of_critical = .8;
size_t nodes_per_step = 25;
size_t fuzzing = 0;
double share_of_critical = 1;
size_t nodes_per_step = 5;
size_t fuzzing = 1;
size_t number_of_epochs = 3;
......@@ -31,7 +31,8 @@ int main(int argc, char** argv){
{{"Flow", Attribute(max, 0)},{"Upper", Attribute(fix, 1)}, {"Selected", Attribute(fix, 0)}, {"Edgepotential", Attribute(min, 0)}},
{{"Nodepotential", Attribute(min, 0)}}
),
share_of_critical, number_of_epochs, false
// number_of_steps simulate multiple sources? only_tip_fringes? only_tip_extreme_layer?
share_of_critical, number_of_epochs, number_of_nodes/nodes_per_step, fuzzing, true, false, true
);