70 typename CapacityMap = typename Graph::template EdgeMap<int>, |
68 typename CapacityMap = typename Graph::template EdgeMap<int>, |
71 typename CostMap = typename Graph::template EdgeMap<int>, |
69 typename CostMap = typename Graph::template EdgeMap<int>, |
72 typename SupplyMap = typename Graph::template NodeMap<int> > |
70 typename SupplyMap = typename Graph::template NodeMap<int> > |
73 class NetworkSimplex |
71 class NetworkSimplex |
74 { |
72 { |
|
73 GRAPH_TYPEDEFS(typename Graph); |
|
74 |
75 typedef typename CapacityMap::Value Capacity; |
75 typedef typename CapacityMap::Value Capacity; |
76 typedef typename CostMap::Value Cost; |
76 typedef typename CostMap::Value Cost; |
77 typedef typename SupplyMap::Value Supply; |
77 typedef typename SupplyMap::Value Supply; |
78 |
78 |
79 typedef SmartGraph SGraph; |
|
80 GRAPH_TYPEDEFS(typename SGraph); |
|
81 |
|
82 typedef typename SGraph::template EdgeMap<Capacity> SCapacityMap; |
|
83 typedef typename SGraph::template EdgeMap<Cost> SCostMap; |
|
84 typedef typename SGraph::template NodeMap<Supply> SSupplyMap; |
|
85 typedef typename SGraph::template NodeMap<Cost> SPotentialMap; |
|
86 |
|
87 typedef typename SGraph::template NodeMap<int> IntNodeMap; |
|
88 typedef typename SGraph::template NodeMap<bool> BoolNodeMap; |
|
89 typedef typename SGraph::template NodeMap<Node> NodeNodeMap; |
|
90 typedef typename SGraph::template NodeMap<Edge> EdgeNodeMap; |
|
91 typedef typename SGraph::template EdgeMap<int> IntEdgeMap; |
|
92 typedef typename SGraph::template EdgeMap<bool> BoolEdgeMap; |
|
93 |
|
94 typedef typename Graph::template NodeMap<Node> NodeRefMap; |
|
95 typedef typename Graph::template EdgeMap<Edge> EdgeRefMap; |
|
96 |
|
97 typedef std::vector<Edge> EdgeVector; |
79 typedef std::vector<Edge> EdgeVector; |
|
80 typedef std::vector<Node> NodeVector; |
|
81 typedef std::vector<int> IntVector; |
|
82 typedef std::vector<bool> BoolVector; |
|
83 typedef std::vector<Capacity> CapacityVector; |
|
84 typedef std::vector<Cost> CostVector; |
|
85 typedef std::vector<Supply> SupplyVector; |
|
86 |
|
87 typedef typename Graph::template NodeMap<int> IntNodeMap; |
98 |
88 |
99 public: |
89 public: |
100 |
90 |
101 /// The type of the flow map. |
91 /// The type of the flow map. |
102 typedef typename Graph::template EdgeMap<Capacity> FlowMap; |
92 typedef typename Graph::template EdgeMap<Capacity> FlowMap; |
155 class FirstEligiblePivotRule |
116 class FirstEligiblePivotRule |
156 { |
117 { |
157 private: |
118 private: |
158 |
119 |
159 // References to the NetworkSimplex class |
120 // References to the NetworkSimplex class |
160 NetworkSimplex &_ns; |
121 const EdgeVector &_edge; |
161 EdgeVector &_edges; |
122 const IntVector &_source; |
162 |
123 const IntVector &_target; |
|
124 const CostVector &_cost; |
|
125 const IntVector &_state; |
|
126 const CostVector &_pi; |
|
127 int &_in_edge; |
|
128 int _edge_num; |
|
129 |
|
130 // Pivot rule data |
163 int _next_edge; |
131 int _next_edge; |
164 |
132 |
165 public: |
133 public: |
166 |
134 |
167 /// Constructor |
135 /// Constructor |
168 FirstEligiblePivotRule(NetworkSimplex &ns, EdgeVector &edges) : |
136 FirstEligiblePivotRule(NetworkSimplex &ns) : |
169 _ns(ns), _edges(edges), _next_edge(0) {} |
137 _edge(ns._edge), _source(ns._source), _target(ns._target), |
|
138 _cost(ns._cost), _state(ns._state), _pi(ns._pi), |
|
139 _in_edge(ns._in_edge), _edge_num(ns._edge_num), _next_edge(0) |
|
140 {} |
170 |
141 |
171 /// Find next entering edge |
142 /// Find next entering edge |
172 bool findEnteringEdge() { |
143 bool findEnteringEdge() { |
173 Edge e; |
144 Cost c; |
174 for (int i = _next_edge; i < int(_edges.size()); ++i) { |
145 for (int e = _next_edge; e < _edge_num; ++e) { |
175 e = _edges[i]; |
146 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
176 if (_ns._state[e] * _ns._red_cost[e] < 0) { |
147 if (c < 0) { |
177 _ns._in_edge = e; |
148 _in_edge = e; |
178 _next_edge = i + 1; |
149 _next_edge = e + 1; |
179 return true; |
150 return true; |
180 } |
151 } |
181 } |
152 } |
182 for (int i = 0; i < _next_edge; ++i) { |
153 for (int e = 0; e < _next_edge; ++e) { |
183 e = _edges[i]; |
154 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
184 if (_ns._state[e] * _ns._red_cost[e] < 0) { |
155 if (c < 0) { |
185 _ns._in_edge = e; |
156 _in_edge = e; |
186 _next_edge = i + 1; |
157 _next_edge = e + 1; |
187 return true; |
158 return true; |
188 } |
159 } |
189 } |
160 } |
190 return false; |
161 return false; |
191 } |
162 } |
|
163 |
192 }; //class FirstEligiblePivotRule |
164 }; //class FirstEligiblePivotRule |
|
165 |
193 |
166 |
194 /// \brief Implementation of the "Best Eligible" pivot rule for the |
167 /// \brief Implementation of the "Best Eligible" pivot rule for the |
195 /// \ref NetworkSimplex "network simplex" algorithm. |
168 /// \ref NetworkSimplex "network simplex" algorithm. |
196 /// |
169 /// |
197 /// This class implements the "Best Eligible" pivot rule |
170 /// This class implements the "Best Eligible" pivot rule |
237 class BlockSearchPivotRule |
220 class BlockSearchPivotRule |
238 { |
221 { |
239 private: |
222 private: |
240 |
223 |
241 // References to the NetworkSimplex class |
224 // References to the NetworkSimplex class |
242 NetworkSimplex &_ns; |
225 const EdgeVector &_edge; |
243 EdgeVector &_edges; |
226 const IntVector &_source; |
244 |
227 const IntVector &_target; |
|
228 const CostVector &_cost; |
|
229 const IntVector &_state; |
|
230 const CostVector &_pi; |
|
231 int &_in_edge; |
|
232 int _edge_num; |
|
233 |
|
234 // Pivot rule data |
245 int _block_size; |
235 int _block_size; |
246 int _next_edge, _min_edge; |
236 int _next_edge; |
247 |
237 |
248 public: |
238 public: |
249 |
239 |
250 /// Constructor |
240 /// Constructor |
251 BlockSearchPivotRule(NetworkSimplex &ns, EdgeVector &edges) : |
241 BlockSearchPivotRule(NetworkSimplex &ns) : |
252 _ns(ns), _edges(edges), _next_edge(0), _min_edge(0) |
242 _edge(ns._edge), _source(ns._source), _target(ns._target), |
|
243 _cost(ns._cost), _state(ns._state), _pi(ns._pi), |
|
244 _in_edge(ns._in_edge), _edge_num(ns._edge_num), _next_edge(0) |
253 { |
245 { |
254 // The main parameters of the pivot rule |
246 // The main parameters of the pivot rule |
255 const double BLOCK_SIZE_FACTOR = 2.0; |
247 const double BLOCK_SIZE_FACTOR = 2.0; |
256 const int MIN_BLOCK_SIZE = 10; |
248 const int MIN_BLOCK_SIZE = 10; |
257 |
249 |
258 _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_edges.size())), |
250 _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_edge_num)), |
259 MIN_BLOCK_SIZE ); |
251 MIN_BLOCK_SIZE ); |
260 } |
252 } |
261 |
253 |
262 /// Find next entering edge |
254 /// Find next entering edge |
263 bool findEnteringEdge() { |
255 bool findEnteringEdge() { |
264 Cost curr, min = 0; |
256 Cost c, min = 0; |
265 Edge e; |
|
266 int cnt = _block_size; |
257 int cnt = _block_size; |
267 int i; |
258 int e, min_edge = _next_edge; |
268 for (i = _next_edge; i < int(_edges.size()); ++i) { |
259 for (e = _next_edge; e < _edge_num; ++e) { |
269 e = _edges[i]; |
260 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
270 if ((curr = _ns._state[e] * _ns._red_cost[e]) < min) { |
261 if (c < min) { |
271 min = curr; |
262 min = c; |
272 _min_edge = i; |
263 min_edge = e; |
273 } |
264 } |
274 if (--cnt == 0) { |
265 if (--cnt == 0) { |
275 if (min < 0) break; |
266 if (min < 0) break; |
276 cnt = _block_size; |
267 cnt = _block_size; |
277 } |
268 } |
278 } |
269 } |
279 if (min == 0 || cnt > 0) { |
270 if (min == 0 || cnt > 0) { |
280 for (i = 0; i < _next_edge; ++i) { |
271 for (e = 0; e < _next_edge; ++e) { |
281 e = _edges[i]; |
272 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
282 if ((curr = _ns._state[e] * _ns._red_cost[e]) < min) { |
273 if (c < min) { |
283 min = curr; |
274 min = c; |
284 _min_edge = i; |
275 min_edge = e; |
285 } |
276 } |
286 if (--cnt == 0) { |
277 if (--cnt == 0) { |
287 if (min < 0) break; |
278 if (min < 0) break; |
288 cnt = _block_size; |
279 cnt = _block_size; |
289 } |
280 } |
290 } |
281 } |
291 } |
282 } |
292 if (min >= 0) return false; |
283 if (min >= 0) return false; |
293 _ns._in_edge = _edges[_min_edge]; |
284 _in_edge = min_edge; |
294 _next_edge = i; |
285 _next_edge = e; |
295 return true; |
286 return true; |
296 } |
287 } |
|
288 |
297 }; //class BlockSearchPivotRule |
289 }; //class BlockSearchPivotRule |
|
290 |
298 |
291 |
299 /// \brief Implementation of the "Candidate List" pivot rule for the |
292 /// \brief Implementation of the "Candidate List" pivot rule for the |
300 /// \ref NetworkSimplex "network simplex" algorithm. |
293 /// \ref NetworkSimplex "network simplex" algorithm. |
301 /// |
294 /// |
302 /// This class implements the "Candidate List" pivot rule |
295 /// This class implements the "Candidate List" pivot rule |
306 class CandidateListPivotRule |
299 class CandidateListPivotRule |
307 { |
300 { |
308 private: |
301 private: |
309 |
302 |
310 // References to the NetworkSimplex class |
303 // References to the NetworkSimplex class |
311 NetworkSimplex &_ns; |
304 const EdgeVector &_edge; |
312 EdgeVector &_edges; |
305 const IntVector &_source; |
313 |
306 const IntVector &_target; |
314 EdgeVector _candidates; |
307 const CostVector &_cost; |
|
308 const IntVector &_state; |
|
309 const CostVector &_pi; |
|
310 int &_in_edge; |
|
311 int _edge_num; |
|
312 |
|
313 // Pivot rule data |
|
314 IntVector _candidates; |
315 int _list_length, _minor_limit; |
315 int _list_length, _minor_limit; |
316 int _curr_length, _minor_count; |
316 int _curr_length, _minor_count; |
317 int _next_edge, _min_edge; |
317 int _next_edge; |
318 |
318 |
319 public: |
319 public: |
320 |
320 |
321 /// Constructor |
321 /// Constructor |
322 CandidateListPivotRule(NetworkSimplex &ns, EdgeVector &edges) : |
322 CandidateListPivotRule(NetworkSimplex &ns) : |
323 _ns(ns), _edges(edges), _next_edge(0), _min_edge(0) |
323 _edge(ns._edge), _source(ns._source), _target(ns._target), |
|
324 _cost(ns._cost), _state(ns._state), _pi(ns._pi), |
|
325 _in_edge(ns._in_edge), _edge_num(ns._edge_num), _next_edge(0) |
324 { |
326 { |
325 // The main parameters of the pivot rule |
327 // The main parameters of the pivot rule |
326 const double LIST_LENGTH_FACTOR = 1.0; |
328 const double LIST_LENGTH_FACTOR = 1.0; |
327 const int MIN_LIST_LENGTH = 10; |
329 const int MIN_LIST_LENGTH = 10; |
328 const double MINOR_LIMIT_FACTOR = 0.1; |
330 const double MINOR_LIMIT_FACTOR = 0.1; |
329 const int MIN_MINOR_LIMIT = 3; |
331 const int MIN_MINOR_LIMIT = 3; |
330 |
332 |
331 _list_length = std::max( int(LIST_LENGTH_FACTOR * sqrt(_edges.size())), |
333 _list_length = std::max( int(LIST_LENGTH_FACTOR * sqrt(_edge_num)), |
332 MIN_LIST_LENGTH ); |
334 MIN_LIST_LENGTH ); |
333 _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length), |
335 _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length), |
334 MIN_MINOR_LIMIT ); |
336 MIN_MINOR_LIMIT ); |
335 _curr_length = _minor_count = 0; |
337 _curr_length = _minor_count = 0; |
336 _candidates.resize(_list_length); |
338 _candidates.resize(_list_length); |
337 } |
339 } |
338 |
340 |
339 /// Find next entering edge |
341 /// Find next entering edge |
340 bool findEnteringEdge() { |
342 bool findEnteringEdge() { |
341 Cost min, curr; |
343 Cost min, c; |
|
344 int e, min_edge = _next_edge; |
342 if (_curr_length > 0 && _minor_count < _minor_limit) { |
345 if (_curr_length > 0 && _minor_count < _minor_limit) { |
343 // Minor iteration: select the best eligible edge from the |
346 // Minor iteration: select the best eligible edge from the |
344 // current candidate list |
347 // current candidate list |
345 ++_minor_count; |
348 ++_minor_count; |
346 Edge e; |
|
347 min = 0; |
349 min = 0; |
348 for (int i = 0; i < _curr_length; ++i) { |
350 for (int i = 0; i < _curr_length; ++i) { |
349 e = _candidates[i]; |
351 e = _candidates[i]; |
350 curr = _ns._state[e] * _ns._red_cost[e]; |
352 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
351 if (curr < min) { |
353 if (c < min) { |
352 min = curr; |
354 min = c; |
353 _ns._in_edge = e; |
355 min_edge = e; |
354 } |
356 } |
355 if (curr >= 0) { |
357 if (c >= 0) { |
356 _candidates[i--] = _candidates[--_curr_length]; |
358 _candidates[i--] = _candidates[--_curr_length]; |
357 } |
359 } |
358 } |
360 } |
359 if (min < 0) return true; |
361 if (min < 0) { |
|
362 _in_edge = min_edge; |
|
363 return true; |
|
364 } |
360 } |
365 } |
361 |
366 |
362 // Major iteration: build a new candidate list |
367 // Major iteration: build a new candidate list |
363 Edge e; |
|
364 min = 0; |
368 min = 0; |
365 _curr_length = 0; |
369 _curr_length = 0; |
366 int i; |
370 for (e = _next_edge; e < _edge_num; ++e) { |
367 for (i = _next_edge; i < int(_edges.size()); ++i) { |
371 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
368 e = _edges[i]; |
372 if (c < 0) { |
369 if ((curr = _ns._state[e] * _ns._red_cost[e]) < 0) { |
|
370 _candidates[_curr_length++] = e; |
373 _candidates[_curr_length++] = e; |
371 if (curr < min) { |
374 if (c < min) { |
372 min = curr; |
375 min = c; |
373 _min_edge = i; |
376 min_edge = e; |
374 } |
377 } |
375 if (_curr_length == _list_length) break; |
378 if (_curr_length == _list_length) break; |
376 } |
379 } |
377 } |
380 } |
378 if (_curr_length < _list_length) { |
381 if (_curr_length < _list_length) { |
379 for (i = 0; i < _next_edge; ++i) { |
382 for (e = 0; e < _next_edge; ++e) { |
380 e = _edges[i]; |
383 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
381 if ((curr = _ns._state[e] * _ns._red_cost[e]) < 0) { |
384 if (c < 0) { |
382 _candidates[_curr_length++] = e; |
385 _candidates[_curr_length++] = e; |
383 if (curr < min) { |
386 if (c < min) { |
384 min = curr; |
387 min = c; |
385 _min_edge = i; |
388 min_edge = e; |
386 } |
389 } |
387 if (_curr_length == _list_length) break; |
390 if (_curr_length == _list_length) break; |
388 } |
391 } |
389 } |
392 } |
390 } |
393 } |
391 if (_curr_length == 0) return false; |
394 if (_curr_length == 0) return false; |
392 _minor_count = 1; |
395 _minor_count = 1; |
393 _ns._in_edge = _edges[_min_edge]; |
396 _in_edge = min_edge; |
394 _next_edge = i; |
397 _next_edge = e; |
395 return true; |
398 return true; |
396 } |
399 } |
|
400 |
397 }; //class CandidateListPivotRule |
401 }; //class CandidateListPivotRule |
|
402 |
398 |
403 |
399 /// \brief Implementation of the "Altering Candidate List" pivot rule |
404 /// \brief Implementation of the "Altering Candidate List" pivot rule |
400 /// for the \ref NetworkSimplex "network simplex" algorithm. |
405 /// for the \ref NetworkSimplex "network simplex" algorithm. |
401 /// |
406 /// |
402 /// This class implements the "Altering Candidate List" pivot rule |
407 /// This class implements the "Altering Candidate List" pivot rule |
406 class AlteringListPivotRule |
411 class AlteringListPivotRule |
407 { |
412 { |
408 private: |
413 private: |
409 |
414 |
410 // References to the NetworkSimplex class |
415 // References to the NetworkSimplex class |
411 NetworkSimplex &_ns; |
416 const EdgeVector &_edge; |
412 EdgeVector &_edges; |
417 const IntVector &_source; |
413 |
418 const IntVector &_target; |
414 EdgeVector _candidates; |
419 const CostVector &_cost; |
415 SCostMap _cand_cost; |
420 const IntVector &_state; |
|
421 const CostVector &_pi; |
|
422 int &_in_edge; |
|
423 int _edge_num; |
|
424 |
416 int _block_size, _head_length, _curr_length; |
425 int _block_size, _head_length, _curr_length; |
417 int _next_edge; |
426 int _next_edge; |
|
427 IntVector _candidates; |
|
428 CostVector _cand_cost; |
418 |
429 |
419 // Functor class to compare edges during sort of the candidate list |
430 // Functor class to compare edges during sort of the candidate list |
420 class SortFunc |
431 class SortFunc |
421 { |
432 { |
422 private: |
433 private: |
423 const SCostMap &_map; |
434 const CostVector &_map; |
424 public: |
435 public: |
425 SortFunc(const SCostMap &map) : _map(map) {} |
436 SortFunc(const CostVector &map) : _map(map) {} |
426 bool operator()(const Edge &e1, const Edge &e2) { |
437 bool operator()(int left, int right) { |
427 return _map[e1] > _map[e2]; |
438 return _map[left] > _map[right]; |
428 } |
439 } |
429 }; |
440 }; |
430 |
441 |
431 SortFunc _sort_func; |
442 SortFunc _sort_func; |
432 |
443 |
433 public: |
444 public: |
434 |
445 |
435 /// Constructor |
446 /// Constructor |
436 AlteringListPivotRule(NetworkSimplex &ns, EdgeVector &edges) : |
447 AlteringListPivotRule(NetworkSimplex &ns) : |
437 _ns(ns), _edges(edges), _cand_cost(_ns._graph), |
448 _edge(ns._edge), _source(ns._source), _target(ns._target), |
438 _next_edge(0), _sort_func(_cand_cost) |
449 _cost(ns._cost), _state(ns._state), _pi(ns._pi), |
|
450 _in_edge(ns._in_edge), _edge_num(ns._edge_num), |
|
451 _next_edge(0), _cand_cost(ns._edge_num),_sort_func(_cand_cost) |
439 { |
452 { |
440 // The main parameters of the pivot rule |
453 // The main parameters of the pivot rule |
441 const double BLOCK_SIZE_FACTOR = 1.5; |
454 const double BLOCK_SIZE_FACTOR = 1.5; |
442 const int MIN_BLOCK_SIZE = 10; |
455 const int MIN_BLOCK_SIZE = 10; |
443 const double HEAD_LENGTH_FACTOR = 0.1; |
456 const double HEAD_LENGTH_FACTOR = 0.1; |
444 const int MIN_HEAD_LENGTH = 3; |
457 const int MIN_HEAD_LENGTH = 3; |
445 |
458 |
446 _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_edges.size())), |
459 _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_edge_num)), |
447 MIN_BLOCK_SIZE ); |
460 MIN_BLOCK_SIZE ); |
448 _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size), |
461 _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size), |
449 MIN_HEAD_LENGTH ); |
462 MIN_HEAD_LENGTH ); |
450 _candidates.resize(_head_length + _block_size); |
463 _candidates.resize(_head_length + _block_size); |
451 _curr_length = 0; |
464 _curr_length = 0; |
452 } |
465 } |
453 |
466 |
454 /// Find next entering edge |
467 /// Find next entering edge |
455 bool findEnteringEdge() { |
468 bool findEnteringEdge() { |
456 // Check the current candidate list |
469 // Check the current candidate list |
457 Edge e; |
470 int e; |
458 for (int ix = 0; ix < _curr_length; ++ix) { |
471 for (int i = 0; i < _curr_length; ++i) { |
459 e = _candidates[ix]; |
472 e = _candidates[i]; |
460 if ((_cand_cost[e] = _ns._state[e] * _ns._red_cost[e]) >= 0) { |
473 _cand_cost[e] = _state[e] * |
461 _candidates[ix--] = _candidates[--_curr_length]; |
474 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
|
475 if (_cand_cost[e] >= 0) { |
|
476 _candidates[i--] = _candidates[--_curr_length]; |
462 } |
477 } |
463 } |
478 } |
464 |
479 |
465 // Extend the list |
480 // Extend the list |
466 int cnt = _block_size; |
481 int cnt = _block_size; |
467 int last_edge = 0; |
482 int last_edge = 0; |
468 int limit = _head_length; |
483 int limit = _head_length; |
469 for (int i = _next_edge; i < int(_edges.size()); ++i) { |
484 |
470 e = _edges[i]; |
485 for (int e = _next_edge; e < _edge_num; ++e) { |
471 if ((_cand_cost[e] = _ns._state[e] * _ns._red_cost[e]) < 0) { |
486 _cand_cost[e] = _state[e] * |
|
487 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
|
488 if (_cand_cost[e] < 0) { |
472 _candidates[_curr_length++] = e; |
489 _candidates[_curr_length++] = e; |
473 last_edge = i; |
490 last_edge = e; |
474 } |
491 } |
475 if (--cnt == 0) { |
492 if (--cnt == 0) { |
476 if (_curr_length > limit) break; |
493 if (_curr_length > limit) break; |
477 limit = 0; |
494 limit = 0; |
478 cnt = _block_size; |
495 cnt = _block_size; |
479 } |
496 } |
480 } |
497 } |
481 if (_curr_length <= limit) { |
498 if (_curr_length <= limit) { |
482 for (int i = 0; i < _next_edge; ++i) { |
499 for (int e = 0; e < _next_edge; ++e) { |
483 e = _edges[i]; |
500 _cand_cost[e] = _state[e] * |
484 if ((_cand_cost[e] = _ns._state[e] * _ns._red_cost[e]) < 0) { |
501 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); |
|
502 if (_cand_cost[e] < 0) { |
485 _candidates[_curr_length++] = e; |
503 _candidates[_curr_length++] = e; |
486 last_edge = i; |
504 last_edge = e; |
487 } |
505 } |
488 if (--cnt == 0) { |
506 if (--cnt == 0) { |
489 if (_curr_length > limit) break; |
507 if (_curr_length > limit) break; |
490 limit = 0; |
508 limit = 0; |
491 cnt = _block_size; |
509 cnt = _block_size; |
517 STATE_LOWER = 1 |
536 STATE_LOWER = 1 |
518 }; |
537 }; |
519 |
538 |
520 private: |
539 private: |
521 |
540 |
522 // The directed graph the algorithm runs on |
|
523 SGraph _graph; |
|
524 // The original graph |
541 // The original graph |
525 const Graph &_graph_ref; |
542 const Graph &_orig_graph; |
526 // The original lower bound map |
543 // The original lower bound map |
527 const LowerMap *_lower; |
544 const LowerMap *_orig_lower; |
528 // The capacity map |
545 // The original capacity map |
529 SCapacityMap _capacity; |
546 const CapacityMap &_orig_cap; |
530 // The cost map |
547 // The original cost map |
531 SCostMap _cost; |
548 const CostMap &_orig_cost; |
532 // The supply map |
549 // The original supply map |
533 SSupplyMap _supply; |
550 const SupplyMap *_orig_supply; |
534 bool _valid_supply; |
551 // The source node (if no supply map was given) |
535 |
552 Node _orig_source; |
536 // Edge map of the current flow |
553 // The target node (if no supply map was given) |
537 SCapacityMap _flow; |
554 Node _orig_target; |
538 // Node map of the current potentials |
555 // The flow value (if no supply map was given) |
539 SPotentialMap _potential; |
556 Capacity _orig_flow_value; |
540 |
557 |
541 // The depth node map of the spanning tree structure |
558 // The flow result map |
542 IntNodeMap _depth; |
|
543 // The parent node map of the spanning tree structure |
|
544 NodeNodeMap _parent; |
|
545 // The pred_edge node map of the spanning tree structure |
|
546 EdgeNodeMap _pred_edge; |
|
547 // The thread node map of the spanning tree structure |
|
548 NodeNodeMap _thread; |
|
549 // The forward node map of the spanning tree structure |
|
550 BoolNodeMap _forward; |
|
551 // The state edge map |
|
552 IntEdgeMap _state; |
|
553 // The artificial root node of the spanning tree structure |
|
554 Node _root; |
|
555 |
|
556 // The reduced cost map |
|
557 ReducedCostMap _red_cost; |
|
558 |
|
559 // The non-artifical edges |
|
560 EdgeVector _edges; |
|
561 |
|
562 // Members for handling the original graph |
|
563 FlowMap *_flow_result; |
559 FlowMap *_flow_result; |
|
560 // The potential result map |
564 PotentialMap *_potential_result; |
561 PotentialMap *_potential_result; |
|
562 // Indicate if the flow result map is local |
565 bool _local_flow; |
563 bool _local_flow; |
|
564 // Indicate if the potential result map is local |
566 bool _local_potential; |
565 bool _local_potential; |
567 NodeRefMap _node_ref; |
566 |
568 EdgeRefMap _edge_ref; |
567 // The edge references |
|
568 EdgeVector _edge; |
|
569 // The node references |
|
570 NodeVector _node; |
|
571 // The node ids |
|
572 IntNodeMap _node_id; |
|
573 // The source nodes of the edges |
|
574 IntVector _source; |
|
575 // The target nodess of the edges |
|
576 IntVector _target; |
|
577 |
|
578 // The (modified) capacity vector |
|
579 CapacityVector _cap; |
|
580 // The cost vector |
|
581 CostVector _cost; |
|
582 // The (modified) supply vector |
|
583 CostVector _supply; |
|
584 // The current flow vector |
|
585 CapacityVector _flow; |
|
586 // The current potential vector |
|
587 CostVector _pi; |
|
588 |
|
589 // The number of nodes in the original graph |
|
590 int _node_num; |
|
591 // The number of edges in the original graph |
|
592 int _edge_num; |
|
593 |
|
594 // The depth vector of the spanning tree structure |
|
595 IntVector _depth; |
|
596 // The parent vector of the spanning tree structure |
|
597 IntVector _parent; |
|
598 // The pred_edge vector of the spanning tree structure |
|
599 IntVector _pred; |
|
600 // The thread vector of the spanning tree structure |
|
601 IntVector _thread; |
|
602 // The forward vector of the spanning tree structure |
|
603 BoolVector _forward; |
|
604 // The state vector |
|
605 IntVector _state; |
|
606 // The root node |
|
607 int _root; |
569 |
608 |
570 // The entering edge of the current pivot iteration |
609 // The entering edge of the current pivot iteration |
571 Edge _in_edge; |
610 int _in_edge; |
572 |
611 |
573 // Temporary nodes used in the current pivot iteration |
612 // Temporary nodes used in the current pivot iteration |
574 Node join, u_in, v_in, u_out, v_out; |
613 int join, u_in, v_in, u_out, v_out; |
575 Node right, first, second, last; |
614 int right, first, second, last; |
576 Node stem, par_stem, new_stem; |
615 int stem, par_stem, new_stem; |
|
616 |
577 // The maximum augment amount along the found cycle in the current |
617 // The maximum augment amount along the found cycle in the current |
578 // pivot iteration |
618 // pivot iteration |
579 Capacity delta; |
619 Capacity delta; |
580 |
620 |
581 public : |
621 public: |
582 |
622 |
583 /// \brief General constructor (with lower bounds). |
623 /// \brief General constructor (with lower bounds). |
584 /// |
624 /// |
585 /// General constructor (with lower bounds). |
625 /// General constructor (with lower bounds). |
586 /// |
626 /// |
592 NetworkSimplex( const Graph &graph, |
632 NetworkSimplex( const Graph &graph, |
593 const LowerMap &lower, |
633 const LowerMap &lower, |
594 const CapacityMap &capacity, |
634 const CapacityMap &capacity, |
595 const CostMap &cost, |
635 const CostMap &cost, |
596 const SupplyMap &supply ) : |
636 const SupplyMap &supply ) : |
597 _graph(), _graph_ref(graph), _lower(&lower), _capacity(_graph), |
637 _orig_graph(graph), _orig_lower(&lower), _orig_cap(capacity), |
598 _cost(_graph), _supply(_graph), _flow(_graph), |
638 _orig_cost(cost), _orig_supply(&supply), |
599 _potential(_graph), _depth(_graph), _parent(_graph), |
|
600 _pred_edge(_graph), _thread(_graph), _forward(_graph), |
|
601 _state(_graph), _red_cost(_graph, _cost, _potential), |
|
602 _flow_result(NULL), _potential_result(NULL), |
639 _flow_result(NULL), _potential_result(NULL), |
603 _local_flow(false), _local_potential(false), |
640 _local_flow(false), _local_potential(false), |
604 _node_ref(graph), _edge_ref(graph) |
641 _node_id(graph) |
605 { |
642 {} |
606 // Check the sum of supply values |
|
607 Supply sum = 0; |
|
608 for (typename Graph::NodeIt n(_graph_ref); n != INVALID; ++n) |
|
609 sum += supply[n]; |
|
610 if (!(_valid_supply = sum == 0)) return; |
|
611 |
|
612 // Copy _graph_ref to _graph |
|
613 _graph.reserveNode(countNodes(_graph_ref) + 1); |
|
614 _graph.reserveEdge(countEdges(_graph_ref) + countNodes(_graph_ref)); |
|
615 copyGraph(_graph, _graph_ref) |
|
616 .edgeMap(_capacity, capacity) |
|
617 .edgeMap(_cost, cost) |
|
618 .nodeMap(_supply, supply) |
|
619 .nodeRef(_node_ref) |
|
620 .edgeRef(_edge_ref) |
|
621 .run(); |
|
622 |
|
623 // Remove non-zero lower bounds |
|
624 for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e) { |
|
625 if (lower[e] != 0) { |
|
626 _capacity[_edge_ref[e]] = capacity[e] - lower[e]; |
|
627 _supply[_node_ref[_graph_ref.source(e)]] -= lower[e]; |
|
628 _supply[_node_ref[_graph_ref.target(e)]] += lower[e]; |
|
629 } |
|
630 } |
|
631 } |
|
632 |
643 |
633 /// \brief General constructor (without lower bounds). |
644 /// \brief General constructor (without lower bounds). |
634 /// |
645 /// |
635 /// General constructor (without lower bounds). |
646 /// General constructor (without lower bounds). |
636 /// |
647 /// |
640 /// \param supply The supply values of the nodes (signed). |
651 /// \param supply The supply values of the nodes (signed). |
641 NetworkSimplex( const Graph &graph, |
652 NetworkSimplex( const Graph &graph, |
642 const CapacityMap &capacity, |
653 const CapacityMap &capacity, |
643 const CostMap &cost, |
654 const CostMap &cost, |
644 const SupplyMap &supply ) : |
655 const SupplyMap &supply ) : |
645 _graph(), _graph_ref(graph), _lower(NULL), _capacity(_graph), |
656 _orig_graph(graph), _orig_lower(NULL), _orig_cap(capacity), |
646 _cost(_graph), _supply(_graph), _flow(_graph), |
657 _orig_cost(cost), _orig_supply(&supply), |
647 _potential(_graph), _depth(_graph), _parent(_graph), |
|
648 _pred_edge(_graph), _thread(_graph), _forward(_graph), |
|
649 _state(_graph), _red_cost(_graph, _cost, _potential), |
|
650 _flow_result(NULL), _potential_result(NULL), |
658 _flow_result(NULL), _potential_result(NULL), |
651 _local_flow(false), _local_potential(false), |
659 _local_flow(false), _local_potential(false), |
652 _node_ref(graph), _edge_ref(graph) |
660 _node_id(graph) |
653 { |
661 {} |
654 // Check the sum of supply values |
|
655 Supply sum = 0; |
|
656 for (typename Graph::NodeIt n(_graph_ref); n != INVALID; ++n) |
|
657 sum += supply[n]; |
|
658 if (!(_valid_supply = sum == 0)) return; |
|
659 |
|
660 // Copy _graph_ref to _graph |
|
661 _graph.reserveNode(countNodes(_graph_ref) + 1); |
|
662 _graph.reserveEdge(countEdges(_graph_ref) + countNodes(_graph_ref)); |
|
663 copyGraph(_graph, _graph_ref) |
|
664 .edgeMap(_capacity, capacity) |
|
665 .edgeMap(_cost, cost) |
|
666 .nodeMap(_supply, supply) |
|
667 .nodeRef(_node_ref) |
|
668 .edgeRef(_edge_ref) |
|
669 .run(); |
|
670 } |
|
671 |
662 |
672 /// \brief Simple constructor (with lower bounds). |
663 /// \brief Simple constructor (with lower bounds). |
673 /// |
664 /// |
674 /// Simple constructor (with lower bounds). |
665 /// Simple constructor (with lower bounds). |
675 /// |
666 /// |
683 /// to node \c t (i.e. the supply of \c s and the demand of \c t). |
674 /// to node \c t (i.e. the supply of \c s and the demand of \c t). |
684 NetworkSimplex( const Graph &graph, |
675 NetworkSimplex( const Graph &graph, |
685 const LowerMap &lower, |
676 const LowerMap &lower, |
686 const CapacityMap &capacity, |
677 const CapacityMap &capacity, |
687 const CostMap &cost, |
678 const CostMap &cost, |
688 typename Graph::Node s, |
679 Node s, Node t, |
689 typename Graph::Node t, |
680 Capacity flow_value ) : |
690 typename SupplyMap::Value flow_value ) : |
681 _orig_graph(graph), _orig_lower(&lower), _orig_cap(capacity), |
691 _graph(), _graph_ref(graph), _lower(&lower), _capacity(_graph), |
682 _orig_cost(cost), _orig_supply(NULL), |
692 _cost(_graph), _supply(_graph, 0), _flow(_graph), |
683 _orig_source(s), _orig_target(t), _orig_flow_value(flow_value), |
693 _potential(_graph), _depth(_graph), _parent(_graph), |
|
694 _pred_edge(_graph), _thread(_graph), _forward(_graph), |
|
695 _state(_graph), _red_cost(_graph, _cost, _potential), |
|
696 _flow_result(NULL), _potential_result(NULL), |
684 _flow_result(NULL), _potential_result(NULL), |
697 _local_flow(false), _local_potential(false), |
685 _local_flow(false), _local_potential(false), |
698 _node_ref(graph), _edge_ref(graph) |
686 _node_id(graph) |
699 { |
687 {} |
700 // Copy _graph_ref to graph |
|
701 _graph.reserveNode(countNodes(_graph_ref) + 1); |
|
702 _graph.reserveEdge(countEdges(_graph_ref) + countNodes(_graph_ref)); |
|
703 copyGraph(_graph, _graph_ref) |
|
704 .edgeMap(_capacity, capacity) |
|
705 .edgeMap(_cost, cost) |
|
706 .nodeRef(_node_ref) |
|
707 .edgeRef(_edge_ref) |
|
708 .run(); |
|
709 |
|
710 // Remove non-zero lower bounds |
|
711 _supply[_node_ref[s]] = flow_value; |
|
712 _supply[_node_ref[t]] = -flow_value; |
|
713 for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e) { |
|
714 if (lower[e] != 0) { |
|
715 _capacity[_edge_ref[e]] = capacity[e] - lower[e]; |
|
716 _supply[_node_ref[_graph_ref.source(e)]] -= lower[e]; |
|
717 _supply[_node_ref[_graph_ref.target(e)]] += lower[e]; |
|
718 } |
|
719 } |
|
720 _valid_supply = true; |
|
721 } |
|
722 |
688 |
723 /// \brief Simple constructor (without lower bounds). |
689 /// \brief Simple constructor (without lower bounds). |
724 /// |
690 /// |
725 /// Simple constructor (without lower bounds). |
691 /// Simple constructor (without lower bounds). |
726 /// |
692 /// |
732 /// \param flow_value The required amount of flow from node \c s |
698 /// \param flow_value The required amount of flow from node \c s |
733 /// to node \c t (i.e. the supply of \c s and the demand of \c t). |
699 /// to node \c t (i.e. the supply of \c s and the demand of \c t). |
734 NetworkSimplex( const Graph &graph, |
700 NetworkSimplex( const Graph &graph, |
735 const CapacityMap &capacity, |
701 const CapacityMap &capacity, |
736 const CostMap &cost, |
702 const CostMap &cost, |
737 typename Graph::Node s, |
703 Node s, Node t, |
738 typename Graph::Node t, |
704 Capacity flow_value ) : |
739 typename SupplyMap::Value flow_value ) : |
705 _orig_graph(graph), _orig_lower(NULL), _orig_cap(capacity), |
740 _graph(), _graph_ref(graph), _lower(NULL), _capacity(_graph), |
706 _orig_cost(cost), _orig_supply(NULL), |
741 _cost(_graph), _supply(_graph, 0), _flow(_graph), |
707 _orig_source(s), _orig_target(t), _orig_flow_value(flow_value), |
742 _potential(_graph), _depth(_graph), _parent(_graph), |
|
743 _pred_edge(_graph), _thread(_graph), _forward(_graph), |
|
744 _state(_graph), _red_cost(_graph, _cost, _potential), |
|
745 _flow_result(NULL), _potential_result(NULL), |
708 _flow_result(NULL), _potential_result(NULL), |
746 _local_flow(false), _local_potential(false), |
709 _local_flow(false), _local_potential(false), |
747 _node_ref(graph), _edge_ref(graph) |
710 _node_id(graph) |
748 { |
711 {} |
749 // Copy _graph_ref to graph |
|
750 _graph.reserveNode(countNodes(_graph_ref) + 1); |
|
751 _graph.reserveEdge(countEdges(_graph_ref) + countNodes(_graph_ref)); |
|
752 copyGraph(_graph, _graph_ref) |
|
753 .edgeMap(_capacity, capacity) |
|
754 .edgeMap(_cost, cost) |
|
755 .nodeRef(_node_ref) |
|
756 .edgeRef(_edge_ref) |
|
757 .run(); |
|
758 _supply[_node_ref[s]] = flow_value; |
|
759 _supply[_node_ref[t]] = -flow_value; |
|
760 _valid_supply = true; |
|
761 } |
|
762 |
712 |
763 /// Destructor. |
713 /// Destructor. |
764 ~NetworkSimplex() { |
714 ~NetworkSimplex() { |
765 if (_local_flow) delete _flow_result; |
715 if (_local_flow) delete _flow_result; |
766 if (_local_potential) delete _potential_result; |
716 if (_local_potential) delete _potential_result; |
892 /// function is \f$ O(e) \f$. |
842 /// function is \f$ O(e) \f$. |
893 /// |
843 /// |
894 /// \pre \ref run() must be called before using this function. |
844 /// \pre \ref run() must be called before using this function. |
895 Cost totalCost() const { |
845 Cost totalCost() const { |
896 Cost c = 0; |
846 Cost c = 0; |
897 for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e) |
847 for (EdgeIt e(_orig_graph); e != INVALID; ++e) |
898 c += (*_flow_result)[e] * _cost[_edge_ref[e]]; |
848 c += (*_flow_result)[e] * _orig_cost[e]; |
899 return c; |
849 return c; |
900 } |
850 } |
901 |
851 |
902 /// @} |
852 /// @} |
903 |
853 |
904 private: |
854 private: |
905 |
855 |
906 // Extend the underlying graph and initialize all the node and edge maps |
856 // Initialize internal data structures |
907 bool init() { |
857 bool init() { |
908 if (!_valid_supply) return false; |
|
909 |
|
910 // Initialize result maps |
858 // Initialize result maps |
911 if (!_flow_result) { |
859 if (!_flow_result) { |
912 _flow_result = new FlowMap(_graph_ref); |
860 _flow_result = new FlowMap(_orig_graph); |
913 _local_flow = true; |
861 _local_flow = true; |
914 } |
862 } |
915 if (!_potential_result) { |
863 if (!_potential_result) { |
916 _potential_result = new PotentialMap(_graph_ref); |
864 _potential_result = new PotentialMap(_orig_graph); |
917 _local_potential = true; |
865 _local_potential = true; |
918 } |
866 } |
919 |
867 |
920 // Initialize the edge vector and the edge maps |
868 // Initialize vectors |
921 _edges.reserve(countEdges(_graph)); |
869 _node_num = countNodes(_orig_graph); |
922 for (EdgeIt e(_graph); e != INVALID; ++e) { |
870 _edge_num = countEdges(_orig_graph); |
923 _edges.push_back(e); |
871 int all_node_num = _node_num + 1; |
924 _flow[e] = 0; |
872 int all_edge_num = _edge_num + _node_num; |
925 _state[e] = STATE_LOWER; |
873 |
926 } |
874 _edge.resize(_edge_num); |
927 |
875 _node.reserve(_node_num); |
928 // Add an artificial root node to the graph |
876 _source.resize(all_edge_num); |
929 _root = _graph.addNode(); |
877 _target.resize(all_edge_num); |
930 _parent[_root] = INVALID; |
878 |
931 _pred_edge[_root] = INVALID; |
879 _cap.resize(all_edge_num); |
|
880 _cost.resize(all_edge_num); |
|
881 _supply.resize(all_node_num); |
|
882 _flow.resize(all_edge_num, 0); |
|
883 _pi.resize(all_node_num, 0); |
|
884 |
|
885 _depth.resize(all_node_num); |
|
886 _parent.resize(all_node_num); |
|
887 _pred.resize(all_node_num); |
|
888 _thread.resize(all_node_num); |
|
889 _forward.resize(all_node_num); |
|
890 _state.resize(all_edge_num, STATE_LOWER); |
|
891 |
|
892 // Initialize node related data |
|
893 bool valid_supply = true; |
|
894 if (_orig_supply) { |
|
895 Supply sum = 0; |
|
896 int i = 0; |
|
897 for (NodeIt n(_orig_graph); n != INVALID; ++n, ++i) { |
|
898 _node.push_back(n); |
|
899 _node_id[n] = i; |
|
900 _supply[i] = (*_orig_supply)[n]; |
|
901 sum += _supply[i]; |
|
902 } |
|
903 valid_supply = (sum == 0); |
|
904 } else { |
|
905 int i = 0; |
|
906 for (NodeIt n(_orig_graph); n != INVALID; ++n, ++i) { |
|
907 _node.push_back(n); |
|
908 _node_id[n] = i; |
|
909 _supply[i] = 0; |
|
910 } |
|
911 _supply[_node_id[_orig_source]] = _orig_flow_value; |
|
912 _supply[_node_id[_orig_target]] = -_orig_flow_value; |
|
913 } |
|
914 if (!valid_supply) return false; |
|
915 |
|
916 // Set data for the artificial root node |
|
917 _root = _node_num; |
932 _depth[_root] = 0; |
918 _depth[_root] = 0; |
|
919 _parent[_root] = -1; |
|
920 _pred[_root] = -1; |
|
921 _thread[_root] = 0; |
933 _supply[_root] = 0; |
922 _supply[_root] = 0; |
934 _potential[_root] = 0; |
923 _pi[_root] = 0; |
935 |
924 |
936 // Add artificial edges to the graph and initialize the node maps |
925 // Store the edges in a mixed order |
937 // of the spanning tree data structure |
926 int k = std::max(int(sqrt(_edge_num)), 10); |
938 Node last = _root; |
927 int i = 0; |
939 Edge e; |
928 for (EdgeIt e(_orig_graph); e != INVALID; ++e) { |
|
929 _edge[i] = e; |
|
930 if ((i += k) >= _edge_num) i = (i % k) + 1; |
|
931 } |
|
932 |
|
933 // Initialize edge maps |
|
934 for (int i = 0; i != _edge_num; ++i) { |
|
935 Edge e = _edge[i]; |
|
936 _source[i] = _node_id[_orig_graph.source(e)]; |
|
937 _target[i] = _node_id[_orig_graph.target(e)]; |
|
938 _cost[i] = _orig_cost[e]; |
|
939 _cap[i] = _orig_cap[e]; |
|
940 } |
|
941 |
|
942 // Remove non-zero lower bounds |
|
943 if (_orig_lower) { |
|
944 for (int i = 0; i != _edge_num; ++i) { |
|
945 Capacity c = (*_orig_lower)[_edge[i]]; |
|
946 if (c != 0) { |
|
947 _cap[i] -= c; |
|
948 _supply[_source[i]] -= c; |
|
949 _supply[_target[i]] += c; |
|
950 } |
|
951 } |
|
952 } |
|
953 |
|
954 // Add artificial edges and initialize the spanning tree data structure |
940 Cost max_cost = std::numeric_limits<Cost>::max() / 4; |
955 Cost max_cost = std::numeric_limits<Cost>::max() / 4; |
941 for (NodeIt u(_graph); u != INVALID; ++u) { |
956 Capacity max_cap = std::numeric_limits<Capacity>::max(); |
942 if (u == _root) continue; |
957 for (int u = 0, e = _edge_num; u != _node_num; ++u, ++e) { |
943 _thread[last] = u; |
958 _thread[u] = u + 1; |
944 last = u; |
959 _depth[u] = 1; |
945 _parent[u] = _root; |
960 _parent[u] = _root; |
946 _depth[u] = 1; |
961 _pred[u] = e; |
947 if (_supply[u] >= 0) { |
962 if (_supply[u] >= 0) { |
948 e = _graph.addEdge(u, _root); |
|
949 _flow[e] = _supply[u]; |
963 _flow[e] = _supply[u]; |
950 _forward[u] = true; |
964 _forward[u] = true; |
951 _potential[u] = -max_cost; |
965 _pi[u] = -max_cost; |
952 } else { |
966 } else { |
953 e = _graph.addEdge(_root, u); |
|
954 _flow[e] = -_supply[u]; |
967 _flow[e] = -_supply[u]; |
955 _forward[u] = false; |
968 _forward[u] = false; |
956 _potential[u] = max_cost; |
969 _pi[u] = max_cost; |
957 } |
970 } |
958 _cost[e] = max_cost; |
971 _cost[e] = max_cost; |
959 _capacity[e] = std::numeric_limits<Capacity>::max(); |
972 _cap[e] = max_cap; |
960 _state[e] = STATE_TREE; |
973 _state[e] = STATE_TREE; |
961 _pred_edge[u] = e; |
974 } |
962 } |
|
963 _thread[last] = _root; |
|
964 |
975 |
965 return true; |
976 return true; |
966 } |
977 } |
967 |
978 |
968 // Find the join node |
979 // Find the join node |
969 void findJoinNode() { |
980 void findJoinNode() { |
970 Node u = _graph.source(_in_edge); |
981 int u = _source[_in_edge]; |
971 Node v = _graph.target(_in_edge); |
982 int v = _target[_in_edge]; |
|
983 while (_depth[u] > _depth[v]) u = _parent[u]; |
|
984 while (_depth[v] > _depth[u]) v = _parent[v]; |
972 while (u != v) { |
985 while (u != v) { |
973 if (_depth[u] == _depth[v]) { |
986 u = _parent[u]; |
974 u = _parent[u]; |
987 v = _parent[v]; |
975 v = _parent[v]; |
|
976 } |
|
977 else if (_depth[u] > _depth[v]) u = _parent[u]; |
|
978 else v = _parent[v]; |
|
979 } |
988 } |
980 join = u; |
989 join = u; |
981 } |
990 } |
982 |
991 |
983 // Find the leaving edge of the cycle and returns true if the |
992 // Find the leaving edge of the cycle and returns true if the |
984 // leaving edge is not the same as the entering edge |
993 // leaving edge is not the same as the entering edge |
985 bool findLeavingEdge() { |
994 bool findLeavingEdge() { |
986 // Initialize first and second nodes according to the direction |
995 // Initialize first and second nodes according to the direction |
987 // of the cycle |
996 // of the cycle |
988 if (_state[_in_edge] == STATE_LOWER) { |
997 if (_state[_in_edge] == STATE_LOWER) { |
989 first = _graph.source(_in_edge); |
998 first = _source[_in_edge]; |
990 second = _graph.target(_in_edge); |
999 second = _target[_in_edge]; |
991 } else { |
1000 } else { |
992 first = _graph.target(_in_edge); |
1001 first = _target[_in_edge]; |
993 second = _graph.source(_in_edge); |
1002 second = _source[_in_edge]; |
994 } |
1003 } |
995 delta = _capacity[_in_edge]; |
1004 delta = _cap[_in_edge]; |
996 bool result = false; |
1005 int result = 0; |
997 Capacity d; |
1006 Capacity d; |
998 Edge e; |
1007 int e; |
999 |
1008 |
1000 // Search the cycle along the path form the first node to the root |
1009 // Search the cycle along the path form the first node to the root |
1001 for (Node u = first; u != join; u = _parent[u]) { |
1010 for (int u = first; u != join; u = _parent[u]) { |
1002 e = _pred_edge[u]; |
1011 e = _pred[u]; |
1003 d = _forward[u] ? _flow[e] : _capacity[e] - _flow[e]; |
1012 d = _forward[u] ? _flow[e] : _cap[e] - _flow[e]; |
1004 if (d < delta) { |
1013 if (d < delta) { |
1005 delta = d; |
1014 delta = d; |
1006 u_out = u; |
1015 u_out = u; |
1007 u_in = first; |
1016 result = 1; |
1008 v_in = second; |
|
1009 result = true; |
|
1010 } |
1017 } |
1011 } |
1018 } |
1012 // Search the cycle along the path form the second node to the root |
1019 // Search the cycle along the path form the second node to the root |
1013 for (Node u = second; u != join; u = _parent[u]) { |
1020 for (int u = second; u != join; u = _parent[u]) { |
1014 e = _pred_edge[u]; |
1021 e = _pred[u]; |
1015 d = _forward[u] ? _capacity[e] - _flow[e] : _flow[e]; |
1022 d = _forward[u] ? _cap[e] - _flow[e] : _flow[e]; |
1016 if (d <= delta) { |
1023 if (d <= delta) { |
1017 delta = d; |
1024 delta = d; |
1018 u_out = u; |
1025 u_out = u; |
1019 u_in = second; |
1026 result = 2; |
1020 v_in = first; |
1027 } |
1021 result = true; |
1028 } |
1022 } |
1029 |
1023 } |
1030 if (result == 1) { |
1024 return result; |
1031 u_in = first; |
1025 } |
1032 v_in = second; |
1026 |
1033 } else { |
1027 // Change _flow and _state edge maps |
1034 u_in = second; |
1028 void changeFlows(bool change) { |
1035 v_in = first; |
|
1036 } |
|
1037 return result != 0; |
|
1038 } |
|
1039 |
|
1040 // Change _flow and _state vectors |
|
1041 void changeFlow(bool change) { |
1029 // Augment along the cycle |
1042 // Augment along the cycle |
1030 if (delta > 0) { |
1043 if (delta > 0) { |
1031 Capacity val = _state[_in_edge] * delta; |
1044 Capacity val = _state[_in_edge] * delta; |
1032 _flow[_in_edge] += val; |
1045 _flow[_in_edge] += val; |
1033 for (Node u = _graph.source(_in_edge); u != join; u = _parent[u]) { |
1046 for (int u = _source[_in_edge]; u != join; u = _parent[u]) { |
1034 _flow[_pred_edge[u]] += _forward[u] ? -val : val; |
1047 _flow[_pred[u]] += _forward[u] ? -val : val; |
1035 } |
1048 } |
1036 for (Node u = _graph.target(_in_edge); u != join; u = _parent[u]) { |
1049 for (int u = _target[_in_edge]; u != join; u = _parent[u]) { |
1037 _flow[_pred_edge[u]] += _forward[u] ? val : -val; |
1050 _flow[_pred[u]] += _forward[u] ? val : -val; |
1038 } |
1051 } |
1039 } |
1052 } |
1040 // Update the state of the entering and leaving edges |
1053 // Update the state of the entering and leaving edges |
1041 if (change) { |
1054 if (change) { |
1042 _state[_in_edge] = STATE_TREE; |
1055 _state[_in_edge] = STATE_TREE; |
1043 _state[_pred_edge[u_out]] = |
1056 _state[_pred[u_out]] = |
1044 (_flow[_pred_edge[u_out]] == 0) ? STATE_LOWER : STATE_UPPER; |
1057 (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER; |
1045 } else { |
1058 } else { |
1046 _state[_in_edge] = -_state[_in_edge]; |
1059 _state[_in_edge] = -_state[_in_edge]; |
1047 } |
1060 } |
1048 } |
1061 } |
1049 |
1062 |
1050 // Update _thread and _parent node maps |
1063 // Update _thread and _parent vectors |
1051 void updateThreadParent() { |
1064 void updateThreadParent() { |
1052 Node u; |
1065 int u; |
1053 v_out = _parent[u_out]; |
1066 v_out = _parent[u_out]; |
1054 |
1067 |
1055 // Handle the case when join and v_out coincide |
1068 // Handle the case when join and v_out coincide |
1056 bool par_first = false; |
1069 bool par_first = false; |
1057 if (join == v_out) { |
1070 if (join == v_out) { |
1150 return false; |
1163 return false; |
1151 } |
1164 } |
1152 |
1165 |
1153 template<class PivotRuleImplementation> |
1166 template<class PivotRuleImplementation> |
1154 bool start() { |
1167 bool start() { |
1155 PivotRuleImplementation pivot(*this, _edges); |
1168 PivotRuleImplementation pivot(*this); |
1156 |
1169 |
1157 // Execute the network simplex algorithm |
1170 // Execute the network simplex algorithm |
1158 while (pivot.findEnteringEdge()) { |
1171 while (pivot.findEnteringEdge()) { |
1159 findJoinNode(); |
1172 findJoinNode(); |
1160 bool change = findLeavingEdge(); |
1173 bool change = findLeavingEdge(); |
1161 changeFlows(change); |
1174 changeFlow(change); |
1162 if (change) { |
1175 if (change) { |
1163 updateThreadParent(); |
1176 updateThreadParent(); |
1164 updatePredEdge(); |
1177 updatePredEdge(); |
1165 updateDepthPotential(); |
1178 updateDepthPotential(); |
1166 } |
1179 } |
1167 } |
1180 } |
1168 |
1181 |
1169 // Check if the flow amount equals zero on all the artificial edges |
1182 // Check if the flow amount equals zero on all the artificial edges |
1170 for (InEdgeIt e(_graph, _root); e != INVALID; ++e) |
1183 for (int e = _edge_num; e != _edge_num + _node_num; ++e) { |
1171 if (_flow[e] > 0) return false; |
1184 if (_flow[e] > 0) return false; |
1172 for (OutEdgeIt e(_graph, _root); e != INVALID; ++e) |
1185 } |
1173 if (_flow[e] > 0) return false; |
|
1174 |
1186 |
1175 // Copy flow values to _flow_result |
1187 // Copy flow values to _flow_result |
1176 if (_lower) { |
1188 if (_orig_lower) { |
1177 for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e) |
1189 for (int i = 0; i != _edge_num; ++i) { |
1178 (*_flow_result)[e] = (*_lower)[e] + _flow[_edge_ref[e]]; |
1190 Edge e = _edge[i]; |
|
1191 (*_flow_result)[e] = (*_orig_lower)[e] + _flow[i]; |
|
1192 } |
1179 } else { |
1193 } else { |
1180 for (typename Graph::EdgeIt e(_graph_ref); e != INVALID; ++e) |
1194 for (int i = 0; i != _edge_num; ++i) { |
1181 (*_flow_result)[e] = _flow[_edge_ref[e]]; |
1195 (*_flow_result)[_edge[i]] = _flow[i]; |
|
1196 } |
1182 } |
1197 } |
1183 // Copy potential values to _potential_result |
1198 // Copy potential values to _potential_result |
1184 for (typename Graph::NodeIt n(_graph_ref); n != INVALID; ++n) |
1199 for (int i = 0; i != _node_num; ++i) { |
1185 (*_potential_result)[n] = _potential[_node_ref[n]]; |
1200 (*_potential_result)[_node[i]] = _pi[i]; |
|
1201 } |
1186 |
1202 |
1187 return true; |
1203 return true; |
1188 } |
1204 } |
1189 |
1205 |
1190 }; //class NetworkSimplex |
1206 }; //class NetworkSimplex |