Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

MinCostFlowReinelt.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <ogdf/basic/Array.h>
35 #include <ogdf/basic/EpsilonTest.h>
36 #include <ogdf/basic/Graph.h>
37 #include <ogdf/basic/GraphList.h>
38 #include <ogdf/basic/basic.h>
39 #include <ogdf/basic/memory.h>
41 
42 #include <cstdlib>
43 #include <limits>
44 
45 namespace ogdf {
46 
48 
51 template<typename TCost>
52 class MinCostFlowReinelt : public MinCostFlowModule<TCost> {
53 public:
55 
57 
73  virtual bool call(const Graph& G, // directed graph
74  const EdgeArray<int>& lowerBound, // lower bound for flow
75  const EdgeArray<int>& upperBound, // upper bound for flow
76  const EdgeArray<TCost>& cost, // cost of an edge
77  const NodeArray<int>& supply, // supply (if neg. demand) of a node
78  EdgeArray<int>& flow, // computed flow
79  NodeArray<TCost>& dual) override; // computed dual variables
80 
81  int infinity() const { return std::numeric_limits<int>::max(); }
82 
83 private:
84  struct arctype;
85 
86  struct nodetype {
87  nodetype* father; /* ->father in basis tree */
88  nodetype* successor; /* ->successor in preorder */
89  arctype* arc_id; /* ->arc (node,father) */
90  bool orientation; /* false<=>basic arc=(father->node)*/
91  TCost dual; /* value of dual variable */
92  int flow; /* flow in basic arc (node,father) */
93  int name; /* identification of node = node-nr*/
94  nodetype* last; /* last node in subtree */
95  int nr_of_nodes; /* number of nodes in subtree */
96  };
97 
98  struct arctype {
99  arctype* next_arc; /* -> next arc in list */
100  nodetype* tail; /* -> tail of arc */
101  nodetype* head; /* -> head of arc */
102  TCost cost; /* cost of unit flow */
103  int upper_bound; /* capacity of arc */
104  int arcnum; /* number of arc in input */
105 
107  };
108 
109  int mcf(int mcfNrNodes, int mcfNrArcs, Array<int>& mcfSupply, Array<int>& mcfTail,
110  Array<int>& mcfHead, Array<int>& mcfLb, Array<int>& mcfUb, Array<TCost>& mcfCost,
111  Array<int>& mcfFlow, Array<TCost>& mcfDual, TCost* mcfObj);
112 
113  void start(Array<int>& supply);
114 
115  void beacircle(arctype** eplus, arctype** pre, bool* from_ub);
116  void beadouble(arctype** eplus, arctype** pre, bool* from_ub);
117 
119 
120  Array<nodetype> nodes; /* node space */
121  Array<arctype> arcs; /* arc space */
122  //Array<nodetype *> p; /*used for starting procedure*/
123 
124  nodetype* root = nullptr; /*->root of basis tree*/
126 
127  arctype* last_n1 = nullptr; /*->start for search for entering arc in N' */
128  arctype* last_n2 = nullptr; /*->start for search for entering arc in N''*/
129  arctype* start_arc = nullptr; /* -> initial arc list*/
130  arctype* start_b = nullptr; /* -> first basic arc*/
131  arctype* start_n1 = nullptr; /* -> first nonbasic arc in n'*/
132  arctype* start_n2 = nullptr; /* -> first nonbasic arc in n''*/
133  arctype* startsearch = nullptr; /* ->start of search for basis entering arc */
134  arctype* searchend = nullptr; /* ->end of search for entering arc in bea */
135  arctype* searchend_n1 = nullptr; /*->end of search for entering arc in N' */
136  arctype* searchend_n2 = nullptr; /*->end of search for entering arc in N''*/
137 
138  //int artvalue; /*cost and upper_bound of artificial arc */
139  TCost m_maxCost = std::numeric_limits<TCost>::lowest(); // maximum of the cost of all input arcs
140 
141  int nn = 0; /*number of original nodes*/
142  int mm = 0; /*number of original arcs*/
143 };
144 
145 }
146 
147 // Implementation
148 
149 namespace ogdf {
150 
151 // computes min-cost-flow, call front-end for mcf()
152 // returns true if a feasible minimum cost flow could be found
153 template<typename TCost>
154 bool MinCostFlowReinelt<TCost>::call(const Graph& G, const EdgeArray<int>& lowerBound,
155  const EdgeArray<int>& upperBound, const EdgeArray<TCost>& cost,
156  const NodeArray<int>& supply, EdgeArray<int>& flow, NodeArray<TCost>& dual) {
157  OGDF_ASSERT(this->checkProblem(G, lowerBound, upperBound, supply));
158 
159  const int n = G.numberOfNodes();
160  const int m = G.numberOfEdges();
161 
162  // assign indices 0, ..., n-1 to nodes in G
163  // (this is not guaranteed for v->index() )
164  NodeArray<int> vIndex(G);
165  // assigning supply
166  Array<int> mcfSupply(n);
167 
168  int i = 0;
169  for (node v : G.nodes) {
170  mcfSupply[i] = supply[v];
171  vIndex[v] = ++i;
172  }
173 
174 
175  // allocation of arrays for arcs
176  Array<int> mcfTail(m);
177  Array<int> mcfHead(m);
178  Array<int> mcfLb(m);
179  Array<int> mcfUb(m);
180  Array<TCost> mcfCost(m);
181  Array<int> mcfFlow(m);
182  Array<TCost> mcfDual(n + 1); // dual[n] = dual variable of root struct
183 
184  // set input data in edge arrays
185  int nSelfLoops = 0;
186  i = 0;
187  for (edge e : G.edges) {
188  // We handle self-loops in the network already in the front-end
189  // (they are just set to the lower bound below when copying result)
190  if (e->isSelfLoop()) {
191  ++nSelfLoops;
192  continue;
193  }
194 
195  mcfTail[i] = vIndex[e->source()];
196  mcfHead[i] = vIndex[e->target()];
197  mcfLb[i] = lowerBound[e];
198  mcfUb[i] = upperBound[e];
199  mcfCost[i] = cost[e];
200 
201  ++i;
202  }
203 
204 
205  int retCode = 0; // return (error or success) code
206  TCost objVal; // value of flow
207 
208  // call actual min-cost-flow function
209  // mcf does not support single nodes
210  if (n > 1) {
211  //mcf does not support single edges
212  if (m < 2) {
213  if (m == 1) {
214  edge eFirst = G.firstEdge();
215  flow[eFirst] = lowerBound[eFirst];
216  }
217  } else {
218  retCode = mcf(n, m - nSelfLoops, mcfSupply, mcfTail, mcfHead, mcfLb, mcfUb, mcfCost,
219  mcfFlow, mcfDual, &objVal);
220  }
221  }
222 
223  // copy resulting flow for return
224  i = 0;
225  for (edge e : G.edges) {
226  if (e->isSelfLoop()) {
227  flow[e] = lowerBound[e];
228  continue;
229  }
230 
231  flow[e] = mcfFlow[i];
232  if (retCode == 0) {
233  OGDF_ASSERT(flow[e] >= lowerBound[e]);
234  OGDF_ASSERT(flow[e] <= upperBound[e]);
235  }
236  ++i;
237  }
238 
239  // copy resulting dual values for return
240  i = 0;
241  for (node v : G.nodes) {
242  dual[v] = mcfDual[i];
243  ++i;
244  }
245 
246  // successful if retCode == 0
247  return retCode == 0;
248 }
249 
250 template<typename TCost>
252  // determine intial basis tree and initialize data structure
253 
254  /* initialize artificial root node */
255  root->father = root;
256  root->successor = &nodes[1];
257  root->arc_id = nullptr;
258  root->orientation = false;
259  root->dual = 0;
260  root->flow = 0;
261  root->nr_of_nodes = nn + 1;
262  root->last = &nodes[nn];
263  root->name = nn + 1;
264  // artificials = nn; moved to mcf() [CG]
265  TCost highCost = 1 + (nn + 1) * m_maxCost;
266 
267  for (int i = 1; i <= nn; ++i) { /* for every node an artificial arc is created */
268  arctype* ep = new arctype;
269  if (supply[i - 1] >= 0) {
270  ep->tail = &nodes[i];
271  ep->head = root;
272  } else {
273  ep->tail = root;
274  ep->head = &nodes[i];
275  }
276  ep->cost = highCost;
277  ep->upper_bound = infinity();
278  ep->arcnum = mm + i - 1;
279  ep->next_arc = start_b;
280  start_b = ep;
281  nodes[i].father = root;
282  if (i < nn) {
283  nodes[i].successor = &nodes[i + 1];
284  } else {
285  nodes[i].successor = root;
286  }
287  if (supply[i - 1] < 0) {
288  nodes[i].orientation = false;
289  nodes[i].dual = -highCost;
290  } else {
291  nodes[i].orientation = true;
292  nodes[i].dual = highCost;
293  }
294  nodes[i].flow = abs(supply[i - 1]);
295  nodes[i].nr_of_nodes = 1;
296  nodes[i].last = &nodes[i];
297  nodes[i].arc_id = ep;
298  } /* for i */
299  start_n1 = start_arc;
300 } /*start*/
301 
302 // circle variant for determine basis entering arc
303 template<typename TCost>
304 void MinCostFlowReinelt<TCost>::beacircle(arctype** eplus, arctype** pre, bool* from_ub) {
305  //the first arc with negative reduced costs is taken, but the search is
306  //started at the successor of the successor of eplus in the last iteration
307 
308  bool found = false; /* true<=>entering arc found */
309 
310  *pre = startsearch;
311  if (*pre != nullptr) {
312  *eplus = (*pre)->next_arc;
313  } else {
314  *eplus = nullptr;
315  }
316  searchend = *eplus;
317 
318  if (!*from_ub) {
319  while (*eplus != nullptr && !found) { /* search in n' for an arc with negative reduced costs */
320  if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
321  found = true;
322  } else {
323  *pre = *eplus; /* save predecessor */
324  *eplus = (*eplus)->next_arc; /* go to next arc */
325  }
326  } /* while */
327 
328  if (!found) { /* entering arc still not found */
329  /* search in n'' */
330  *from_ub = true;
331  *eplus = start_n2;
332  *pre = nullptr;
333 
334  while (*eplus != nullptr && !found) {
335  if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
336  found = true;
337  } else {
338  *pre = *eplus; /* save predecessor */
339  *eplus = (*eplus)->next_arc; /* go to next arc */
340  }
341  } /* while */
342 
343 
344  if (!found) { /* search again in n' */
345  *from_ub = false;
346  *eplus = start_n1;
347  *pre = nullptr;
348 
349  while (*eplus != searchend && !found) {
350  if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
351  found = true;
352  } else {
353  *pre = *eplus; /* save predecessor */
354  *eplus = (*eplus)->next_arc; /* go to next arc */
355  }
356  } /* while */
357 
358  } /* search in n'' */
359  } /* serch again in n' */
360  } /* if from_ub */
361  else { /* startsearch in n'' */
362 
363  while (*eplus != nullptr && !found) {
364  if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
365  found = true;
366  } else {
367  *pre = *eplus; /* save predecessor */
368  *eplus = (*eplus)->next_arc; /* go to next arc */
369  }
370  } /* while */
371 
372  if (!found) { /* search now in n' */
373  *from_ub = false;
374  *eplus = start_n1;
375  *pre = nullptr;
376 
377  while (*eplus != nullptr && !found) {
378  if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
379  found = true;
380  } else {
381  *pre = *eplus; /* save predecessor */
382  *eplus = (*eplus)->next_arc; /* go to next arc */
383  }
384  } /* while */
385 
386 
387  if (!found) { /* search again in n'' */
388  *from_ub = true;
389  *eplus = start_n2;
390  *pre = nullptr;
391 
392  while (*eplus != searchend && !found) {
393  if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
394  found = true;
395  } else {
396  *pre = *eplus; /* save predecessor */
397  *eplus = (*eplus)->next_arc; /* go to next arc */
398  }
399  } /* while */
400 
401  } /* search in n' */
402  } /* search in n'' */
403  } /* from_ub = true */
404 
405 
406  if (!found) {
407  *pre = nullptr;
408  *eplus = nullptr;
409  } else {
410  startsearch = (*eplus)->next_arc;
411  }
412 
413 } /* beacircle */
414 
415 // doublecircle variant for determine basis entering arc
416 template<typename TCost>
417 void MinCostFlowReinelt<TCost>::beadouble(arctype** eplus, arctype** pre, bool* from_ub) {
418  /* search as in procedure beacircle, but in each list the search started is
419  at the last movement
420  */
421  bool found = false; /* true<=>entering arc found */
422 
423  if (!*from_ub) {
424  *pre = last_n1;
425  if (*pre != nullptr) {
426  *eplus = (*pre)->next_arc;
427  } else {
428  *eplus = nullptr;
429  }
430  searchend_n1 = *eplus;
431 
432  while (*eplus != nullptr && !found) { /* search in n' for an arc with negative reduced costs */
433  if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
434  found = true;
435  } else {
436  *pre = *eplus; /* save predecessor */
437  *eplus = (*eplus)->next_arc; /* go to next arc */
438  }
439  } /* while */
440 
441  if (!found) { /* entering arc still not found */
442  /* search in n'' beginning at the last movement */
443  *from_ub = true;
444  *pre = last_n2;
445  if (*pre != nullptr) {
446  *eplus = (*pre)->next_arc;
447  } else {
448  *eplus = nullptr;
449  }
450  searchend_n2 = *eplus;
451 
452  while (*eplus != nullptr && !found) {
453  if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
454  found = true;
455  } else {
456  *pre = *eplus; /* save predecessor */
457  *eplus = (*eplus)->next_arc; /* go to next arc */
458  }
459 
460  } /* while */
461 
462  if (!found) { /* entering arc still not found */
463  /* search in n'' in the first part of the list */
464  *eplus = start_n2;
465  *pre = nullptr;
466 
467  while (*eplus != searchend_n2 && !found) {
468  if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
469  found = true;
470  } else {
471  *pre = *eplus; /* save predecessor */
472  *eplus = (*eplus)->next_arc; /* go to next arc */
473  }
474 
475  } /* while */
476 
477 
478  if (!found) {
479  /* search again in n' in the first part of the list*/
480  *from_ub = false;
481  *eplus = start_n1;
482  *pre = nullptr;
483 
484  while (*eplus != searchend_n1 && !found) {
485  if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
486  found = true;
487  } else {
488  *pre = *eplus; /* save predecessor */
489  *eplus = (*eplus)->next_arc; /* go to next arc */
490  }
491  } /* while */
492  } /* first part n' */
493  } /* first part n'' */
494  } /* second part n'' */
495  } /* if from_ub */
496  else { /* startsearch in n'' */
497  *pre = last_n2;
498  if (*pre != nullptr) {
499  *eplus = (*pre)->next_arc;
500  } else {
501  *eplus = nullptr;
502  }
503  searchend_n2 = *eplus;
504 
505  while (*eplus != nullptr && !found) {
506  if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
507  found = true;
508  } else {
509  *pre = *eplus; /* save predecessor */
510  *eplus = (*eplus)->next_arc; /* go to next arc */
511  }
512  } /* while */
513 
514  if (!found) { /* search now in n' beginning at the last movement */
515  *from_ub = false;
516  *pre = last_n1;
517  if (*pre != nullptr) {
518  *eplus = (*pre)->next_arc;
519  } else {
520  *eplus = nullptr;
521  }
522  searchend_n1 = *eplus;
523 
524  while (*eplus != nullptr && !found) {
525  if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
526  found = true;
527  } else {
528  *pre = *eplus; /* save predecessor */
529  *eplus = (*eplus)->next_arc; /* go to next arc */
530  }
531  } /* while */
532 
533 
534  if (!found) { /* search now in n' in the first part */
535  *eplus = start_n1;
536  *pre = nullptr;
537 
538  while (*eplus != searchend_n1 && !found) {
539  if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
540  found = true;
541  } else {
542  *pre = *eplus; /* save predecessor */
543  *eplus = (*eplus)->next_arc; /* go to next arc */
544  }
545  } /* while */
546 
547 
548  if (!found) { /* search again in n'' in the first part */
549  *from_ub = true;
550  *eplus = start_n2;
551  *pre = nullptr;
552 
553  while (*eplus != searchend_n2 && !found) {
554  if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
555  found = true;
556  } else {
557  *pre = *eplus; /* save predecessor */
558  *eplus = (*eplus)->next_arc; /* go to next arc */
559  }
560  } /* while */
561  } /* first part of n'' */
562  } /* first part of n' */
563  } /* second part of n' */
564  } /* from_ub = true */
565 
566 
567  if (!found) {
568  *pre = nullptr;
569  *eplus = nullptr;
570  return;
571  }
572 
573  if (*from_ub) {
574  last_n2 = (*eplus)->next_arc;
575  } else {
576  last_n1 = (*eplus)->next_arc;
577  }
578 
579 } /* beadouble */
580 
581 // Min Cost Flow Function
582 template<typename TCost>
583 int MinCostFlowReinelt<TCost>::mcf(int mcfNrNodes, int mcfNrArcs, Array<int>& supply,
584  Array<int>& mcfTail, Array<int>& mcfHead, Array<int>& mcfLb, Array<int>& mcfUb,
585  Array<TCost>& mcfCost, Array<int>& mcfFlow, Array<TCost>& mcfDual, TCost* mcfObj) {
586  int i;
587  int low, up;
588 
589  /* 1: Allocations (malloc's no longer required) */
590 
591  root = &rootStruct;
592 
593  /* 2: Initializations */
594 
595  /* Number of nodes/arcs */
596  nn = mcfNrNodes;
597  OGDF_ASSERT(nn >= 2);
598  mm = mcfNrArcs;
599  OGDF_ASSERT(mm >= 2);
600 
601  // number of artificial basis arcs
602  int artificials = nn;
603 
604 
605  /* Node space and pointers to nodes */
606  nodes.init(nn + 1);
607  nodes[0].name = -1; // for debuggin, should not occur(?)
608  for (i = 1; i <= nn; ++i) {
609  nodes[i].name = i;
610  }
611 
612  /* Arc space and arc data */
613  arcs.init(mm + 1);
614 
615  TCost lb_cost = 0; // cost of lower bound
616  m_maxCost = 0;
617  int from = mcfTail[0]; // name of tail (input)
618  int toh = mcfHead[0]; // name of head (input)
619  low = mcfLb[0];
620  up = mcfUb[0];
621  TCost c = mcfCost[0]; // cost (input)
622  if (from <= 0 || from > nn || toh <= 0 || toh > nn || up < 0 || low > up || low < 0) {
623  return 4;
624  }
625  TCost abs_c = c < 0 ? -c : c;
626  if (abs_c > m_maxCost) {
627  m_maxCost = abs_c;
628  }
629 
630  start_arc = &arcs[1];
631  start_arc->tail = &nodes[from];
632  start_arc->head = &nodes[toh];
633  start_arc->cost = c;
634  start_arc->upper_bound = up - low;
635  start_arc->arcnum = 0;
636  supply[from - 1] -= low;
637  supply[toh - 1] += low;
638  lb_cost += start_arc->cost * low;
639 
640  arctype* e = start_arc;
641 
642  int lower; // lower bound (input)
643  for (lower = 2; lower <= mm; ++lower) {
644  from = mcfTail[lower - 1];
645  toh = mcfHead[lower - 1];
646  low = mcfLb[lower - 1];
647  up = mcfUb[lower - 1];
648  c = mcfCost[lower - 1];
649  if (from <= 0 || from > nn || toh <= 0 || toh > nn || up < 0 || low > up || low < 0) {
650  return 4;
651  }
652  abs_c = c < 0 ? -c : c;
653  if (abs_c > m_maxCost) {
654  m_maxCost = abs_c;
655  }
656 
657  arctype* ep = &arcs[lower];
658  e->next_arc = ep;
659  ep->tail = &nodes[from];
660  ep->head = &nodes[toh];
661  ep->cost = c;
662  ep->upper_bound = up - low;
663  ep->arcnum = lower - 1;
664  supply[from - 1] -= low;
665  supply[toh - 1] += low;
666  lb_cost += ep->cost * low;
667  e = ep;
668  }
669 
670  e->next_arc = nullptr;
671  // feasible = true <=> feasible solution exists
672  bool feasible = true;
673 
674 
675  /* 3: Starting solution */
676 
677  start_n1 = nullptr;
678  start_n2 = nullptr;
679  start_b = nullptr;
680 
681  start(supply);
682 
683  /* 4: Iteration loop */
684 
685  /* 4.1: Determine basis entering arc */
686 
687  // finished = true <=> iteration finished
688  bool finished = false;
689  // from_ub = true <=> entering arc at upper bound
690  bool from_ub = false;
691  startsearch = start_n1;
692 #if 0
693  startsearchpre = nullptr;
694 #endif
695  last_n1 = nullptr;
696  last_n2 = nullptr;
697  nodetype* np; // general nodeptr
698 
699  do {
700  arctype* eplus; // ->basis entering arc
701  arctype* pre; // ->predecessor of eplus in list
702  beacircle(&eplus, &pre, &from_ub);
703 
704  if (eplus == nullptr) {
705  finished = true;
706  } else {
707  nodetype* iplus = eplus->tail; // -> tail of basis entering arc
708  nodetype* jplus = eplus->head; // -> head of basis entering arc
709 
710  /* 4.2: Determine leaving arc and maximal flow change */
711 
712  int delta = eplus->upper_bound; // maximal flow change
713  nodetype* iminus = nullptr; // -> tail of basis leaving arc
714  nodetype* p1 = iplus;
715  nodetype* p2 = jplus;
716 
717  bool to_ub; // to_ub = true <=> leaving arc goes to upperbound
718  bool xchange; // xchange = true <=> exchange iplus and jplus
719  while (p1 != p2) {
720  if (p1->nr_of_nodes <= p2->nr_of_nodes) {
721  np = p1;
722  if (from_ub == np->orientation) {
723  if (delta > np->arc_id->upper_bound - np->flow) {
724  iminus = np;
725  delta = np->arc_id->upper_bound - np->flow;
726  xchange = false;
727  to_ub = true;
728  }
729  } else if (delta > np->flow) {
730  iminus = np;
731  delta = np->flow;
732  xchange = false;
733  to_ub = false;
734  }
735  p1 = np->father;
736  continue;
737  }
738  np = p2;
739  if (from_ub != np->orientation) {
740  if (delta > np->arc_id->upper_bound - np->flow) {
741  iminus = np;
742  delta = np->arc_id->upper_bound - np->flow;
743  xchange = true;
744  to_ub = true;
745  }
746  } else if (delta > np->flow) {
747  iminus = np;
748  delta = np->flow;
749  xchange = true;
750  to_ub = false;
751  }
752  p2 = np->father;
753  }
754  // paths from iplus and jplus to root meet at w
755  nodetype* w = p1;
756  nodetype* iw;
757  nodetype* jminus; // -> head of basis leaving arc
758 
759  arctype* eminus;
760  if (iminus == nullptr) {
761  to_ub = !from_ub;
762  eminus = eplus;
763  iminus = iplus;
764  jminus = jplus;
765  } else {
766  if (xchange) {
767  iw = jplus;
768  jplus = iplus;
769  iplus = iw;
770  }
771  jminus = iminus->father;
772  eminus = iminus->arc_id;
773  }
774 
775  // artif_to_lb = true <=> artif. arc goes to lower bound
776  bool artif_to_lb = false;
777  if (artificials > 1) {
778  if (iminus == root || jminus == root) {
779  if (jplus != root && iplus != root) {
780  artificials--;
781  artif_to_lb = true;
782  } else if (eminus == eplus) {
783  if (from_ub) {
784  artificials--;
785  artif_to_lb = true;
786  } else {
787  artificials++;
788  }
789  }
790  } else {
791  if (iplus == root || jplus == root) {
792  artificials++;
793  }
794  }
795  }
796 
797  /* 4.3: Update of data structure */
798 
799  TCost sigma; // change of dual variables
800 
801  if (eminus == eplus) {
802  if (from_ub) {
803  delta = -delta;
804  }
805 
806  bool s_orientation;
807  s_orientation = eminus->tail == iplus;
808 
809  np = iplus;
810  while (np != w) {
811  if (np->orientation == s_orientation) {
812  np->flow -= delta;
813  } else {
814  np->flow += delta;
815  }
816  np = np->father;
817  }
818 
819  np = jplus;
820  while (np != w) {
821  if (np->orientation == s_orientation) {
822  np->flow += delta;
823  } else {
824  np->flow -= delta;
825  }
826  np = np->father;
827  }
828 
829  } else {
830  /* 4.3.2.1 : initialize sigma */
831 
832  if (eplus->tail == iplus) {
833  sigma = eplus->cost + jplus->dual - iplus->dual;
834  } else {
835  sigma = jplus->dual - iplus->dual - eplus->cost;
836  }
837 
838  // 4.3.2.2 : find new succ. of jminus if current succ. is iminus
839 
840  nodetype* newsuc = jminus->successor; // -> new successor
841  if (newsuc == iminus) {
842  for (i = 1; i <= iminus->nr_of_nodes; ++i) {
843  newsuc = newsuc->successor;
844  }
845  }
846 
847  /* 4.3.2.3 : initialize data for iplus */
848 
849  nodetype* s_father = jplus; // save area
850  bool s_orientation = (eplus->tail != jplus);
851 
852  // eplus_ori = true <=> eplus = (iplus,jplus)
853  bool eplus_ori = s_orientation;
854 
855  int s_flow;
856  if (from_ub) {
857  s_flow = eplus->upper_bound - delta;
858  delta = -delta;
859  } else {
860  s_flow = delta;
861  }
862 
863  arctype* s_arc_id = eminus;
864  int oldnumber = 0;
865  nodetype* nd = iplus; // -> current node
866  nodetype* f = nd->father; // ->father of nd
867 
868  /* 4.3.2.4 : traverse subtree under iminus */
869 
870  while (nd != jminus) {
871  nodetype* pred = f; // ->predecessor of current node
872  while (pred->successor != nd) {
873  pred = pred->successor;
874  }
875  nodetype* lastnode = nd; // -> last node of subtree
876  i = 1;
877  int non = nd->nr_of_nodes - oldnumber;
878  while (i < non) {
879  lastnode = lastnode->successor;
880  lastnode->dual += sigma;
881  i++;
882  }
883  nd->dual += sigma;
884  pred->successor = lastnode->successor;
885 
886  if (nd != iminus) {
887  lastnode->successor = f;
888  } else {
889  lastnode->successor = jplus->successor;
890  }
891 
892  nodetype* w_father = nd; // save area
893  arctype* w_arc_id = nd->arc_id; // save area
894 
895  bool w_orientation;
896  w_orientation = nd->arc_id->tail != nd;
897 
898  int w_flow;
899  if (w_orientation == eplus_ori) {
900  w_flow = nd->flow + delta;
901  } else {
902  w_flow = nd->flow - delta;
903  }
904 
905  nd->father = s_father;
906  nd->orientation = s_orientation;
907  nd->arc_id = s_arc_id;
908  nd->flow = s_flow;
909  s_father = w_father;
910  s_orientation = w_orientation;
911  s_arc_id = w_arc_id;
912  s_flow = w_flow;
913 
914  oldnumber = nd->nr_of_nodes;
915  nd = f;
916  f = f->father;
917  }
918 
919  jminus->successor = newsuc;
920  jplus->successor = iplus;
921 
922  // 4.3.2.5: assign new nr_of_nodes in path from iminus to iplus
923 
924  oldnumber = iminus->nr_of_nodes;
925  np = iminus;
926  while (np != iplus) {
927  np->nr_of_nodes = oldnumber - np->father->nr_of_nodes;
928  np = np->father;
929  }
930 
931  iplus->nr_of_nodes = oldnumber;
932 
933  // 4.3.2.6: update flows and nr_of_nodes in path from jminus to w
934 
935  np = jminus;
936  while (np != w) {
937  np->nr_of_nodes -= oldnumber;
938  if (np->orientation != eplus_ori) {
939  np->flow += delta;
940  } else {
941  np->flow -= delta;
942  }
943  np = np->father;
944  }
945 
946  // 4.3.2.7 update flows and nr_of_nodes in path from jplus to w
947 
948  np = jplus;
949  while (np != w) {
950  np->nr_of_nodes += oldnumber;
951  if (np->orientation == eplus_ori) {
952  np->flow += delta;
953  } else {
954  np->flow -= delta;
955  }
956  np = np->father;
957  }
958  }
959 
960  /* 4.4: Update lists B, N' and N'' */
961 
962  if (eminus == eplus) {
963  if (!from_ub) {
964  if (pre == nullptr) {
965  start_n1 = eminus->next_arc;
966  } else {
967  pre->next_arc = eminus->next_arc;
968  }
969 
970  eminus->next_arc = start_n2;
971  start_n2 = eminus;
972  } else {
973  if (pre == nullptr) {
974  start_n2 = eminus->next_arc;
975  } else {
976  pre->next_arc = eminus->next_arc;
977  }
978  eminus->next_arc = start_n1;
979  start_n1 = eminus;
980  }
981  } else {
982  TCost wcost = eminus->cost;
983  int wub = eminus->upper_bound;
984  int wnum = eminus->arcnum;
985  nodetype* w_head = eminus->head;
986  nodetype* w_tail = eminus->tail;
987  eminus->tail = eplus->tail;
988  eminus->head = eplus->head;
989  eminus->upper_bound = eplus->upper_bound;
990  eminus->arcnum = eplus->arcnum;
991  eminus->cost = eplus->cost;
992  eplus->tail = w_tail;
993  eplus->head = w_head;
994  eplus->upper_bound = wub;
995  eplus->cost = wcost;
996  eplus->arcnum = wnum;
997  arctype* ep = eplus;
998 
999  if (pre != nullptr) {
1000  pre->next_arc = ep->next_arc;
1001  } else {
1002  if (from_ub) {
1003  start_n2 = ep->next_arc;
1004  } else {
1005  start_n1 = ep->next_arc;
1006  }
1007  }
1008 
1009  if (to_ub) {
1010  ep->next_arc = start_n2;
1011  start_n2 = ep;
1012  } else {
1013  if (!artif_to_lb) {
1014  ep->next_arc = start_n1;
1015  start_n1 = ep;
1016  }
1017  }
1018  }
1019 
1020  /* 4.5: Eliminate artificial arcs and artificial root node */
1021 
1022  if (artificials == 1) {
1023  artificials = 0;
1024  nodetype* nd = root->successor;
1025  arctype* e1 = nd->arc_id;
1026 
1027  if (nd->flow > 0) {
1028  feasible = false;
1029  finished = true;
1030  } else {
1031  feasible = true;
1032  if (e1 == start_b) {
1033  start_b = e1->next_arc;
1034  } else {
1035  e = start_b;
1036  while (e->next_arc != e1) {
1037  e = e->next_arc;
1038  }
1039  e->next_arc = e1->next_arc;
1040  }
1041 
1042  iw = root;
1043  root = root->successor;
1044  root->father = root;
1045  sigma = root->dual;
1046 
1047  np = root;
1048  while (np->successor != iw) {
1049  np->dual -= sigma;
1050  np = np->successor;
1051  }
1052 
1053  np->dual -= sigma;
1054  np->successor = root;
1055  }
1056  }
1057  }
1058 
1059  } while (!finished);
1060 
1061  /* 5: Return results */
1062 
1063  /* Feasible solution? */
1064  if (artificials != 0 && feasible) {
1065  np = root->successor;
1066  do {
1067  if (np->father == root && np->flow > 0) {
1068  feasible = false;
1069  np = root;
1070  } else {
1071  np = np->successor;
1072  }
1073  } while (np != root);
1074 
1075  arctype* ep = start_n2;
1076  while (ep != nullptr && feasible) {
1077  if (ep == nullptr) {
1078  break;
1079  }
1080  if (ep->tail == root && ep->head == root) {
1081  feasible = false;
1082  }
1083  ep = ep->next_arc;
1084  }
1085  }
1086 
1087  int retValue = 0;
1088 
1089  if (feasible) {
1090  /* Objective function value */
1091  TCost zfw = 0; // current total cost
1092  np = root->successor;
1093  while (np != root) {
1094  if (np->flow != 0) {
1095  zfw += np->flow * np->arc_id->cost;
1096  }
1097  np = np->successor;
1098  }
1099  arctype* ep = start_n2;
1100  while (ep != nullptr) {
1101  zfw += ep->cost * ep->upper_bound;
1102  ep = ep->next_arc;
1103  }
1104  *mcfObj = zfw + lb_cost;
1105 
1106  /* Dual variables */
1107  // CG: removed computation of duals
1108  np = root->successor;
1109  while (np != root) {
1110  mcfDual[np->name - 1] = np->dual;
1111  np = np->successor;
1112  }
1113  mcfDual[root->name - 1] = root->dual;
1114 
1115  /* Arc flows */
1116  for (i = 0; i < mm; ++i) {
1117  mcfFlow[i] = mcfLb[i];
1118  }
1119 
1120  np = root->successor;
1121  while (np != root) {
1122  // flow on artificial arcs has to be 0 to be ignored! [CG]
1123  OGDF_ASSERT(np->arc_id->arcnum < mm || np->flow == 0);
1124 
1125  if (np->arc_id->arcnum < mm) {
1126  mcfFlow[np->arc_id->arcnum] += np->flow;
1127  }
1128 
1129  np = np->successor;
1130  }
1131 
1132  ep = start_n2;
1133  while (ep != nullptr) {
1134  mcfFlow[ep->arcnum] += ep->upper_bound;
1135  ep = ep->next_arc;
1136  }
1137 
1138  } else {
1139  retValue = 10;
1140  }
1141 
1142  // deallocate artificial arcs
1143  for (i = 1; i <= nn; ++i)
1144 #if 0
1145  delete p[i]->arc_id;
1146 #endif
1147  delete nodes[i].arc_id;
1148 
1149  return retValue;
1150 }
1151 
1152 }
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ogdf::MinCostFlowReinelt
Computes a min-cost flow using a network simplex method.
Definition: MinCostFlowReinelt.h:52
EpsilonTest.h
Compare floating point numbers with epsilons and integral numbers with normal compare operators.
Graph.h
Includes declaration of graph class.
ogdf::EpsilonTest
Definition: EpsilonTest.h:39
ogdf::MinCostFlowReinelt::MinCostFlowReinelt
MinCostFlowReinelt()
Definition: MinCostFlowReinelt.h:54
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::MinCostFlowReinelt::last_n1
arctype * last_n1
Definition: MinCostFlowReinelt.h:127
ogdf::matching_blossom::infinity
TWeight infinity()
Helper function to get the maximum value for a given weight type.
Definition: utils.h:46
ogdf::MinCostFlowReinelt::startsearch
arctype * startsearch
Definition: MinCostFlowReinelt.h:133
ogdf::MinCostFlowReinelt::arctype::upper_bound
int upper_bound
Definition: MinCostFlowReinelt.h:103
ogdf::MinCostFlowReinelt::m_eps
EpsilonTest m_eps
Definition: MinCostFlowReinelt.h:118
ogdf::MinCostFlowReinelt::rootStruct
nodetype rootStruct
Definition: MinCostFlowReinelt.h:125
ogdf::MinCostFlowReinelt::nodetype::successor
nodetype * successor
Definition: MinCostFlowReinelt.h:88
ogdf::MinCostFlowReinelt::searchend_n1
arctype * searchend_n1
Definition: MinCostFlowReinelt.h:135
ogdf::MinCostFlowReinelt::nodetype::father
nodetype * father
Definition: MinCostFlowReinelt.h:87
ogdf::MinCostFlowReinelt::start_arc
arctype * start_arc
Definition: MinCostFlowReinelt.h:129
ogdf::MinCostFlowReinelt::nodetype::orientation
bool orientation
Definition: MinCostFlowReinelt.h:90
ogdf::MinCostFlowReinelt::call
virtual bool call(const Graph &G, const EdgeArray< int > &lowerBound, const EdgeArray< int > &upperBound, const EdgeArray< TCost > &cost, const NodeArray< int > &supply, EdgeArray< int > &flow, NodeArray< TCost > &dual) override
Computes a min-cost flow in the directed graph G using a network simplex method.
Definition: MinCostFlowReinelt.h:154
ogdf::MinCostFlowReinelt::nodetype::flow
int flow
Definition: MinCostFlowReinelt.h:92
ogdf::MinCostFlowReinelt::arctype::tail
nodetype * tail
Definition: MinCostFlowReinelt.h:100
ogdf::MinCostFlowReinelt::beadouble
void beadouble(arctype **eplus, arctype **pre, bool *from_ub)
Definition: MinCostFlowReinelt.h:417
ogdf::MinCostFlowReinelt::nodetype
Definition: MinCostFlowReinelt.h:86
ogdf::MinCostFlowReinelt::infinity
int infinity() const
Definition: MinCostFlowReinelt.h:81
OGDF_NEW_DELETE
#define OGDF_NEW_DELETE
Makes the class use OGDF's memory allocator.
Definition: memory.h:85
ogdf::MinCostFlowReinelt::nodetype::arc_id
arctype * arc_id
Definition: MinCostFlowReinelt.h:89
ogdf::MinCostFlowReinelt::start_b
arctype * start_b
Definition: MinCostFlowReinelt.h:130
ogdf::MinCostFlowReinelt::mcf
int mcf(int mcfNrNodes, int mcfNrArcs, Array< int > &mcfSupply, Array< int > &mcfTail, Array< int > &mcfHead, Array< int > &mcfLb, Array< int > &mcfUb, Array< TCost > &mcfCost, Array< int > &mcfFlow, Array< TCost > &mcfDual, TCost *mcfObj)
Definition: MinCostFlowReinelt.h:583
ogdf::MinCostFlowReinelt::start_n1
arctype * start_n1
Definition: MinCostFlowReinelt.h:131
ogdf::MinCostFlowReinelt::searchend_n2
arctype * searchend_n2
Definition: MinCostFlowReinelt.h:136
ogdf::EdgeElement::isSelfLoop
bool isSelfLoop() const
Returns true iff the edge is a self-loop (source node = target node).
Definition: Graph_d.h:419
ogdf::MinCostFlowReinelt::arctype::head
nodetype * head
Definition: MinCostFlowReinelt.h:101
ogdf::Array< int >
GraphList.h
Decralation of GraphElement and GraphList classes.
ogdf::MinCostFlowModule
Interface for min-cost flow algorithms.
Definition: MinCostFlowModule.h:50
ogdf::MinCostFlowReinelt::arctype::cost
TCost cost
Definition: MinCostFlowReinelt.h:102
ogdf::MinCostFlowReinelt::start_n2
arctype * start_n2
Definition: MinCostFlowReinelt.h:132
ogdf::MinCostFlowReinelt::arctype
Definition: MinCostFlowReinelt.h:98
ogdf::MinCostFlowReinelt::nn
int nn
Definition: MinCostFlowReinelt.h:141
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:398
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:658
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:869
ogdf::MinCostFlowReinelt::beacircle
void beacircle(arctype **eplus, arctype **pre, bool *from_ub)
Definition: MinCostFlowReinelt.h:304
ogdf::MinCostFlowReinelt::mm
int mm
Definition: MinCostFlowReinelt.h:142
ogdf::MinCostFlowReinelt::m_maxCost
TCost m_maxCost
Definition: MinCostFlowReinelt.h:139
ogdf::MinCostFlowReinelt::searchend
arctype * searchend
Definition: MinCostFlowReinelt.h:134
ogdf::MinCostFlowReinelt::nodetype::nr_of_nodes
int nr_of_nodes
Definition: MinCostFlowReinelt.h:95
ogdf::MinCostFlowReinelt::arctype::next_arc
arctype * next_arc
Definition: MinCostFlowReinelt.h:99
basic.h
Basic declarations, included by all source files.
ogdf::MinCostFlowReinelt::nodetype::dual
TCost dual
Definition: MinCostFlowReinelt.h:91
ogdf::MinCostFlowReinelt::root
nodetype * root
Definition: MinCostFlowReinelt.h:124
ogdf::MinCostFlowReinelt::start
void start(Array< int > &supply)
Definition: MinCostFlowReinelt.h:251
Array.h
Declaration and implementation of Array class and Array algorithms.
ogdf::MinCostFlowReinelt::arctype::arcnum
int arcnum
Definition: MinCostFlowReinelt.h:104
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:363
ogdf::MinCostFlowReinelt::last_n2
arctype * last_n2
Definition: MinCostFlowReinelt.h:128
MinCostFlowModule.h
Definition of ogdf::MinCostFlowModule class template.
ogdf::MinCostFlowReinelt::nodetype::last
nodetype * last
Definition: MinCostFlowReinelt.h:94
ogdf::MinCostFlowReinelt::nodes
Array< nodetype > nodes
Definition: MinCostFlowReinelt.h:120
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:401
ogdf::MinCostFlowReinelt::arcs
Array< arctype > arcs
Definition: MinCostFlowReinelt.h:121
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:240
memory.h
Declaration of memory manager for allocating small pieces of memory.
ogdf::MinCostFlowReinelt::nodetype::name
int name
Definition: MinCostFlowReinelt.h:93
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:716