43template<
typename TCost>
73 int infinity()
const {
return std::numeric_limits<int>::max(); }
145template<
typename TCost>
151 const int n = G.numberOfNodes();
152 const int m = G.numberOfEdges();
161 for (
node v : G.nodes) {
179 for (
edge e : G.edges) {
182 if (e->isSelfLoop()) {
189 mcfLb[i] = lowerBound[e];
190 mcfUb[i] = upperBound[e];
217 for (
edge e : G.edges) {
218 if (e->isSelfLoop()) {
219 flow[e] = lowerBound[e];
233 for (
node v : G.nodes) {
242template<
typename TCost>
248 root->successor = &nodes[1];
249 root->arc_id =
nullptr;
250 root->orientation =
false;
253 root->nr_of_nodes = nn + 1;
254 root->last = &nodes[nn];
259 for (
int i = 1; i <= nn; ++i) {
262 ep->tail = &nodes[i];
266 ep->head = &nodes[i];
269 ep->upper_bound = infinity();
270 ep->arcnum = mm + i - 1;
271 ep->next_arc = start_b;
273 nodes[i].father = root;
275 nodes[i].successor = &nodes[i + 1];
277 nodes[i].successor = root;
280 nodes[i].orientation =
false;
283 nodes[i].orientation =
true;
286 nodes[i].flow = abs(
supply[i - 1]);
287 nodes[i].nr_of_nodes = 1;
288 nodes[i].last = &nodes[i];
289 nodes[i].arc_id =
ep;
291 start_n1 = start_arc;
295template<
typename TCost>
303 if (*
pre !=
nullptr) {
304 *
eplus = (*pre)->next_arc;
312 if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
316 *
eplus = (*eplus)->next_arc;
327 if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
331 *
eplus = (*eplus)->next_arc;
342 if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
346 *
eplus = (*eplus)->next_arc;
356 if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
360 *
eplus = (*eplus)->next_arc;
370 if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
374 *
eplus = (*eplus)->next_arc;
385 if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
389 *
eplus = (*eplus)->next_arc;
402 startsearch = (*eplus)->next_arc;
408template<
typename TCost>
417 if (*
pre !=
nullptr) {
418 *
eplus = (*pre)->next_arc;
422 searchend_n1 = *
eplus;
425 if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
429 *
eplus = (*eplus)->next_arc;
437 if (*
pre !=
nullptr) {
438 *
eplus = (*pre)->next_arc;
442 searchend_n2 = *
eplus;
445 if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
449 *
eplus = (*eplus)->next_arc;
460 if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
464 *
eplus = (*eplus)->next_arc;
477 if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
481 *
eplus = (*eplus)->next_arc;
490 if (*
pre !=
nullptr) {
491 *
eplus = (*pre)->next_arc;
495 searchend_n2 = *
eplus;
498 if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
502 *
eplus = (*eplus)->next_arc;
509 if (*
pre !=
nullptr) {
510 *
eplus = (*pre)->next_arc;
514 searchend_n1 = *
eplus;
517 if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
521 *
eplus = (*eplus)->next_arc;
531 if (m_eps.less((*eplus)->cost + (*eplus)->head->dual, (*eplus)->tail->dual)) {
535 *
eplus = (*eplus)->next_arc;
546 if (m_eps.less((*eplus)->tail->dual, (*eplus)->head->dual + (*eplus)->cost)) {
550 *
eplus = (*eplus)->next_arc;
566 last_n2 = (*eplus)->next_arc;
568 last_n1 = (*eplus)->next_arc;
574template<
typename TCost>
600 for (i = 1; i <= nn; ++i) {
618 if (
abs_c > m_maxCost) {
622 start_arc = &arcs[1];
623 start_arc->tail = &nodes[
from];
624 start_arc->head = &nodes[
toh];
626 start_arc->upper_bound = up - low;
627 start_arc->arcnum = 0;
630 lb_cost += start_arc->cost * low;
644 abs_c = c < 0 ? -c : c;
645 if (
abs_c > m_maxCost) {
652 ep->head = &nodes[
toh];
654 ep->upper_bound = up - low;
664 bool feasible =
true;
680 bool finished =
false;
683 startsearch = start_n1;
696 if (
eplus ==
nullptr) {
704 int delta =
eplus->upper_bound;
715 if (delta >
np->arc_id->upper_bound -
np->flow) {
717 delta =
np->arc_id->upper_bound -
np->flow;
721 }
else if (delta >
np->flow) {
732 if (delta >
np->arc_id->upper_bound -
np->flow) {
734 delta =
np->arc_id->upper_bound -
np->flow;
738 }
else if (delta >
np->flow) {
834 for (i = 1; i <=
iminus->nr_of_nodes; ++i) {
956 if (
pre ==
nullptr) {
957 start_n1 =
eminus->next_arc;
962 eminus->next_arc = start_n2;
965 if (
pre ==
nullptr) {
966 start_n2 =
eminus->next_arc;
970 eminus->next_arc = start_n1;
991 if (
pre !=
nullptr) {
992 pre->next_arc =
ep->next_arc;
995 start_n2 =
ep->next_arc;
997 start_n1 =
ep->next_arc;
1002 ep->next_arc = start_n2;
1006 ep->next_arc = start_n1;
1024 if (
e1 == start_b) {
1025 start_b =
e1->next_arc;
1035 root = root->successor;
1036 root->father = root;
1040 while (
np->successor !=
iw) {
1046 np->successor = root;
1051 }
while (!finished);
1057 np = root->successor;
1059 if (
np->father == root &&
np->flow > 0) {
1065 }
while (
np != root);
1068 while (
ep !=
nullptr && feasible) {
1069 if (
ep ==
nullptr) {
1072 if (
ep->tail == root &&
ep->head == root) {
1084 np = root->successor;
1085 while (
np != root) {
1086 if (
np->flow != 0) {
1087 zfw +=
np->flow *
np->arc_id->cost;
1092 while (
ep !=
nullptr) {
1093 zfw +=
ep->cost *
ep->upper_bound;
1100 np = root->successor;
1101 while (
np != root) {
1105 mcfDual[root->name - 1] = root->dual;
1108 for (i = 0; i < mm; ++i) {
1112 np = root->successor;
1113 while (
np != root) {
1117 if (
np->arc_id->arcnum < mm) {
1125 while (
ep !=
nullptr) {
1135 for (i = 1; i <= nn; ++i)
1137 delete p[i]->arc_id;
1139 delete nodes[i].arc_id;
Compare floating point numbers with epsilons and integral numbers with normal compare operators.
Definition of ogdf::MinCostFlowModule class template.
The parameterized class Array implements dynamic arrays of type E.
Dynamic arrays indexed with edges.
Class for the representation of edges.
Data type for general directed graphs (adjacency list representation).
Interface for min-cost flow algorithms.
Computes a min-cost flow using a network simplex method.
void beacircle(arctype **eplus, arctype **pre, bool *from_ub)
void start(Array< int > &supply)
void beadouble(arctype **eplus, arctype **pre, bool *from_ub)
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.
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)
Dynamic arrays indexed with nodes.
Class for the representation of nodes.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
#define OGDF_NEW_DELETE
Makes the class use OGDF's memory allocator.
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.