gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Faster computation of the dual solution in CostScaling (#417)
0 1 0
default
1 file changed with 54 insertions and 26 deletions:
↑ Collapse diff ↑
Ignore white space 96 line context
... ...
@@ -192,202 +192,192 @@
192 192
      PUSH,
193 193
      /// Augment operations are used, i.e. flow is moved on admissible
194 194
      /// paths from a node with excess to a node with deficit.
195 195
      AUGMENT,
196 196
      /// Partial augment operations are used, i.e. flow is moved on
197 197
      /// admissible paths started from a node with excess, but the
198 198
      /// lengths of these paths are limited. This method can be viewed
199 199
      /// as a combined version of the previous two operations.
200 200
      PARTIAL_AUGMENT
201 201
    };
202 202

	
203 203
  private:
204 204

	
205 205
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
206 206

	
207 207
    typedef std::vector<int> IntVector;
208 208
    typedef std::vector<Value> ValueVector;
209 209
    typedef std::vector<Cost> CostVector;
210 210
    typedef std::vector<LargeCost> LargeCostVector;
211 211
    typedef std::vector<char> BoolVector;
212 212
    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
213 213

	
214 214
  private:
215 215

	
216 216
    template <typename KT, typename VT>
217 217
    class StaticVectorMap {
218 218
    public:
219 219
      typedef KT Key;
220 220
      typedef VT Value;
221 221

	
222 222
      StaticVectorMap(std::vector<Value>& v) : _v(v) {}
223 223

	
224 224
      const Value& operator[](const Key& key) const {
225 225
        return _v[StaticDigraph::id(key)];
226 226
      }
227 227

	
228 228
      Value& operator[](const Key& key) {
229 229
        return _v[StaticDigraph::id(key)];
230 230
      }
231 231

	
232 232
      void set(const Key& key, const Value& val) {
233 233
        _v[StaticDigraph::id(key)] = val;
234 234
      }
235 235

	
236 236
    private:
237 237
      std::vector<Value>& _v;
238 238
    };
239 239

	
240
    typedef StaticVectorMap<StaticDigraph::Node, LargeCost> LargeCostNodeMap;
241 240
    typedef StaticVectorMap<StaticDigraph::Arc, LargeCost> LargeCostArcMap;
242 241

	
243 242
  private:
244 243

	
245 244
    // Data related to the underlying digraph
246 245
    const GR &_graph;
247 246
    int _node_num;
248 247
    int _arc_num;
249 248
    int _res_node_num;
250 249
    int _res_arc_num;
251 250
    int _root;
252 251

	
253 252
    // Parameters of the problem
254 253
    bool _have_lower;
255 254
    Value _sum_supply;
256 255
    int _sup_node_num;
257 256

	
258 257
    // Data structures for storing the digraph
259 258
    IntNodeMap _node_id;
260 259
    IntArcMap _arc_idf;
261 260
    IntArcMap _arc_idb;
262 261
    IntVector _first_out;
263 262
    BoolVector _forward;
264 263
    IntVector _source;
265 264
    IntVector _target;
266 265
    IntVector _reverse;
267 266

	
268 267
    // Node and arc data
269 268
    ValueVector _lower;
270 269
    ValueVector _upper;
271 270
    CostVector _scost;
272 271
    ValueVector _supply;
273 272

	
274 273
    ValueVector _res_cap;
275 274
    LargeCostVector _cost;
276 275
    LargeCostVector _pi;
277 276
    ValueVector _excess;
278 277
    IntVector _next_out;
279 278
    std::deque<int> _active_nodes;
280 279

	
281 280
    // Data for scaling
282 281
    LargeCost _epsilon;
283 282
    int _alpha;
284 283

	
285 284
    IntVector _buckets;
286 285
    IntVector _bucket_next;
287 286
    IntVector _bucket_prev;
288 287
    IntVector _rank;
289 288
    int _max_rank;
290 289

	
291
    // Data for a StaticDigraph structure
292
    typedef std::pair<int, int> IntPair;
293
    StaticDigraph _sgr;
294
    std::vector<IntPair> _arc_vec;
295
    std::vector<LargeCost> _cost_vec;
296
    LargeCostArcMap _cost_map;
297
    LargeCostNodeMap _pi_map;
298

	
299 290
  public:
300 291

	
301 292
    /// \brief Constant for infinite upper bounds (capacities).
302 293
    ///
303 294
    /// Constant for infinite upper bounds (capacities).
304 295
    /// It is \c std::numeric_limits<Value>::infinity() if available,
305 296
    /// \c std::numeric_limits<Value>::max() otherwise.
306 297
    const Value INF;
307 298

	
308 299
  public:
309 300

	
310 301
    /// \name Named Template Parameters
311 302
    /// @{
312 303

	
313 304
    template <typename T>
314 305
    struct SetLargeCostTraits : public Traits {
315 306
      typedef T LargeCost;
316 307
    };
317 308

	
318 309
    /// \brief \ref named-templ-param "Named parameter" for setting
319 310
    /// \c LargeCost type.
320 311
    ///
321 312
    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
322 313
    /// type, which is used for internal computations in the algorithm.
323 314
    /// \c Cost must be convertible to \c LargeCost.
324 315
    template <typename T>
325 316
    struct SetLargeCost
326 317
      : public CostScaling<GR, V, C, SetLargeCostTraits<T> > {
327 318
      typedef  CostScaling<GR, V, C, SetLargeCostTraits<T> > Create;
328 319
    };
329 320

	
330 321
    /// @}
331 322

	
332 323
  protected:
333 324

	
334 325
    CostScaling() {}
335 326

	
336 327
  public:
337 328

	
338 329
    /// \brief Constructor.
339 330
    ///
340 331
    /// The constructor of the class.
341 332
    ///
342 333
    /// \param graph The digraph the algorithm runs on.
343 334
    CostScaling(const GR& graph) :
344 335
      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
345
      _cost_map(_cost_vec), _pi_map(_pi),
346 336
      INF(std::numeric_limits<Value>::has_infinity ?
347 337
          std::numeric_limits<Value>::infinity() :
348 338
          std::numeric_limits<Value>::max())
349 339
    {
350 340
      // Check the number types
351 341
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
352 342
        "The flow type of CostScaling must be signed");
353 343
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
354 344
        "The cost type of CostScaling must be signed");
355 345

	
356 346
      // Reset data structures
357 347
      reset();
358 348
    }
359 349

	
360 350
    /// \name Parameters
361 351
    /// The parameters of the algorithm can be specified using these
362 352
    /// functions.
363 353

	
364 354
    /// @{
365 355

	
366 356
    /// \brief Set the lower bounds on the arcs.
367 357
    ///
368 358
    /// This function sets the lower bounds on the arcs.
369 359
    /// If it is not used before calling \ref run(), the lower bounds
370 360
    /// will be set to zero on all arcs.
371 361
    ///
372 362
    /// \param map An arc map storing the lower bounds.
373 363
    /// Its \c Value type must be convertible to the \c Value type
374 364
    /// of the algorithm.
375 365
    ///
376 366
    /// \return <tt>(*this)</tt>
377 367
    template <typename LowerMap>
378 368
    CostScaling& lowerMap(const LowerMap& map) {
379 369
      _have_lower = true;
380 370
      for (ArcIt a(_graph); a != INVALID; ++a) {
381 371
        _lower[_arc_idf[a]] = map[a];
382 372
        _lower[_arc_idb[a]] = map[a];
383 373
      }
384 374
      return *this;
385 375
    }
386 376

	
387 377
    /// \brief Set the upper bounds (capacities) on the arcs.
388 378
    ///
389 379
    /// This function sets the upper bounds (capacities) on the arcs.
390 380
    /// If it is not used before calling \ref run(), the upper bounds
391 381
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
392 382
    /// unbounded from above).
393 383
    ///
... ...
@@ -574,99 +564,96 @@
574 564
      _have_lower = false;
575 565
      return *this;
576 566
    }
577 567

	
578 568
    /// \brief Reset the internal data structures and all the parameters
579 569
    /// that have been given before.
580 570
    ///
581 571
    /// This function resets the internal data structures and all the
582 572
    /// paramaters that have been given before using functions \ref lowerMap(),
583 573
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
584 574
    ///
585 575
    /// It is useful for multiple \ref run() calls. By default, all the given
586 576
    /// parameters are kept for the next \ref run() call, unless
587 577
    /// \ref resetParams() or \ref reset() is used.
588 578
    /// If the underlying digraph was also modified after the construction
589 579
    /// of the class or the last \ref reset() call, then the \ref reset()
590 580
    /// function must be used, otherwise \ref resetParams() is sufficient.
591 581
    ///
592 582
    /// See \ref resetParams() for examples.
593 583
    ///
594 584
    /// \return <tt>(*this)</tt>
595 585
    ///
596 586
    /// \see resetParams(), run()
597 587
    CostScaling& reset() {
598 588
      // Resize vectors
599 589
      _node_num = countNodes(_graph);
600 590
      _arc_num = countArcs(_graph);
601 591
      _res_node_num = _node_num + 1;
602 592
      _res_arc_num = 2 * (_arc_num + _node_num);
603 593
      _root = _node_num;
604 594

	
605 595
      _first_out.resize(_res_node_num + 1);
606 596
      _forward.resize(_res_arc_num);
607 597
      _source.resize(_res_arc_num);
608 598
      _target.resize(_res_arc_num);
609 599
      _reverse.resize(_res_arc_num);
610 600

	
611 601
      _lower.resize(_res_arc_num);
612 602
      _upper.resize(_res_arc_num);
613 603
      _scost.resize(_res_arc_num);
614 604
      _supply.resize(_res_node_num);
615 605

	
616 606
      _res_cap.resize(_res_arc_num);
617 607
      _cost.resize(_res_arc_num);
618 608
      _pi.resize(_res_node_num);
619 609
      _excess.resize(_res_node_num);
620 610
      _next_out.resize(_res_node_num);
621 611

	
622
      _arc_vec.reserve(_res_arc_num);
623
      _cost_vec.reserve(_res_arc_num);
624

	
625 612
      // Copy the graph
626 613
      int i = 0, j = 0, k = 2 * _arc_num + _node_num;
627 614
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
628 615
        _node_id[n] = i;
629 616
      }
630 617
      i = 0;
631 618
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
632 619
        _first_out[i] = j;
633 620
        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
634 621
          _arc_idf[a] = j;
635 622
          _forward[j] = true;
636 623
          _source[j] = i;
637 624
          _target[j] = _node_id[_graph.runningNode(a)];
638 625
        }
639 626
        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
640 627
          _arc_idb[a] = j;
641 628
          _forward[j] = false;
642 629
          _source[j] = i;
643 630
          _target[j] = _node_id[_graph.runningNode(a)];
644 631
        }
645 632
        _forward[j] = false;
646 633
        _source[j] = i;
647 634
        _target[j] = _root;
648 635
        _reverse[j] = k;
649 636
        _forward[k] = true;
650 637
        _source[k] = _root;
651 638
        _target[k] = i;
652 639
        _reverse[k] = j;
653 640
        ++j; ++k;
654 641
      }
655 642
      _first_out[i] = j;
656 643
      _first_out[_res_node_num] = k;
657 644
      for (ArcIt a(_graph); a != INVALID; ++a) {
658 645
        int fi = _arc_idf[a];
659 646
        int bi = _arc_idb[a];
660 647
        _reverse[fi] = bi;
661 648
        _reverse[bi] = fi;
662 649
      }
663 650

	
664 651
      // Reset parameters
665 652
      resetParams();
666 653
      return *this;
667 654
    }
668 655

	
669 656
    /// @}
670 657

	
671 658
    /// \name Query Functions
672 659
    /// The results of the algorithm can be obtained using these
... ...
@@ -878,112 +865,153 @@
878 865
          int ra = _reverse[a];
879 866
          _res_cap[a] = -_sum_supply + 1;
880 867
          _res_cap[ra] = -_excess[u];
881 868
          _cost[a] = 0;
882 869
          _cost[ra] = 0;
883 870
          _excess[u] = 0;
884 871
        }
885 872
      } else {
886 873
        for (ArcIt a(_graph); a != INVALID; ++a) {
887 874
          Value fa = flow[a];
888 875
          _res_cap[_arc_idf[a]] = cap[a] - fa;
889 876
          _res_cap[_arc_idb[a]] = fa;
890 877
        }
891 878
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
892 879
          int ra = _reverse[a];
893 880
          _res_cap[a] = 0;
894 881
          _res_cap[ra] = 0;
895 882
          _cost[a] = 0;
896 883
          _cost[ra] = 0;
897 884
        }
898 885
      }
899 886

	
900 887
      // Initialize data structures for buckets
901 888
      _max_rank = _alpha * _res_node_num;
902 889
      _buckets.resize(_max_rank);
903 890
      _bucket_next.resize(_res_node_num + 1);
904 891
      _bucket_prev.resize(_res_node_num + 1);
905 892
      _rank.resize(_res_node_num + 1);
906 893

	
907 894
      return OPTIMAL;
908 895
    }
909 896

	
910 897
    // Execute the algorithm and transform the results
911 898
    void start(Method method) {
912 899
      const int MAX_PARTIAL_PATH_LENGTH = 4;
913 900

	
914 901
      switch (method) {
915 902
        case PUSH:
916 903
          startPush();
917 904
          break;
918 905
        case AUGMENT:
919 906
          startAugment(_res_node_num - 1);
920 907
          break;
921 908
        case PARTIAL_AUGMENT:
922 909
          startAugment(MAX_PARTIAL_PATH_LENGTH);
923 910
          break;
924 911
      }
925 912

	
926
      // Compute node potentials for the original costs
927
      _arc_vec.clear();
928
      _cost_vec.clear();
929
      for (int j = 0; j != _res_arc_num; ++j) {
930
        if (_res_cap[j] > 0) {
931
          _arc_vec.push_back(IntPair(_source[j], _target[j]));
932
          _cost_vec.push_back(_scost[j]);
913
      // Compute node potentials (dual solution)
914
      for (int i = 0; i != _res_node_num; ++i) {
915
        _pi[i] = static_cast<Cost>(_pi[i] / (_res_node_num * _alpha));
916
      }
917
      bool optimal = true;
918
      for (int i = 0; optimal && i != _res_node_num; ++i) {
919
        LargeCost pi_i = _pi[i];
920
        int last_out = _first_out[i+1];
921
        for (int j = _first_out[i]; j != last_out; ++j) {
922
          if (_res_cap[j] > 0 && _scost[j] + pi_i - _pi[_target[j]] < 0) {
923
            optimal = false;
924
            break;
925
          }
933 926
        }
934 927
      }
935
      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
936 928

	
937
      typename BellmanFord<StaticDigraph, LargeCostArcMap>
938
        ::template SetDistMap<LargeCostNodeMap>::Create bf(_sgr, _cost_map);
939
      bf.distMap(_pi_map);
940
      bf.init(0);
941
      bf.start();
929
      if (!optimal) {
930
        // Compute node potentials for the original costs with BellmanFord
931
        // (if it is necessary)
932
        typedef std::pair<int, int> IntPair;
933
        StaticDigraph sgr;
934
        std::vector<IntPair> arc_vec;
935
        std::vector<LargeCost> cost_vec;
936
        LargeCostArcMap cost_map(cost_vec);
937

	
938
        arc_vec.clear();
939
        cost_vec.clear();
940
        for (int j = 0; j != _res_arc_num; ++j) {
941
          if (_res_cap[j] > 0) {
942
            int u = _source[j], v = _target[j];
943
            arc_vec.push_back(IntPair(u, v));
944
            cost_vec.push_back(_scost[j] + _pi[u] - _pi[v]);
945
          }
946
        }
947
        sgr.build(_res_node_num, arc_vec.begin(), arc_vec.end());
948

	
949
        typename BellmanFord<StaticDigraph, LargeCostArcMap>::Create
950
          bf(sgr, cost_map);
951
        bf.init(0);
952
        bf.start();
953

	
954
        for (int i = 0; i != _res_node_num; ++i) {
955
          _pi[i] += bf.dist(sgr.node(i));
956
        }
957
      }
958

	
959
      // Shift potentials to meet the requirements of the GEQ type
960
      // optimality conditions
961
      LargeCost max_pot = _pi[_root];
962
      for (int i = 0; i != _res_node_num; ++i) {
963
        if (_pi[i] > max_pot) max_pot = _pi[i];
964
      }
965
      if (max_pot != 0) {
966
        for (int i = 0; i != _res_node_num; ++i) {
967
          _pi[i] -= max_pot;
968
        }
969
      }
942 970

	
943 971
      // Handle non-zero lower bounds
944 972
      if (_have_lower) {
945 973
        int limit = _first_out[_root];
946 974
        for (int j = 0; j != limit; ++j) {
947 975
          if (!_forward[j]) _res_cap[j] += _lower[j];
948 976
        }
949 977
      }
950 978
    }
951 979

	
952 980
    // Initialize a cost scaling phase
953 981
    void initPhase() {
954 982
      // Saturate arcs not satisfying the optimality condition
955 983
      for (int u = 0; u != _res_node_num; ++u) {
956 984
        int last_out = _first_out[u+1];
957 985
        LargeCost pi_u = _pi[u];
958 986
        for (int a = _first_out[u]; a != last_out; ++a) {
959 987
          Value delta = _res_cap[a];
960 988
          if (delta > 0) {
961 989
            int v = _target[a];
962 990
            if (_cost[a] + pi_u - _pi[v] < 0) {
963 991
              _excess[u] -= delta;
964 992
              _excess[v] += delta;
965 993
              _res_cap[a] = 0;
966 994
              _res_cap[_reverse[a]] += delta;
967 995
            }
968 996
          }
969 997
        }
970 998
      }
971 999

	
972 1000
      // Find active nodes (i.e. nodes with positive excess)
973 1001
      for (int u = 0; u != _res_node_num; ++u) {
974 1002
        if (_excess[u] > 0) _active_nodes.push_back(u);
975 1003
      }
976 1004

	
977 1005
      // Initialize the next arcs
978 1006
      for (int u = 0; u != _res_node_num; ++u) {
979 1007
        _next_out[u] = _first_out[u];
980 1008
      }
981 1009
    }
982 1010

	
983 1011
    // Price (potential) refinement heuristic
984 1012
    bool priceRefinement() {
985 1013

	
986 1014
      // Stack for stroing the topological order
987 1015
      IntVector stack(_res_node_num);
988 1016
      int stack_top;
989 1017

	
0 comments (0 inline)