gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Fix wrong initialization in Preflow (#414)
0 2 0
default
2 files changed with 30 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 48 line context
... ...
@@ -504,65 +504,63 @@
504 504
              _level->initAddItem(u);
505 505
              nqueue.push_back(u);
506 506
            }
507 507
          }
508 508
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
509 509
            Node v = _graph.target(e);
510 510
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
511 511
              reached[v] = true;
512 512
              _level->initAddItem(v);
513 513
              nqueue.push_back(v);
514 514
            }
515 515
          }
516 516
        }
517 517
        queue.swap(nqueue);
518 518
      }
519 519
      _level->initFinish();
520 520

	
521 521
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
522 522
        Value rem = (*_capacity)[e] - (*_flow)[e];
523 523
        if (_tolerance.positive(rem)) {
524 524
          Node u = _graph.target(e);
525 525
          if ((*_level)[u] == _level->maxLevel()) continue;
526 526
          _flow->set(e, (*_capacity)[e]);
527 527
          (*_excess)[u] += rem;
528
          if (u != _target && !_level->active(u)) {
529
            _level->activate(u);
530
          }
531 528
        }
532 529
      }
533 530
      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
534 531
        Value rem = (*_flow)[e];
535 532
        if (_tolerance.positive(rem)) {
536 533
          Node v = _graph.source(e);
537 534
          if ((*_level)[v] == _level->maxLevel()) continue;
538 535
          _flow->set(e, 0);
539 536
          (*_excess)[v] += rem;
540
          if (v != _target && !_level->active(v)) {
541
            _level->activate(v);
542
          }
543 537
        }
544 538
      }
539
      for (NodeIt n(_graph); n != INVALID; ++n) 
540
        if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n]))
541
          _level->activate(n);
542
          
545 543
      return true;
546 544
    }
547 545

	
548 546
    /// \brief Starts the first phase of the preflow algorithm.
549 547
    ///
550 548
    /// The preflow algorithm consists of two phases, this method runs
551 549
    /// the first phase. After the first phase the maximum flow value
552 550
    /// and a minimum value cut can already be computed, although a
553 551
    /// maximum flow is not yet obtained. So after calling this method
554 552
    /// \ref flowValue() returns the value of a maximum flow and \ref
555 553
    /// minCut() returns a minimum cut.
556 554
    /// \pre One of the \ref init() functions must be called before
557 555
    /// using this function.
558 556
    void startFirstPhase() {
559 557
      _phase = true;
560 558

	
561 559
      while (true) {
562 560
        int num = _node_num;
563 561

	
564 562
        Node n = INVALID;
565 563
        int level = -1;
566 564

	
567 565
        while (num > 0) {
568 566
          n = _level->highestActive();
Ignore white space 48 line context
... ...
@@ -130,48 +130,72 @@
130 130

	
131 131
bool checkFlow(const SmartDigraph& g,
132 132
               const SmartDigraph::ArcMap<int>& flow,
133 133
               const SmartDigraph::ArcMap<int>& cap,
134 134
               SmartDigraph::Node s, SmartDigraph::Node t) {
135 135

	
136 136
  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
137 137
    if (flow[e] < 0 || flow[e] > cap[e]) return false;
138 138
  }
139 139

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

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

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

	
177

	
154 178
int main() {
155 179

	
156 180
  typedef SmartDigraph Digraph;
157 181

	
158 182
  typedef Digraph::Node Node;
159 183
  typedef Digraph::NodeIt NodeIt;
160 184
  typedef Digraph::ArcIt ArcIt;
161 185
  typedef Digraph::ArcMap<int> CapMap;
162 186
  typedef Digraph::ArcMap<int> FlowMap;
163 187
  typedef Digraph::NodeMap<bool> CutMap;
164 188

	
165 189
  typedef Preflow<Digraph, CapMap> PType;
166 190

	
167 191
  Digraph g;
168 192
  Node s, t;
169 193
  CapMap cap(g);
170 194
  std::istringstream input(test_lgf);
171 195
  DigraphReader<Digraph>(g,input).
172 196
    arcMap("capacity", cap).
173 197
    node("source",s).
174 198
    node("target",t).
175 199
    run();
176 200

	
177 201
  PType preflow_test(g, cap, s, t);
... ...
@@ -220,26 +244,28 @@
220 244

	
221 245
  preflow_test.flowMap(flow);
222 246

	
223 247
  NodeIt tmp1(g,s);
224 248
  ++tmp1;
225 249
  if ( tmp1 != INVALID ) s=tmp1;
226 250

	
227 251
  NodeIt tmp2(g,t);
228 252
  ++tmp2;
229 253
  if ( tmp2 != INVALID ) t=tmp2;
230 254

	
231 255
  preflow_test.source(s);
232 256
  preflow_test.target(t);
233 257

	
234 258
  preflow_test.run();
235 259

	
236 260
  CutMap min_cut3(g);
237 261
  preflow_test.minCutMap(min_cut3);
238 262
  min_cut_value=cutValue(g,min_cut3,cap);
239 263

	
240 264

	
241 265
  check(preflow_test.flowValue() == min_cut_value,
242 266
        "The max flow value or the three min cut values are incorrect.");
243 267

	
268
  initFlowTest();
269
  
244 270
  return 0;
245 271
}
0 comments (0 inline)