Commit 4bce0d45 authored by Jonas Seidel's avatar Jonas Seidel

Maintenance problem implementation

parent 7ca13859
#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<CircSelectNodeFields, CircSelectEdgeFields> CircSelectNode;
typedef Edge<CircSelectNodeFields, CircSelectEdgeFields> CircSelectEdge;
typedef Path<CircSelectNodeFields, CircSelectEdgeFields> CircSelectPath;
typedef Graph<CircSelectNodeFields, CircSelectEdgeFields> CircSelectNetwork;
#endif
#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<CircSelectEdge*> critical, size_t intervals)
: Linear_Program(true)//, _g(g)
{
std::vector<std::pair< std::map<std::pair<CircSelectNode*,CircSelectNodeFields>, size_t>, std::map<std::pair<CircSelectEdge*,CircSelectEdgeFields>, 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<CircSelectNodeFields, CircSelectEdgeFields>(
*this,
g,
[&critical, epoch](CircSelectEdge* edge) -> std::vector<constraint_data<CircSelectNodeFields, CircSelectEdgeFields>> {
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<constraint_data<CircSelectNodeFields, CircSelectEdgeFields>> 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<constraint_data<CircSelectNodeFields, CircSelectEdgeFields>> {
if(node == source || node == target) return {};
std::stringstream name;
name << "node_" << node << "_flow_conservation_epoch_" << epoch;
lhs_constraint_data<CircSelectNodeFields, CircSelectEdgeFields> 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<double> lhs (this->polyeder().vs_dim());
std::vector<std::pair<std::pair<CircSelectEdge*,CircSelectEdgeFields>,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<double> 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();
}
#ifndef MAINTENANCE_PROBLEM_H
#define MAINTENANCE_PROBLEM_H
#include <cstddef>
#include <vector>
#include <sstream>
#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<CircSelectEdge*> critical, size_t intervals);
void operator=(Maintenance_Problem& mp);
void operator=(Maintenance_Problem&& mp);
};
#endif
#include "maintenance_problem_generator.h"
maintenance_problem_generator::maintenance_problem_generator(random_graph_generator<CircSelectNodeFields, CircSelectEdgeFields> 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<std::pair<CircSelectNode*,CircSelectNode*>, CircSelectNetwork> stg = this->_graph_generator.next_acyclic_2_tips();
std::set<CircSelectEdge*> critical_edges;
random_set_element_generator<CircSelectEdge*> 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();
}
#include "Maintenance_Problem.h"
#include "../Graph_Specialization/CircSelect_Network.h"
#include "../../Graphtheory/Generators/random_graph_generator.h"
class maintenance_problem_generator{
random_graph_generator<CircSelectNodeFields, CircSelectEdgeFields> _graph_generator;
size_t _number_of_critical_edges;
size_t _length_of_interval;
public:
maintenance_problem_generator(random_graph_generator<CircSelectNodeFields, CircSelectEdgeFields> graph_generator, size_t number_of_critical_edges, size_t length_of_interval);
Maintenance_Problem next();
void operator>>(Maintenance_Problem& mp);
};
#include <iostream>
#include <fstream>
#include <cstdlib>
#include "./Specialization/LP_Problems/Maintenance_Problem.h"
#include "./Specialization/LP_Problems/maintenance_problem_generator.h"
int main(){
maintenance_problem_generator mpg (
random_graph_generator<CircSelectNodeFields, CircSelectEdgeFields>(
{{Flow, Attribute(max, 0)}, {Demand, Attribute(fix, 0)}, {Capacity, Attribute(fix, 1)}, {Critical, Attribute(fix, 0)}},
{},
3,
random_attribute_generator<CircSelectEdgeFields>({ {Capacity, {Continuous, 0, 5}} }),
4,
random_attribute_generator<CircSelectNodeFields>({})
),
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();
}
}
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