Query improvements in the min cost flow algorithms.
- External flow and potential maps can be used.
- New query functions: flow() and potential().
- CycleCanceling also provides dual solution (node potentials).
- Doc improvements.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
22 #include "test_tools.h"
23 #include <lemon/smart_graph.h>
24 #include <lemon/dimacs.h>
25 #include <lemon/preflow.h>
26 #include <lemon/concepts/graph.h>
27 #include <lemon/concepts/maps.h>
29 using namespace lemon;
34 typedef concepts::Graph Graph;
36 typedef Graph::Node Node;
37 typedef Graph::Edge Edge;
38 typedef concepts::ReadMap<Edge,VType> CapMap;
39 typedef concepts::ReadWriteMap<Edge,VType> FlowMap;
40 typedef concepts::WriteMap<Node,bool> CutMap;
49 Preflow<Graph, CapMap>::DefFlowMap<FlowMap>::Create preflow_test(g,cap,n,n);
51 preflow_test.capacityMap(cap);
52 flow = preflow_test.flowMap();
53 preflow_test.flowMap(flow);
54 preflow_test.source(n);
55 preflow_test.target(n);
58 preflow_test.flowInit(cap);
59 preflow_test.startFirstPhase();
60 preflow_test.startSecondPhase();
62 preflow_test.runMinCut();
64 preflow_test.flowValue();
65 preflow_test.minCut(n);
66 preflow_test.minCutMap(cut);
71 int cutValue (const SmartGraph& g,
72 const SmartGraph::NodeMap<bool>& cut,
73 const SmartGraph::EdgeMap<int>& cap) {
76 for(SmartGraph::EdgeIt e(g); e!=INVALID; ++e) {
77 if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
82 bool checkFlow(const SmartGraph& g,
83 const SmartGraph::EdgeMap<int>& flow,
84 const SmartGraph::EdgeMap<int>& cap,
85 SmartGraph::Node s, SmartGraph::Node t) {
87 for (SmartGraph::EdgeIt e(g); e != INVALID; ++e) {
88 if (flow[e] < 0 || flow[e] > cap[e]) return false;
91 for (SmartGraph::NodeIt n(g); n != INVALID; ++n) {
92 if (n == s || n == t) continue;
94 for (SmartGraph::OutEdgeIt e(g, n); e != INVALID; ++e) {
97 for (SmartGraph::InEdgeIt e(g, n); e != INVALID; ++e) {
100 if (sum != 0) return false;
107 typedef SmartGraph Graph;
109 typedef Graph::Node Node;
110 typedef Graph::NodeIt NodeIt;
111 typedef Graph::EdgeIt EdgeIt;
112 typedef Graph::EdgeMap<int> CapMap;
113 typedef Graph::EdgeMap<int> FlowMap;
114 typedef Graph::NodeMap<bool> CutMap;
116 typedef Preflow<Graph, CapMap> PType;
119 if( getenv("srcdir") )
120 f_name = std::string(getenv("srcdir"));
122 f_name += "/test/preflow_graph.dim";
124 std::ifstream file(f_name.c_str());
126 check(file, "Input file '" << f_name << "' not found.");
131 readDimacs(file, g, cap, s, t);
133 PType preflow_test(g, cap, s, t);
136 check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
137 "The flow is not feasible.");
140 preflow_test.minCutMap(min_cut);
141 int min_cut_value=cutValue(g,min_cut,cap);
143 check(preflow_test.flowValue() == min_cut_value,
144 "The max flow value is not equal to the three min cut values.");
147 flow = preflow_test.flowMap();
149 int flow_value=preflow_test.flowValue();
151 for(EdgeIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
152 preflow_test.flowInit(flow);
153 preflow_test.startFirstPhase();
156 preflow_test.minCutMap(min_cut1);
157 min_cut_value=cutValue(g,min_cut1,cap);
159 check(preflow_test.flowValue() == min_cut_value &&
160 min_cut_value == 2*flow_value,
161 "The max flow value or the min cut value is wrong.");
163 preflow_test.startSecondPhase();
165 check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
166 "The flow is not feasible.");
169 preflow_test.minCutMap(min_cut2);
170 min_cut_value=cutValue(g,min_cut2,cap);
172 check(preflow_test.flowValue() == min_cut_value &&
173 min_cut_value == 2*flow_value,
174 "The max flow value or the three min cut values were not doubled");
177 preflow_test.flowMap(flow);
181 if ( tmp1 != INVALID ) s=tmp1;
185 if ( tmp2 != INVALID ) t=tmp2;
187 preflow_test.source(s);
188 preflow_test.target(t);
193 preflow_test.minCutMap(min_cut3);
194 min_cut_value=cutValue(g,min_cut3,cap);
197 check(preflow_test.flowValue() == min_cut_value,
198 "The max flow value or the three min cut values are incorrect.");