1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
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/preflow.h>
25 #include <lemon/concepts/digraph.h>
26 #include <lemon/concepts/maps.h>
27 #include <lemon/lgf_reader.h>
28 #include <lemon/elevator.h>
30 using namespace lemon;
32 void checkPreflowCompile()
35 typedef concepts::Digraph Digraph;
37 typedef Digraph::Node Node;
38 typedef Digraph::Arc Arc;
39 typedef concepts::ReadMap<Arc,VType> CapMap;
40 typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
41 typedef concepts::WriteMap<Node,bool> CutMap;
43 typedef Elevator<Digraph, Digraph::Node> Elev;
44 typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
53 Preflow<Digraph, CapMap>
56 ::SetStandardElevator<LinkedElev>
57 ::Create preflow_test(g,cap,n,n);
59 preflow_test.capacityMap(cap);
60 flow = preflow_test.flowMap();
61 preflow_test.flowMap(flow);
62 preflow_test.source(n);
63 preflow_test.target(n);
66 preflow_test.init(cap);
67 preflow_test.startFirstPhase();
68 preflow_test.startSecondPhase();
70 preflow_test.runMinCut();
72 preflow_test.flowValue();
73 preflow_test.minCut(n);
74 preflow_test.minCutMap(cut);
79 int cutValue (const SmartDigraph& g,
80 const SmartDigraph::NodeMap<bool>& cut,
81 const SmartDigraph::ArcMap<int>& cap) {
84 for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
85 if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
90 bool checkFlow(const SmartDigraph& g,
91 const SmartDigraph::ArcMap<int>& flow,
92 const SmartDigraph::ArcMap<int>& cap,
93 SmartDigraph::Node s, SmartDigraph::Node t) {
95 for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
96 if (flow[e] < 0 || flow[e] > cap[e]) return false;
99 for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
100 if (n == s || n == t) continue;
102 for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
105 for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
108 if (sum != 0) return false;
115 typedef SmartDigraph Digraph;
117 typedef Digraph::Node Node;
118 typedef Digraph::NodeIt NodeIt;
119 typedef Digraph::ArcIt ArcIt;
120 typedef Digraph::ArcMap<int> CapMap;
121 typedef Digraph::ArcMap<int> FlowMap;
122 typedef Digraph::NodeMap<bool> CutMap;
124 typedef Preflow<Digraph, CapMap> PType;
127 if( getenv("srcdir") )
128 f_name = std::string(getenv("srcdir"));
130 f_name += "/test/preflow_graph.lgf";
132 std::ifstream file(f_name.c_str());
134 check(file, "Input file '" << f_name << "' not found.");
139 DigraphReader<Digraph>(g,file).
140 arcMap("capacity", cap).
145 PType preflow_test(g, cap, s, t);
148 check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
149 "The flow is not feasible.");
152 preflow_test.minCutMap(min_cut);
153 int min_cut_value=cutValue(g,min_cut,cap);
155 check(preflow_test.flowValue() == min_cut_value,
156 "The max flow value is not equal to the three min cut values.");
159 for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
161 int flow_value=preflow_test.flowValue();
163 for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
164 preflow_test.init(flow);
165 preflow_test.startFirstPhase();
168 preflow_test.minCutMap(min_cut1);
169 min_cut_value=cutValue(g,min_cut1,cap);
171 check(preflow_test.flowValue() == min_cut_value &&
172 min_cut_value == 2*flow_value,
173 "The max flow value or the min cut value is wrong.");
175 preflow_test.startSecondPhase();
177 check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
178 "The flow is not feasible.");
181 preflow_test.minCutMap(min_cut2);
182 min_cut_value=cutValue(g,min_cut2,cap);
184 check(preflow_test.flowValue() == min_cut_value &&
185 min_cut_value == 2*flow_value,
186 "The max flow value or the three min cut values were not doubled");
189 preflow_test.flowMap(flow);
193 if ( tmp1 != INVALID ) s=tmp1;
197 if ( tmp2 != INVALID ) t=tmp2;
199 preflow_test.source(s);
200 preflow_test.target(t);
205 preflow_test.minCutMap(min_cut3);
206 min_cut_value=cutValue(g,min_cut3,cap);
209 check(preflow_test.flowValue() == min_cut_value,
210 "The max flow value or the three min cut values are incorrect.");