# 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). |