Changes in / [843:81f7e910060b:842:c2ff0a365245] in lemon-main
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/capacity_scaling.h
r840 r831 140 140 141 141 typedef std::vector<int> IntVector; 142 typedef std::vector<char> BoolVector; 142 143 typedef std::vector<Value> ValueVector; 143 144 typedef std::vector<Cost> CostVector; 144 typedef std::vector<char> BoolVector;145 // Note: vector<char> is used instead of vector<bool> for efficiency reasons146 145 147 146 private: … … 800 799 if (_factor > 1) { 801 800 // With scaling 802 Value max_sup = 0, max_dem = 0 , max_cap = 0;803 for (int i = 0; i != _ root; ++i) {801 Value max_sup = 0, max_dem = 0; 802 for (int i = 0; i != _node_num; ++i) { 804 803 Value ex = _excess[i]; 805 804 if ( ex > max_sup) max_sup = ex; 806 805 if (-ex > max_dem) max_dem = -ex; 807 int last_out = _first_out[i+1] - 1;808 for (int j = _first_out[i]; j != last_out; ++j) {809 if (_res_cap[j] > max_cap) max_cap = _res_cap[j];810 }806 } 807 Value max_cap = 0; 808 for (int j = 0; j != _res_arc_num; ++j) { 809 if (_res_cap[j] > max_cap) max_cap = _res_cap[j]; 811 810 } 812 811 max_sup = std::min(std::min(max_sup, max_dem), max_cap); -
lemon/cost_scaling.h
r840 r831 202 202 203 203 typedef std::vector<int> IntVector; 204 typedef std::vector<char> BoolVector; 204 205 typedef std::vector<Value> ValueVector; 205 206 typedef std::vector<Cost> CostVector; 206 207 typedef std::vector<LargeCost> LargeCostVector; 207 typedef std::vector<char> BoolVector;208 // Note: vector<char> is used instead of vector<bool> for efficiency reasons209 208 210 209 private: … … 250 249 bool _have_lower; 251 250 Value _sum_supply; 252 int _sup_node_num;253 251 254 252 // Data structures for storing the digraph … … 279 277 int _alpha; 280 278 281 IntVector _buckets;282 IntVector _bucket_next;283 IntVector _bucket_prev;284 IntVector _rank;285 int _max_rank;286 287 279 // Data for a StaticDigraph structure 288 280 typedef std::pair<int, int> IntPair; … … 837 829 } 838 830 839 _sup_node_num = 0;840 for (NodeIt n(_graph); n != INVALID; ++n) {841 if (sup[n] > 0) ++_sup_node_num;842 }843 844 831 // Find a feasible flow using Circulation 845 832 Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap> … … 876 863 for (int a = _first_out[_root]; a != _res_arc_num; ++a) { 877 864 int ra = _reverse[a]; 878 _res_cap[a] = 0;865 _res_cap[a] = 1; 879 866 _res_cap[ra] = 0; 880 867 _cost[a] = 0; … … 890 877 // Maximum path length for partial augment 891 878 const int MAX_PATH_LENGTH = 4; 892 893 // Initialize data structures for buckets 894 _max_rank = _alpha * _res_node_num; 895 _buckets.resize(_max_rank); 896 _bucket_next.resize(_res_node_num + 1); 897 _bucket_prev.resize(_res_node_num + 1); 898 _rank.resize(_res_node_num + 1); 899 879 900 880 // Execute the algorithm 901 881 switch (method) { … … 936 916 } 937 917 } 938 939 // Initialize a cost scaling phase 940 void initPhase() { 941 // Saturate arcs not satisfying the optimality condition 942 for (int u = 0; u != _res_node_num; ++u) { 943 int last_out = _first_out[u+1]; 944 LargeCost pi_u = _pi[u]; 945 for (int a = _first_out[u]; a != last_out; ++a) { 946 int v = _target[a]; 947 if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) { 918 919 /// Execute the algorithm performing augment and relabel operations 920 void startAugment(int max_length = std::numeric_limits<int>::max()) { 921 // Paramters for heuristics 922 const int BF_HEURISTIC_EPSILON_BOUND = 1000; 923 const int BF_HEURISTIC_BOUND_FACTOR = 3; 924 925 // Perform cost scaling phases 926 IntVector pred_arc(_res_node_num); 927 std::vector<int> path_nodes; 928 for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ? 929 1 : _epsilon / _alpha ) 930 { 931 // "Early Termination" heuristic: use Bellman-Ford algorithm 932 // to check if the current flow is optimal 933 if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) { 934 _arc_vec.clear(); 935 _cost_vec.clear(); 936 for (int j = 0; j != _res_arc_num; ++j) { 937 if (_res_cap[j] > 0) { 938 _arc_vec.push_back(IntPair(_source[j], _target[j])); 939 _cost_vec.push_back(_cost[j] + 1); 940 } 941 } 942 _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); 943 944 BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map); 945 bf.init(0); 946 bool done = false; 947 int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(_res_node_num)); 948 for (int i = 0; i < K && !done; ++i) 949 done = bf.processNextWeakRound(); 950 if (done) break; 951 } 952 953 // Saturate arcs not satisfying the optimality condition 954 for (int a = 0; a != _res_arc_num; ++a) { 955 if (_res_cap[a] > 0 && 956 _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) { 948 957 Value delta = _res_cap[a]; 949 _excess[ u] -= delta;950 _excess[ v] += delta;958 _excess[_source[a]] -= delta; 959 _excess[_target[a]] += delta; 951 960 _res_cap[a] = 0; 952 961 _res_cap[_reverse[a]] += delta; 953 962 } 954 963 } 955 } 956 957 // Find active nodes (i.e. nodes with positive excess) 958 for (int u = 0; u != _res_node_num; ++u) { 959 if (_excess[u] > 0) _active_nodes.push_back(u); 960 } 961 962 // Initialize the next arcs 963 for (int u = 0; u != _res_node_num; ++u) { 964 _next_out[u] = _first_out[u]; 965 } 966 } 967 968 // Early termination heuristic 969 bool earlyTermination() { 970 const double EARLY_TERM_FACTOR = 3.0; 971 972 // Build a static residual graph 973 _arc_vec.clear(); 974 _cost_vec.clear(); 975 for (int j = 0; j != _res_arc_num; ++j) { 976 if (_res_cap[j] > 0) { 977 _arc_vec.push_back(IntPair(_source[j], _target[j])); 978 _cost_vec.push_back(_cost[j] + 1); 979 } 980 } 981 _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); 982 983 // Run Bellman-Ford algorithm to check if the current flow is optimal 984 BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map); 985 bf.init(0); 986 bool done = false; 987 int K = int(EARLY_TERM_FACTOR * std::sqrt(double(_res_node_num))); 988 for (int i = 0; i < K && !done; ++i) { 989 done = bf.processNextWeakRound(); 990 } 991 return done; 992 } 993 994 // Global potential update heuristic 995 void globalUpdate() { 996 int bucket_end = _root + 1; 997 998 // Initialize buckets 999 for (int r = 0; r != _max_rank; ++r) { 1000 _buckets[r] = bucket_end; 1001 } 1002 Value total_excess = 0; 1003 for (int i = 0; i != _res_node_num; ++i) { 1004 if (_excess[i] < 0) { 1005 _rank[i] = 0; 1006 _bucket_next[i] = _buckets[0]; 1007 _bucket_prev[_buckets[0]] = i; 1008 _buckets[0] = i; 1009 } else { 1010 total_excess += _excess[i]; 1011 _rank[i] = _max_rank; 1012 } 1013 } 1014 if (total_excess == 0) return; 1015 1016 // Search the buckets 1017 int r = 0; 1018 for ( ; r != _max_rank; ++r) { 1019 while (_buckets[r] != bucket_end) { 1020 // Remove the first node from the current bucket 1021 int u = _buckets[r]; 1022 _buckets[r] = _bucket_next[u]; 1023 1024 // Search the incomming arcs of u 1025 LargeCost pi_u = _pi[u]; 1026 int last_out = _first_out[u+1]; 1027 for (int a = _first_out[u]; a != last_out; ++a) { 1028 int ra = _reverse[a]; 1029 if (_res_cap[ra] > 0) { 1030 int v = _source[ra]; 1031 int old_rank_v = _rank[v]; 1032 if (r < old_rank_v) { 1033 // Compute the new rank of v 1034 LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon; 1035 int new_rank_v = old_rank_v; 1036 if (nrc < LargeCost(_max_rank)) 1037 new_rank_v = r + 1 + int(nrc); 1038 1039 // Change the rank of v 1040 if (new_rank_v < old_rank_v) { 1041 _rank[v] = new_rank_v; 1042 _next_out[v] = _first_out[v]; 1043 1044 // Remove v from its old bucket 1045 if (old_rank_v < _max_rank) { 1046 if (_buckets[old_rank_v] == v) { 1047 _buckets[old_rank_v] = _bucket_next[v]; 1048 } else { 1049 _bucket_next[_bucket_prev[v]] = _bucket_next[v]; 1050 _bucket_prev[_bucket_next[v]] = _bucket_prev[v]; 1051 } 1052 } 1053 1054 // Insert v to its new bucket 1055 _bucket_next[v] = _buckets[new_rank_v]; 1056 _bucket_prev[_buckets[new_rank_v]] = v; 1057 _buckets[new_rank_v] = v; 1058 } 1059 } 1060 } 1061 } 1062 1063 // Finish search if there are no more active nodes 1064 if (_excess[u] > 0) { 1065 total_excess -= _excess[u]; 1066 if (total_excess <= 0) break; 1067 } 1068 } 1069 if (total_excess <= 0) break; 1070 } 1071 1072 // Relabel nodes 1073 for (int u = 0; u != _res_node_num; ++u) { 1074 int k = std::min(_rank[u], r); 1075 if (k > 0) { 1076 _pi[u] -= _epsilon * k; 964 965 // Find active nodes (i.e. nodes with positive excess) 966 for (int u = 0; u != _res_node_num; ++u) { 967 if (_excess[u] > 0) _active_nodes.push_back(u); 968 } 969 970 // Initialize the next arcs 971 for (int u = 0; u != _res_node_num; ++u) { 1077 972 _next_out[u] = _first_out[u]; 1078 973 } 1079 } 1080 } 1081 1082 /// Execute the algorithm performing augment and relabel operations 1083 void startAugment(int max_length = std::numeric_limits<int>::max()) { 1084 // Paramters for heuristics 1085 const int EARLY_TERM_EPSILON_LIMIT = 1000; 1086 const double GLOBAL_UPDATE_FACTOR = 3.0; 1087 1088 const int global_update_freq = int(GLOBAL_UPDATE_FACTOR * 1089 (_res_node_num + _sup_node_num * _sup_node_num)); 1090 int next_update_limit = global_update_freq; 1091 1092 int relabel_cnt = 0; 1093 1094 // Perform cost scaling phases 1095 std::vector<int> path; 1096 for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ? 1097 1 : _epsilon / _alpha ) 1098 { 1099 // Early termination heuristic 1100 if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) { 1101 if (earlyTermination()) break; 1102 } 1103 1104 // Initialize current phase 1105 initPhase(); 1106 974 1107 975 // Perform partial augment and relabel operations 1108 976 while (true) { … … 1114 982 if (_active_nodes.size() == 0) break; 1115 983 int start = _active_nodes.front(); 984 path_nodes.clear(); 985 path_nodes.push_back(start); 1116 986 1117 987 // Find an augmenting path from the start node 1118 path.clear();1119 988 int tip = start; 1120 while (_excess[tip] >= 0 && int(path.size()) < max_length) { 989 while (_excess[tip] >= 0 && 990 int(path_nodes.size()) <= max_length) { 1121 991 int u; 1122 LargeCost min_red_cost, rc, pi_tip = _pi[tip]; 1123 int last_out = _first_out[tip+1]; 992 LargeCost min_red_cost, rc; 993 int last_out = _sum_supply < 0 ? 994 _first_out[tip+1] : _first_out[tip+1] - 1; 1124 995 for (int a = _next_out[tip]; a != last_out; ++a) { 1125 u = _target[a]; 1126 if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) { 1127 path.push_back(a); 996 if (_res_cap[a] > 0 && 997 _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) { 998 u = _target[a]; 999 pred_arc[u] = a; 1128 1000 _next_out[tip] = a; 1129 1001 tip = u; 1002 path_nodes.push_back(tip); 1130 1003 goto next_step; 1131 1004 } … … 1133 1006 1134 1007 // Relabel tip node 1135 min_red_cost = std::numeric_limits<LargeCost>::max(); 1136 if (tip != start) { 1137 int ra = _reverse[path.back()]; 1138 min_red_cost = _cost[ra] + pi_tip - _pi[_target[ra]]; 1139 } 1008 min_red_cost = std::numeric_limits<LargeCost>::max() / 2; 1140 1009 for (int a = _first_out[tip]; a != last_out; ++a) { 1141 rc = _cost[a] + pi_tip- _pi[_target[a]];1010 rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]]; 1142 1011 if (_res_cap[a] > 0 && rc < min_red_cost) { 1143 1012 min_red_cost = rc; … … 1145 1014 } 1146 1015 _pi[tip] -= min_red_cost + _epsilon; 1016 1017 // Reset the next arc of tip 1147 1018 _next_out[tip] = _first_out[tip]; 1148 ++relabel_cnt;1149 1019 1150 1020 // Step back 1151 1021 if (tip != start) { 1152 tip = _source[path.back()];1153 path.pop_back();1022 path_nodes.pop_back(); 1023 tip = path_nodes.back(); 1154 1024 } 1155 1025 … … 1159 1029 // Augment along the found path (as much flow as possible) 1160 1030 Value delta; 1161 int pa, u, v = start; 1162 for (int i = 0; i != int(path.size()); ++i) { 1163 pa = path[i]; 1031 int u, v = path_nodes.front(), pa; 1032 for (int i = 1; i < int(path_nodes.size()); ++i) { 1164 1033 u = v; 1165 v = _target[pa]; 1034 v = path_nodes[i]; 1035 pa = pred_arc[v]; 1166 1036 delta = std::min(_res_cap[pa], _excess[u]); 1167 1037 _res_cap[pa] -= delta; … … 1172 1042 _active_nodes.push_back(v); 1173 1043 } 1174 1175 // Global update heuristic1176 if (relabel_cnt >= next_update_limit) {1177 globalUpdate();1178 next_update_limit += global_update_freq;1179 }1180 1044 } 1181 1045 } … … 1185 1049 void startPush() { 1186 1050 // Paramters for heuristics 1187 const int EARLY_TERM_EPSILON_LIMIT = 1000; 1188 const double GLOBAL_UPDATE_FACTOR = 2.0; 1189 1190 const int global_update_freq = int(GLOBAL_UPDATE_FACTOR * 1191 (_res_node_num + _sup_node_num * _sup_node_num)); 1192 int next_update_limit = global_update_freq; 1193 1194 int relabel_cnt = 0; 1195 1051 const int BF_HEURISTIC_EPSILON_BOUND = 1000; 1052 const int BF_HEURISTIC_BOUND_FACTOR = 3; 1053 1196 1054 // Perform cost scaling phases 1197 1055 BoolVector hyper(_res_node_num, false); 1198 LargeCostVector hyper_cost(_res_node_num);1199 1056 for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ? 1200 1057 1 : _epsilon / _alpha ) 1201 1058 { 1202 // Early termination heuristic 1203 if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) { 1204 if (earlyTermination()) break; 1205 } 1206 1207 // Initialize current phase 1208 initPhase(); 1059 // "Early Termination" heuristic: use Bellman-Ford algorithm 1060 // to check if the current flow is optimal 1061 if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) { 1062 _arc_vec.clear(); 1063 _cost_vec.clear(); 1064 for (int j = 0; j != _res_arc_num; ++j) { 1065 if (_res_cap[j] > 0) { 1066 _arc_vec.push_back(IntPair(_source[j], _target[j])); 1067 _cost_vec.push_back(_cost[j] + 1); 1068 } 1069 } 1070 _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); 1071 1072 BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map); 1073 bf.init(0); 1074 bool done = false; 1075 int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(_res_node_num)); 1076 for (int i = 0; i < K && !done; ++i) 1077 done = bf.processNextWeakRound(); 1078 if (done) break; 1079 } 1080 1081 // Saturate arcs not satisfying the optimality condition 1082 for (int a = 0; a != _res_arc_num; ++a) { 1083 if (_res_cap[a] > 0 && 1084 _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) { 1085 Value delta = _res_cap[a]; 1086 _excess[_source[a]] -= delta; 1087 _excess[_target[a]] += delta; 1088 _res_cap[a] = 0; 1089 _res_cap[_reverse[a]] += delta; 1090 } 1091 } 1092 1093 // Find active nodes (i.e. nodes with positive excess) 1094 for (int u = 0; u != _res_node_num; ++u) { 1095 if (_excess[u] > 0) _active_nodes.push_back(u); 1096 } 1097 1098 // Initialize the next arcs 1099 for (int u = 0; u != _res_node_num; ++u) { 1100 _next_out[u] = _first_out[u]; 1101 } 1209 1102 1210 1103 // Perform push and relabel operations 1211 1104 while (_active_nodes.size() > 0) { 1212 LargeCost min_red_cost, rc , pi_n;1105 LargeCost min_red_cost, rc; 1213 1106 Value delta; 1214 1107 int n, t, a, last_out = _res_arc_num; 1215 1108 1109 // Select an active node (FIFO selection) 1216 1110 next_node: 1217 // Select an active node (FIFO selection)1218 1111 n = _active_nodes.front(); 1219 last_out = _ first_out[n+1];1220 pi_n = _pi[n];1221 1112 last_out = _sum_supply < 0 ? 1113 _first_out[n+1] : _first_out[n+1] - 1; 1114 1222 1115 // Perform push operations if there are admissible arcs 1223 1116 if (_excess[n] > 0) { 1224 1117 for (a = _next_out[n]; a != last_out; ++a) { 1225 1118 if (_res_cap[a] > 0 && 1226 _cost[a] + pi_n- _pi[_target[a]] < 0) {1119 _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) { 1227 1120 delta = std::min(_res_cap[a], _excess[n]); 1228 1121 t = _target[a]; … … 1230 1123 // Push-look-ahead heuristic 1231 1124 Value ahead = -_excess[t]; 1232 int last_out_t = _ first_out[t+1];1233 LargeCost pi_t = _pi[t];1125 int last_out_t = _sum_supply < 0 ? 1126 _first_out[t+1] : _first_out[t+1] - 1; 1234 1127 for (int ta = _next_out[t]; ta != last_out_t; ++ta) { 1235 1128 if (_res_cap[ta] > 0 && 1236 _cost[ta] + pi_t- _pi[_target[ta]] < 0)1129 _cost[ta] + _pi[_source[ta]] - _pi[_target[ta]] < 0) 1237 1130 ahead += _res_cap[ta]; 1238 1131 if (ahead >= delta) break; … … 1241 1134 1242 1135 // Push flow along the arc 1243 if (ahead < delta && !hyper[t]) {1136 if (ahead < delta) { 1244 1137 _res_cap[a] -= ahead; 1245 1138 _res_cap[_reverse[a]] += ahead; … … 1248 1141 _active_nodes.push_front(t); 1249 1142 hyper[t] = true; 1250 hyper_cost[t] = _cost[a] + pi_n - pi_t;1251 1143 _next_out[n] = a; 1252 1144 goto next_node; … … 1271 1163 // Relabel the node if it is still active (or hyper) 1272 1164 if (_excess[n] > 0 || hyper[n]) { 1273 min_red_cost = hyper[n] ? -hyper_cost[n] : 1274 std::numeric_limits<LargeCost>::max(); 1165 min_red_cost = std::numeric_limits<LargeCost>::max() / 2; 1275 1166 for (int a = _first_out[n]; a != last_out; ++a) { 1276 rc = _cost[a] + pi_n- _pi[_target[a]];1167 rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]]; 1277 1168 if (_res_cap[a] > 0 && rc < min_red_cost) { 1278 1169 min_red_cost = rc; … … 1280 1171 } 1281 1172 _pi[n] -= min_red_cost + _epsilon; 1173 hyper[n] = false; 1174 1175 // Reset the next arc 1282 1176 _next_out[n] = _first_out[n]; 1283 hyper[n] = false;1284 ++relabel_cnt;1285 1177 } 1286 1178 … … 1292 1184 _active_nodes.pop_front(); 1293 1185 } 1294 1295 // Global update heuristic1296 if (relabel_cnt >= next_update_limit) {1297 globalUpdate();1298 for (int u = 0; u != _res_node_num; ++u)1299 hyper[u] = false;1300 next_update_limit += global_update_freq;1301 }1302 1186 } 1303 1187 } -
lemon/cycle_canceling.h
r840 r830 145 145 146 146 typedef std::vector<int> IntVector; 147 typedef std::vector<char> CharVector; 147 148 typedef std::vector<double> DoubleVector; 148 149 typedef std::vector<Value> ValueVector; 149 150 typedef std::vector<Cost> CostVector; 150 typedef std::vector<char> BoolVector;151 // Note: vector<char> is used instead of vector<bool> for efficiency reasons152 151 153 152 private: … … 200 199 IntArcMap _arc_idb; 201 200 IntVector _first_out; 202 BoolVector _forward;201 CharVector _forward; 203 202 IntVector _source; 204 203 IntVector _target; … … 964 963 DoubleVector pi(_res_node_num, 0.0); 965 964 IntVector level(_res_node_num); 966 BoolVector reached(_res_node_num);967 BoolVector processed(_res_node_num);965 CharVector reached(_res_node_num); 966 CharVector processed(_res_node_num); 968 967 IntVector pred_node(_res_node_num); 969 968 IntVector pred_arc(_res_node_num); -
lemon/glpk.h
r833 r746 26 26 #include <lemon/lp_base.h> 27 27 28 // forward declaration 29 #if !defined _GLP_PROB && !defined GLP_PROB 30 #define _GLP_PROB 31 #define GLP_PROB 32 typedef struct { double _opaque_prob; } glp_prob; 33 /* LP/MIP problem object */ 34 #endif 35 28 36 namespace lemon { 29 37 30 namespace _solver_bits {31 class VoidPtr {32 private:33 void *_ptr;34 public:35 VoidPtr() : _ptr(0) {}36 37 template <typename T>38 VoidPtr(T* ptr) : _ptr(reinterpret_cast<void*>(ptr)) {}39 40 template <typename T>41 VoidPtr& operator=(T* ptr) {42 _ptr = reinterpret_cast<void*>(ptr);43 return *this;44 }45 46 template <typename T>47 operator T*() const { return reinterpret_cast<T*>(_ptr); }48 };49 }50 38 51 39 /// \brief Base interface for the GLPK LP and MIP solver … … 56 44 protected: 57 45 58 _solver_bits::VoidPtr lp; 46 typedef glp_prob LPX; 47 glp_prob* lp; 59 48 60 49 GlpkBase(); … … 135 124 136 125 ///Pointer to the underlying GLPK data structure. 137 _solver_bits::VoidPtrlpx() {return lp;}126 LPX *lpx() {return lp;} 138 127 ///Const pointer to the underlying GLPK data structure. 139 _solver_bits::VoidPtrlpx() const {return lp;}128 const LPX *lpx() const {return lp;} 140 129 141 130 ///Returns the constraint identifier understood by GLPK. -
lemon/graph_to_eps.h
r838 r786 685 685 #else 686 686 os << bits::getWinFormattedDate(); 687 os << std::endl;688 687 #endif 689 688 } 689 os << std::endl; 690 690 691 691 if (_autoArcWidthScale) { -
lemon/hartmann_orlin.h
r841 r825 406 406 /// \pre \ref run() or \ref findMinMean() must be called before 407 407 /// using this function. 408 Value cycleLength() const {409 return static_cast<Value>(_best_length);408 LargeValue cycleLength() const { 409 return _best_length; 410 410 } 411 411 -
lemon/howard.h
r841 r825 385 385 /// \pre \ref run() or \ref findMinMean() must be called before 386 386 /// using this function. 387 Value cycleLength() const {388 return static_cast<Value>(_best_length);387 LargeValue cycleLength() const { 388 return _best_length; 389 389 } 390 390 -
lemon/karp.h
r841 r825 393 393 /// \pre \ref run() or \ref findMinMean() must be called before 394 394 /// using this function. 395 Value cycleLength() const {396 return static_cast<Value>(_cycle_length);395 LargeValue cycleLength() const { 396 return _cycle_length; 397 397 } 398 398 -
lemon/lp_base.h
r834 r786 1230 1230 Row r; 1231 1231 c.expr().simplify(); 1232 r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound() -*c.expr():-INF,1232 r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound():-INF, 1233 1233 ExprIterator(c.expr().comps.begin(), cols), 1234 1234 ExprIterator(c.expr().comps.end(), cols), 1235 c.upperBounded()?c.upperBound() -*c.expr():INF));1235 c.upperBounded()?c.upperBound():INF)); 1236 1236 return r; 1237 1237 } -
lemon/network_simplex.h
r840 r830 165 165 166 166 typedef std::vector<int> IntVector; 167 typedef std::vector<char> CharVector; 167 168 typedef std::vector<Value> ValueVector; 168 169 typedef std::vector<Cost> CostVector; 169 typedef std::vector<char> BoolVector;170 // Note: vector<char> is used instead of vector<bool> for efficiency reasons171 170 172 171 // State constants for arcs … … 215 214 IntVector _last_succ; 216 215 IntVector _dirty_revs; 217 BoolVector _forward;218 BoolVector _state;216 CharVector _forward; 217 CharVector _state; 219 218 int _root; 220 219 … … 247 246 const IntVector &_target; 248 247 const CostVector &_cost; 249 const BoolVector &_state;248 const CharVector &_state; 250 249 const CostVector &_pi; 251 250 int &_in_arc; … … 268 267 bool findEnteringArc() { 269 268 Cost c; 270 for (int e = _next_arc; e !=_search_arc_num; ++e) {269 for (int e = _next_arc; e < _search_arc_num; ++e) { 271 270 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 272 271 if (c < 0) { … … 276 275 } 277 276 } 278 for (int e = 0; e !=_next_arc; ++e) {277 for (int e = 0; e < _next_arc; ++e) { 279 278 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 280 279 if (c < 0) { … … 299 298 const IntVector &_target; 300 299 const CostVector &_cost; 301 const BoolVector &_state;300 const CharVector &_state; 302 301 const CostVector &_pi; 303 302 int &_in_arc; … … 316 315 bool findEnteringArc() { 317 316 Cost c, min = 0; 318 for (int e = 0; e !=_search_arc_num; ++e) {317 for (int e = 0; e < _search_arc_num; ++e) { 319 318 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 320 319 if (c < min) { … … 338 337 const IntVector &_target; 339 338 const CostVector &_cost; 340 const BoolVector &_state;339 const CharVector &_state; 341 340 const CostVector &_pi; 342 341 int &_in_arc; … … 357 356 { 358 357 // The main parameters of the pivot rule 359 const double BLOCK_SIZE_FACTOR = 1.0;358 const double BLOCK_SIZE_FACTOR = 0.5; 360 359 const int MIN_BLOCK_SIZE = 10; 361 360 … … 370 369 int cnt = _block_size; 371 370 int e; 372 for (e = _next_arc; e !=_search_arc_num; ++e) {371 for (e = _next_arc; e < _search_arc_num; ++e) { 373 372 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 374 373 if (c < min) { … … 381 380 } 382 381 } 383 for (e = 0; e !=_next_arc; ++e) {382 for (e = 0; e < _next_arc; ++e) { 384 383 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 385 384 if (c < min) { … … 411 410 const IntVector &_target; 412 411 const CostVector &_cost; 413 const BoolVector &_state;412 const CharVector &_state; 414 413 const CostVector &_pi; 415 414 int &_in_arc; … … 472 471 min = 0; 473 472 _curr_length = 0; 474 for (e = _next_arc; e !=_search_arc_num; ++e) {473 for (e = _next_arc; e < _search_arc_num; ++e) { 475 474 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 476 475 if (c < 0) { … … 483 482 } 484 483 } 485 for (e = 0; e !=_next_arc; ++e) {484 for (e = 0; e < _next_arc; ++e) { 486 485 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 487 486 if (c < 0) { … … 514 513 const IntVector &_target; 515 514 const CostVector &_cost; 516 const BoolVector &_state;515 const CharVector &_state; 517 516 const CostVector &_pi; 518 517 int &_in_arc; … … 567 566 // Check the current candidate list 568 567 int e; 569 for (int i = 0; i !=_curr_length; ++i) {568 for (int i = 0; i < _curr_length; ++i) { 570 569 e = _candidates[i]; 571 570 _cand_cost[e] = _state[e] * … … 580 579 int limit = _head_length; 581 580 582 for (e = _next_arc; e !=_search_arc_num; ++e) {581 for (e = _next_arc; e < _search_arc_num; ++e) { 583 582 _cand_cost[e] = _state[e] * 584 583 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); … … 592 591 } 593 592 } 594 for (e = 0; e !=_next_arc; ++e) {593 for (e = 0; e < _next_arc; ++e) { 595 594 _cand_cost[e] = _state[e] * 596 595 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); … … 1362 1361 1363 1362 // Update _rev_thread using the new _thread values 1364 for (int i = 0; i !=int(_dirty_revs.size()); ++i) {1363 for (int i = 0; i < int(_dirty_revs.size()); ++i) { 1365 1364 u = _dirty_revs[i]; 1366 1365 _rev_thread[_thread[u]] = u; … … 1432 1431 _pi[u] += sigma; 1433 1432 } 1434 }1435 1436 // Heuristic initial pivots1437 bool initialPivots() {1438 Value curr, total = 0;1439 std::vector<Node> supply_nodes, demand_nodes;1440 for (NodeIt u(_graph); u != INVALID; ++u) {1441 curr = _supply[_node_id[u]];1442 if (curr > 0) {1443 total += curr;1444 supply_nodes.push_back(u);1445 }1446 else if (curr < 0) {1447 demand_nodes.push_back(u);1448 }1449 }1450 if (_sum_supply > 0) total -= _sum_supply;1451 if (total <= 0) return true;1452 1453 IntVector arc_vector;1454 if (_sum_supply >= 0) {1455 if (supply_nodes.size() == 1 && demand_nodes.size() == 1) {1456 // Perform a reverse graph search from the sink to the source1457 typename GR::template NodeMap<bool> reached(_graph, false);1458 Node s = supply_nodes[0], t = demand_nodes[0];1459 std::vector<Node> stack;1460 reached[t] = true;1461 stack.push_back(t);1462 while (!stack.empty()) {1463 Node u, v = stack.back();1464 stack.pop_back();1465 if (v == s) break;1466 for (InArcIt a(_graph, v); a != INVALID; ++a) {1467 if (reached[u = _graph.source(a)]) continue;1468 int j = _arc_id[a];1469 if (_cap[j] >= total) {1470 arc_vector.push_back(j);1471 reached[u] = true;1472 stack.push_back(u);1473 }1474 }1475 }1476 } else {1477 // Find the min. cost incomming arc for each demand node1478 for (int i = 0; i != int(demand_nodes.size()); ++i) {1479 Node v = demand_nodes[i];1480 Cost c, min_cost = std::numeric_limits<Cost>::max();1481 Arc min_arc = INVALID;1482 for (InArcIt a(_graph, v); a != INVALID; ++a) {1483 c = _cost[_arc_id[a]];1484 if (c < min_cost) {1485 min_cost = c;1486 min_arc = a;1487 }1488 }1489 if (min_arc != INVALID) {1490 arc_vector.push_back(_arc_id[min_arc]);1491 }1492 }1493 }1494 } else {1495 // Find the min. cost outgoing arc for each supply node1496 for (int i = 0; i != int(supply_nodes.size()); ++i) {1497 Node u = supply_nodes[i];1498 Cost c, min_cost = std::numeric_limits<Cost>::max();1499 Arc min_arc = INVALID;1500 for (OutArcIt a(_graph, u); a != INVALID; ++a) {1501 c = _cost[_arc_id[a]];1502 if (c < min_cost) {1503 min_cost = c;1504 min_arc = a;1505 }1506 }1507 if (min_arc != INVALID) {1508 arc_vector.push_back(_arc_id[min_arc]);1509 }1510 }1511 }1512 1513 // Perform heuristic initial pivots1514 for (int i = 0; i != int(arc_vector.size()); ++i) {1515 in_arc = arc_vector[i];1516 if (_state[in_arc] * (_cost[in_arc] + _pi[_source[in_arc]] -1517 _pi[_target[in_arc]]) >= 0) continue;1518 findJoinNode();1519 bool change = findLeavingArc();1520 if (delta >= MAX) return false;1521 changeFlow(change);1522 if (change) {1523 updateTreeStructure();1524 updatePotential();1525 }1526 }1527 return true;1528 1433 } 1529 1434 … … 1550 1455 PivotRuleImpl pivot(*this); 1551 1456 1552 // Perform heuristic initial pivots1553 if (!initialPivots()) return UNBOUNDED;1554 1555 1457 // Execute the Network Simplex algorithm 1556 1458 while (pivot.findEnteringArc()) { -
scripts/bib2dox.py
r836 r754 1 #! /usr/bin/env python1 #!/usr/bin/env /usr/local/Python/bin/python2.1 2 2 """ 3 3 BibTeX to Doxygen converter 4 4 Usage: python bib2dox.py bibfile.bib > bibfile.dox 5 5 6 This file is a part of LEMON, a generic C++ optimization library.7 8 **********************************************************************9 10 6 This code is the modification of the BibTeX to XML converter 11 by Vidar Bronken Gundersen et al. 12 See the original copyright notices below. 7 by Vidar Bronken Gundersen et al. See the original copyright notices below. 13 8 14 9 **********************************************************************
Note: See TracChangeset
for help on using the changeset viewer.