gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
dimacs.h reads MAT files to both dir and undir graphs (#231)
0 1 0
default
1 file changed with 46 insertions and 8 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
... ...
@@ -106,252 +106,290 @@
106 106
  /// \endcode
107 107
  /// At the beginning, \c g is cleared by \c g.clear(). The supply
108 108
  /// amount of the nodes are written to \c supply (signed). The
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 112
  /// If the file type was previously evaluated by dimacsType(), then
113 113
  /// the descriptor struct should be given by the \c dest parameter.
114 114
  template <typename Digraph, typename LowerMap,
115 115
            typename CapacityMap, typename CostMap,
116 116
            typename SupplyMap>
117 117
  void readDimacsMin(std::istream& is,
118 118
                     Digraph &g,
119 119
                     LowerMap& lower,
120 120
                     CapacityMap& capacity,
121 121
                     CostMap& cost,
122 122
                     SupplyMap& supply,
123 123
                     DimacsDescriptor desc=DimacsDescriptor())
124 124
  {
125 125
    g.clear();
126 126
    std::vector<typename Digraph::Node> nodes;
127 127
    typename Digraph::Arc e;
128 128
    std::string problem, str;
129 129
    char c;
130 130
    int i, j;
131 131
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
132 132
    if(desc.type!=DimacsDescriptor::MIN)
133 133
      throw FormatError("Problem type mismatch");
134 134

	
135 135
    nodes.resize(desc.nodeNum + 1);
136 136
    for (int k = 1; k <= desc.nodeNum; ++k) {
137 137
      nodes[k] = g.addNode();
138 138
      supply.set(nodes[k], 0);
139 139
    }
140 140

	
141 141
    typename SupplyMap::Value sup;
142 142
    typename CapacityMap::Value low;
143 143
    typename CapacityMap::Value cap;
144 144
    typename CostMap::Value co;
145 145
    while (is >> c) {
146 146
      switch (c) {
147 147
      case 'c': // comment line
148 148
        getline(is, str);
149 149
        break;
150 150
      case 'n': // node definition line
151 151
        is >> i >> sup;
152 152
        getline(is, str);
153 153
        supply.set(nodes[i], sup);
154 154
        break;
155 155
      case 'a': // arc (arc) definition line
156 156
        is >> i >> j >> low >> cap >> co;
157 157
        getline(is, str);
158 158
        e = g.addArc(nodes[i], nodes[j]);
159 159
        lower.set(e, low);
160 160
        if (cap >= 0)
161 161
          capacity.set(e, cap);
162 162
        else
163 163
          capacity.set(e, -1);
164 164
        cost.set(e, co);
165 165
        break;
166 166
      }
167 167
    }
168 168
  }
169 169

	
170 170
  template<typename Digraph, typename CapacityMap>
171 171
  void _readDimacs(std::istream& is,
172 172
                   Digraph &g,
173 173
                   CapacityMap& capacity,
174 174
                   typename Digraph::Node &s,
175 175
                   typename Digraph::Node &t,
176 176
                   DimacsDescriptor desc=DimacsDescriptor()) {
177 177
    g.clear();
178 178
    s=t=INVALID;
179 179
    std::vector<typename Digraph::Node> nodes;
180 180
    typename Digraph::Arc e;
181 181
    char c, d;
182 182
    int i, j;
183 183
    typename CapacityMap::Value _cap;
184 184
    std::string str;
185 185
    nodes.resize(desc.nodeNum + 1);
186 186
    for (int k = 1; k <= desc.nodeNum; ++k) {
187 187
      nodes[k] = g.addNode();
188 188
    }
189 189

	
190 190
    while (is >> c) {
191 191
      switch (c) {
192 192
      case 'c': // comment line
193 193
        getline(is, str);
194 194
        break;
195 195
      case 'n': // node definition line
196 196
        if (desc.type==DimacsDescriptor::SP) { // shortest path problem
197 197
          is >> i;
198 198
          getline(is, str);
199 199
          s = nodes[i];
200 200
        }
201 201
        if (desc.type==DimacsDescriptor::MAX) { // max flow problem
202 202
          is >> i >> d;
203 203
          getline(is, str);
204 204
          if (d == 's') s = nodes[i];
205 205
          if (d == 't') t = nodes[i];
206 206
        }
207 207
        break;
208 208
      case 'a': // arc (arc) definition line
209 209
        if (desc.type==DimacsDescriptor::SP ||
210 210
            desc.type==DimacsDescriptor::MAX) {
211 211
          is >> i >> j >> _cap;
212 212
          getline(is, str);
213 213
          e = g.addArc(nodes[i], nodes[j]);
214 214
          capacity.set(e, _cap);
215 215
        } else {
216 216
          is >> i >> j;
217 217
          getline(is, str);
218 218
          g.addArc(nodes[i], nodes[j]);
219 219
        }
220 220
        break;
221 221
      }
222 222
    }
223 223
  }
224 224

	
225 225
  /// DIMACS maximum flow reader function.
226 226
  ///
227 227
  /// This function reads a maximum flow instance from DIMACS format,
228 228
  /// i.e. from a DIMACS file having a line starting with
229 229
  /// \code
230 230
  ///   p max
231 231
  /// \endcode
232 232
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
233 233
  /// capacities are written to \c capacity and \c s and \c t are
234 234
  /// set to the source and the target nodes.
235 235
  ///
236 236
  /// If the file type was previously evaluated by dimacsType(), then
237 237
  /// the descriptor struct should be given by the \c dest parameter.
238 238
  template<typename Digraph, typename CapacityMap>
239 239
  void readDimacsMax(std::istream& is,
240 240
                     Digraph &g,
241 241
                     CapacityMap& capacity,
242 242
                     typename Digraph::Node &s,
243 243
                     typename Digraph::Node &t,
244 244
                     DimacsDescriptor desc=DimacsDescriptor()) {
245 245
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
246 246
    if(desc.type!=DimacsDescriptor::MAX)
247 247
      throw FormatError("Problem type mismatch");
248 248
    _readDimacs(is,g,capacity,s,t,desc);
249 249
  }
250 250

	
251 251
  /// DIMACS shortest path reader function.
252 252
  ///
253 253
  /// This function reads a shortest path instance from DIMACS format,
254 254
  /// i.e. from a DIMACS file having a line starting with
255 255
  /// \code
256 256
  ///   p sp
257 257
  /// \endcode
258 258
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
259 259
  /// lengths are written to \c length and \c s is set to the
260 260
  /// source node.
261 261
  ///
262 262
  /// If the file type was previously evaluated by dimacsType(), then
263 263
  /// the descriptor struct should be given by the \c dest parameter.
264 264
  template<typename Digraph, typename LengthMap>
265 265
  void readDimacsSp(std::istream& is,
266 266
                    Digraph &g,
267 267
                    LengthMap& length,
268 268
                    typename Digraph::Node &s,
269 269
                    DimacsDescriptor desc=DimacsDescriptor()) {
270 270
    typename Digraph::Node t;
271 271
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
272 272
    if(desc.type!=DimacsDescriptor::SP)
273 273
      throw FormatError("Problem type mismatch");
274 274
    _readDimacs(is, g, length, s, t,desc);
275 275
  }
276 276

	
277 277
  /// DIMACS capacitated digraph reader function.
278 278
  ///
279 279
  /// This function reads an arc capacitated digraph instance from
280 280
  /// DIMACS 'mat' or 'sp' format.
281 281
  /// At the beginning, \c g is cleared by \c g.clear()
282 282
  /// and the arc capacities/lengths are written to \c capacity.
283 283
  ///
284 284
  /// If the file type was previously evaluated by dimacsType(), then
285 285
  /// the descriptor struct should be given by the \c dest parameter.
286 286
  template<typename Digraph, typename CapacityMap>
287 287
  void readDimacsCap(std::istream& is,
288 288
                     Digraph &g,
289 289
                     CapacityMap& capacity,
290 290
                     DimacsDescriptor desc=DimacsDescriptor()) {
291 291
    typename Digraph::Node u,v;
292 292
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
293 293
    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
294 294
      throw FormatError("Problem type mismatch");
295 295
    _readDimacs(is, g, capacity, u, v, desc);
296 296
  }
297 297

	
298
  /// DIMACS plain digraph reader function.
298
  template<typename Graph>
299
  typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
300
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
301
              dummy<0> = 0)
302
  {
303
    g.addEdge(s,t);
304
  }
305
  template<typename Graph>
306
  typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
307
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
308
              dummy<1> = 1)
309
  {
310
    g.addArc(s,t);
311
  }
312
  
313
  /// DIMACS plain (di)graph reader function.
299 314
  ///
300
  /// This function reads a digraph without any designated nodes and
315
  /// This function reads a (di)graph without any designated nodes and
301 316
  /// maps from DIMACS format, i.e. from DIMACS files having a line
302 317
  /// starting with
303 318
  /// \code
304 319
  ///   p mat
305 320
  /// \endcode
306 321
  /// At the beginning, \c g is cleared by \c g.clear().
307 322
  ///
308 323
  /// If the file type was previously evaluated by dimacsType(), then
309 324
  /// the descriptor struct should be given by the \c dest parameter.
310
  template<typename Digraph>
311
  void readDimacsMat(std::istream& is, Digraph &g,
312
                     DimacsDescriptor desc=DimacsDescriptor()) {
313
    typename Digraph::Node u,v;
314
    NullMap<typename Digraph::Arc, int> n;
325
  template<typename Graph>
326
  void readDimacsMat(std::istream& is, Graph &g,
327
                     DimacsDescriptor desc=DimacsDescriptor())
328
  {
315 329
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
316 330
    if(desc.type!=DimacsDescriptor::MAT)
317 331
      throw FormatError("Problem type mismatch");
318
    _readDimacs(is, g, n, u, v, desc);
332

	
333
    g.clear();
334
    std::vector<typename Graph::Node> nodes;
335
    char c;
336
    int i, j;
337
    std::string str;
338
    nodes.resize(desc.nodeNum + 1);
339
    for (int k = 1; k <= desc.nodeNum; ++k) {
340
      nodes[k] = g.addNode();
341
    }
342
    
343
    while (is >> c) {
344
      switch (c) {
345
      case 'c': // comment line
346
        getline(is, str);
347
        break;
348
      case 'n': // node definition line
349
        break;
350
      case 'a': // arc (arc) definition line
351
        is >> i >> j;
352
        getline(is, str);
353
        _addArcEdge(g,nodes[i], nodes[j]);
354
        break;
355
      }
356
    }
319 357
  }
320 358

	
321 359
  /// DIMACS plain digraph writer function.
322 360
  ///
323 361
  /// This function writes a digraph without any designated nodes and
324 362
  /// maps into DIMACS format, i.e. into DIMACS file having a line
325 363
  /// starting with
326 364
  /// \code
327 365
  ///   p mat
328 366
  /// \endcode
329 367
  /// If \c comment is not empty, then it will be printed in the first line
330 368
  /// prefixed by 'c'.
331 369
  template<typename Digraph>
332 370
  void writeDimacsMat(std::ostream& os, const Digraph &g,
333 371
                      std::string comment="") {
334 372
    typedef typename Digraph::NodeIt NodeIt;
335 373
    typedef typename Digraph::ArcIt ArcIt;
336 374

	
337 375
    if(!comment.empty())
338 376
      os << "c " << comment << std::endl;
339 377
    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
340 378

	
341 379
    typename Digraph::template NodeMap<int> nodes(g);
342 380
    int i = 1;
343 381
    for(NodeIt v(g); v != INVALID; ++v) {
344 382
      nodes.set(v, i);
345 383
      ++i;
346 384
    }
347 385
    for(ArcIt e(g); e != INVALID; ++e) {
348 386
      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
349 387
         << std::endl;
350 388
    }
351 389
  }
352 390

	
353 391
  /// @}
354 392

	
355 393
} //namespace lemon
356 394

	
357 395
#endif //LEMON_DIMACS_H
0 comments (0 inline)