4 #include "../core/math_func.hpp"
8 #include "../safeguards.h"
10 typedef std::map<NodeID, Path *> PathViaMap;
92 i(NULL, NULL, INVALID_NODE),
end(NULL, NULL, INVALID_NODE)
102 this->
i = this->
job[node].Begin();
103 this->
end = this->
job[node].End();
112 return this->
i != this->
end ? (this->
i++)->first : INVALID_NODE;
127 FlowStat::SharesMap::const_iterator
it;
130 FlowStat::SharesMap::const_iterator
end;
139 for (NodeID i = 0; i < job.
Size(); ++i) {
152 FlowStatMap::const_iterator
it = flows.find(this->
job[source].
Station());
153 if (it != flows.end()) {
154 this->it = it->second.GetShares()->begin();
155 this->
end = it->second.GetShares()->end();
168 if (this->
it == this->
end)
return INVALID_NODE;
183 int free_cap, uint dist)
const
189 }
else if (this->
distance == UINT_MAX) {
217 int free_cap, uint dist)
const
221 if (min_cap == this_cap) {
226 return min_cap > this_cap;
239 template<
class Tannotation,
class Tedge_iterator>
242 typedef std::set<Tannotation *, typename Tannotation::Comparator> AnnoSet;
243 Tedge_iterator iter(this->
job);
246 paths.resize(size, NULL);
247 for (NodeID node = 0; node < size; ++node) {
248 Tannotation *anno =
new Tannotation(node, node == source_node);
252 while (!annos.empty()) {
253 typename AnnoSet::iterator i = annos.begin();
254 Tannotation *source = *i;
256 NodeID from = source->GetNode();
257 iter.SetNode(source_node, from);
258 for (NodeID to = iter.Next(); to != INVALID_NODE; to = iter.Next()) {
259 if (to == from)
continue;
260 Edge edge = this->
job[from][to];
265 if (capacity == 0) capacity = 1;
269 Tannotation *dest =
static_cast<Tannotation *
>(paths[to]);
270 if (dest->IsBetter(source, capacity, capacity - edge.Flow(), distance)) {
272 dest->Fork(source, capacity, capacity - edge.Flow(), distance);
286 Path *source = paths[source_id];
287 paths[source_id] = NULL;
288 for (PathVector::iterator i = paths.begin(); i != paths.end(); ++i) {
290 if (path == NULL)
continue;
292 while (path != source && path != NULL && path->
GetFlow() == 0) {
318 assert(edge.UnsatisfiedDemand() > 0);
319 uint flow =
Clamp(edge.Demand() / accuracy, 1, edge.UnsatisfiedDemand());
320 flow = path->
AddFlow(flow, this->
job, max_saturation);
321 edge.SatisfyDemand(flow);
333 uint flow = UINT_MAX;
334 const Path *cycle_end = cycle_begin;
337 cycle_begin = path[cycle_begin->GetNode()];
338 }
while (cycle_begin != cycle_end);
350 Path *cycle_end = cycle_begin;
352 NodeID prev = cycle_begin->
GetNode();
354 if (cycle_begin->
GetFlow() == 0) {
356 for (PathList::iterator i = node_paths.begin(); i != node_paths.end(); ++i) {
357 if (*i == cycle_begin) {
359 node_paths.push_back(cycle_begin);
364 cycle_begin = path[prev];
366 edge.RemoveFlow(flow);
367 }
while (cycle_begin != cycle_end);
381 Path *at_next_pos = path[next_id];
386 if (at_next_pos == NULL) {
389 PathList &paths = this->
job[next_id].Paths();
390 PathViaMap next_hops;
391 for (PathList::iterator i = paths.begin(); i != paths.end();) {
392 Path *new_child = *i;
393 uint new_flow = new_child->
GetFlow();
394 if (new_flow == 0)
break;
395 if (new_child->
GetOrigin() == origin_id) {
396 PathViaMap::iterator via_it = next_hops.find(new_child->
GetNode());
397 if (via_it == next_hops.end()) {
398 next_hops[new_child->
GetNode()] = new_child;
401 Path *child = via_it->second;
409 paths.push_back(new_child);
417 for (PathViaMap::iterator via_it = next_hops.begin();
418 via_it != next_hops.end(); ++via_it) {
419 Path *child = via_it->second;
423 path[next_id] = child;
454 bool cycles_found =
false;
456 PathVector path(size, NULL);
457 for (NodeID node = 0; node < size; ++node) {
460 std::fill(path.begin(), path.end(), (
Path *)NULL);
473 uint size = job.
Size();
479 for (NodeID source = 0; source < size; ++source) {
481 this->Dijkstra<DistanceAnnotation, GraphEdgeIterator>(source, paths);
483 for (NodeID dest = 0; dest < size; ++dest) {
484 Edge edge = job[source][dest];
485 if (edge.UnsatisfiedDemand() > 0) {
486 Path *path = paths[dest];
487 assert(path != NULL);
495 more_loops = more_loops || (edge.UnsatisfiedDemand() > 0);
496 }
else if (edge.UnsatisfiedDemand() == edge.Demand() &&
498 this->
PushFlow(edge, path, accuracy, UINT_MAX);
516 uint size = job.
Size();
518 bool demand_left =
true;
519 while (demand_left) {
521 for (NodeID source = 0; source < size; ++source) {
522 this->Dijkstra<CapacityAnnotation, FlowEdgeIterator>(source, paths);
523 for (NodeID dest = 0; dest < size; ++dest) {
524 Edge edge = this->job[source][dest];
525 Path *path = paths[dest];
526 if (edge.UnsatisfiedDemand() > 0 && path->
GetFreeCapacity() > INT_MIN) {
527 this->
PushFlow(edge, path, accuracy, UINT_MAX);
528 if (edge.UnsatisfiedDemand() > 0) demand_left =
true;
547 template <
typename T>
548 bool Greater(T x_anno, T y_anno, NodeID x, NodeID y)
550 if (x_anno > y_anno)
return true;
551 if (x_anno < y_anno)
return false;