changeset 895 | dca9eed2c375 |
parent 889 | 0bca98cbebbb |
child 896 | fb932bcfd803 |
31:ab65107fbc11 | 32:955f5986005d |
---|---|
164 TEMPLATE_DIGRAPH_TYPEDEFS(GR); |
164 TEMPLATE_DIGRAPH_TYPEDEFS(GR); |
165 |
165 |
166 typedef std::vector<int> IntVector; |
166 typedef std::vector<int> IntVector; |
167 typedef std::vector<Value> ValueVector; |
167 typedef std::vector<Value> ValueVector; |
168 typedef std::vector<Cost> CostVector; |
168 typedef std::vector<Cost> CostVector; |
169 typedef std::vector<char> BoolVector; |
169 typedef std::vector<signed char> CharVector; |
170 // Note: vector<char> is used instead of vector<bool> for efficiency reasons |
170 // Note: vector<signed char> is used instead of vector<ArcState> and |
171 // vector<ArcDirection> for efficiency reasons |
|
171 |
172 |
172 // State constants for arcs |
173 // State constants for arcs |
173 enum ArcState { |
174 enum ArcState { |
174 STATE_UPPER = -1, |
175 STATE_UPPER = -1, |
175 STATE_TREE = 0, |
176 STATE_TREE = 0, |
176 STATE_LOWER = 1 |
177 STATE_LOWER = 1 |
177 }; |
178 }; |
178 |
179 |
179 typedef std::vector<signed char> StateVector; |
180 // Direction constants for tree arcs |
180 // Note: vector<signed char> is used instead of vector<ArcState> for |
181 enum ArcDirection { |
181 // efficiency reasons |
182 DIR_DOWN = -1, |
183 DIR_UP = 1 |
|
184 }; |
|
182 |
185 |
183 private: |
186 private: |
184 |
187 |
185 // Data related to the underlying digraph |
188 // Data related to the underlying digraph |
186 const GR &_graph; |
189 const GR &_graph; |
215 IntVector _pred; |
218 IntVector _pred; |
216 IntVector _thread; |
219 IntVector _thread; |
217 IntVector _rev_thread; |
220 IntVector _rev_thread; |
218 IntVector _succ_num; |
221 IntVector _succ_num; |
219 IntVector _last_succ; |
222 IntVector _last_succ; |
223 CharVector _pred_dir; |
|
224 CharVector _state; |
|
220 IntVector _dirty_revs; |
225 IntVector _dirty_revs; |
221 BoolVector _forward; |
|
222 StateVector _state; |
|
223 int _root; |
226 int _root; |
224 |
227 |
225 // Temporary data used in the current pivot iteration |
228 // Temporary data used in the current pivot iteration |
226 int in_arc, join, u_in, v_in, u_out, v_out; |
229 int in_arc, join, u_in, v_in, u_out, v_out; |
227 int first, second, right, last; |
|
228 int stem, par_stem, new_stem; |
|
229 Value delta; |
230 Value delta; |
230 |
231 |
231 const Value MAX; |
232 const Value MAX; |
232 |
233 |
233 public: |
234 public: |
248 |
249 |
249 // References to the NetworkSimplex class |
250 // References to the NetworkSimplex class |
250 const IntVector &_source; |
251 const IntVector &_source; |
251 const IntVector &_target; |
252 const IntVector &_target; |
252 const CostVector &_cost; |
253 const CostVector &_cost; |
253 const StateVector &_state; |
254 const CharVector &_state; |
254 const CostVector &_pi; |
255 const CostVector &_pi; |
255 int &_in_arc; |
256 int &_in_arc; |
256 int _search_arc_num; |
257 int _search_arc_num; |
257 |
258 |
258 // Pivot rule data |
259 // Pivot rule data |
300 |
301 |
301 // References to the NetworkSimplex class |
302 // References to the NetworkSimplex class |
302 const IntVector &_source; |
303 const IntVector &_source; |
303 const IntVector &_target; |
304 const IntVector &_target; |
304 const CostVector &_cost; |
305 const CostVector &_cost; |
305 const StateVector &_state; |
306 const CharVector &_state; |
306 const CostVector &_pi; |
307 const CostVector &_pi; |
307 int &_in_arc; |
308 int &_in_arc; |
308 int _search_arc_num; |
309 int _search_arc_num; |
309 |
310 |
310 public: |
311 public: |
339 |
340 |
340 // References to the NetworkSimplex class |
341 // References to the NetworkSimplex class |
341 const IntVector &_source; |
342 const IntVector &_source; |
342 const IntVector &_target; |
343 const IntVector &_target; |
343 const CostVector &_cost; |
344 const CostVector &_cost; |
344 const StateVector &_state; |
345 const CharVector &_state; |
345 const CostVector &_pi; |
346 const CostVector &_pi; |
346 int &_in_arc; |
347 int &_in_arc; |
347 int _search_arc_num; |
348 int _search_arc_num; |
348 |
349 |
349 // Pivot rule data |
350 // Pivot rule data |
412 |
413 |
413 // References to the NetworkSimplex class |
414 // References to the NetworkSimplex class |
414 const IntVector &_source; |
415 const IntVector &_source; |
415 const IntVector &_target; |
416 const IntVector &_target; |
416 const CostVector &_cost; |
417 const CostVector &_cost; |
417 const StateVector &_state; |
418 const CharVector &_state; |
418 const CostVector &_pi; |
419 const CostVector &_pi; |
419 int &_in_arc; |
420 int &_in_arc; |
420 int _search_arc_num; |
421 int _search_arc_num; |
421 |
422 |
422 // Pivot rule data |
423 // Pivot rule data |
515 |
516 |
516 // References to the NetworkSimplex class |
517 // References to the NetworkSimplex class |
517 const IntVector &_source; |
518 const IntVector &_source; |
518 const IntVector &_target; |
519 const IntVector &_target; |
519 const CostVector &_cost; |
520 const CostVector &_cost; |
520 const StateVector &_state; |
521 const CharVector &_state; |
521 const CostVector &_pi; |
522 const CostVector &_pi; |
522 int &_in_arc; |
523 int &_in_arc; |
523 int _search_arc_num; |
524 int _search_arc_num; |
524 |
525 |
525 // Pivot rule data |
526 // Pivot rule data |
568 |
569 |
569 // Find next entering arc |
570 // Find next entering arc |
570 bool findEnteringArc() { |
571 bool findEnteringArc() { |
571 // Check the current candidate list |
572 // Check the current candidate list |
572 int e; |
573 int e; |
574 Cost c; |
|
573 for (int i = 0; i != _curr_length; ++i) { |
575 for (int i = 0; i != _curr_length; ++i) { |
574 e = _candidates[i]; |
576 e = _candidates[i]; |
575 _cand_cost[e] = _state[e] * |
577 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
576 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
578 if (c < 0) { |
577 if (_cand_cost[e] >= 0) { |
579 _cand_cost[e] = c; |
580 } else { |
|
578 _candidates[i--] = _candidates[--_curr_length]; |
581 _candidates[i--] = _candidates[--_curr_length]; |
579 } |
582 } |
580 } |
583 } |
581 |
584 |
582 // Extend the list |
585 // Extend the list |
583 int cnt = _block_size; |
586 int cnt = _block_size; |
584 int limit = _head_length; |
587 int limit = _head_length; |
585 |
588 |
586 for (e = _next_arc; e != _search_arc_num; ++e) { |
589 for (e = _next_arc; e != _search_arc_num; ++e) { |
587 _cand_cost[e] = _state[e] * |
590 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
588 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
591 if (c < 0) { |
589 if (_cand_cost[e] < 0) { |
592 _cand_cost[e] = c; |
590 _candidates[_curr_length++] = e; |
593 _candidates[_curr_length++] = e; |
591 } |
594 } |
592 if (--cnt == 0) { |
595 if (--cnt == 0) { |
593 if (_curr_length > limit) goto search_end; |
596 if (_curr_length > limit) goto search_end; |
594 limit = 0; |
597 limit = 0; |
911 _flow.resize(max_arc_num); |
914 _flow.resize(max_arc_num); |
912 _pi.resize(all_node_num); |
915 _pi.resize(all_node_num); |
913 |
916 |
914 _parent.resize(all_node_num); |
917 _parent.resize(all_node_num); |
915 _pred.resize(all_node_num); |
918 _pred.resize(all_node_num); |
916 _forward.resize(all_node_num); |
919 _pred_dir.resize(all_node_num); |
917 _thread.resize(all_node_num); |
920 _thread.resize(all_node_num); |
918 _rev_thread.resize(all_node_num); |
921 _rev_thread.resize(all_node_num); |
919 _succ_num.resize(all_node_num); |
922 _succ_num.resize(all_node_num); |
920 _last_succ.resize(all_node_num); |
923 _last_succ.resize(all_node_num); |
921 _state.resize(max_arc_num); |
924 _state.resize(max_arc_num); |
1114 _succ_num[u] = 1; |
1117 _succ_num[u] = 1; |
1115 _last_succ[u] = u; |
1118 _last_succ[u] = u; |
1116 _cap[e] = INF; |
1119 _cap[e] = INF; |
1117 _state[e] = STATE_TREE; |
1120 _state[e] = STATE_TREE; |
1118 if (_supply[u] >= 0) { |
1121 if (_supply[u] >= 0) { |
1119 _forward[u] = true; |
1122 _pred_dir[u] = DIR_UP; |
1120 _pi[u] = 0; |
1123 _pi[u] = 0; |
1121 _source[e] = u; |
1124 _source[e] = u; |
1122 _target[e] = _root; |
1125 _target[e] = _root; |
1123 _flow[e] = _supply[u]; |
1126 _flow[e] = _supply[u]; |
1124 _cost[e] = 0; |
1127 _cost[e] = 0; |
1125 } else { |
1128 } else { |
1126 _forward[u] = false; |
1129 _pred_dir[u] = DIR_DOWN; |
1127 _pi[u] = ART_COST; |
1130 _pi[u] = ART_COST; |
1128 _source[e] = _root; |
1131 _source[e] = _root; |
1129 _target[e] = u; |
1132 _target[e] = u; |
1130 _flow[e] = -_supply[u]; |
1133 _flow[e] = -_supply[u]; |
1131 _cost[e] = ART_COST; |
1134 _cost[e] = ART_COST; |
1141 _thread[u] = u + 1; |
1144 _thread[u] = u + 1; |
1142 _rev_thread[u + 1] = u; |
1145 _rev_thread[u + 1] = u; |
1143 _succ_num[u] = 1; |
1146 _succ_num[u] = 1; |
1144 _last_succ[u] = u; |
1147 _last_succ[u] = u; |
1145 if (_supply[u] >= 0) { |
1148 if (_supply[u] >= 0) { |
1146 _forward[u] = true; |
1149 _pred_dir[u] = DIR_UP; |
1147 _pi[u] = 0; |
1150 _pi[u] = 0; |
1148 _pred[u] = e; |
1151 _pred[u] = e; |
1149 _source[e] = u; |
1152 _source[e] = u; |
1150 _target[e] = _root; |
1153 _target[e] = _root; |
1151 _cap[e] = INF; |
1154 _cap[e] = INF; |
1152 _flow[e] = _supply[u]; |
1155 _flow[e] = _supply[u]; |
1153 _cost[e] = 0; |
1156 _cost[e] = 0; |
1154 _state[e] = STATE_TREE; |
1157 _state[e] = STATE_TREE; |
1155 } else { |
1158 } else { |
1156 _forward[u] = false; |
1159 _pred_dir[u] = DIR_DOWN; |
1157 _pi[u] = ART_COST; |
1160 _pi[u] = ART_COST; |
1158 _pred[u] = f; |
1161 _pred[u] = f; |
1159 _source[f] = _root; |
1162 _source[f] = _root; |
1160 _target[f] = u; |
1163 _target[f] = u; |
1161 _cap[f] = INF; |
1164 _cap[f] = INF; |
1182 _thread[u] = u + 1; |
1185 _thread[u] = u + 1; |
1183 _rev_thread[u + 1] = u; |
1186 _rev_thread[u + 1] = u; |
1184 _succ_num[u] = 1; |
1187 _succ_num[u] = 1; |
1185 _last_succ[u] = u; |
1188 _last_succ[u] = u; |
1186 if (_supply[u] <= 0) { |
1189 if (_supply[u] <= 0) { |
1187 _forward[u] = false; |
1190 _pred_dir[u] = DIR_DOWN; |
1188 _pi[u] = 0; |
1191 _pi[u] = 0; |
1189 _pred[u] = e; |
1192 _pred[u] = e; |
1190 _source[e] = _root; |
1193 _source[e] = _root; |
1191 _target[e] = u; |
1194 _target[e] = u; |
1192 _cap[e] = INF; |
1195 _cap[e] = INF; |
1193 _flow[e] = -_supply[u]; |
1196 _flow[e] = -_supply[u]; |
1194 _cost[e] = 0; |
1197 _cost[e] = 0; |
1195 _state[e] = STATE_TREE; |
1198 _state[e] = STATE_TREE; |
1196 } else { |
1199 } else { |
1197 _forward[u] = true; |
1200 _pred_dir[u] = DIR_UP; |
1198 _pi[u] = -ART_COST; |
1201 _pi[u] = -ART_COST; |
1199 _pred[u] = f; |
1202 _pred[u] = f; |
1200 _source[f] = u; |
1203 _source[f] = u; |
1201 _target[f] = _root; |
1204 _target[f] = _root; |
1202 _cap[f] = INF; |
1205 _cap[f] = INF; |
1235 // Find the leaving arc of the cycle and returns true if the |
1238 // Find the leaving arc of the cycle and returns true if the |
1236 // leaving arc is not the same as the entering arc |
1239 // leaving arc is not the same as the entering arc |
1237 bool findLeavingArc() { |
1240 bool findLeavingArc() { |
1238 // Initialize first and second nodes according to the direction |
1241 // Initialize first and second nodes according to the direction |
1239 // of the cycle |
1242 // of the cycle |
1243 int first, second; |
|
1240 if (_state[in_arc] == STATE_LOWER) { |
1244 if (_state[in_arc] == STATE_LOWER) { |
1241 first = _source[in_arc]; |
1245 first = _source[in_arc]; |
1242 second = _target[in_arc]; |
1246 second = _target[in_arc]; |
1243 } else { |
1247 } else { |
1244 first = _target[in_arc]; |
1248 first = _target[in_arc]; |
1245 second = _source[in_arc]; |
1249 second = _source[in_arc]; |
1246 } |
1250 } |
1247 delta = _cap[in_arc]; |
1251 delta = _cap[in_arc]; |
1248 int result = 0; |
1252 int result = 0; |
1249 Value d; |
1253 Value c, d; |
1250 int e; |
1254 int e; |
1251 |
1255 |
1252 // Search the cycle along the path form the first node to the root |
1256 // Search the cycle form the first node to the join node |
1253 for (int u = first; u != join; u = _parent[u]) { |
1257 for (int u = first; u != join; u = _parent[u]) { |
1254 e = _pred[u]; |
1258 e = _pred[u]; |
1255 d = _forward[u] ? |
1259 d = _flow[e]; |
1256 _flow[e] : (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]); |
1260 if (_pred_dir[u] == DIR_DOWN) { |
1261 c = _cap[e]; |
|
1262 d = c >= MAX ? INF : c - d; |
|
1263 } |
|
1257 if (d < delta) { |
1264 if (d < delta) { |
1258 delta = d; |
1265 delta = d; |
1259 u_out = u; |
1266 u_out = u; |
1260 result = 1; |
1267 result = 1; |
1261 } |
1268 } |
1262 } |
1269 } |
1263 // Search the cycle along the path form the second node to the root |
1270 |
1271 // Search the cycle form the second node to the join node |
|
1264 for (int u = second; u != join; u = _parent[u]) { |
1272 for (int u = second; u != join; u = _parent[u]) { |
1265 e = _pred[u]; |
1273 e = _pred[u]; |
1266 d = _forward[u] ? |
1274 d = _flow[e]; |
1267 (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e]; |
1275 if (_pred_dir[u] == DIR_UP) { |
1276 c = _cap[e]; |
|
1277 d = c >= MAX ? INF : c - d; |
|
1278 } |
|
1268 if (d <= delta) { |
1279 if (d <= delta) { |
1269 delta = d; |
1280 delta = d; |
1270 u_out = u; |
1281 u_out = u; |
1271 result = 2; |
1282 result = 2; |
1272 } |
1283 } |
1287 // Augment along the cycle |
1298 // Augment along the cycle |
1288 if (delta > 0) { |
1299 if (delta > 0) { |
1289 Value val = _state[in_arc] * delta; |
1300 Value val = _state[in_arc] * delta; |
1290 _flow[in_arc] += val; |
1301 _flow[in_arc] += val; |
1291 for (int u = _source[in_arc]; u != join; u = _parent[u]) { |
1302 for (int u = _source[in_arc]; u != join; u = _parent[u]) { |
1292 _flow[_pred[u]] += _forward[u] ? -val : val; |
1303 _flow[_pred[u]] -= _pred_dir[u] * val; |
1293 } |
1304 } |
1294 for (int u = _target[in_arc]; u != join; u = _parent[u]) { |
1305 for (int u = _target[in_arc]; u != join; u = _parent[u]) { |
1295 _flow[_pred[u]] += _forward[u] ? val : -val; |
1306 _flow[_pred[u]] += _pred_dir[u] * val; |
1296 } |
1307 } |
1297 } |
1308 } |
1298 // Update the state of the entering and leaving arcs |
1309 // Update the state of the entering and leaving arcs |
1299 if (change) { |
1310 if (change) { |
1300 _state[in_arc] = STATE_TREE; |
1311 _state[in_arc] = STATE_TREE; |
1305 } |
1316 } |
1306 } |
1317 } |
1307 |
1318 |
1308 // Update the tree structure |
1319 // Update the tree structure |
1309 void updateTreeStructure() { |
1320 void updateTreeStructure() { |
1310 int u, w; |
|
1311 int old_rev_thread = _rev_thread[u_out]; |
1321 int old_rev_thread = _rev_thread[u_out]; |
1312 int old_succ_num = _succ_num[u_out]; |
1322 int old_succ_num = _succ_num[u_out]; |
1313 int old_last_succ = _last_succ[u_out]; |
1323 int old_last_succ = _last_succ[u_out]; |
1314 v_out = _parent[u_out]; |
1324 v_out = _parent[u_out]; |
1315 |
1325 |
1316 u = _last_succ[u_in]; // the last successor of u_in |
1326 // Check if u_in and u_out coincide |
1317 right = _thread[u]; // the node after it |
1327 if (u_in == u_out) { |
1318 |
1328 // Update _parent, _pred, _pred_dir |
1319 // Handle the case when old_rev_thread equals to v_in |
1329 _parent[u_in] = v_in; |
1320 // (it also means that join and v_out coincide) |
1330 _pred[u_in] = in_arc; |
1321 if (old_rev_thread == v_in) { |
1331 _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN; |
1322 last = _thread[_last_succ[u_out]]; |
1332 |
1333 // Update _thread and _rev_thread |
|
1334 if (_thread[v_in] != u_out) { |
|
1335 int after = _thread[old_last_succ]; |
|
1336 _thread[old_rev_thread] = after; |
|
1337 _rev_thread[after] = old_rev_thread; |
|
1338 after = _thread[v_in]; |
|
1339 _thread[v_in] = u_out; |
|
1340 _rev_thread[u_out] = v_in; |
|
1341 _thread[old_last_succ] = after; |
|
1342 _rev_thread[after] = old_last_succ; |
|
1343 } |
|
1323 } else { |
1344 } else { |
1324 last = _thread[v_in]; |
1345 // Handle the case when old_rev_thread equals to v_in |
1325 } |
1346 // (it also means that join and v_out coincide) |
1326 |
1347 int thread_continue = old_rev_thread == v_in ? |
1327 // Update _thread and _parent along the stem nodes (i.e. the nodes |
1348 _thread[old_last_succ] : _thread[v_in]; |
1328 // between u_in and u_out, whose parent have to be changed) |
1349 |
1329 _thread[v_in] = stem = u_in; |
1350 // Update _thread and _parent along the stem nodes (i.e. the nodes |
1330 _dirty_revs.clear(); |
1351 // between u_in and u_out, whose parent have to be changed) |
1331 _dirty_revs.push_back(v_in); |
1352 int stem = u_in; // the current stem node |
1332 par_stem = v_in; |
1353 int par_stem = v_in; // the new parent of stem |
1333 while (stem != u_out) { |
1354 int next_stem; // the next stem node |
1334 // Insert the next stem node into the thread list |
1355 int last = _last_succ[u_in]; // the last successor of stem |
1335 new_stem = _parent[stem]; |
1356 int before, after = _thread[last]; |
1336 _thread[u] = new_stem; |
1357 _thread[v_in] = u_in; |
1337 _dirty_revs.push_back(u); |
1358 _dirty_revs.clear(); |
1338 |
1359 _dirty_revs.push_back(v_in); |
1339 // Remove the subtree of stem from the thread list |
1360 while (stem != u_out) { |
1340 w = _rev_thread[stem]; |
1361 // Insert the next stem node into the thread list |
1341 _thread[w] = right; |
1362 next_stem = _parent[stem]; |
1342 _rev_thread[right] = w; |
1363 _thread[last] = next_stem; |
1343 |
1364 _dirty_revs.push_back(last); |
1344 // Change the parent node and shift stem nodes |
1365 |
1345 _parent[stem] = par_stem; |
1366 // Remove the subtree of stem from the thread list |
1346 par_stem = stem; |
1367 before = _rev_thread[stem]; |
1347 stem = new_stem; |
1368 _thread[before] = after; |
1348 |
1369 _rev_thread[after] = before; |
1349 // Update u and right |
1370 |
1350 u = _last_succ[stem] == _last_succ[par_stem] ? |
1371 // Change the parent node and shift stem nodes |
1351 _rev_thread[par_stem] : _last_succ[stem]; |
1372 _parent[stem] = par_stem; |
1352 right = _thread[u]; |
1373 par_stem = stem; |
1353 } |
1374 stem = next_stem; |
1354 _parent[u_out] = par_stem; |
1375 |
1355 _thread[u] = last; |
1376 // Update last and after |
1356 _rev_thread[last] = u; |
1377 last = _last_succ[stem] == _last_succ[par_stem] ? |
1357 _last_succ[u_out] = u; |
1378 _rev_thread[par_stem] : _last_succ[stem]; |
1358 |
1379 after = _thread[last]; |
1359 // Remove the subtree of u_out from the thread list except for |
1380 } |
1360 // the case when old_rev_thread equals to v_in |
1381 _parent[u_out] = par_stem; |
1361 // (it also means that join and v_out coincide) |
1382 _thread[last] = thread_continue; |
1362 if (old_rev_thread != v_in) { |
1383 _rev_thread[thread_continue] = last; |
1363 _thread[old_rev_thread] = right; |
1384 _last_succ[u_out] = last; |
1364 _rev_thread[right] = old_rev_thread; |
1385 |
1365 } |
1386 // Remove the subtree of u_out from the thread list except for |
1366 |
1387 // the case when old_rev_thread equals to v_in |
1367 // Update _rev_thread using the new _thread values |
1388 if (old_rev_thread != v_in) { |
1368 for (int i = 0; i != int(_dirty_revs.size()); ++i) { |
1389 _thread[old_rev_thread] = after; |
1369 u = _dirty_revs[i]; |
1390 _rev_thread[after] = old_rev_thread; |
1370 _rev_thread[_thread[u]] = u; |
1391 } |
1371 } |
1392 |
1372 |
1393 // Update _rev_thread using the new _thread values |
1373 // Update _pred, _forward, _last_succ and _succ_num for the |
1394 for (int i = 0; i != int(_dirty_revs.size()); ++i) { |
1374 // stem nodes from u_out to u_in |
1395 int u = _dirty_revs[i]; |
1375 int tmp_sc = 0, tmp_ls = _last_succ[u_out]; |
1396 _rev_thread[_thread[u]] = u; |
1376 u = u_out; |
1397 } |
1377 while (u != u_in) { |
1398 |
1378 w = _parent[u]; |
1399 // Update _pred, _pred_dir, _last_succ and _succ_num for the |
1379 _pred[u] = _pred[w]; |
1400 // stem nodes from u_out to u_in |
1380 _forward[u] = !_forward[w]; |
1401 int tmp_sc = 0, tmp_ls = _last_succ[u_out]; |
1381 tmp_sc += _succ_num[u] - _succ_num[w]; |
1402 for (int u = u_out, p = _parent[u]; u != u_in; u = p, p = _parent[u]) { |
1382 _succ_num[u] = tmp_sc; |
1403 _pred[u] = _pred[p]; |
1383 _last_succ[w] = tmp_ls; |
1404 _pred_dir[u] = -_pred_dir[p]; |
1384 u = w; |
1405 tmp_sc += _succ_num[u] - _succ_num[p]; |
1385 } |
1406 _succ_num[u] = tmp_sc; |
1386 _pred[u_in] = in_arc; |
1407 _last_succ[p] = tmp_ls; |
1387 _forward[u_in] = (u_in == _source[in_arc]); |
1408 } |
1388 _succ_num[u_in] = old_succ_num; |
1409 _pred[u_in] = in_arc; |
1389 |
1410 _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN; |
1390 // Set limits for updating _last_succ form v_in and v_out |
1411 _succ_num[u_in] = old_succ_num; |
1391 // towards the root |
|
1392 int up_limit_in = -1; |
|
1393 int up_limit_out = -1; |
|
1394 if (_last_succ[join] == v_in) { |
|
1395 up_limit_out = join; |
|
1396 } else { |
|
1397 up_limit_in = join; |
|
1398 } |
1412 } |
1399 |
1413 |
1400 // Update _last_succ from v_in towards the root |
1414 // Update _last_succ from v_in towards the root |
1401 for (u = v_in; u != up_limit_in && _last_succ[u] == v_in; |
1415 int up_limit_out = _last_succ[join] == v_in ? join : -1; |
1402 u = _parent[u]) { |
1416 int last_succ_out = _last_succ[u_out]; |
1403 _last_succ[u] = _last_succ[u_out]; |
1417 for (int u = v_in; u != -1 && _last_succ[u] == v_in; u = _parent[u]) { |
1404 } |
1418 _last_succ[u] = last_succ_out; |
1419 } |
|
1420 |
|
1405 // Update _last_succ from v_out towards the root |
1421 // Update _last_succ from v_out towards the root |
1406 if (join != old_rev_thread && v_in != old_rev_thread) { |
1422 if (join != old_rev_thread && v_in != old_rev_thread) { |
1407 for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ; |
1423 for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ; |
1408 u = _parent[u]) { |
1424 u = _parent[u]) { |
1409 _last_succ[u] = old_rev_thread; |
1425 _last_succ[u] = old_rev_thread; |
1410 } |
1426 } |
1411 } else { |
1427 } |
1412 for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ; |
1428 else if (last_succ_out != old_last_succ) { |
1429 for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ; |
|
1413 u = _parent[u]) { |
1430 u = _parent[u]) { |
1414 _last_succ[u] = _last_succ[u_out]; |
1431 _last_succ[u] = last_succ_out; |
1415 } |
1432 } |
1416 } |
1433 } |
1417 |
1434 |
1418 // Update _succ_num from v_in to join |
1435 // Update _succ_num from v_in to join |
1419 for (u = v_in; u != join; u = _parent[u]) { |
1436 for (int u = v_in; u != join; u = _parent[u]) { |
1420 _succ_num[u] += old_succ_num; |
1437 _succ_num[u] += old_succ_num; |
1421 } |
1438 } |
1422 // Update _succ_num from v_out to join |
1439 // Update _succ_num from v_out to join |
1423 for (u = v_out; u != join; u = _parent[u]) { |
1440 for (int u = v_out; u != join; u = _parent[u]) { |
1424 _succ_num[u] -= old_succ_num; |
1441 _succ_num[u] -= old_succ_num; |
1425 } |
1442 } |
1426 } |
1443 } |
1427 |
1444 |
1428 // Update potentials |
1445 // Update potentials in the subtree that has been moved |
1429 void updatePotential() { |
1446 void updatePotential() { |
1430 Cost sigma = _forward[u_in] ? |
1447 Cost sigma = _pi[v_in] - _pi[u_in] - |
1431 _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] : |
1448 _pred_dir[u_in] * _cost[in_arc]; |
1432 _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]]; |
|
1433 // Update potentials in the subtree, which has been moved |
|
1434 int end = _thread[_last_succ[u_in]]; |
1449 int end = _thread[_last_succ[u_in]]; |
1435 for (int u = u_in; u != end; u = _thread[u]) { |
1450 for (int u = u_in; u != end; u = _thread[u]) { |
1436 _pi[u] += sigma; |
1451 _pi[u] += sigma; |
1437 } |
1452 } |
1438 } |
1453 } |