4 #include "../core/math_func.hpp"
8 #include "../safeguards.h"
10 typedef std::map<NodeID, Path *> PathViaMap;
55 int cached_annotation;
107 i(NULL, NULL, INVALID_NODE),
end(NULL, NULL, INVALID_NODE)
117 this->
i = this->
job[node].Begin();
118 this->
end = this->
job[node].End();
127 return this->
i != this->
end ? (this->
i++)->first : INVALID_NODE;
142 FlowStat::SharesMap::const_iterator
it;
145 FlowStat::SharesMap::const_iterator
end;
154 for (NodeID i = 0; i < job.
Size(); ++i) {
155 StationID st = job[i].Station();
171 FlowStatMap::const_iterator
it = flows.find(this->
job[source].
Station());
172 if (it != flows.end()) {
173 this->it = it->second.GetShares()->begin();
174 this->
end = it->second.GetShares()->end();
187 if (this->
it == this->
end)
return INVALID_NODE;
202 int free_cap, uint dist)
const
208 }
else if (this->
distance == UINT_MAX) {
236 int free_cap, uint dist)
const
240 if (min_cap == this_cap) {
245 return min_cap > this_cap;
258 template<
class Tannotation,
class Tedge_iterator>
261 typedef std::set<Tannotation *, typename Tannotation::Comparator> AnnoSet;
262 Tedge_iterator iter(this->
job);
265 paths.resize(size, NULL);
266 for (NodeID node = 0; node < size; ++node) {
267 Tannotation *anno =
new Tannotation(node, node == source_node);
268 anno->UpdateAnnotation();
272 while (!annos.empty()) {
273 typename AnnoSet::iterator i = annos.begin();
274 Tannotation *source = *i;
276 NodeID from = source->GetNode();
277 iter.SetNode(source_node, from);
278 for (NodeID to = iter.Next(); to != INVALID_NODE; to = iter.Next()) {
279 if (to == from)
continue;
280 Edge edge = this->
job[from][to];
285 if (capacity == 0) capacity = 1;
289 Tannotation *dest =
static_cast<Tannotation *
>(paths[to]);
290 if (dest->IsBetter(source, capacity, capacity - edge.Flow(), distance)) {
292 dest->Fork(source, capacity, capacity - edge.Flow(), distance);
293 dest->UpdateAnnotation();
307 Path *source = paths[source_id];
308 paths[source_id] = NULL;
309 for (PathVector::iterator i = paths.begin(); i != paths.end(); ++i) {
311 if (path == NULL)
continue;
313 while (path != source && path != NULL && path->
GetFlow() == 0) {
339 assert(edge.UnsatisfiedDemand() > 0);
340 uint flow =
Clamp(edge.Demand() / accuracy, 1, edge.UnsatisfiedDemand());
341 flow = path->
AddFlow(flow, this->
job, max_saturation);
342 edge.SatisfyDemand(flow);
354 uint flow = UINT_MAX;
355 const Path *cycle_end = cycle_begin;
358 cycle_begin = path[cycle_begin->GetNode()];
359 }
while (cycle_begin != cycle_end);
371 Path *cycle_end = cycle_begin;
373 NodeID prev = cycle_begin->
GetNode();
375 if (cycle_begin->
GetFlow() == 0) {
377 for (PathList::iterator i = node_paths.begin(); i != node_paths.end(); ++i) {
378 if (*i == cycle_begin) {
380 node_paths.push_back(cycle_begin);
385 cycle_begin = path[prev];
387 edge.RemoveFlow(flow);
388 }
while (cycle_begin != cycle_end);
402 Path *at_next_pos = path[next_id];
407 if (at_next_pos == NULL) {
410 PathList &paths = this->
job[next_id].Paths();
411 PathViaMap next_hops;
412 for (PathList::iterator i = paths.begin(); i != paths.end();) {
413 Path *new_child = *i;
414 uint new_flow = new_child->
GetFlow();
415 if (new_flow == 0)
break;
416 if (new_child->
GetOrigin() == origin_id) {
417 PathViaMap::iterator via_it = next_hops.find(new_child->
GetNode());
418 if (via_it == next_hops.end()) {
419 next_hops[new_child->
GetNode()] = new_child;
422 Path *child = via_it->second;
430 paths.push_back(new_child);
438 for (PathViaMap::iterator via_it = next_hops.begin();
439 via_it != next_hops.end(); ++via_it) {
440 Path *child = via_it->second;
444 path[next_id] = child;
475 bool cycles_found =
false;
477 PathVector path(size, NULL);
478 for (NodeID node = 0; node < size; ++node) {
481 std::fill(path.begin(), path.end(), (
Path *)NULL);
494 uint size = job.
Size();
500 for (NodeID source = 0; source < size; ++source) {
502 this->Dijkstra<DistanceAnnotation, GraphEdgeIterator>(source, paths);
504 for (NodeID dest = 0; dest < size; ++dest) {
505 Edge edge = job[source][dest];
506 if (edge.UnsatisfiedDemand() > 0) {
507 Path *path = paths[dest];
508 assert(path != NULL);
516 more_loops = more_loops || (edge.UnsatisfiedDemand() > 0);
517 }
else if (edge.UnsatisfiedDemand() == edge.Demand() &&
519 this->
PushFlow(edge, path, accuracy, UINT_MAX);
537 uint size = job.
Size();
539 bool demand_left =
true;
540 while (demand_left) {
542 for (NodeID source = 0; source < size; ++source) {
543 this->Dijkstra<CapacityAnnotation, FlowEdgeIterator>(source, paths);
544 for (NodeID dest = 0; dest < size; ++dest) {
545 Edge edge = this->job[source][dest];
546 Path *path = paths[dest];
547 if (edge.UnsatisfiedDemand() > 0 && path->
GetFreeCapacity() > INT_MIN) {
548 this->
PushFlow(edge, path, accuracy, UINT_MAX);
549 if (edge.UnsatisfiedDemand() > 0) demand_left =
true;
568 template <
typename T>
569 bool Greater(T x_anno, T y_anno, NodeID x, NodeID y)
571 if (x_anno > y_anno)
return true;
572 if (x_anno < y_anno)
return false;