28 #include <limits> |
28 #include <limits> |
29 #include <lemon/smart_graph.h> |
29 #include <lemon/smart_graph.h> |
30 #include <lemon/graph_utils.h> |
30 #include <lemon/graph_utils.h> |
31 |
31 |
32 /// \brief The pivot rule used in the algorithm. |
32 /// \brief The pivot rule used in the algorithm. |
33 #define EDGE_BLOCK_PIVOT |
|
34 //#define FIRST_ELIGIBLE_PIVOT |
33 //#define FIRST_ELIGIBLE_PIVOT |
35 //#define BEST_ELIGIBLE_PIVOT |
34 //#define BEST_ELIGIBLE_PIVOT |
|
35 #define EDGE_BLOCK_PIVOT |
36 //#define CANDIDATE_LIST_PIVOT |
36 //#define CANDIDATE_LIST_PIVOT |
37 //#define SORTED_LIST_PIVOT |
37 //#define SORTED_LIST_PIVOT |
|
38 |
|
39 //#define _DEBUG_ITER_ |
|
40 |
38 |
41 |
39 /// \brief State constant for edges at their lower bounds. |
42 /// \brief State constant for edges at their lower bounds. |
40 #define LOWER 1 |
43 #define LOWER 1 |
41 /// \brief State constant for edges in the spanning tree. |
44 /// \brief State constant for edges in the spanning tree. |
42 #define TREE 0 |
45 #define TREE 0 |
43 /// \brief State constant for edges at their upper bounds. |
46 /// \brief State constant for edges at their upper bounds. |
44 #define UPPER -1 |
47 #define UPPER -1 |
45 |
48 |
46 #ifdef EDGE_BLOCK_PIVOT |
49 #ifdef EDGE_BLOCK_PIVOT |
47 /// \brief Number of blocks for the "Edge Block" pivot rule. |
50 /// \brief Number of blocks for the "Edge Block" pivot rule. |
48 #define BLOCK_NUM 100 |
51 #define BLOCK_NUM 100 |
49 /// \brief Lower bound for the number of edges to use "Edge Block" |
52 /// \brief Lower bound for the size of blocks. |
50 // pivot rule instead of "First Eligible" pivot rule. |
53 #define MIN_BLOCK_SIZE 10 |
51 #define MIN_BOUND 1000 |
|
52 #endif |
54 #endif |
53 |
55 |
54 #ifdef CANDIDATE_LIST_PIVOT |
56 #ifdef CANDIDATE_LIST_PIVOT |
55 #include <list> |
57 #include <list> |
56 /// \brief The maximum length of the edge list for the |
58 /// \brief The maximum length of the edge list for the |
57 /// "Candidate List" pivot rule. |
59 /// "Candidate List" pivot rule. |
58 #define LIST_LENGTH 100 |
60 #define LIST_LENGTH 100 |
59 /// \brief The maximum number of minor iterations between two major |
61 /// \brief The maximum number of minor iterations between two major |
60 /// itarations. |
62 /// itarations. |
61 #define MINOR_LIMIT 50 |
63 #define MINOR_LIMIT 10 |
62 #endif |
64 #endif |
63 |
65 |
64 #ifdef SORTED_LIST_PIVOT |
66 #ifdef SORTED_LIST_PIVOT |
65 #include <deque> |
67 #include <deque> |
66 #include <algorithm> |
68 #include <algorithm> |
67 /// \brief The maximum length of the edge list for the |
69 /// \brief The maximum length of the edge list for the |
68 /// "Sorted List" pivot rule. |
70 /// "Sorted List" pivot rule. |
69 #define LIST_LENGTH 500 |
71 #define LIST_LENGTH 500 |
70 #define LOWER_DIV 4 |
72 #define LOWER_DIV 3 |
71 #endif |
73 #endif |
72 |
|
73 //#define _DEBUG_ITER_ |
|
74 |
74 |
75 namespace lemon { |
75 namespace lemon { |
76 |
76 |
77 /// \addtogroup min_cost_flow |
77 /// \addtogroup min_cost_flow |
78 /// @{ |
78 /// @{ |
561 |
562 |
562 #ifdef EDGE_BLOCK_PIVOT |
563 #ifdef EDGE_BLOCK_PIVOT |
563 /// \brief Finds entering edge according to the "Edge Block" |
564 /// \brief Finds entering edge according to the "Edge Block" |
564 /// pivot rule. |
565 /// pivot rule. |
565 bool findEnteringEdge(EdgeIt &next_edge) { |
566 bool findEnteringEdge(EdgeIt &next_edge) { |
566 if (block_size == 1) { |
567 // Performing edge block selection |
567 // Performing first eligible selection |
568 Cost curr, min = 0; |
568 for (EdgeIt e = next_edge; e != INVALID; ++e) { |
569 EdgeIt min_edge(graph); |
569 if (state[e] * red_cost[e] < 0) { |
570 int cnt = 0; |
570 in_edge = e; |
571 for (EdgeIt e = next_edge; e != INVALID; ++e) { |
571 next_edge = ++e; |
572 if ((curr = state[e] * red_cost[e]) < min) { |
572 return true; |
573 min = curr; |
573 } |
574 min_edge = e; |
574 } |
575 } |
|
576 if (++cnt == block_size) { |
|
577 if (min < 0) break; |
|
578 cnt = 0; |
|
579 } |
|
580 } |
|
581 if (!(min < 0)) { |
575 for (EdgeIt e(graph); e != next_edge; ++e) { |
582 for (EdgeIt e(graph); e != next_edge; ++e) { |
576 if (state[e] * red_cost[e] < 0) { |
|
577 in_edge = e; |
|
578 next_edge = ++e; |
|
579 return true; |
|
580 } |
|
581 } |
|
582 return false; |
|
583 } else { |
|
584 // Performing edge block selection |
|
585 Cost curr, min = 0; |
|
586 EdgeIt min_edge(graph); |
|
587 int cnt = 0; |
|
588 for (EdgeIt e = next_edge; e != INVALID; ++e) { |
|
589 if ((curr = state[e] * red_cost[e]) < min) { |
583 if ((curr = state[e] * red_cost[e]) < min) { |
590 min = curr; |
584 min = curr; |
591 min_edge = e; |
585 min_edge = e; |
592 } |
586 } |
593 if (++cnt == block_size) { |
587 if (++cnt == block_size) { |
594 if (min < 0) break; |
588 if (min < 0) break; |
595 cnt = 0; |
589 cnt = 0; |
596 } |
590 } |
597 } |
591 } |
598 if (!(min < 0)) { |
592 } |
599 for (EdgeIt e(graph); e != next_edge; ++e) { |
593 in_edge = min_edge; |
600 if ((curr = state[e] * red_cost[e]) < min) { |
594 if ((next_edge = ++min_edge) == INVALID) |
601 min = curr; |
595 next_edge = EdgeIt(graph); |
602 min_edge = e; |
596 return min < 0; |
603 } |
|
604 if (++cnt == block_size) { |
|
605 if (min < 0) break; |
|
606 cnt = 0; |
|
607 } |
|
608 } |
|
609 } |
|
610 in_edge = min_edge; |
|
611 if ((next_edge = ++min_edge) == INVALID) |
|
612 next_edge = EdgeIt(graph); |
|
613 return min < 0; |
|
614 } |
|
615 } |
597 } |
616 #endif |
598 #endif |
617 |
599 |
618 #ifdef CANDIDATE_LIST_PIVOT |
600 #ifdef CANDIDATE_LIST_PIVOT |
619 /// \brief Functor class for removing non-eligible edges from the |
601 /// \brief Functor class for removing non-eligible edges from the |
694 Cost curr, min = 0; |
676 Cost curr, min = 0; |
695 for (EdgeIt e(graph); e != INVALID; ++e) { |
677 for (EdgeIt e(graph); e != INVALID; ++e) { |
696 if ((curr = state[e] * red_cost[e]) < min / LOWER_DIV) { |
678 if ((curr = state[e] * red_cost[e]) < min / LOWER_DIV) { |
697 candidates.push_back(e); |
679 candidates.push_back(e); |
698 if (curr < min) min = curr; |
680 if (curr < min) min = curr; |
699 if (candidates.size() >= LIST_LENGTH) break; |
681 if (candidates.size() == LIST_LENGTH) break; |
700 } |
682 } |
701 } |
683 } |
702 if (candidates.size() == 0) return false; |
684 if (candidates.size() == 0) return false; |
703 sort(candidates.begin(), candidates.end(), sort_func); |
685 sort(candidates.begin(), candidates.end(), sort_func); |
|
686 in_edge = candidates.front(); |
|
687 candidates.pop_front(); |
704 return true; |
688 return true; |
705 } |
689 } |
706 #endif |
690 #endif |
707 |
691 |
708 /// \brief Finds the join node. |
692 /// \brief Finds the join node. |