Maintenance_Problem.cpp 4.27 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 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<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();
}