1 /* -*- mode: C++; indent-tabs-mode: nil; -*- |
1 /* -*- mode: C++; indent-tabs-mode: nil; -*- |
2 * |
2 * |
3 * This file is a part of LEMON, a generic C++ optimization library. |
3 * This file is a part of LEMON, a generic C++ optimization library. |
4 * |
4 * |
5 * Copyright (C) 2003-2010 |
5 * Copyright (C) 2003-2013 |
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 * |
8 * |
9 * Permission to use, modify and distribute this software is granted |
9 * Permission to use, modify and distribute this software is granted |
10 * provided that this copyright notice appears in all copies. For |
10 * provided that this copyright notice appears in all copies. For |
412 |
412 |
413 int index = 0; |
413 int index = 0; |
414 for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) { |
414 for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) { |
415 for (typename Graph::OutArcIt a(_graph, n); a != INVALID; ++a) { |
415 for (typename Graph::OutArcIt a(_graph, n); a != INVALID; ++a) { |
416 typename Graph::Node m = _graph.target(a); |
416 typename Graph::Node m = _graph.target(a); |
417 |
417 |
418 if (!(n < m)) continue; |
418 if (!(n < m)) continue; |
419 |
419 |
420 (*_nodes)[n].sum += (*_capacity)[a]; |
420 (*_nodes)[n].sum += (*_capacity)[a]; |
421 (*_nodes)[m].sum += (*_capacity)[a]; |
421 (*_nodes)[m].sum += (*_capacity)[a]; |
422 |
422 |
423 int c = (*_nodes)[m].curr_arc; |
423 int c = (*_nodes)[m].curr_arc; |
424 if (c != -1 && _arcs[c ^ 1].target == n) { |
424 if (c != -1 && _arcs[c ^ 1].target == n) { |
425 _edges[c >> 1].capacity += (*_capacity)[a]; |
425 _edges[c >> 1].capacity += (*_capacity)[a]; |
426 } else { |
426 } else { |
427 _edges[index].capacity = (*_capacity)[a]; |
427 _edges[index].capacity = (*_capacity)[a]; |
428 |
428 |
429 _arcs[index << 1].prev = -1; |
429 _arcs[index << 1].prev = -1; |
430 if ((*_nodes)[n].first_arc != -1) { |
430 if ((*_nodes)[n].first_arc != -1) { |
431 _arcs[(*_nodes)[n].first_arc].prev = (index << 1); |
431 _arcs[(*_nodes)[n].first_arc].prev = (index << 1); |
432 } |
432 } |
433 _arcs[index << 1].next = (*_nodes)[n].first_arc; |
433 _arcs[index << 1].next = (*_nodes)[n].first_arc; |
434 (*_nodes)[n].first_arc = (index << 1); |
434 (*_nodes)[n].first_arc = (index << 1); |
435 _arcs[index << 1].target = m; |
435 _arcs[index << 1].target = m; |
436 |
436 |
437 (*_nodes)[m].curr_arc = (index << 1); |
437 (*_nodes)[m].curr_arc = (index << 1); |
438 |
438 |
439 _arcs[(index << 1) | 1].prev = -1; |
439 _arcs[(index << 1) | 1].prev = -1; |
440 if ((*_nodes)[m].first_arc != -1) { |
440 if ((*_nodes)[m].first_arc != -1) { |
441 _arcs[(*_nodes)[m].first_arc].prev = ((index << 1) | 1); |
441 _arcs[(*_nodes)[m].first_arc].prev = ((index << 1) | 1); |
442 } |
442 } |
443 _arcs[(index << 1) | 1].next = (*_nodes)[m].first_arc; |
443 _arcs[(index << 1) | 1].next = (*_nodes)[m].first_arc; |
444 (*_nodes)[m].first_arc = ((index << 1) | 1); |
444 (*_nodes)[m].first_arc = ((index << 1) | 1); |
445 _arcs[(index << 1) | 1].target = n; |
445 _arcs[(index << 1) | 1].target = n; |
446 |
446 |
447 ++index; |
447 ++index; |
448 } |
448 } |
449 } |
449 } |
450 } |
450 } |
451 |
451 |
452 typename Graph::Node cut_node = INVALID; |
452 typename Graph::Node cut_node = INVALID; |
453 _min_cut = std::numeric_limits<Value>::max(); |
453 _min_cut = std::numeric_limits<Value>::max(); |
454 |
454 |
455 for (typename Graph::Node n = _first_node; |
455 for (typename Graph::Node n = _first_node; |
456 n != INVALID; n = (*_nodes)[n].next) { |
456 n != INVALID; n = (*_nodes)[n].next) { |
457 if ((*_nodes)[n].sum < _min_cut) { |
457 if ((*_nodes)[n].sum < _min_cut) { |
458 cut_node = n; |
458 cut_node = n; |
459 _min_cut = (*_nodes)[n].sum; |
459 _min_cut = (*_nodes)[n].sum; |
460 } |
460 } |
475 ///\return %True when the algorithm finished. |
475 ///\return %True when the algorithm finished. |
476 bool processNextPhase() { |
476 bool processNextPhase() { |
477 if (_first_node == INVALID) return true; |
477 if (_first_node == INVALID) return true; |
478 |
478 |
479 _heap->clear(); |
479 _heap->clear(); |
480 for (typename Graph::Node n = _first_node; |
480 for (typename Graph::Node n = _first_node; |
481 n != INVALID; n = (*_nodes)[n].next) { |
481 n != INVALID; n = (*_nodes)[n].next) { |
482 (*_heap_cross_ref)[n] = Heap::PRE_HEAP; |
482 (*_heap_cross_ref)[n] = Heap::PRE_HEAP; |
483 } |
483 } |
484 |
484 |
485 std::vector<typename Graph::Node> order; |
485 std::vector<typename Graph::Node> order; |
495 Value v = _heap->prio(); |
495 Value v = _heap->prio(); |
496 |
496 |
497 _heap->pop(); |
497 _heap->pop(); |
498 for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) { |
498 for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) { |
499 switch (_heap->state(_arcs[a].target)) { |
499 switch (_heap->state(_arcs[a].target)) { |
500 case Heap::PRE_HEAP: |
500 case Heap::PRE_HEAP: |
501 { |
501 { |
502 Value nv = _edges[a >> 1].capacity; |
502 Value nv = _edges[a >> 1].capacity; |
503 _heap->push(_arcs[a].target, nv); |
503 _heap->push(_arcs[a].target, nv); |
504 _edges[a >> 1].cut = nv; |
504 _edges[a >> 1].cut = nv; |
505 } break; |
505 } break; |
561 bool merged = false; |
561 bool merged = false; |
562 for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) { |
562 for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) { |
563 if (!(_edges[a >> 1].cut < pmc)) { |
563 if (!(_edges[a >> 1].cut < pmc)) { |
564 if (!merged) { |
564 if (!merged) { |
565 for (int b = (*_nodes)[n].first_arc; b != -1; b = _arcs[b].next) { |
565 for (int b = (*_nodes)[n].first_arc; b != -1; b = _arcs[b].next) { |
566 (*_nodes)[_arcs[b].target].curr_arc = b; |
566 (*_nodes)[_arcs[b].target].curr_arc = b; |
567 } |
567 } |
568 merged = true; |
568 merged = true; |
569 } |
569 } |
570 typename Graph::Node m = _arcs[a].target; |
570 typename Graph::Node m = _arcs[a].target; |
571 int nb = 0; |
571 int nb = 0; |
572 for (int b = (*_nodes)[m].first_arc; b != -1; b = nb) { |
572 for (int b = (*_nodes)[m].first_arc; b != -1; b = nb) { |
573 nb = _arcs[b].next; |
573 nb = _arcs[b].next; |
574 if ((b ^ a) == 1) continue; |
574 if ((b ^ a) == 1) continue; |
575 typename Graph::Node o = _arcs[b].target; |
575 typename Graph::Node o = _arcs[b].target; |
576 int c = (*_nodes)[o].curr_arc; |
576 int c = (*_nodes)[o].curr_arc; |
577 if (c != -1 && _arcs[c ^ 1].target == n) { |
577 if (c != -1 && _arcs[c ^ 1].target == n) { |
578 _edges[c >> 1].capacity += _edges[b >> 1].capacity; |
578 _edges[c >> 1].capacity += _edges[b >> 1].capacity; |
579 (*_nodes)[n].sum += _edges[b >> 1].capacity; |
579 (*_nodes)[n].sum += _edges[b >> 1].capacity; |
580 if (_edges[b >> 1].cut < _edges[c >> 1].cut) { |
580 if (_edges[b >> 1].cut < _edges[c >> 1].cut) { |
581 _edges[b >> 1].cut = _edges[c >> 1].cut; |
581 _edges[b >> 1].cut = _edges[c >> 1].cut; |
604 |
604 |
605 if (_arcs[a].prev != -1) { |
605 if (_arcs[a].prev != -1) { |
606 _arcs[_arcs[a].prev].next = _arcs[a].next; |
606 _arcs[_arcs[a].prev].next = _arcs[a].next; |
607 } else { |
607 } else { |
608 (*_nodes)[n].first_arc = _arcs[a].next; |
608 (*_nodes)[n].first_arc = _arcs[a].next; |
609 } |
609 } |
610 if (_arcs[a].next != -1) { |
610 if (_arcs[a].next != -1) { |
611 _arcs[_arcs[a].next].prev = _arcs[a].prev; |
611 _arcs[_arcs[a].next].prev = _arcs[a].prev; |
612 } |
612 } |
613 |
613 |
614 (*_nodes)[n].sum -= _edges[a >> 1].capacity; |
614 (*_nodes)[n].sum -= _edges[a >> 1].capacity; |
615 (*_next_rep)[(*_nodes)[n].last_rep] = m; |
615 (*_next_rep)[(*_nodes)[n].last_rep] = m; |
616 (*_nodes)[n].last_rep = (*_nodes)[m].last_rep; |
616 (*_nodes)[n].last_rep = (*_nodes)[m].last_rep; |
617 |
617 |
618 if ((*_nodes)[m].prev != INVALID) { |
618 if ((*_nodes)[m].prev != INVALID) { |
619 (*_nodes)[(*_nodes)[m].prev].next = (*_nodes)[m].next; |
619 (*_nodes)[(*_nodes)[m].prev].next = (*_nodes)[m].next; |
620 } else{ |
620 } else{ |
621 _first_node = (*_nodes)[m].next; |
621 _first_node = (*_nodes)[m].next; |
622 } |
622 } |