39 /// \brief Implementation of the primal Network Simplex algorithm |
39 /// \brief Implementation of the primal Network Simplex algorithm |
40 /// for finding a \ref min_cost_flow "minimum cost flow". |
40 /// for finding a \ref min_cost_flow "minimum cost flow". |
41 /// |
41 /// |
42 /// \ref NetworkSimplex implements the primal Network Simplex algorithm |
42 /// \ref NetworkSimplex implements the primal Network Simplex algorithm |
43 /// for finding a \ref min_cost_flow "minimum cost flow". |
43 /// for finding a \ref min_cost_flow "minimum cost flow". |
|
44 /// This algorithm is a specialized version of the linear programming |
|
45 /// simplex method directly for the minimum cost flow problem. |
|
46 /// It is one of the most efficient solution methods. |
|
47 /// |
|
48 /// In general this class is the fastest implementation available |
|
49 /// in LEMON for the minimum cost flow problem. |
44 /// |
50 /// |
45 /// \tparam GR The digraph type the algorithm runs on. |
51 /// \tparam GR The digraph type the algorithm runs on. |
46 /// \tparam V The value type used in the algorithm. |
52 /// \tparam V The value type used in the algorithm. |
47 /// By default it is \c int. |
53 /// By default it is \c int. |
48 /// |
54 /// |
49 /// \warning \c V must be a signed integer type. |
55 /// \warning The value type must be a signed integer type. |
50 /// |
56 /// |
51 /// \note %NetworkSimplex provides five different pivot rule |
57 /// \note %NetworkSimplex provides five different pivot rule |
52 /// implementations. For more information see \ref PivotRule. |
58 /// implementations. For more information see \ref PivotRule. |
53 template <typename GR, typename V = int> |
59 template <typename GR, typename V = int> |
54 class NetworkSimplex |
60 class NetworkSimplex |
787 |
793 |
788 /// \brief Run the algorithm. |
794 /// \brief Run the algorithm. |
789 /// |
795 /// |
790 /// This function runs the algorithm. |
796 /// This function runs the algorithm. |
791 /// The paramters can be specified using \ref lowerMap(), |
797 /// The paramters can be specified using \ref lowerMap(), |
792 /// \ref upperMap(), \ref capacityMap(), \ref boundMaps(), |
798 /// \ref upperMap(), \ref capacityMap(), \ref boundMaps(), |
793 /// \ref costMap(), \ref supplyMap() and \ref stSupply() |
799 /// \ref costMap(), \ref supplyMap() and \ref stSupply() |
794 /// functions. For example, |
800 /// functions. For example, |
795 /// \code |
801 /// \code |
796 /// NetworkSimplex<ListDigraph> ns(graph); |
802 /// NetworkSimplex<ListDigraph> ns(graph); |
797 /// ns.boundMaps(lower, upper).costMap(cost) |
803 /// ns.boundMaps(lower, upper).costMap(cost) |
798 /// .supplyMap(sup).run(); |
804 /// .supplyMap(sup).run(); |
799 /// \endcode |
805 /// \endcode |
800 /// |
806 /// |
|
807 /// This function can be called more than once. All the parameters |
|
808 /// that have been given are kept for the next call, unless |
|
809 /// \ref reset() is called, thus only the modified parameters |
|
810 /// have to be set again. See \ref reset() for examples. |
|
811 /// |
801 /// \param pivot_rule The pivot rule that will be used during the |
812 /// \param pivot_rule The pivot rule that will be used during the |
802 /// algorithm. For more information see \ref PivotRule. |
813 /// algorithm. For more information see \ref PivotRule. |
803 /// |
814 /// |
804 /// \return \c true if a feasible flow can be found. |
815 /// \return \c true if a feasible flow can be found. |
805 bool run(PivotRule pivot_rule = BLOCK_SEARCH) { |
816 bool run(PivotRule pivot_rule = BLOCK_SEARCH) { |
806 return init() && start(pivot_rule); |
817 return init() && start(pivot_rule); |
|
818 } |
|
819 |
|
820 /// \brief Reset all the parameters that have been given before. |
|
821 /// |
|
822 /// This function resets all the paramaters that have been given |
|
823 /// using \ref lowerMap(), \ref upperMap(), \ref capacityMap(), |
|
824 /// \ref boundMaps(), \ref costMap(), \ref supplyMap() and |
|
825 /// \ref stSupply() functions before. |
|
826 /// |
|
827 /// It is useful for multiple run() calls. If this function is not |
|
828 /// used, all the parameters given before are kept for the next |
|
829 /// \ref run() call. |
|
830 /// |
|
831 /// For example, |
|
832 /// \code |
|
833 /// NetworkSimplex<ListDigraph> ns(graph); |
|
834 /// |
|
835 /// // First run |
|
836 /// ns.lowerMap(lower).capacityMap(cap).costMap(cost) |
|
837 /// .supplyMap(sup).run(); |
|
838 /// |
|
839 /// // Run again with modified cost map (reset() is not called, |
|
840 /// // so only the cost map have to be set again) |
|
841 /// cost[e] += 100; |
|
842 /// ns.costMap(cost).run(); |
|
843 /// |
|
844 /// // Run again from scratch using reset() |
|
845 /// // (the lower bounds will be set to zero on all arcs) |
|
846 /// ns.reset(); |
|
847 /// ns.capacityMap(cap).costMap(cost) |
|
848 /// .supplyMap(sup).run(); |
|
849 /// \endcode |
|
850 /// |
|
851 /// \return <tt>(*this)</tt> |
|
852 NetworkSimplex& reset() { |
|
853 delete _plower; |
|
854 delete _pupper; |
|
855 delete _pcost; |
|
856 delete _psupply; |
|
857 _plower = NULL; |
|
858 _pupper = NULL; |
|
859 _pcost = NULL; |
|
860 _psupply = NULL; |
|
861 _pstsup = false; |
|
862 return *this; |
807 } |
863 } |
808 |
864 |
809 /// @} |
865 /// @} |
810 |
866 |
811 /// \name Query Functions |
867 /// \name Query Functions |
918 _target.resize(all_arc_num); |
974 _target.resize(all_arc_num); |
919 |
975 |
920 _cap.resize(all_arc_num); |
976 _cap.resize(all_arc_num); |
921 _cost.resize(all_arc_num); |
977 _cost.resize(all_arc_num); |
922 _supply.resize(all_node_num); |
978 _supply.resize(all_node_num); |
923 _flow.resize(all_arc_num, 0); |
979 _flow.resize(all_arc_num); |
924 _pi.resize(all_node_num, 0); |
980 _pi.resize(all_node_num); |
925 |
981 |
926 _parent.resize(all_node_num); |
982 _parent.resize(all_node_num); |
927 _pred.resize(all_node_num); |
983 _pred.resize(all_node_num); |
928 _forward.resize(all_node_num); |
984 _forward.resize(all_node_num); |
929 _thread.resize(all_node_num); |
985 _thread.resize(all_node_num); |
930 _rev_thread.resize(all_node_num); |
986 _rev_thread.resize(all_node_num); |
931 _succ_num.resize(all_node_num); |
987 _succ_num.resize(all_node_num); |
932 _last_succ.resize(all_node_num); |
988 _last_succ.resize(all_node_num); |
933 _state.resize(all_arc_num, STATE_LOWER); |
989 _state.resize(all_arc_num); |
934 |
990 |
935 // Initialize node related data |
991 // Initialize node related data |
936 bool valid_supply = true; |
992 bool valid_supply = true; |
937 if (!_pstsup && !_psupply) { |
993 if (!_pstsup && !_psupply) { |
938 _pstsup = true; |
994 _pstsup = true; |
984 Arc e = _arc_ref[i]; |
1040 Arc e = _arc_ref[i]; |
985 _source[i] = _node_id[_graph.source(e)]; |
1041 _source[i] = _node_id[_graph.source(e)]; |
986 _target[i] = _node_id[_graph.target(e)]; |
1042 _target[i] = _node_id[_graph.target(e)]; |
987 _cap[i] = (*_pupper)[e]; |
1043 _cap[i] = (*_pupper)[e]; |
988 _cost[i] = (*_pcost)[e]; |
1044 _cost[i] = (*_pcost)[e]; |
|
1045 _flow[i] = 0; |
|
1046 _state[i] = STATE_LOWER; |
989 } |
1047 } |
990 } else { |
1048 } else { |
991 for (int i = 0; i != _arc_num; ++i) { |
1049 for (int i = 0; i != _arc_num; ++i) { |
992 Arc e = _arc_ref[i]; |
1050 Arc e = _arc_ref[i]; |
993 _source[i] = _node_id[_graph.source(e)]; |
1051 _source[i] = _node_id[_graph.source(e)]; |
994 _target[i] = _node_id[_graph.target(e)]; |
1052 _target[i] = _node_id[_graph.target(e)]; |
|
1053 _flow[i] = 0; |
|
1054 _state[i] = STATE_LOWER; |
995 } |
1055 } |
996 if (_pupper) { |
1056 if (_pupper) { |
997 for (int i = 0; i != _arc_num; ++i) |
1057 for (int i = 0; i != _arc_num; ++i) |
998 _cap[i] = (*_pupper)[_arc_ref[i]]; |
1058 _cap[i] = (*_pupper)[_arc_ref[i]]; |
999 } else { |
1059 } else { |