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) {
151 static const FlowStat::SharesMap empty;
153 FlowStatMap::const_iterator
it = flows.find(this->
job[source].
Station());
154 if (it != flows.end()) {
155 this->it = it->second.GetShares()->begin();
156 this->
end = it->second.GetShares()->end();
158 this->it = empty.begin();
159 this->
end = empty.end();
169 if (this->
it == this->
end)
return INVALID_NODE;
184 int free_cap, uint dist)
const
190 }
else if (this->
distance == UINT_MAX) {
218 int free_cap, uint dist)
const
222 if (min_cap == this_cap) {
227 return min_cap > this_cap;
240 template<
class Tannotation,
class Tedge_iterator>
243 typedef std::set<Tannotation *, typename Tannotation::Comparator> AnnoSet;
244 Tedge_iterator iter(this->
job);
247 paths.resize(size, NULL);
248 for (NodeID node = 0; node < size; ++node) {
249 Tannotation *anno =
new Tannotation(node, node == source_node);
253 while (!annos.empty()) {
254 typename AnnoSet::iterator i = annos.begin();
255 Tannotation *source = *i;
257 NodeID from = source->GetNode();
258 iter.SetNode(source_node, from);
259 for (NodeID to = iter.Next(); to != INVALID_NODE; to = iter.Next()) {
260 if (to == from)
continue;
261 Edge edge = this->
job[from][to];
266 if (capacity == 0) capacity = 1;
270 Tannotation *dest =
static_cast<Tannotation *
>(paths[to]);
271 if (dest->IsBetter(source, capacity, capacity - edge.Flow(), distance)) {
273 dest->Fork(source, capacity, capacity - edge.Flow(), distance);
287 Path *source = paths[source_id];
288 paths[source_id] = NULL;
289 for (PathVector::iterator i = paths.begin(); i != paths.end(); ++i) {
291 if (path == NULL)
continue;
293 while (path != source && path != NULL && path->
GetFlow() == 0) {
319 assert(edge.UnsatisfiedDemand() > 0);
320 uint flow =
Clamp(edge.Demand() / accuracy, 1, edge.UnsatisfiedDemand());
321 flow = path->
AddFlow(flow, this->
job, max_saturation);
322 edge.SatisfyDemand(flow);
334 uint flow = UINT_MAX;
335 const Path *cycle_end = cycle_begin;
338 cycle_begin = path[cycle_begin->GetNode()];
339 }
while (cycle_begin != cycle_end);
351 Path *cycle_end = cycle_begin;
353 NodeID prev = cycle_begin->
GetNode();
355 if (cycle_begin->
GetFlow() == 0) {
357 for (PathList::iterator i = node_paths.begin(); i != node_paths.end(); ++i) {
358 if (*i == cycle_begin) {
360 node_paths.push_back(cycle_begin);
365 cycle_begin = path[prev];
367 edge.RemoveFlow(flow);
368 }
while (cycle_begin != cycle_end);
382 static Path *invalid_path =
new Path(INVALID_NODE,
true);
383 Path *at_next_pos = path[next_id];
386 if (at_next_pos == invalid_path)
return false;
388 if (at_next_pos == NULL) {
391 PathList &paths = this->
job[next_id].Paths();
392 PathViaMap next_hops;
393 for (PathList::iterator i = paths.begin(); i != paths.end();) {
394 Path *new_child = *i;
395 uint new_flow = new_child->
GetFlow();
396 if (new_flow == 0)
break;
397 if (new_child->
GetOrigin() == origin_id) {
398 PathViaMap::iterator via_it = next_hops.find(new_child->
GetNode());
399 if (via_it == next_hops.end()) {
400 next_hops[new_child->
GetNode()] = new_child;
403 Path *child = via_it->second;
411 paths.push_back(new_child);
419 for (PathViaMap::iterator via_it = next_hops.begin();
420 via_it != next_hops.end(); ++via_it) {
421 Path *child = via_it->second;
425 path[next_id] = child;
434 path[next_id] = found ? NULL : invalid_path;
456 bool cycles_found =
false;
458 PathVector path(size, NULL);
459 for (NodeID node = 0; node < size; ++node) {
462 std::fill(path.begin(), path.end(), (
Path *)NULL);
475 uint size = job.
Size();
481 for (NodeID source = 0; source < size; ++source) {
483 this->Dijkstra<DistanceAnnotation, GraphEdgeIterator>(source, paths);
485 for (NodeID dest = 0; dest < size; ++dest) {
486 Edge edge = job[source][dest];
487 if (edge.UnsatisfiedDemand() > 0) {
488 Path *path = paths[dest];
489 assert(path != NULL);
497 more_loops = more_loops || (edge.UnsatisfiedDemand() > 0);
498 }
else if (edge.UnsatisfiedDemand() == edge.Demand() &&
500 this->
PushFlow(edge, path, accuracy, UINT_MAX);
518 uint size = job.
Size();
520 bool demand_left =
true;
521 while (demand_left) {
523 for (NodeID source = 0; source < size; ++source) {
524 this->Dijkstra<CapacityAnnotation, FlowEdgeIterator>(source, paths);
525 for (NodeID dest = 0; dest < size; ++dest) {
526 Edge edge = this->job[source][dest];
527 Path *path = paths[dest];
528 if (edge.UnsatisfiedDemand() > 0 && path->
GetFreeCapacity() > INT_MIN) {
529 this->
PushFlow(edge, path, accuracy, UINT_MAX);
530 if (edge.UnsatisfiedDemand() > 0) demand_left =
true;
549 template <
typename T>
550 bool Greater(T x_anno, T y_anno, NodeID x, NodeID y)
552 if (x_anno > y_anno)
return true;
553 if (x_anno < y_anno)
return false;