LCOV - code coverage report
Current view: top level - app/src/Static - Solution.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 71 85 83.5 %
Date: 2023-08-17 16:45:52 Functions: 11 13 84.6 %

          Line data    Source code
       1             : #include "Static/Solution.hpp"
       2             : 
       3             : #include <algorithm>
       4             : #include <set>
       5             : #include <unordered_map>
       6             : 
       7             : using namespace std;
       8             : using namespace Static;
       9             : 
      10             : typedef Network::Edge    Edge;
      11             : typedef Network::Path    Path;
      12             : typedef Solution::Routes Routes;
      13             : 
      14         189 : Solution::Solution() {}
      15             : 
      16         170 : Solution::Solution(const Solution &sol):
      17          13 :     s(sol.s) {}
      18             : 
      19           3 : void Solution::Internals::addToRoutes(
      20             :     Routes &routes
      21             : ) const {
      22           3 :     if(s1 == nullptr && s2 == nullptr) {
      23           0 :         routes = paths;
      24           0 :         return;
      25             :     }
      26             : 
      27           3 :     addToRoutes(routes, 1.0);
      28             : }
      29             : 
      30           7 : void Solution::Internals::addToRoutes(
      31             :     Routes &routes,
      32             :     double  a
      33             : ) const {
      34          18 :     for(const auto &[path, flow]: paths) {
      35           7 :         routes[path] += a * flow;
      36             :     }
      37          11 :     if(s1 != nullptr) s1->addToRoutes(routes, a * (1.0 - alpha));
      38          11 :     if(s2 != nullptr) s2->addToRoutes(routes, a * alpha);
      39           7 : }
      40             : 
      41         482 : unordered_set<Edge::ID> Solution::getEdges() const {
      42         482 :     const auto &edges = s.get()->edges;
      43         482 :     return edges;
      44             : }
      45             : 
      46       29239 : Flow Solution::getFlowInEdge(Edge::ID id) const {
      47       29239 :     const auto &flows = s.get()->flows;
      48       29239 :     if((Edge::ID)flows.size() <= id)
      49             :         return 0.0;
      50             :     else
      51        1461 :         return flows[(size_t)id];
      52             : }
      53             : 
      54           3 : Routes Solution::getRoutes() const {
      55           3 :     Routes ret;
      56           3 :     s->addToRoutes(ret);
      57           3 :     return ret;
      58             : }
      59             : 
      60          21 : Solution &Solution::operator=(const Solution &sol) {
      61          21 :     s = sol.s;
      62             : 
      63          21 :     return *this;
      64             : }
      65             : 
      66         159 : Solution Solution::interpolate(
      67             :     const Solution &s1,
      68             :     const Solution &s2,
      69             :     Flow            alpha
      70             : ) {
      71         159 : #pragma GCC diagnostic push
      72         159 : #pragma GCC diagnostic ignored "-Wfloat-equal"
      73         159 :     if(alpha == 0.0)
      74           1 :         return s1;
      75         158 :     if(alpha == 1.0)
      76           1 :         return s2;
      77         157 : #pragma GCC diagnostic pop
      78             : 
      79         316 :     Solution ret;
      80             : 
      81         157 :     ret.s->alpha = alpha;
      82         157 :     ret.s->s1    = s1.s;
      83         157 :     ret.s->s2    = s2.s;
      84             : 
      85         314 :     const unordered_set<Edge::ID> &edges1 = s1.getEdges();
      86         314 :     const unordered_set<Edge::ID> &edges2 = s2.getEdges();
      87             : 
      88         157 :     auto &edges = ret.s->edges;
      89         157 :     auto &flows = ret.s->flows;
      90             : 
      91         157 :     edges.insert(edges1.begin(), edges1.end());
      92         157 :     edges.insert(edges2.begin(), edges2.end());
      93             : 
      94         157 :     if(edges.empty())
      95           0 :         flows.resize(0);
      96             :     else
      97         314 :         flows.resize(*max_element(edges.begin(), edges.end()) + 1, 0.0);
      98             : 
      99         700 :     for(size_t id = 0; id < flows.size(); ++id) {
     100         543 :         Edge::ID edgeID = (Edge::ID)id;
     101        1086 :         flows[id] =
     102         543 :             (1.0 - alpha) * s1.getFlowInEdge(edgeID) + (alpha)*s2.getFlowInEdge(edgeID);
     103             :     }
     104             : 
     105         157 :     return ret;
     106             : }
     107             : 
     108           0 : void Solution::materialize() {
     109           0 :     s->materialize();
     110           0 : }
     111             : 
     112           0 : void Solution::Internals::materialize() {
     113           0 :     if(s1) {
     114           0 :         s1->addToRoutes(paths, 1.0 - alpha);
     115           0 :         s1.reset();
     116             :     }
     117           0 :     if(s2) {
     118           0 :         s2->addToRoutes(paths, alpha);
     119           0 :         s2.reset();
     120             :     }
     121           0 : }
     122             : 
     123           3 : double Solution::getTotalFlow() const {
     124           3 :     double ret    = 0.0;
     125           3 :     Routes routes = getRoutes();
     126           9 :     for(const auto &[path, flow]: routes) {
     127           6 :         ret += flow;
     128             :     }
     129           3 :     return ret;
     130             : }
     131             : 
     132          18 : void SolutionBase::addPath(const Path &path, Flow newFlow) {
     133          18 :     auto &paths = s.get()->paths;
     134          18 :     auto &flows = s.get()->flows;
     135          18 :     auto &edges = s.get()->edges;
     136             : 
     137          18 :     Flow &f     = paths[path];
     138          18 :     Flow  delta = newFlow - f;
     139             : 
     140             :     /*
     141             :      * TODO: check if this is correct. Because it would make more sense to have
     142             :      * f += delta instead of f = newFlow; in which case it should be discussed
     143             :      * what the definition of newFlow is. Because we are not actually adding a
     144             :      * flow, we are modifying the flow of a path.
     145             :      */
     146          18 :     f = newFlow;
     147             : 
     148          18 :     if(!path.empty()) {
     149          18 :         Edge::ID maxId = *max_element(path.begin(), path.end());
     150          18 :         if(maxId >= (Edge::ID)flows.size()) flows.resize(maxId + 1, 0.0);
     151             :     }
     152             : 
     153          65 :     for(const Edge::ID &id: path) {
     154          47 :         edges.insert(id);
     155          47 :         flows[id] += delta;
     156             :     }
     157          18 : }

Generated by: LCOV version 1.14