From 4bce0d45fb9960e7ade822751bbc6a9388f753ce Mon Sep 17 00:00:00 2001 From: Jonas Seidel Date: Mon, 7 Sep 2020 18:04:31 +0200 Subject: [PATCH] Maintenance problem implementation --- .../Graph_Specialization/CircSelect_Network.h | 13 ++ .../LP_Problems/Maintenance_Problem.cpp | 117 ++++++++++++++++++ .../LP_Problems/Maintenance_Problem.h | 24 ++++ .../maintenance_problem_generator.cpp | 26 ++++ .../maintenance_problem_generator.h | 15 +++ maintenance_problem_test.cpp | 35 ++++++ 6 files changed, 230 insertions(+) create mode 100644 Specialization/Graph_Specialization/CircSelect_Network.h create mode 100644 Specialization/LP_Problems/Maintenance_Problem.cpp create mode 100644 Specialization/LP_Problems/Maintenance_Problem.h create mode 100644 Specialization/LP_Problems/maintenance_problem_generator.cpp create mode 100644 Specialization/LP_Problems/maintenance_problem_generator.h create mode 100644 maintenance_problem_test.cpp diff --git a/Specialization/Graph_Specialization/CircSelect_Network.h b/Specialization/Graph_Specialization/CircSelect_Network.h new file mode 100644 index 0000000..8dd1f30 --- /dev/null +++ b/Specialization/Graph_Specialization/CircSelect_Network.h @@ -0,0 +1,13 @@ +#ifndef CIRCSELECT_H +#define CIRCSELECT_H + +#include "../../Graphtheory/Graph.h" + +typedef enum{} CircSelectNodeFields; +typedef enum : char {Flow = 'f', Demand = 'l', Capacity = 'u', Critical = 's'} CircSelectEdgeFields; +typedef Node CircSelectNode; +typedef Edge CircSelectEdge; +typedef Path CircSelectPath; +typedef Graph CircSelectNetwork; + +#endif diff --git a/Specialization/LP_Problems/Maintenance_Problem.cpp b/Specialization/LP_Problems/Maintenance_Problem.cpp new file mode 100644 index 0000000..6fdbbf6 --- /dev/null +++ b/Specialization/LP_Problems/Maintenance_Problem.cpp @@ -0,0 +1,117 @@ +#include "Maintenance_Problem.h" + +Maintenance_Problem::Maintenance_Problem() : Linear_Program(true) {} + +Maintenance_Problem::Maintenance_Problem(Maintenance_Problem& mp) : Linear_Program(mp) { + // this->_g = mp._g; + // mp._g = CircSelectNetwork(); +} + +Maintenance_Problem::Maintenance_Problem(Maintenance_Problem&& mp) : Linear_Program(std::move(mp)) { + // this->_g = std::move(mp._g); + // mp._g = CircSelectNetwork(); +} + +Maintenance_Problem::Maintenance_Problem(CircSelectNetwork& g, CircSelectNode* source, CircSelectNode* target, std::set critical, size_t intervals) + : Linear_Program(true)//, _g(g) +{ + std::vector, size_t>, std::map, size_t> >> lookup; + + /* + flow conservation constraints for all epochs + */ + for(size_t epoch = 0; epoch < intervals; ++epoch){ + lookup.push_back(lp_generator::grow_from_graph( + *this, + g, + [&critical, epoch](CircSelectEdge* edge) -> std::vector> { + std::stringstream capacity_name; + capacity_name << "edge_" << edge << "_capacity_epoch_" << epoch; + std::stringstream non_critical_fix; + non_critical_fix << "edge_" << edge << "_non_critical_epoch_" << epoch; + + std::vector> constraints; + if(critical.find(edge) == critical.end()){ + constraints.push_back({capacity_name.str(), Inequality, {{}, {{{edge, Flow}, 1}}}, edge->attribute(Capacity).value()}); + constraints.push_back({non_critical_fix.str(), Equality, {{}, {{{edge, Critical}, 1}}}, 0}); + }else{ + constraints.push_back({capacity_name.str(), Inequality, {{}, {{{edge, Flow}, 1},{{edge,Critical}, -edge->attribute(Capacity).value()}}}, edge->attribute(Capacity).value()}); + } + return constraints; + }, + [source, target, &critical, epoch](CircSelectNode* node) -> std::vector> { + if(node == source || node == target) return {}; + std::stringstream name; + name << "node_" << node << "_flow_conservation_epoch_" << epoch; + lhs_constraint_data lhs = {{},{}}; + for(CircSelectEdge* edge : node->incident()){ + lhs.second.push_back({{edge,Flow}, (edge->to() == node ? 1 : -1) }); + } + return {{name.str(), Equality, lhs, 0}}; + }, + {{Flow, {Integral, {true, 0}, {false, 0}}}, {Critical, {Integral, {true, 0}, {true, 1}}}}, + {} + )); + } + + /* + critical edges processed + */ + for(CircSelectEdge* e : critical){ + std::vector lhs (this->polyeder().vs_dim()); + std::vector,double>> critical_processed; + for(auto lookup_during_epoch : lookup){ + lhs[lookup_during_epoch.second.find({e, Critical})->second] = 1; + } + std::stringstream name; + name << "critical_edge_" << e << "_processed"; + this->polyeder().add_constraint( + { // constraint + name.str(), + Equality, + lhs, + 1, + } + ); + } + + /* + value bounded by flow + */ + this->polyeder().add_variable(Variable("target_variable", Continuous)); + + for(size_t epoch = 0; epoch < intervals; ++epoch){ + auto lookup_during_epoch = lookup[epoch]; + std::vector lhs (this->polyeder().vs_dim()); + for(CircSelectEdge* e : source->incident()){ + lhs[lookup_during_epoch.second.find({e, Flow})->second] = -1; + } + lhs[this->polyeder().vs_dim()-1] = 1; + + std::stringstream name; + name << "target_variable_bounds_epoch_" << epoch; + this->polyeder().add_constraint( + { // constraint + name.str(), + Inequality, + lhs, + 0 + } + ); + } + + this->direction() = {1}; + this->direction_start() = this->polyeder().vs_dim()-1; +} + +void Maintenance_Problem::operator=(Maintenance_Problem& mp){ + this->Linear_Program::operator=(mp); + //this->_g = mp._g; + //mp._g = CircSelectNetwork(); +} + +void Maintenance_Problem::operator=(Maintenance_Problem&& mp){ + this->Linear_Program::operator=(mp); + // this->_g = std::move(mp._g); + // mp._g = CircSelectNetwork(); +} diff --git a/Specialization/LP_Problems/Maintenance_Problem.h b/Specialization/LP_Problems/Maintenance_Problem.h new file mode 100644 index 0000000..5c66285 --- /dev/null +++ b/Specialization/LP_Problems/Maintenance_Problem.h @@ -0,0 +1,24 @@ +#ifndef MAINTENANCE_PROBLEM_H +#define MAINTENANCE_PROBLEM_H + +#include +#include +#include + +#include "../../Specialization/Graph_Specialization/CircSelect_Network.h" +#include "../../Linear_Programming/Linear_Program.h" +#include "../../Linear_Programming/lp_generator.h" + +class Maintenance_Problem : public Linear_Program { + //CircSelectNetwork _g; +public: + Maintenance_Problem(); + Maintenance_Problem(Maintenance_Problem& mp); + Maintenance_Problem(Maintenance_Problem&& mp); + Maintenance_Problem(CircSelectNetwork& g, CircSelectNode* source, CircSelectNode* target, std::set critical, size_t intervals); + + void operator=(Maintenance_Problem& mp); + void operator=(Maintenance_Problem&& mp); +}; + +#endif diff --git a/Specialization/LP_Problems/maintenance_problem_generator.cpp b/Specialization/LP_Problems/maintenance_problem_generator.cpp new file mode 100644 index 0000000..ffbcffa --- /dev/null +++ b/Specialization/LP_Problems/maintenance_problem_generator.cpp @@ -0,0 +1,26 @@ +#include "maintenance_problem_generator.h" + +maintenance_problem_generator::maintenance_problem_generator(random_graph_generator graph_generator, size_t number_of_critical_edges, size_t length_of_interval) + : _graph_generator(graph_generator), _number_of_critical_edges(number_of_critical_edges), _length_of_interval(length_of_interval) {} + +Maintenance_Problem maintenance_problem_generator::next(){ + std::pair, CircSelectNetwork> stg = this->_graph_generator.next_acyclic_2_tips(); + + std::set critical_edges; + random_set_element_generator set_gen (&stg.second.edges()); + for(size_t i = 0; i < this->_number_of_critical_edges; i++){ + CircSelectEdge* curr = set_gen.next(); + while(critical_edges.find(curr) != critical_edges.end()){ + set_gen >> curr; + } + + critical_edges.insert(curr); + curr->attribute(Critical).value() = true; + } + + return Maintenance_Problem(stg.second, stg.first.first, stg.first.second, critical_edges, this->_length_of_interval); +} + +void maintenance_problem_generator::operator>>(Maintenance_Problem& mp){ + mp = this->next(); +} diff --git a/Specialization/LP_Problems/maintenance_problem_generator.h b/Specialization/LP_Problems/maintenance_problem_generator.h new file mode 100644 index 0000000..29136f3 --- /dev/null +++ b/Specialization/LP_Problems/maintenance_problem_generator.h @@ -0,0 +1,15 @@ +#include "Maintenance_Problem.h" +#include "../Graph_Specialization/CircSelect_Network.h" +#include "../../Graphtheory/Generators/random_graph_generator.h" + +class maintenance_problem_generator{ + random_graph_generator _graph_generator; + size_t _number_of_critical_edges; + size_t _length_of_interval; +public: + maintenance_problem_generator(random_graph_generator graph_generator, size_t number_of_critical_edges, size_t length_of_interval); + + Maintenance_Problem next(); + void operator>>(Maintenance_Problem& mp); + +}; diff --git a/maintenance_problem_test.cpp b/maintenance_problem_test.cpp new file mode 100644 index 0000000..0018913 --- /dev/null +++ b/maintenance_problem_test.cpp @@ -0,0 +1,35 @@ +#include +#include +#include + +#include "./Specialization/LP_Problems/Maintenance_Problem.h" +#include "./Specialization/LP_Problems/maintenance_problem_generator.h" + +int main(){ + + maintenance_problem_generator mpg ( + random_graph_generator( + {{Flow, Attribute(max, 0)}, {Demand, Attribute(fix, 0)}, {Capacity, Attribute(fix, 1)}, {Critical, Attribute(fix, 0)}}, + {}, + 3, + random_attribute_generator({ {Capacity, {Continuous, 0, 5}} }), + 4, + random_attribute_generator({}) + ), + 2, 2 + ); + + while(true){ + Maintenance_Problem mp; + mpg >> mp; + + std::ofstream ofs("./.data/Maintenance_Problem/mp"); + ofs << mp << std::endl; + std::cout << mp << std::endl; + ofs.close(); + + system("polymake --script .data/Maintenance_Problem/pm_script_lp2facets"); + + std::cin.ignore(); + } +} -- GitLab