# HG changeset patch
# User Alpar Juttner <alpar@cs.elte.hu>
# Date 1238427997 -3600
# Node ID 5d1dc5085b442dcf54533aca3a689fc7abc49efc
# Parent 49a39bae067c4eca487e09c782ab3edba172b030
Accept negative values as unbounded capacity in dimacs readers (#243)
diff --git a/lemon/dimacs.h b/lemon/dimacs.h
a
|
b
|
|
22 | 22 | #include <iostream> |
23 | 23 | #include <string> |
24 | 24 | #include <vector> |
| 25 | #include <limits> |
25 | 26 | #include <lemon/maps.h> |
26 | 27 | #include <lemon/error.h> |
27 | | |
28 | 28 | /// \ingroup dimacs_group |
29 | 29 | /// \file |
30 | 30 | /// \brief DIMACS file format reader. |
… |
… |
|
109 | 109 | /// lower bounds, capacities and costs of the arcs are written to |
110 | 110 | /// \c lower, \c capacity and \c cost. |
111 | 111 | /// |
| 112 | /// If the capacity of an arc is less than the lower bound, it will |
| 113 | /// be set to "infinite" instead. The value if "infinite" is contolled |
| 114 | /// by the \c infty parameter. If it is 0 (the default value), |
| 115 | /// std::numeric_limits<Capacity>::infinity() will be used if available, |
| 116 | /// std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to |
| 117 | /// a nonzero value, that value will be used as "infinite". |
| 118 | /// |
112 | 119 | /// If the file type was previously evaluated by dimacsType(), then |
113 | 120 | /// the descriptor struct should be given by the \c dest parameter. |
114 | 121 | template <typename Digraph, typename LowerMap, |
… |
… |
|
120 | 127 | CapacityMap& capacity, |
121 | 128 | CostMap& cost, |
122 | 129 | SupplyMap& supply, |
| 130 | typename CapacityMap::Value infty = 0, |
123 | 131 | DimacsDescriptor desc=DimacsDescriptor()) |
124 | 132 | { |
125 | 133 | g.clear(); |
… |
… |
|
142 | 150 | typename CapacityMap::Value low; |
143 | 151 | typename CapacityMap::Value cap; |
144 | 152 | typename CostMap::Value co; |
| 153 | typedef typename CapacityMap::Value Capacity; |
| 154 | if(infty==0) |
| 155 | infty = std::numeric_limits<Capacity>::has_infinity ? |
| 156 | std::numeric_limits<Capacity>::infinity() : |
| 157 | std::numeric_limits<Capacity>::max(); |
| 158 | |
145 | 159 | while (is >> c) { |
146 | 160 | switch (c) { |
147 | 161 | case 'c': // comment line |
… |
… |
|
152 | 166 | getline(is, str); |
153 | 167 | supply.set(nodes[i], sup); |
154 | 168 | break; |
155 | | case 'a': // arc (arc) definition line |
| 169 | case 'a': // arc definition line |
156 | 170 | is >> i >> j >> low >> cap >> co; |
157 | 171 | getline(is, str); |
158 | 172 | e = g.addArc(nodes[i], nodes[j]); |
159 | 173 | lower.set(e, low); |
160 | | if (cap >= 0) |
| 174 | if (cap >= low) |
161 | 175 | capacity.set(e, cap); |
162 | 176 | else |
163 | | capacity.set(e, -1); |
| 177 | capacity.set(e, infty); |
164 | 178 | cost.set(e, co); |
165 | 179 | break; |
166 | 180 | } |
… |
… |
|
173 | 187 | CapacityMap& capacity, |
174 | 188 | typename Digraph::Node &s, |
175 | 189 | typename Digraph::Node &t, |
| 190 | typename CapacityMap::Value infty = 0, |
176 | 191 | DimacsDescriptor desc=DimacsDescriptor()) { |
177 | 192 | g.clear(); |
178 | 193 | s=t=INVALID; |
… |
… |
|
186 | 201 | for (int k = 1; k <= desc.nodeNum; ++k) { |
187 | 202 | nodes[k] = g.addNode(); |
188 | 203 | } |
| 204 | typedef typename CapacityMap::Value Capacity; |
189 | 205 | |
| 206 | if(infty==0) |
| 207 | infty = std::numeric_limits<Capacity>::has_infinity ? |
| 208 | std::numeric_limits<Capacity>::infinity() : |
| 209 | std::numeric_limits<Capacity>::max(); |
| 210 | |
190 | 211 | while (is >> c) { |
191 | 212 | switch (c) { |
192 | 213 | case 'c': // comment line |
… |
… |
|
205 | 226 | if (d == 't') t = nodes[i]; |
206 | 227 | } |
207 | 228 | break; |
208 | | case 'a': // arc (arc) definition line |
209 | | if (desc.type==DimacsDescriptor::SP || |
210 | | desc.type==DimacsDescriptor::MAX) { |
| 229 | case 'a': // arc definition line |
| 230 | if (desc.type==DimacsDescriptor::SP) { |
211 | 231 | is >> i >> j >> _cap; |
212 | 232 | getline(is, str); |
213 | 233 | e = g.addArc(nodes[i], nodes[j]); |
214 | 234 | capacity.set(e, _cap); |
215 | | } else { |
| 235 | } |
| 236 | else if (desc.type==DimacsDescriptor::MAX) { |
| 237 | is >> i >> j >> _cap; |
| 238 | getline(is, str); |
| 239 | e = g.addArc(nodes[i], nodes[j]); |
| 240 | if (_cap >= 0) |
| 241 | capacity.set(e, _cap); |
| 242 | else |
| 243 | capacity.set(e, infty); |
| 244 | } |
| 245 | else { |
216 | 246 | is >> i >> j; |
217 | 247 | getline(is, str); |
218 | 248 | g.addArc(nodes[i], nodes[j]); |
… |
… |
|
233 | 263 | /// capacities are written to \c capacity and \c s and \c t are |
234 | 264 | /// set to the source and the target nodes. |
235 | 265 | /// |
| 266 | /// If the capacity of an arc is less than 0, it will |
| 267 | /// be set to "infinite" instead. The value if "infinite" is contolled |
| 268 | /// by the \c infty parameter. If it is 0 (the default value), |
| 269 | /// std::numeric_limits<Capacity>::infinity() will be used if available, |
| 270 | /// std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to |
| 271 | /// a nonzero value, that value will be used as "infinite". |
| 272 | /// |
236 | 273 | /// If the file type was previously evaluated by dimacsType(), then |
237 | 274 | /// the descriptor struct should be given by the \c dest parameter. |
238 | 275 | template<typename Digraph, typename CapacityMap> |
… |
… |
|
241 | 278 | CapacityMap& capacity, |
242 | 279 | typename Digraph::Node &s, |
243 | 280 | typename Digraph::Node &t, |
| 281 | typename CapacityMap::Value infty = 0, |
244 | 282 | DimacsDescriptor desc=DimacsDescriptor()) { |
245 | 283 | if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is); |
246 | 284 | if(desc.type!=DimacsDescriptor::MAX) |
247 | 285 | throw FormatError("Problem type mismatch"); |
248 | | _readDimacs(is,g,capacity,s,t,desc); |
| 286 | _readDimacs(is,g,capacity,s,t,infty,desc); |
249 | 287 | } |
250 | 288 | |
251 | 289 | /// DIMACS shortest path reader function. |
… |
… |
|
271 | 309 | if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is); |
272 | 310 | if(desc.type!=DimacsDescriptor::SP) |
273 | 311 | throw FormatError("Problem type mismatch"); |
274 | | _readDimacs(is, g, length, s, t,desc); |
| 312 | _readDimacs(is, g, length, s, t, 0, desc); |
275 | 313 | } |
276 | 314 | |
277 | 315 | /// DIMACS capacitated digraph reader function. |
… |
… |
|
281 | 319 | /// At the beginning, \c g is cleared by \c g.clear() |
282 | 320 | /// and the arc capacities/lengths are written to \c capacity. |
283 | 321 | /// |
| 322 | /// If the capacity of an arc is less than 0, it will |
| 323 | /// be set to "infinite" instead. The value if "infinite" is contolled |
| 324 | /// by the \c infty parameter. If it is 0 (the default value), |
| 325 | /// std::numeric_limits<Capacity>::infinity() will be used if available, |
| 326 | /// std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to |
| 327 | /// a nonzero value, that value will be used as "infinite". |
| 328 | /// |
284 | 329 | /// If the file type was previously evaluated by dimacsType(), then |
285 | 330 | /// the descriptor struct should be given by the \c dest parameter. |
286 | 331 | template<typename Digraph, typename CapacityMap> |
287 | 332 | void readDimacsCap(std::istream& is, |
288 | 333 | Digraph &g, |
289 | 334 | CapacityMap& capacity, |
| 335 | typename CapacityMap::Value infty = 0, |
290 | 336 | DimacsDescriptor desc=DimacsDescriptor()) { |
291 | 337 | typename Digraph::Node u,v; |
292 | 338 | if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is); |
293 | 339 | if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP) |
294 | 340 | throw FormatError("Problem type mismatch"); |
295 | | _readDimacs(is, g, capacity, u, v, desc); |
| 341 | _readDimacs(is, g, capacity, u, v, infty, desc); |
296 | 342 | } |
297 | 343 | |
298 | 344 | template<typename Graph> |
diff --git a/tools/dimacs-solver.cc b/tools/dimacs-solver.cc
a
|
b
|
|
72 | 72 | |
73 | 73 | template<class Value> |
74 | 74 | void solve_max(ArgParser &ap, std::istream &is, std::ostream &, |
75 | | DimacsDescriptor &desc) |
| 75 | Value infty, DimacsDescriptor &desc) |
76 | 76 | { |
77 | 77 | bool report = !ap.given("q"); |
78 | 78 | Digraph g; |
… |
… |
|
80 | 80 | Digraph::ArcMap<Value> cap(g); |
81 | 81 | Timer ti; |
82 | 82 | ti.restart(); |
83 | | readDimacsMax(is, g, cap, s, t, desc); |
| 83 | readDimacsMax(is, g, cap, s, t, infty, desc); |
84 | 84 | if(report) std::cerr << "Read the file: " << ti << '\n'; |
85 | 85 | ti.restart(); |
86 | 86 | Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t); |
… |
… |
|
115 | 115 | void solve(ArgParser &ap, std::istream &is, std::ostream &os, |
116 | 116 | DimacsDescriptor &desc) |
117 | 117 | { |
| 118 | std::stringstream iss(ap["infty"]); |
| 119 | Value infty; |
| 120 | iss >> infty; |
| 121 | if(is.fail()) |
| 122 | { |
| 123 | std::cerr << "Cannot interpret '" |
| 124 | << static_cast<std::string>(ap["infty"]) << "' as infinite" |
| 125 | << std::endl; |
| 126 | exit(1); |
| 127 | } |
| 128 | |
118 | 129 | switch(desc.type) |
119 | 130 | { |
120 | 131 | case DimacsDescriptor::MIN: |
… |
… |
|
122 | 133 | "\n\n Sorry, the min. cost flow solver is not yet available.\n"; |
123 | 134 | break; |
124 | 135 | case DimacsDescriptor::MAX: |
125 | | solve_max<Value>(ap,is,os,desc); |
| 136 | solve_max<Value>(ap,is,os,infty,desc); |
126 | 137 | break; |
127 | 138 | case DimacsDescriptor::SP: |
128 | 139 | solve_sp<Value>(ap,is,os,desc); |
… |
… |
|
159 | 170 | .boolOption("ldouble","Use 'long double' for capacities, costs etc.") |
160 | 171 | .optionGroup("datatype","ldouble") |
161 | 172 | .onlyOneGroup("datatype") |
| 173 | .stringOption("infcap","Value of 'very high' capacities","0") |
162 | 174 | .run(); |
163 | 175 | |
164 | 176 | std::ifstream input; |
diff --git a/tools/dimacs-to-lgf.cc b/tools/dimacs-to-lgf.cc
a
|
b
|
|
96 | 96 | Digraph digraph; |
97 | 97 | DoubleArcMap lower(digraph), capacity(digraph), cost(digraph); |
98 | 98 | DoubleNodeMap supply(digraph); |
99 | | readDimacsMin(is, digraph, lower, capacity, cost, supply, desc); |
| 99 | readDimacsMin(is, digraph, lower, capacity, cost, supply, 0, desc); |
100 | 100 | DigraphWriter<Digraph>(digraph, os). |
101 | 101 | nodeMap("supply", supply). |
102 | 102 | arcMap("lower", lower). |
… |
… |
|
111 | 111 | Digraph digraph; |
112 | 112 | Node s, t; |
113 | 113 | DoubleArcMap capacity(digraph); |
114 | | readDimacsMax(is, digraph, capacity, s, t, desc); |
| 114 | readDimacsMax(is, digraph, capacity, s, t, 0, desc); |
115 | 115 | DigraphWriter<Digraph>(digraph, os). |
116 | 116 | arcMap("capacity", capacity). |
117 | 117 | node("source", s). |