gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge bugfix #414
0 2 0
merge default
2 files changed with 30 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -482,145 +482,143 @@
482 482
    template <typename FlowMap>
483 483
    bool init(const FlowMap& flowMap) {
484 484
      createStructures();
485 485

	
486 486
      for (ArcIt e(_graph); e != INVALID; ++e) {
487 487
        _flow->set(e, flowMap[e]);
488 488
      }
489 489

	
490 490
      for (NodeIt n(_graph); n != INVALID; ++n) {
491 491
        Value excess = 0;
492 492
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
493 493
          excess += (*_flow)[e];
494 494
        }
495 495
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
496 496
          excess -= (*_flow)[e];
497 497
        }
498 498
        if (excess < 0 && n != _source) return false;
499 499
        (*_excess)[n] = excess;
500 500
      }
501 501

	
502 502
      typename Digraph::template NodeMap<bool> reached(_graph, false);
503 503

	
504 504
      _level->initStart();
505 505
      _level->initAddItem(_target);
506 506

	
507 507
      std::vector<Node> queue;
508 508
      reached[_source] = true;
509 509

	
510 510
      queue.push_back(_target);
511 511
      reached[_target] = true;
512 512
      while (!queue.empty()) {
513 513
        _level->initNewLevel();
514 514
        std::vector<Node> nqueue;
515 515
        for (int i = 0; i < int(queue.size()); ++i) {
516 516
          Node n = queue[i];
517 517
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
518 518
            Node u = _graph.source(e);
519 519
            if (!reached[u] &&
520 520
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
521 521
              reached[u] = true;
522 522
              _level->initAddItem(u);
523 523
              nqueue.push_back(u);
524 524
            }
525 525
          }
526 526
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
527 527
            Node v = _graph.target(e);
528 528
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
529 529
              reached[v] = true;
530 530
              _level->initAddItem(v);
531 531
              nqueue.push_back(v);
532 532
            }
533 533
          }
534 534
        }
535 535
        queue.swap(nqueue);
536 536
      }
537 537
      _level->initFinish();
538 538

	
539 539
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
540 540
        Value rem = (*_capacity)[e] - (*_flow)[e];
541 541
        if (_tolerance.positive(rem)) {
542 542
          Node u = _graph.target(e);
543 543
          if ((*_level)[u] == _level->maxLevel()) continue;
544 544
          _flow->set(e, (*_capacity)[e]);
545 545
          (*_excess)[u] += rem;
546
          if (u != _target && !_level->active(u)) {
547
            _level->activate(u);
548
          }
549 546
        }
550 547
      }
551 548
      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
552 549
        Value rem = (*_flow)[e];
553 550
        if (_tolerance.positive(rem)) {
554 551
          Node v = _graph.source(e);
555 552
          if ((*_level)[v] == _level->maxLevel()) continue;
556 553
          _flow->set(e, 0);
557 554
          (*_excess)[v] += rem;
558
          if (v != _target && !_level->active(v)) {
559
            _level->activate(v);
560
          }
561 555
        }
562 556
      }
557
      for (NodeIt n(_graph); n != INVALID; ++n) 
558
        if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n]))
559
          _level->activate(n);
560
          
563 561
      return true;
564 562
    }
565 563

	
566 564
    /// \brief Starts the first phase of the preflow algorithm.
567 565
    ///
568 566
    /// The preflow algorithm consists of two phases, this method runs
569 567
    /// the first phase. After the first phase the maximum flow value
570 568
    /// and a minimum value cut can already be computed, although a
571 569
    /// maximum flow is not yet obtained. So after calling this method
572 570
    /// \ref flowValue() returns the value of a maximum flow and \ref
573 571
    /// minCut() returns a minimum cut.
574 572
    /// \pre One of the \ref init() functions must be called before
575 573
    /// using this function.
576 574
    void startFirstPhase() {
577 575
      _phase = true;
578 576

	
579 577
      while (true) {
580 578
        int num = _node_num;
581 579

	
582 580
        Node n = INVALID;
583 581
        int level = -1;
584 582

	
585 583
        while (num > 0) {
586 584
          n = _level->highestActive();
587 585
          if (n == INVALID) goto first_phase_done;
588 586
          level = _level->highestActiveLevel();
589 587
          --num;
590 588
          
591 589
          Value excess = (*_excess)[n];
592 590
          int new_level = _level->maxLevel();
593 591

	
594 592
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
595 593
            Value rem = (*_capacity)[e] - (*_flow)[e];
596 594
            if (!_tolerance.positive(rem)) continue;
597 595
            Node v = _graph.target(e);
598 596
            if ((*_level)[v] < level) {
599 597
              if (!_level->active(v) && v != _target) {
600 598
                _level->activate(v);
601 599
              }
602 600
              if (!_tolerance.less(rem, excess)) {
603 601
                _flow->set(e, (*_flow)[e] + excess);
604 602
                (*_excess)[v] += excess;
605 603
                excess = 0;
606 604
                goto no_more_push_1;
607 605
              } else {
608 606
                excess -= rem;
609 607
                (*_excess)[v] += rem;
610 608
                _flow->set(e, (*_capacity)[e]);
611 609
              }
612 610
            } else if (new_level > (*_level)[v]) {
613 611
              new_level = (*_level)[v];
614 612
            }
615 613
          }
616 614

	
617 615
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
618 616
            Value rem = (*_flow)[e];
619 617
            if (!_tolerance.positive(rem)) continue;
620 618
            Node v = _graph.source(e);
621 619
            if ((*_level)[v] < level) {
622 620
              if (!_level->active(v) && v != _target) {
623 621
                _level->activate(v);
624 622
              }
625 623
              if (!_tolerance.less(rem, excess)) {
626 624
                _flow->set(e, (*_flow)[e] - excess);
Ignore white space 128 line context
... ...
@@ -95,156 +95,182 @@
95 95
  PreflowType preflow_test(g, cap, n, n);
96 96
  const PreflowType& const_preflow_test = preflow_test;
97 97

	
98 98
  const PreflowType::Elevator& elev = const_preflow_test.elevator();
99 99
  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
100 100
  PreflowType::Tolerance tol = const_preflow_test.tolerance();
101 101
  preflow_test.tolerance(tol);
102 102

	
103 103
  preflow_test
104 104
    .capacityMap(cap)
105 105
    .flowMap(flow)
106 106
    .source(n)
107 107
    .target(n);
108 108

	
109 109
  preflow_test.init();
110 110
  preflow_test.init(cap);
111 111
  preflow_test.startFirstPhase();
112 112
  preflow_test.startSecondPhase();
113 113
  preflow_test.run();
114 114
  preflow_test.runMinCut();
115 115

	
116 116
  v = const_preflow_test.flowValue();
117 117
  v = const_preflow_test.flow(e);
118 118
  const FlowMap& fm = const_preflow_test.flowMap();
119 119
  b = const_preflow_test.minCut(n);
120 120
  const_preflow_test.minCutMap(cut);
121 121

	
122 122
  ignore_unused_variable_warning(fm);
123 123
}
124 124

	
125 125
int cutValue (const SmartDigraph& g,
126 126
              const SmartDigraph::NodeMap<bool>& cut,
127 127
              const SmartDigraph::ArcMap<int>& cap) {
128 128

	
129 129
  int c=0;
130 130
  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
131 131
    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
132 132
  }
133 133
  return c;
134 134
}
135 135

	
136 136
bool checkFlow(const SmartDigraph& g,
137 137
               const SmartDigraph::ArcMap<int>& flow,
138 138
               const SmartDigraph::ArcMap<int>& cap,
139 139
               SmartDigraph::Node s, SmartDigraph::Node t) {
140 140

	
141 141
  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
142 142
    if (flow[e] < 0 || flow[e] > cap[e]) return false;
143 143
  }
144 144

	
145 145
  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
146 146
    if (n == s || n == t) continue;
147 147
    int sum = 0;
148 148
    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
149 149
      sum += flow[e];
150 150
    }
151 151
    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
152 152
      sum -= flow[e];
153 153
    }
154 154
    if (sum != 0) return false;
155 155
  }
156 156
  return true;
157 157
}
158 158

	
159
void initFlowTest()
160
{
161
  DIGRAPH_TYPEDEFS(SmartDigraph);
162
  
163
  SmartDigraph g;
164
  SmartDigraph::ArcMap<int> cap(g),iflow(g);
165
  Node s=g.addNode(); Node t=g.addNode();
166
  Node n1=g.addNode(); Node n2=g.addNode();
167
  Arc a;
168
  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
169
  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
170
  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
171

	
172
  Preflow<SmartDigraph> pre(g,cap,s,t);
173
  pre.init(iflow);
174
  pre.startFirstPhase();
175
  check(pre.flowValue() == 10, "The incorrect max flow value.");
176
  check(pre.minCut(s), "Wrong min cut (Node s).");
177
  check(pre.minCut(n1), "Wrong min cut (Node n1).");
178
  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
179
  check(!pre.minCut(t), "Wrong min cut (Node t).");
180
}
181

	
182

	
159 183
int main() {
160 184

	
161 185
  typedef SmartDigraph Digraph;
162 186

	
163 187
  typedef Digraph::Node Node;
164 188
  typedef Digraph::NodeIt NodeIt;
165 189
  typedef Digraph::ArcIt ArcIt;
166 190
  typedef Digraph::ArcMap<int> CapMap;
167 191
  typedef Digraph::ArcMap<int> FlowMap;
168 192
  typedef Digraph::NodeMap<bool> CutMap;
169 193

	
170 194
  typedef Preflow<Digraph, CapMap> PType;
171 195

	
172 196
  Digraph g;
173 197
  Node s, t;
174 198
  CapMap cap(g);
175 199
  std::istringstream input(test_lgf);
176 200
  DigraphReader<Digraph>(g,input).
177 201
    arcMap("capacity", cap).
178 202
    node("source",s).
179 203
    node("target",t).
180 204
    run();
181 205

	
182 206
  PType preflow_test(g, cap, s, t);
183 207
  preflow_test.run();
184 208

	
185 209
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
186 210
        "The flow is not feasible.");
187 211

	
188 212
  CutMap min_cut(g);
189 213
  preflow_test.minCutMap(min_cut);
190 214
  int min_cut_value=cutValue(g,min_cut,cap);
191 215

	
192 216
  check(preflow_test.flowValue() == min_cut_value,
193 217
        "The max flow value is not equal to the three min cut values.");
194 218

	
195 219
  FlowMap flow(g);
196 220
  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
197 221

	
198 222
  int flow_value=preflow_test.flowValue();
199 223

	
200 224
  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
201 225
  preflow_test.init(flow);
202 226
  preflow_test.startFirstPhase();
203 227

	
204 228
  CutMap min_cut1(g);
205 229
  preflow_test.minCutMap(min_cut1);
206 230
  min_cut_value=cutValue(g,min_cut1,cap);
207 231

	
208 232
  check(preflow_test.flowValue() == min_cut_value &&
209 233
        min_cut_value == 2*flow_value,
210 234
        "The max flow value or the min cut value is wrong.");
211 235

	
212 236
  preflow_test.startSecondPhase();
213 237

	
214 238
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
215 239
        "The flow is not feasible.");
216 240

	
217 241
  CutMap min_cut2(g);
218 242
  preflow_test.minCutMap(min_cut2);
219 243
  min_cut_value=cutValue(g,min_cut2,cap);
220 244

	
221 245
  check(preflow_test.flowValue() == min_cut_value &&
222 246
        min_cut_value == 2*flow_value,
223 247
        "The max flow value or the three min cut values were not doubled");
224 248

	
225 249

	
226 250
  preflow_test.flowMap(flow);
227 251

	
228 252
  NodeIt tmp1(g,s);
229 253
  ++tmp1;
230 254
  if ( tmp1 != INVALID ) s=tmp1;
231 255

	
232 256
  NodeIt tmp2(g,t);
233 257
  ++tmp2;
234 258
  if ( tmp2 != INVALID ) t=tmp2;
235 259

	
236 260
  preflow_test.source(s);
237 261
  preflow_test.target(t);
238 262

	
239 263
  preflow_test.run();
240 264

	
241 265
  CutMap min_cut3(g);
242 266
  preflow_test.minCutMap(min_cut3);
243 267
  min_cut_value=cutValue(g,min_cut3,cap);
244 268

	
245 269

	
246 270
  check(preflow_test.flowValue() == min_cut_value,
247 271
        "The max flow value or the three min cut values are incorrect.");
248 272

	
273
  initFlowTest();
274
  
249 275
  return 0;
250 276
}
0 comments (0 inline)