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