COIN-OR::LEMON - Graph Library

Changeset 840:2914b6f0fde0 in lemon-1.2 for lemon/cost_scaling.h


Ignore:
Timestamp:
02/26/10 14:00:20 (14 years ago)
Author:
Alpar Juttner <alpar@…>
Branch:
default
Parents:
838:2c35bef44dd1 (diff), 839:f3bc4e9b5f3a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Phase:
public
Message:

Merge #340

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • lemon/cost_scaling.h

    r831 r840  
    202202
    203203    typedef std::vector<int> IntVector;
    204     typedef std::vector<char> BoolVector;
    205204    typedef std::vector<Value> ValueVector;
    206205    typedef std::vector<Cost> CostVector;
    207206    typedef std::vector<LargeCost> LargeCostVector;
     207    typedef std::vector<char> BoolVector;
     208    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
    208209
    209210  private:
     
    249250    bool _have_lower;
    250251    Value _sum_supply;
     252    int _sup_node_num;
    251253
    252254    // Data structures for storing the digraph
     
    277279    int _alpha;
    278280
     281    IntVector _buckets;
     282    IntVector _bucket_next;
     283    IntVector _bucket_prev;
     284    IntVector _rank;
     285    int _max_rank;
     286 
    279287    // Data for a StaticDigraph structure
    280288    typedef std::pair<int, int> IntPair;
     
    829837      }
    830838
     839      _sup_node_num = 0;
     840      for (NodeIt n(_graph); n != INVALID; ++n) {
     841        if (sup[n] > 0) ++_sup_node_num;
     842      }
     843
    831844      // Find a feasible flow using Circulation
    832845      Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
     
    863876        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
    864877          int ra = _reverse[a];
    865           _res_cap[a] = 1;
     878          _res_cap[a] = 0;
    866879          _res_cap[ra] = 0;
    867880          _cost[a] = 0;
     
    877890      // Maximum path length for partial augment
    878891      const int MAX_PATH_LENGTH = 4;
    879      
     892
     893      // Initialize data structures for buckets     
     894      _max_rank = _alpha * _res_node_num;
     895      _buckets.resize(_max_rank);
     896      _bucket_next.resize(_res_node_num + 1);
     897      _bucket_prev.resize(_res_node_num + 1);
     898      _rank.resize(_res_node_num + 1);
     899 
    880900      // Execute the algorithm
    881901      switch (method) {
     
    916936      }
    917937    }
     938   
     939    // Initialize a cost scaling phase
     940    void initPhase() {
     941      // Saturate arcs not satisfying the optimality condition
     942      for (int u = 0; u != _res_node_num; ++u) {
     943        int last_out = _first_out[u+1];
     944        LargeCost pi_u = _pi[u];
     945        for (int a = _first_out[u]; a != last_out; ++a) {
     946          int v = _target[a];
     947          if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) {
     948            Value delta = _res_cap[a];
     949            _excess[u] -= delta;
     950            _excess[v] += delta;
     951            _res_cap[a] = 0;
     952            _res_cap[_reverse[a]] += delta;
     953          }
     954        }
     955      }
     956     
     957      // Find active nodes (i.e. nodes with positive excess)
     958      for (int u = 0; u != _res_node_num; ++u) {
     959        if (_excess[u] > 0) _active_nodes.push_back(u);
     960      }
     961
     962      // Initialize the next arcs
     963      for (int u = 0; u != _res_node_num; ++u) {
     964        _next_out[u] = _first_out[u];
     965      }
     966    }
     967   
     968    // Early termination heuristic
     969    bool earlyTermination() {
     970      const double EARLY_TERM_FACTOR = 3.0;
     971
     972      // Build a static residual graph
     973      _arc_vec.clear();
     974      _cost_vec.clear();
     975      for (int j = 0; j != _res_arc_num; ++j) {
     976        if (_res_cap[j] > 0) {
     977          _arc_vec.push_back(IntPair(_source[j], _target[j]));
     978          _cost_vec.push_back(_cost[j] + 1);
     979        }
     980      }
     981      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
     982
     983      // Run Bellman-Ford algorithm to check if the current flow is optimal
     984      BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
     985      bf.init(0);
     986      bool done = false;
     987      int K = int(EARLY_TERM_FACTOR * std::sqrt(double(_res_node_num)));
     988      for (int i = 0; i < K && !done; ++i) {
     989        done = bf.processNextWeakRound();
     990      }
     991      return done;
     992    }
     993
     994    // Global potential update heuristic
     995    void globalUpdate() {
     996      int bucket_end = _root + 1;
     997   
     998      // Initialize buckets
     999      for (int r = 0; r != _max_rank; ++r) {
     1000        _buckets[r] = bucket_end;
     1001      }
     1002      Value total_excess = 0;
     1003      for (int i = 0; i != _res_node_num; ++i) {
     1004        if (_excess[i] < 0) {
     1005          _rank[i] = 0;
     1006          _bucket_next[i] = _buckets[0];
     1007          _bucket_prev[_buckets[0]] = i;
     1008          _buckets[0] = i;
     1009        } else {
     1010          total_excess += _excess[i];
     1011          _rank[i] = _max_rank;
     1012        }
     1013      }
     1014      if (total_excess == 0) return;
     1015
     1016      // Search the buckets
     1017      int r = 0;
     1018      for ( ; r != _max_rank; ++r) {
     1019        while (_buckets[r] != bucket_end) {
     1020          // Remove the first node from the current bucket
     1021          int u = _buckets[r];
     1022          _buckets[r] = _bucket_next[u];
     1023         
     1024          // Search the incomming arcs of u
     1025          LargeCost pi_u = _pi[u];
     1026          int last_out = _first_out[u+1];
     1027          for (int a = _first_out[u]; a != last_out; ++a) {
     1028            int ra = _reverse[a];
     1029            if (_res_cap[ra] > 0) {
     1030              int v = _source[ra];
     1031              int old_rank_v = _rank[v];
     1032              if (r < old_rank_v) {
     1033                // Compute the new rank of v
     1034                LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon;
     1035                int new_rank_v = old_rank_v;
     1036                if (nrc < LargeCost(_max_rank))
     1037                  new_rank_v = r + 1 + int(nrc);
     1038                 
     1039                // Change the rank of v
     1040                if (new_rank_v < old_rank_v) {
     1041                  _rank[v] = new_rank_v;
     1042                  _next_out[v] = _first_out[v];
     1043                 
     1044                  // Remove v from its old bucket
     1045                  if (old_rank_v < _max_rank) {
     1046                    if (_buckets[old_rank_v] == v) {
     1047                      _buckets[old_rank_v] = _bucket_next[v];
     1048                    } else {
     1049                      _bucket_next[_bucket_prev[v]] = _bucket_next[v];
     1050                      _bucket_prev[_bucket_next[v]] = _bucket_prev[v];
     1051                    }
     1052                  }
     1053                 
     1054                  // Insert v to its new bucket
     1055                  _bucket_next[v] = _buckets[new_rank_v];
     1056                  _bucket_prev[_buckets[new_rank_v]] = v;
     1057                  _buckets[new_rank_v] = v;
     1058                }
     1059              }
     1060            }
     1061          }
     1062
     1063          // Finish search if there are no more active nodes
     1064          if (_excess[u] > 0) {
     1065            total_excess -= _excess[u];
     1066            if (total_excess <= 0) break;
     1067          }
     1068        }
     1069        if (total_excess <= 0) break;
     1070      }
     1071     
     1072      // Relabel nodes
     1073      for (int u = 0; u != _res_node_num; ++u) {
     1074        int k = std::min(_rank[u], r);
     1075        if (k > 0) {
     1076          _pi[u] -= _epsilon * k;
     1077          _next_out[u] = _first_out[u];
     1078        }
     1079      }
     1080    }
    9181081
    9191082    /// Execute the algorithm performing augment and relabel operations
    9201083    void startAugment(int max_length = std::numeric_limits<int>::max()) {
    9211084      // Paramters for heuristics
    922       const int BF_HEURISTIC_EPSILON_BOUND = 1000;
    923       const int BF_HEURISTIC_BOUND_FACTOR  = 3;
    924 
     1085      const int EARLY_TERM_EPSILON_LIMIT = 1000;
     1086      const double GLOBAL_UPDATE_FACTOR = 3.0;
     1087
     1088      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
     1089        (_res_node_num + _sup_node_num * _sup_node_num));
     1090      int next_update_limit = global_update_freq;
     1091     
     1092      int relabel_cnt = 0;
     1093     
    9251094      // Perform cost scaling phases
    926       IntVector pred_arc(_res_node_num);
    927       std::vector<int> path_nodes;
     1095      std::vector<int> path;
    9281096      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
    9291097                                        1 : _epsilon / _alpha )
    9301098      {
    931         // "Early Termination" heuristic: use Bellman-Ford algorithm
    932         // to check if the current flow is optimal
    933         if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
    934           _arc_vec.clear();
    935           _cost_vec.clear();
    936           for (int j = 0; j != _res_arc_num; ++j) {
    937             if (_res_cap[j] > 0) {
    938               _arc_vec.push_back(IntPair(_source[j], _target[j]));
    939               _cost_vec.push_back(_cost[j] + 1);
    940             }
    941           }
    942           _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
    943 
    944           BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
    945           bf.init(0);
    946           bool done = false;
    947           int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(_res_node_num));
    948           for (int i = 0; i < K && !done; ++i)
    949             done = bf.processNextWeakRound();
    950           if (done) break;
    951         }
    952 
    953         // Saturate arcs not satisfying the optimality condition
    954         for (int a = 0; a != _res_arc_num; ++a) {
    955           if (_res_cap[a] > 0 &&
    956               _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
    957             Value delta = _res_cap[a];
    958             _excess[_source[a]] -= delta;
    959             _excess[_target[a]] += delta;
    960             _res_cap[a] = 0;
    961             _res_cap[_reverse[a]] += delta;
    962           }
     1099        // Early termination heuristic
     1100        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
     1101          if (earlyTermination()) break;
    9631102        }
    9641103       
    965         // Find active nodes (i.e. nodes with positive excess)
    966         for (int u = 0; u != _res_node_num; ++u) {
    967           if (_excess[u] > 0) _active_nodes.push_back(u);
    968         }
    969 
    970         // Initialize the next arcs
    971         for (int u = 0; u != _res_node_num; ++u) {
    972           _next_out[u] = _first_out[u];
    973         }
    974 
     1104        // Initialize current phase
     1105        initPhase();
     1106       
    9751107        // Perform partial augment and relabel operations
    9761108        while (true) {
     
    9821114          if (_active_nodes.size() == 0) break;
    9831115          int start = _active_nodes.front();
    984           path_nodes.clear();
    985           path_nodes.push_back(start);
    9861116
    9871117          // Find an augmenting path from the start node
     1118          path.clear();
    9881119          int tip = start;
    989           while (_excess[tip] >= 0 &&
    990                  int(path_nodes.size()) <= max_length) {
     1120          while (_excess[tip] >= 0 && int(path.size()) < max_length) {
    9911121            int u;
    992             LargeCost min_red_cost, rc;
    993             int last_out = _sum_supply < 0 ?
    994               _first_out[tip+1] : _first_out[tip+1] - 1;
     1122            LargeCost min_red_cost, rc, pi_tip = _pi[tip];
     1123            int last_out = _first_out[tip+1];
    9951124            for (int a = _next_out[tip]; a != last_out; ++a) {
    996               if (_res_cap[a] > 0 &&
    997                   _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
    998                 u = _target[a];
    999                 pred_arc[u] = a;
     1125              u = _target[a];
     1126              if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) {
     1127                path.push_back(a);
    10001128                _next_out[tip] = a;
    10011129                tip = u;
    1002                 path_nodes.push_back(tip);
    10031130                goto next_step;
    10041131              }
     
    10061133
    10071134            // Relabel tip node
    1008             min_red_cost = std::numeric_limits<LargeCost>::max() / 2;
     1135            min_red_cost = std::numeric_limits<LargeCost>::max();
     1136            if (tip != start) {
     1137              int ra = _reverse[path.back()];
     1138              min_red_cost = _cost[ra] + pi_tip - _pi[_target[ra]];
     1139            }
    10091140            for (int a = _first_out[tip]; a != last_out; ++a) {
    1010               rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]];
     1141              rc = _cost[a] + pi_tip - _pi[_target[a]];
    10111142              if (_res_cap[a] > 0 && rc < min_red_cost) {
    10121143                min_red_cost = rc;
     
    10141145            }
    10151146            _pi[tip] -= min_red_cost + _epsilon;
    1016 
    1017             // Reset the next arc of tip
    10181147            _next_out[tip] = _first_out[tip];
     1148            ++relabel_cnt;
    10191149
    10201150            // Step back
    10211151            if (tip != start) {
    1022               path_nodes.pop_back();
    1023               tip = path_nodes.back();
     1152              tip = _source[path.back()];
     1153              path.pop_back();
    10241154            }
    10251155
     
    10291159          // Augment along the found path (as much flow as possible)
    10301160          Value delta;
    1031           int u, v = path_nodes.front(), pa;
    1032           for (int i = 1; i < int(path_nodes.size()); ++i) {
     1161          int pa, u, v = start;
     1162          for (int i = 0; i != int(path.size()); ++i) {
     1163            pa = path[i];
    10331164            u = v;
    1034             v = path_nodes[i];
    1035             pa = pred_arc[v];
     1165            v = _target[pa];
    10361166            delta = std::min(_res_cap[pa], _excess[u]);
    10371167            _res_cap[pa] -= delta;
     
    10421172              _active_nodes.push_back(v);
    10431173          }
     1174
     1175          // Global update heuristic
     1176          if (relabel_cnt >= next_update_limit) {
     1177            globalUpdate();
     1178            next_update_limit += global_update_freq;
     1179          }
    10441180        }
    10451181      }
     
    10491185    void startPush() {
    10501186      // Paramters for heuristics
    1051       const int BF_HEURISTIC_EPSILON_BOUND = 1000;
    1052       const int BF_HEURISTIC_BOUND_FACTOR  = 3;
    1053 
     1187      const int EARLY_TERM_EPSILON_LIMIT = 1000;
     1188      const double GLOBAL_UPDATE_FACTOR = 2.0;
     1189
     1190      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
     1191        (_res_node_num + _sup_node_num * _sup_node_num));
     1192      int next_update_limit = global_update_freq;
     1193
     1194      int relabel_cnt = 0;
     1195     
    10541196      // Perform cost scaling phases
    10551197      BoolVector hyper(_res_node_num, false);
     1198      LargeCostVector hyper_cost(_res_node_num);
    10561199      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
    10571200                                        1 : _epsilon / _alpha )
    10581201      {
    1059         // "Early Termination" heuristic: use Bellman-Ford algorithm
    1060         // to check if the current flow is optimal
    1061         if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
    1062           _arc_vec.clear();
    1063           _cost_vec.clear();
    1064           for (int j = 0; j != _res_arc_num; ++j) {
    1065             if (_res_cap[j] > 0) {
    1066               _arc_vec.push_back(IntPair(_source[j], _target[j]));
    1067               _cost_vec.push_back(_cost[j] + 1);
    1068             }
    1069           }
    1070           _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
    1071 
    1072           BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
    1073           bf.init(0);
    1074           bool done = false;
    1075           int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(_res_node_num));
    1076           for (int i = 0; i < K && !done; ++i)
    1077             done = bf.processNextWeakRound();
    1078           if (done) break;
    1079         }
    1080 
    1081         // Saturate arcs not satisfying the optimality condition
    1082         for (int a = 0; a != _res_arc_num; ++a) {
    1083           if (_res_cap[a] > 0 &&
    1084               _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
    1085             Value delta = _res_cap[a];
    1086             _excess[_source[a]] -= delta;
    1087             _excess[_target[a]] += delta;
    1088             _res_cap[a] = 0;
    1089             _res_cap[_reverse[a]] += delta;
    1090           }
    1091         }
    1092 
    1093         // Find active nodes (i.e. nodes with positive excess)
    1094         for (int u = 0; u != _res_node_num; ++u) {
    1095           if (_excess[u] > 0) _active_nodes.push_back(u);
    1096         }
    1097 
    1098         // Initialize the next arcs
    1099         for (int u = 0; u != _res_node_num; ++u) {
    1100           _next_out[u] = _first_out[u];
    1101         }
     1202        // Early termination heuristic
     1203        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
     1204          if (earlyTermination()) break;
     1205        }
     1206       
     1207        // Initialize current phase
     1208        initPhase();
    11021209
    11031210        // Perform push and relabel operations
    11041211        while (_active_nodes.size() > 0) {
    1105           LargeCost min_red_cost, rc;
     1212          LargeCost min_red_cost, rc, pi_n;
    11061213          Value delta;
    11071214          int n, t, a, last_out = _res_arc_num;
    11081215
     1216        next_node:
    11091217          // Select an active node (FIFO selection)
    1110         next_node:
    11111218          n = _active_nodes.front();
    1112           last_out = _sum_supply < 0 ?
    1113             _first_out[n+1] : _first_out[n+1] - 1;
    1114 
     1219          last_out = _first_out[n+1];
     1220          pi_n = _pi[n];
     1221         
    11151222          // Perform push operations if there are admissible arcs
    11161223          if (_excess[n] > 0) {
    11171224            for (a = _next_out[n]; a != last_out; ++a) {
    11181225              if (_res_cap[a] > 0 &&
    1119                   _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
     1226                  _cost[a] + pi_n - _pi[_target[a]] < 0) {
    11201227                delta = std::min(_res_cap[a], _excess[n]);
    11211228                t = _target[a];
     
    11231230                // Push-look-ahead heuristic
    11241231                Value ahead = -_excess[t];
    1125                 int last_out_t = _sum_supply < 0 ?
    1126                   _first_out[t+1] : _first_out[t+1] - 1;
     1232                int last_out_t = _first_out[t+1];
     1233                LargeCost pi_t = _pi[t];
    11271234                for (int ta = _next_out[t]; ta != last_out_t; ++ta) {
    11281235                  if (_res_cap[ta] > 0 &&
    1129                       _cost[ta] + _pi[_source[ta]] - _pi[_target[ta]] < 0)
     1236                      _cost[ta] + pi_t - _pi[_target[ta]] < 0)
    11301237                    ahead += _res_cap[ta];
    11311238                  if (ahead >= delta) break;
     
    11341241
    11351242                // Push flow along the arc
    1136                 if (ahead < delta) {
     1243                if (ahead < delta && !hyper[t]) {
    11371244                  _res_cap[a] -= ahead;
    11381245                  _res_cap[_reverse[a]] += ahead;
     
    11411248                  _active_nodes.push_front(t);
    11421249                  hyper[t] = true;
     1250                  hyper_cost[t] = _cost[a] + pi_n - pi_t;
    11431251                  _next_out[n] = a;
    11441252                  goto next_node;
     
    11631271          // Relabel the node if it is still active (or hyper)
    11641272          if (_excess[n] > 0 || hyper[n]) {
    1165             min_red_cost = std::numeric_limits<LargeCost>::max() / 2;
     1273             min_red_cost = hyper[n] ? -hyper_cost[n] :
     1274               std::numeric_limits<LargeCost>::max();
    11661275            for (int a = _first_out[n]; a != last_out; ++a) {
    1167               rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]];
     1276              rc = _cost[a] + pi_n - _pi[_target[a]];
    11681277              if (_res_cap[a] > 0 && rc < min_red_cost) {
    11691278                min_red_cost = rc;
     
    11711280            }
    11721281            _pi[n] -= min_red_cost + _epsilon;
     1282            _next_out[n] = _first_out[n];
    11731283            hyper[n] = false;
    1174 
    1175             // Reset the next arc
    1176             _next_out[n] = _first_out[n];
     1284            ++relabel_cnt;
    11771285          }
    11781286       
     
    11841292            _active_nodes.pop_front();
    11851293          }
     1294         
     1295          // Global update heuristic
     1296          if (relabel_cnt >= next_update_limit) {
     1297            globalUpdate();
     1298            for (int u = 0; u != _res_node_num; ++u)
     1299              hyper[u] = false;
     1300            next_update_limit += global_update_freq;
     1301          }
    11861302        }
    11871303      }
  • lemon/cost_scaling.h

    r839 r840  
    105105  /// \tparam GR The digraph type the algorithm runs on.
    106106  /// \tparam V The number type used for flow amounts, capacity bounds
    107   /// and supply values in the algorithm. By default it is \c int.
     107  /// and supply values in the algorithm. By default, it is \c int.
    108108  /// \tparam C The number type used for costs and potentials in the
    109   /// algorithm. By default it is the same as \c V.
     109  /// algorithm. By default, it is the same as \c V.
     110  /// \tparam TR The traits class that defines various types used by the
     111  /// algorithm. By default, it is \ref CostScalingDefaultTraits
     112  /// "CostScalingDefaultTraits<GR, V, C>".
     113  /// In most cases, this parameter should not be set directly,
     114  /// consider to use the named template parameters instead.
    110115  ///
    111116  /// \warning Both number types must be signed and all input data must
     
    137142    ///
    138143    /// The large cost type used for internal computations.
    139     /// Using the \ref CostScalingDefaultTraits "default traits class",
    140     /// it is \c long \c long if the \c Cost type is integer,
     144    /// By default, it is \c long \c long if the \c Cost type is integer,
    141145    /// otherwise it is \c double.
    142146    typedef typename TR::LargeCost LargeCost;
     
    341345      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
    342346        "The cost type of CostScaling must be signed");
    343 
     347     
     348      // Reset data structures
     349      reset();
     350    }
     351
     352    /// \name Parameters
     353    /// The parameters of the algorithm can be specified using these
     354    /// functions.
     355
     356    /// @{
     357
     358    /// \brief Set the lower bounds on the arcs.
     359    ///
     360    /// This function sets the lower bounds on the arcs.
     361    /// If it is not used before calling \ref run(), the lower bounds
     362    /// will be set to zero on all arcs.
     363    ///
     364    /// \param map An arc map storing the lower bounds.
     365    /// Its \c Value type must be convertible to the \c Value type
     366    /// of the algorithm.
     367    ///
     368    /// \return <tt>(*this)</tt>
     369    template <typename LowerMap>
     370    CostScaling& lowerMap(const LowerMap& map) {
     371      _have_lower = true;
     372      for (ArcIt a(_graph); a != INVALID; ++a) {
     373        _lower[_arc_idf[a]] = map[a];
     374        _lower[_arc_idb[a]] = map[a];
     375      }
     376      return *this;
     377    }
     378
     379    /// \brief Set the upper bounds (capacities) on the arcs.
     380    ///
     381    /// This function sets the upper bounds (capacities) on the arcs.
     382    /// If it is not used before calling \ref run(), the upper bounds
     383    /// will be set to \ref INF on all arcs (i.e. the flow value will be
     384    /// unbounded from above).
     385    ///
     386    /// \param map An arc map storing the upper bounds.
     387    /// Its \c Value type must be convertible to the \c Value type
     388    /// of the algorithm.
     389    ///
     390    /// \return <tt>(*this)</tt>
     391    template<typename UpperMap>
     392    CostScaling& upperMap(const UpperMap& map) {
     393      for (ArcIt a(_graph); a != INVALID; ++a) {
     394        _upper[_arc_idf[a]] = map[a];
     395      }
     396      return *this;
     397    }
     398
     399    /// \brief Set the costs of the arcs.
     400    ///
     401    /// This function sets the costs of the arcs.
     402    /// If it is not used before calling \ref run(), the costs
     403    /// will be set to \c 1 on all arcs.
     404    ///
     405    /// \param map An arc map storing the costs.
     406    /// Its \c Value type must be convertible to the \c Cost type
     407    /// of the algorithm.
     408    ///
     409    /// \return <tt>(*this)</tt>
     410    template<typename CostMap>
     411    CostScaling& costMap(const CostMap& map) {
     412      for (ArcIt a(_graph); a != INVALID; ++a) {
     413        _scost[_arc_idf[a]] =  map[a];
     414        _scost[_arc_idb[a]] = -map[a];
     415      }
     416      return *this;
     417    }
     418
     419    /// \brief Set the supply values of the nodes.
     420    ///
     421    /// This function sets the supply values of the nodes.
     422    /// If neither this function nor \ref stSupply() is used before
     423    /// calling \ref run(), the supply of each node will be set to zero.
     424    ///
     425    /// \param map A node map storing the supply values.
     426    /// Its \c Value type must be convertible to the \c Value type
     427    /// of the algorithm.
     428    ///
     429    /// \return <tt>(*this)</tt>
     430    template<typename SupplyMap>
     431    CostScaling& supplyMap(const SupplyMap& map) {
     432      for (NodeIt n(_graph); n != INVALID; ++n) {
     433        _supply[_node_id[n]] = map[n];
     434      }
     435      return *this;
     436    }
     437
     438    /// \brief Set single source and target nodes and a supply value.
     439    ///
     440    /// This function sets a single source node and a single target node
     441    /// and the required flow value.
     442    /// If neither this function nor \ref supplyMap() is used before
     443    /// calling \ref run(), the supply of each node will be set to zero.
     444    ///
     445    /// Using this function has the same effect as using \ref supplyMap()
     446    /// with such a map in which \c k is assigned to \c s, \c -k is
     447    /// assigned to \c t and all other nodes have zero supply value.
     448    ///
     449    /// \param s The source node.
     450    /// \param t The target node.
     451    /// \param k The required amount of flow from node \c s to node \c t
     452    /// (i.e. the supply of \c s and the demand of \c t).
     453    ///
     454    /// \return <tt>(*this)</tt>
     455    CostScaling& stSupply(const Node& s, const Node& t, Value k) {
     456      for (int i = 0; i != _res_node_num; ++i) {
     457        _supply[i] = 0;
     458      }
     459      _supply[_node_id[s]] =  k;
     460      _supply[_node_id[t]] = -k;
     461      return *this;
     462    }
     463   
     464    /// @}
     465
     466    /// \name Execution control
     467    /// The algorithm can be executed using \ref run().
     468
     469    /// @{
     470
     471    /// \brief Run the algorithm.
     472    ///
     473    /// This function runs the algorithm.
     474    /// The paramters can be specified using functions \ref lowerMap(),
     475    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
     476    /// For example,
     477    /// \code
     478    ///   CostScaling<ListDigraph> cs(graph);
     479    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
     480    ///     .supplyMap(sup).run();
     481    /// \endcode
     482    ///
     483    /// This function can be called more than once. All the given parameters
     484    /// are kept for the next call, unless \ref resetParams() or \ref reset()
     485    /// is used, thus only the modified parameters have to be set again.
     486    /// If the underlying digraph was also modified after the construction
     487    /// of the class (or the last \ref reset() call), then the \ref reset()
     488    /// function must be called.
     489    ///
     490    /// \param method The internal method that will be used in the
     491    /// algorithm. For more information, see \ref Method.
     492    /// \param factor The cost scaling factor. It must be larger than one.
     493    ///
     494    /// \return \c INFEASIBLE if no feasible flow exists,
     495    /// \n \c OPTIMAL if the problem has optimal solution
     496    /// (i.e. it is feasible and bounded), and the algorithm has found
     497    /// optimal flow and node potentials (primal and dual solutions),
     498    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
     499    /// and infinite upper bound. It means that the objective function
     500    /// is unbounded on that arc, however, note that it could actually be
     501    /// bounded over the feasible flows, but this algroithm cannot handle
     502    /// these cases.
     503    ///
     504    /// \see ProblemType, Method
     505    /// \see resetParams(), reset()
     506    ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) {
     507      _alpha = factor;
     508      ProblemType pt = init();
     509      if (pt != OPTIMAL) return pt;
     510      start(method);
     511      return OPTIMAL;
     512    }
     513
     514    /// \brief Reset all the parameters that have been given before.
     515    ///
     516    /// This function resets all the paramaters that have been given
     517    /// before using functions \ref lowerMap(), \ref upperMap(),
     518    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
     519    ///
     520    /// It is useful for multiple \ref run() calls. Basically, all the given
     521    /// parameters are kept for the next \ref run() call, unless
     522    /// \ref resetParams() or \ref reset() is used.
     523    /// If the underlying digraph was also modified after the construction
     524    /// of the class or the last \ref reset() call, then the \ref reset()
     525    /// function must be used, otherwise \ref resetParams() is sufficient.
     526    ///
     527    /// For example,
     528    /// \code
     529    ///   CostScaling<ListDigraph> cs(graph);
     530    ///
     531    ///   // First run
     532    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
     533    ///     .supplyMap(sup).run();
     534    ///
     535    ///   // Run again with modified cost map (resetParams() is not called,
     536    ///   // so only the cost map have to be set again)
     537    ///   cost[e] += 100;
     538    ///   cs.costMap(cost).run();
     539    ///
     540    ///   // Run again from scratch using resetParams()
     541    ///   // (the lower bounds will be set to zero on all arcs)
     542    ///   cs.resetParams();
     543    ///   cs.upperMap(capacity).costMap(cost)
     544    ///     .supplyMap(sup).run();
     545    /// \endcode
     546    ///
     547    /// \return <tt>(*this)</tt>
     548    ///
     549    /// \see reset(), run()
     550    CostScaling& resetParams() {
     551      for (int i = 0; i != _res_node_num; ++i) {
     552        _supply[i] = 0;
     553      }
     554      int limit = _first_out[_root];
     555      for (int j = 0; j != limit; ++j) {
     556        _lower[j] = 0;
     557        _upper[j] = INF;
     558        _scost[j] = _forward[j] ? 1 : -1;
     559      }
     560      for (int j = limit; j != _res_arc_num; ++j) {
     561        _lower[j] = 0;
     562        _upper[j] = INF;
     563        _scost[j] = 0;
     564        _scost[_reverse[j]] = 0;
     565      }     
     566      _have_lower = false;
     567      return *this;
     568    }
     569
     570    /// \brief Reset all the parameters that have been given before.
     571    ///
     572    /// This function resets all the paramaters that have been given
     573    /// before using functions \ref lowerMap(), \ref upperMap(),
     574    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
     575    ///
     576    /// It is useful for multiple run() calls. If this function is not
     577    /// used, all the parameters given before are kept for the next
     578    /// \ref run() call.
     579    /// However, the underlying digraph must not be modified after this
     580    /// class have been constructed, since it copies and extends the graph.
     581    /// \return <tt>(*this)</tt>
     582    CostScaling& reset() {
    344583      // Resize vectors
    345584      _node_num = countNodes(_graph);
     
    409648     
    410649      // Reset parameters
    411       reset();
    412     }
    413 
    414     /// \name Parameters
    415     /// The parameters of the algorithm can be specified using these
    416     /// functions.
    417 
    418     /// @{
    419 
    420     /// \brief Set the lower bounds on the arcs.
    421     ///
    422     /// This function sets the lower bounds on the arcs.
    423     /// If it is not used before calling \ref run(), the lower bounds
    424     /// will be set to zero on all arcs.
    425     ///
    426     /// \param map An arc map storing the lower bounds.
    427     /// Its \c Value type must be convertible to the \c Value type
    428     /// of the algorithm.
    429     ///
    430     /// \return <tt>(*this)</tt>
    431     template <typename LowerMap>
    432     CostScaling& lowerMap(const LowerMap& map) {
    433       _have_lower = true;
    434       for (ArcIt a(_graph); a != INVALID; ++a) {
    435         _lower[_arc_idf[a]] = map[a];
    436         _lower[_arc_idb[a]] = map[a];
    437       }
    438       return *this;
    439     }
    440 
    441     /// \brief Set the upper bounds (capacities) on the arcs.
    442     ///
    443     /// This function sets the upper bounds (capacities) on the arcs.
    444     /// If it is not used before calling \ref run(), the upper bounds
    445     /// will be set to \ref INF on all arcs (i.e. the flow value will be
    446     /// unbounded from above).
    447     ///
    448     /// \param map An arc map storing the upper bounds.
    449     /// Its \c Value type must be convertible to the \c Value type
    450     /// of the algorithm.
    451     ///
    452     /// \return <tt>(*this)</tt>
    453     template<typename UpperMap>
    454     CostScaling& upperMap(const UpperMap& map) {
    455       for (ArcIt a(_graph); a != INVALID; ++a) {
    456         _upper[_arc_idf[a]] = map[a];
    457       }
    458       return *this;
    459     }
    460 
    461     /// \brief Set the costs of the arcs.
    462     ///
    463     /// This function sets the costs of the arcs.
    464     /// If it is not used before calling \ref run(), the costs
    465     /// will be set to \c 1 on all arcs.
    466     ///
    467     /// \param map An arc map storing the costs.
    468     /// Its \c Value type must be convertible to the \c Cost type
    469     /// of the algorithm.
    470     ///
    471     /// \return <tt>(*this)</tt>
    472     template<typename CostMap>
    473     CostScaling& costMap(const CostMap& map) {
    474       for (ArcIt a(_graph); a != INVALID; ++a) {
    475         _scost[_arc_idf[a]] =  map[a];
    476         _scost[_arc_idb[a]] = -map[a];
    477       }
    478       return *this;
    479     }
    480 
    481     /// \brief Set the supply values of the nodes.
    482     ///
    483     /// This function sets the supply values of the nodes.
    484     /// If neither this function nor \ref stSupply() is used before
    485     /// calling \ref run(), the supply of each node will be set to zero.
    486     ///
    487     /// \param map A node map storing the supply values.
    488     /// Its \c Value type must be convertible to the \c Value type
    489     /// of the algorithm.
    490     ///
    491     /// \return <tt>(*this)</tt>
    492     template<typename SupplyMap>
    493     CostScaling& supplyMap(const SupplyMap& map) {
    494       for (NodeIt n(_graph); n != INVALID; ++n) {
    495         _supply[_node_id[n]] = map[n];
    496       }
    497       return *this;
    498     }
    499 
    500     /// \brief Set single source and target nodes and a supply value.
    501     ///
    502     /// This function sets a single source node and a single target node
    503     /// and the required flow value.
    504     /// If neither this function nor \ref supplyMap() is used before
    505     /// calling \ref run(), the supply of each node will be set to zero.
    506     ///
    507     /// Using this function has the same effect as using \ref supplyMap()
    508     /// with such a map in which \c k is assigned to \c s, \c -k is
    509     /// assigned to \c t and all other nodes have zero supply value.
    510     ///
    511     /// \param s The source node.
    512     /// \param t The target node.
    513     /// \param k The required amount of flow from node \c s to node \c t
    514     /// (i.e. the supply of \c s and the demand of \c t).
    515     ///
    516     /// \return <tt>(*this)</tt>
    517     CostScaling& stSupply(const Node& s, const Node& t, Value k) {
    518       for (int i = 0; i != _res_node_num; ++i) {
    519         _supply[i] = 0;
    520       }
    521       _supply[_node_id[s]] =  k;
    522       _supply[_node_id[t]] = -k;
    523       return *this;
    524     }
    525    
    526     /// @}
    527 
    528     /// \name Execution control
    529     /// The algorithm can be executed using \ref run().
    530 
    531     /// @{
    532 
    533     /// \brief Run the algorithm.
    534     ///
    535     /// This function runs the algorithm.
    536     /// The paramters can be specified using functions \ref lowerMap(),
    537     /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
    538     /// For example,
    539     /// \code
    540     ///   CostScaling<ListDigraph> cs(graph);
    541     ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
    542     ///     .supplyMap(sup).run();
    543     /// \endcode
    544     ///
    545     /// This function can be called more than once. All the parameters
    546     /// that have been given are kept for the next call, unless
    547     /// \ref reset() is called, thus only the modified parameters
    548     /// have to be set again. See \ref reset() for examples.
    549     /// However, the underlying digraph must not be modified after this
    550     /// class have been constructed, since it copies and extends the graph.
    551     ///
    552     /// \param method The internal method that will be used in the
    553     /// algorithm. For more information, see \ref Method.
    554     /// \param factor The cost scaling factor. It must be larger than one.
    555     ///
    556     /// \return \c INFEASIBLE if no feasible flow exists,
    557     /// \n \c OPTIMAL if the problem has optimal solution
    558     /// (i.e. it is feasible and bounded), and the algorithm has found
    559     /// optimal flow and node potentials (primal and dual solutions),
    560     /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
    561     /// and infinite upper bound. It means that the objective function
    562     /// is unbounded on that arc, however, note that it could actually be
    563     /// bounded over the feasible flows, but this algroithm cannot handle
    564     /// these cases.
    565     ///
    566     /// \see ProblemType, Method
    567     ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) {
    568       _alpha = factor;
    569       ProblemType pt = init();
    570       if (pt != OPTIMAL) return pt;
    571       start(method);
    572       return OPTIMAL;
    573     }
    574 
    575     /// \brief Reset all the parameters that have been given before.
    576     ///
    577     /// This function resets all the paramaters that have been given
    578     /// before using functions \ref lowerMap(), \ref upperMap(),
    579     /// \ref costMap(), \ref supplyMap(), \ref stSupply().
    580     ///
    581     /// It is useful for multiple run() calls. If this function is not
    582     /// used, all the parameters given before are kept for the next
    583     /// \ref run() call.
    584     /// However, the underlying digraph must not be modified after this
    585     /// class have been constructed, since it copies and extends the graph.
    586     ///
    587     /// For example,
    588     /// \code
    589     ///   CostScaling<ListDigraph> cs(graph);
    590     ///
    591     ///   // First run
    592     ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
    593     ///     .supplyMap(sup).run();
    594     ///
    595     ///   // Run again with modified cost map (reset() is not called,
    596     ///   // so only the cost map have to be set again)
    597     ///   cost[e] += 100;
    598     ///   cs.costMap(cost).run();
    599     ///
    600     ///   // Run again from scratch using reset()
    601     ///   // (the lower bounds will be set to zero on all arcs)
    602     ///   cs.reset();
    603     ///   cs.upperMap(capacity).costMap(cost)
    604     ///     .supplyMap(sup).run();
    605     /// \endcode
    606     ///
    607     /// \return <tt>(*this)</tt>
    608     CostScaling& reset() {
    609       for (int i = 0; i != _res_node_num; ++i) {
    610         _supply[i] = 0;
    611       }
    612       int limit = _first_out[_root];
    613       for (int j = 0; j != limit; ++j) {
    614         _lower[j] = 0;
    615         _upper[j] = INF;
    616         _scost[j] = _forward[j] ? 1 : -1;
    617       }
    618       for (int j = limit; j != _res_arc_num; ++j) {
    619         _lower[j] = 0;
    620         _upper[j] = INF;
    621         _scost[j] = 0;
    622         _scost[_reverse[j]] = 0;
    623       }     
    624       _have_lower = false;
     650      resetParams();
    625651      return *this;
    626652    }
Note: See TracChangeset for help on using the changeset viewer.