gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
GCC 3.3 compatibility fix in nagamochi_ibaraki.h
0 1 0
default
1 file changed with 6 insertions and 1 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
... ...
@@ -111,385 +111,390 @@
111 111
  /// the network reliability, especially to test how many links have
112 112
  /// to be destroyed in the network to split it to at least two
113 113
  /// distinict subnetworks.
114 114
  ///
115 115
  /// The complexity of the algorithm is \f$ O(nm\log(n)) \f$ but with
116 116
  /// \ref FibHeap "Fibonacci heap" it can be decreased to
117 117
  /// \f$ O(nm+n^2\log(n)) \f$.  When the edges have unit capacities,
118 118
  /// \c BucketHeap can be used which yields \f$ O(nm) \f$ time
119 119
  /// complexity.
120 120
  ///
121 121
  /// \warning The value type of the capacity map should be able to
122 122
  /// hold any cut value of the graph, otherwise the result can
123 123
  /// overflow.
124 124
  /// \note This capacity is supposed to be integer type.
125 125
#ifdef DOXYGEN
126 126
  template <typename GR, typename CM, typename TR>
127 127
#else
128 128
  template <typename GR,
129 129
            typename CM = typename GR::template EdgeMap<int>,
130 130
            typename TR = NagamochiIbarakiDefaultTraits<GR, CM> >
131 131
#endif
132 132
  class NagamochiIbaraki {
133 133
  public:
134 134

	
135 135
    typedef TR Traits;
136 136
    /// The type of the underlying graph.
137 137
    typedef typename Traits::Graph Graph;
138 138

	
139 139
    /// The type of the capacity map.
140 140
    typedef typename Traits::CapacityMap CapacityMap;
141 141
    /// The value type of the capacity map.
142 142
    typedef typename Traits::CapacityMap::Value Value;
143 143

	
144 144
    /// The heap type used by the algorithm.
145 145
    typedef typename Traits::Heap Heap;
146 146
    /// The cross reference type used for the heap.
147 147
    typedef typename Traits::HeapCrossRef HeapCrossRef;
148 148

	
149 149
    ///\name Named template parameters
150 150

	
151 151
    ///@{
152 152

	
153 153
    struct SetUnitCapacityTraits : public Traits {
154 154
      typedef ConstMap<typename Graph::Edge, Const<int, 1> > CapacityMap;
155 155
      static CapacityMap *createCapacityMap(const Graph&) {
156 156
        return new CapacityMap();
157 157
      }
158 158
    };
159 159

	
160 160
    /// \brief \ref named-templ-param "Named parameter" for setting
161 161
    /// the capacity map to a constMap<Edge, int, 1>() instance
162 162
    ///
163 163
    /// \ref named-templ-param "Named parameter" for setting
164 164
    /// the capacity map to a constMap<Edge, int, 1>() instance
165 165
    struct SetUnitCapacity
166 166
      : public NagamochiIbaraki<Graph, CapacityMap,
167 167
                                SetUnitCapacityTraits> {
168 168
      typedef NagamochiIbaraki<Graph, CapacityMap,
169 169
                               SetUnitCapacityTraits> Create;
170 170
    };
171 171

	
172 172

	
173 173
    template <class H, class CR>
174 174
    struct SetHeapTraits : public Traits {
175 175
      typedef CR HeapCrossRef;
176 176
      typedef H Heap;
177 177
      static HeapCrossRef *createHeapCrossRef(int num) {
178 178
        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
179 179
        return 0; // ignore warnings
180 180
      }
181 181
      static Heap *createHeap(HeapCrossRef &) {
182 182
        LEMON_ASSERT(false, "Heap is not initialized");
183 183
        return 0; // ignore warnings
184 184
      }
185 185
    };
186 186

	
187 187
    /// \brief \ref named-templ-param "Named parameter" for setting
188 188
    /// heap and cross reference type
189 189
    ///
190 190
    /// \ref named-templ-param "Named parameter" for setting heap and
191 191
    /// cross reference type. The heap has to maximize the priorities.
192 192
    template <class H, class CR = RangeMap<int> >
193 193
    struct SetHeap
194 194
      : public NagamochiIbaraki<Graph, CapacityMap, SetHeapTraits<H, CR> > {
195 195
      typedef NagamochiIbaraki< Graph, CapacityMap, SetHeapTraits<H, CR> >
196 196
      Create;
197 197
    };
198 198

	
199 199
    template <class H, class CR>
200 200
    struct SetStandardHeapTraits : public Traits {
201 201
      typedef CR HeapCrossRef;
202 202
      typedef H Heap;
203 203
      static HeapCrossRef *createHeapCrossRef(int size) {
204 204
        return new HeapCrossRef(size);
205 205
      }
206 206
      static Heap *createHeap(HeapCrossRef &crossref) {
207 207
        return new Heap(crossref);
208 208
      }
209 209
    };
210 210

	
211 211
    /// \brief \ref named-templ-param "Named parameter" for setting
212 212
    /// heap and cross reference type with automatic allocation
213 213
    ///
214 214
    /// \ref named-templ-param "Named parameter" for setting heap and
215 215
    /// cross reference type with automatic allocation. They should
216 216
    /// have standard constructor interfaces to be able to
217 217
    /// automatically created by the algorithm (i.e. the graph should
218 218
    /// be passed to the constructor of the cross reference and the
219 219
    /// cross reference should be passed to the constructor of the
220 220
    /// heap). However, external heap and cross reference objects
221 221
    /// could also be passed to the algorithm using the \ref heap()
222 222
    /// function before calling \ref run() or \ref init(). The heap
223 223
    /// has to maximize the priorities.
224 224
    /// \sa SetHeap
225 225
    template <class H, class CR = RangeMap<int> >
226 226
    struct SetStandardHeap
227 227
      : public NagamochiIbaraki<Graph, CapacityMap,
228 228
                                SetStandardHeapTraits<H, CR> > {
229 229
      typedef NagamochiIbaraki<Graph, CapacityMap,
230 230
                               SetStandardHeapTraits<H, CR> > Create;
231 231
    };
232 232

	
233 233
    ///@}
234 234

	
235 235

	
236 236
  private:
237 237

	
238 238
    const Graph &_graph;
239 239
    const CapacityMap *_capacity;
240 240
    bool _local_capacity; // unit capacity
241 241

	
242 242
    struct ArcData {
243 243
      typename Graph::Node target;
244 244
      int prev, next;
245 245
    };
246 246
    struct EdgeData {
247 247
      Value capacity;
248 248
      Value cut;
249 249
    };
250 250

	
251 251
    struct NodeData {
252 252
      int first_arc;
253 253
      typename Graph::Node prev, next;
254 254
      int curr_arc;
255 255
      typename Graph::Node last_rep;
256 256
      Value sum;
257 257
    };
258 258

	
259 259
    typename Graph::template NodeMap<NodeData> *_nodes;
260 260
    std::vector<ArcData> _arcs;
261 261
    std::vector<EdgeData> _edges;
262 262

	
263 263
    typename Graph::Node _first_node;
264 264
    int _node_num;
265 265

	
266 266
    Value _min_cut;
267 267

	
268 268
    HeapCrossRef *_heap_cross_ref;
269 269
    bool _local_heap_cross_ref;
270 270
    Heap *_heap;
271 271
    bool _local_heap;
272 272

	
273 273
    typedef typename Graph::template NodeMap<typename Graph::Node> NodeList;
274 274
    NodeList *_next_rep;
275 275

	
276 276
    typedef typename Graph::template NodeMap<bool> MinCutMap;
277 277
    MinCutMap *_cut_map;
278 278

	
279 279
    void createStructures() {
280 280
      if (!_nodes) {
281 281
        _nodes = new (typename Graph::template NodeMap<NodeData>)(_graph);
282 282
      }
283 283
      if (!_capacity) {
284 284
        _local_capacity = true;
285 285
        _capacity = Traits::createCapacityMap(_graph);
286 286
      }
287 287
      if (!_heap_cross_ref) {
288 288
        _local_heap_cross_ref = true;
289 289
        _heap_cross_ref = Traits::createHeapCrossRef(_graph);
290 290
      }
291 291
      if (!_heap) {
292 292
        _local_heap = true;
293 293
        _heap = Traits::createHeap(*_heap_cross_ref);
294 294
      }
295 295
      if (!_next_rep) {
296 296
        _next_rep = new NodeList(_graph);
297 297
      }
298 298
      if (!_cut_map) {
299 299
        _cut_map = new MinCutMap(_graph);
300 300
      }
301 301
    }
302 302

	
303
  public :
303
  protected:
304
    //This is here to avoid a gcc-3.3 compilation error.
305
    //It should never be called.
306
    NagamochiIbaraki() {} 
307
    
308
  public:
304 309

	
305 310
    typedef NagamochiIbaraki Create;
306 311

	
307 312

	
308 313
    /// \brief Constructor.
309 314
    ///
310 315
    /// \param graph The graph the algorithm runs on.
311 316
    /// \param capacity The capacity map used by the algorithm.
312 317
    NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity)
313 318
      : _graph(graph), _capacity(&capacity), _local_capacity(false),
314 319
        _nodes(0), _arcs(), _edges(), _min_cut(),
315 320
        _heap_cross_ref(0), _local_heap_cross_ref(false),
316 321
        _heap(0), _local_heap(false),
317 322
        _next_rep(0), _cut_map(0) {}
318 323

	
319 324
    /// \brief Constructor.
320 325
    ///
321 326
    /// This constructor can be used only when the Traits class
322 327
    /// defines how can the local capacity map be instantiated.
323 328
    /// If the SetUnitCapacity used the algorithm automatically
324 329
    /// constructs the capacity map.
325 330
    ///
326 331
    ///\param graph The graph the algorithm runs on.
327 332
    NagamochiIbaraki(const Graph& graph)
328 333
      : _graph(graph), _capacity(0), _local_capacity(false),
329 334
        _nodes(0), _arcs(), _edges(), _min_cut(),
330 335
        _heap_cross_ref(0), _local_heap_cross_ref(false),
331 336
        _heap(0), _local_heap(false),
332 337
        _next_rep(0), _cut_map(0) {}
333 338

	
334 339
    /// \brief Destructor.
335 340
    ///
336 341
    /// Destructor.
337 342
    ~NagamochiIbaraki() {
338 343
      if (_local_capacity) delete _capacity;
339 344
      if (_nodes) delete _nodes;
340 345
      if (_local_heap) delete _heap;
341 346
      if (_local_heap_cross_ref) delete _heap_cross_ref;
342 347
      if (_next_rep) delete _next_rep;
343 348
      if (_cut_map) delete _cut_map;
344 349
    }
345 350

	
346 351
    /// \brief Sets the heap and the cross reference used by algorithm.
347 352
    ///
348 353
    /// Sets the heap and the cross reference used by algorithm.
349 354
    /// If you don't use this function before calling \ref run(),
350 355
    /// it will allocate one. The destuctor deallocates this
351 356
    /// automatically allocated heap and cross reference, of course.
352 357
    /// \return <tt> (*this) </tt>
353 358
    NagamochiIbaraki &heap(Heap& hp, HeapCrossRef &cr)
354 359
    {
355 360
      if (_local_heap_cross_ref) {
356 361
        delete _heap_cross_ref;
357 362
        _local_heap_cross_ref = false;
358 363
      }
359 364
      _heap_cross_ref = &cr;
360 365
      if (_local_heap) {
361 366
        delete _heap;
362 367
        _local_heap = false;
363 368
      }
364 369
      _heap = &hp;
365 370
      return *this;
366 371
    }
367 372

	
368 373
    /// \name Execution control
369 374
    /// The simplest way to execute the algorithm is to use
370 375
    /// one of the member functions called \c run().
371 376
    /// \n
372 377
    /// If you need more control on the execution,
373 378
    /// first you must call \ref init() and then call the start()
374 379
    /// or proper times the processNextPhase() member functions.
375 380

	
376 381
    ///@{
377 382

	
378 383
    /// \brief Initializes the internal data structures.
379 384
    ///
380 385
    /// Initializes the internal data structures.
381 386
    void init() {
382 387
      createStructures();
383 388

	
384 389
      int edge_num = countEdges(_graph);
385 390
      _edges.resize(edge_num);
386 391
      _arcs.resize(2 * edge_num);
387 392

	
388 393
      typename Graph::Node prev = INVALID;
389 394
      _node_num = 0;
390 395
      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
391 396
        (*_cut_map)[n] = false;
392 397
        (*_next_rep)[n] = INVALID;
393 398
        (*_nodes)[n].last_rep = n;
394 399
        (*_nodes)[n].first_arc = -1;
395 400
        (*_nodes)[n].curr_arc = -1;
396 401
        (*_nodes)[n].prev = prev;
397 402
        if (prev != INVALID) {
398 403
          (*_nodes)[prev].next = n;
399 404
        }
400 405
        (*_nodes)[n].next = INVALID;
401 406
        (*_nodes)[n].sum = 0;
402 407
        prev = n;
403 408
        ++_node_num;
404 409
      }
405 410

	
406 411
      _first_node = typename Graph::NodeIt(_graph);
407 412

	
408 413
      int index = 0;
409 414
      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
410 415
        for (typename Graph::OutArcIt a(_graph, n); a != INVALID; ++a) {
411 416
          typename Graph::Node m = _graph.target(a);
412 417
          
413 418
          if (!(n < m)) continue;
414 419

	
415 420
          (*_nodes)[n].sum += (*_capacity)[a];
416 421
          (*_nodes)[m].sum += (*_capacity)[a];
417 422
          
418 423
          int c = (*_nodes)[m].curr_arc;
419 424
          if (c != -1 && _arcs[c ^ 1].target == n) {
420 425
            _edges[c >> 1].capacity += (*_capacity)[a];
421 426
          } else {
422 427
            _edges[index].capacity = (*_capacity)[a];
423 428
            
424 429
            _arcs[index << 1].prev = -1;
425 430
            if ((*_nodes)[n].first_arc != -1) {
426 431
              _arcs[(*_nodes)[n].first_arc].prev = (index << 1);
427 432
            }
428 433
            _arcs[index << 1].next = (*_nodes)[n].first_arc;
429 434
            (*_nodes)[n].first_arc = (index << 1);
430 435
            _arcs[index << 1].target = m;
431 436

	
432 437
            (*_nodes)[m].curr_arc = (index << 1);
433 438
            
434 439
            _arcs[(index << 1) | 1].prev = -1;
435 440
            if ((*_nodes)[m].first_arc != -1) {
436 441
              _arcs[(*_nodes)[m].first_arc].prev = ((index << 1) | 1);
437 442
            }
438 443
            _arcs[(index << 1) | 1].next = (*_nodes)[m].first_arc;
439 444
            (*_nodes)[m].first_arc = ((index << 1) | 1);
440 445
            _arcs[(index << 1) | 1].target = n;
441 446
            
442 447
            ++index;
443 448
          }
444 449
        }
445 450
      }
446 451

	
447 452
      typename Graph::Node cut_node = INVALID;
448 453
      _min_cut = std::numeric_limits<Value>::max();
449 454

	
450 455
      for (typename Graph::Node n = _first_node; 
451 456
           n != INVALID; n = (*_nodes)[n].next) {
452 457
        if ((*_nodes)[n].sum < _min_cut) {
453 458
          cut_node = n;
454 459
          _min_cut = (*_nodes)[n].sum;
455 460
        }
456 461
      }
457 462
      (*_cut_map)[cut_node] = true;
458 463
      if (_min_cut == 0) {
459 464
        _first_node = INVALID;
460 465
      }
461 466
    }
462 467

	
463 468
  public:
464 469

	
465 470
    /// \brief Processes the next phase
466 471
    ///
467 472
    /// Processes the next phase in the algorithm. It must be called
468 473
    /// at most one less the number of the nodes in the graph.
469 474
    ///
470 475
    ///\return %True when the algorithm finished.
471 476
    bool processNextPhase() {
472 477
      if (_first_node == INVALID) return true;
473 478

	
474 479
      _heap->clear();
475 480
      for (typename Graph::Node n = _first_node; 
476 481
           n != INVALID; n = (*_nodes)[n].next) {
477 482
        (*_heap_cross_ref)[n] = Heap::PRE_HEAP;
478 483
      }
479 484

	
480 485
      std::vector<typename Graph::Node> order;
481 486
      order.reserve(_node_num);
482 487
      int sep = 0;
483 488

	
484 489
      Value alpha = 0;
485 490
      Value pmc = std::numeric_limits<Value>::max();
486 491

	
487 492
      _heap->push(_first_node, static_cast<Value>(0));
488 493
      while (!_heap->empty()) {
489 494
        typename Graph::Node n = _heap->top();
490 495
        Value v = _heap->prio();
491 496

	
492 497
        _heap->pop();
493 498
        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
494 499
          switch (_heap->state(_arcs[a].target)) {
495 500
          case Heap::PRE_HEAP: 
0 comments (0 inline)