# HG changeset patch
# User Alpar Juttner <alpar@cs.elte.hu>
# Date 1227823486 0
# Node ID 50d96f2166d770692e9e1d8e3cab7ecebbcb53c1
# Parent  fc6954b4fce49fa09a571eb41b2d16ab7c463569
Port DIMACS tools from svn -r3516

Namely,
 - apply migrate script
 - apply unify sources
 - break long lines
 - Fixes the compilation
 - dim_to_lgf -> dimacs-to-lgf
 - better .hgignore
 - shorten the doc of dimacs-to-lgf

diff -r fc6954b4fce4 -r 50d96f2166d7 .hgignore
--- a/.hgignore	Fri Nov 21 10:49:39 2008 +0000
+++ b/.hgignore	Thu Nov 27 22:04:46 2008 +0000
@@ -36,6 +36,7 @@
 ^build-aux/.*
 ^objs.*/.*
 ^test/[a-z_]*$
+^tools/[a-z-_]*$
 ^demo/.*_demo$
 ^build/.*
 ^doc/gen-images/.*
diff -r fc6954b4fce4 -r 50d96f2166d7 lemon/Makefile.am
--- a/lemon/Makefile.am	Fri Nov 21 10:49:39 2008 +0000
+++ b/lemon/Makefile.am	Thu Nov 27 22:04:46 2008 +0000
@@ -27,6 +27,7 @@
         lemon/dfs.h \
         lemon/dijkstra.h \
         lemon/dim2.h \
+        lemon/dimacs.h \
 	lemon/elevator.h \
 	lemon/error.h \
 	lemon/full_graph.h \
diff -r fc6954b4fce4 -r 50d96f2166d7 lemon/dimacs.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/dimacs.h	Thu Nov 27 22:04:46 2008 +0000
@@ -0,0 +1,248 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_DIMACS_H
+#define LEMON_DIMACS_H
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <lemon/maps.h>
+
+/// \ingroup dimacs_group
+/// \file
+/// \brief DIMACS file format reader.
+
+namespace lemon {
+
+  ///@defgroup dimacs_group DIMACS format
+  ///\brief Read and write files in DIMACS format
+  ///
+  ///Tools to read a digraph from or write it to a file in DIMACS format
+  ///data
+  ///\ingroup io_group
+
+  /// \addtogroup dimacs_group
+  /// @{
+
+  /// DIMACS min cost flow reader function.
+  ///
+  /// This function reads a min cost flow instance from DIMACS format,
+  /// i.e. from DIMACS files having a line starting with
+  /// \code
+  ///   p min
+  /// \endcode
+  /// At the beginning \c g is cleared by \c g.clear(). The supply
+  /// amount of the nodes are written to \c supply (signed). The
+  /// lower bounds, capacities and costs of the arcs are written to
+  /// \c lower, \c capacity and \c cost.
+  template <typename Digraph, typename LowerMap,
+    typename CapacityMap, typename CostMap,
+    typename SupplyMap>
+  void readDimacs( std::istream& is,
+                   Digraph &g,
+                   LowerMap& lower,
+                   CapacityMap& capacity,
+                   CostMap& cost,
+                   SupplyMap& supply )
+  {
+    g.clear();
+    std::vector<typename Digraph::Node> nodes;
+    typename Digraph::Arc e;
+    std::string problem, str;
+    char c;
+    int n, m;
+    int i, j;
+    typename SupplyMap::Value sup;
+    typename CapacityMap::Value low;
+    typename CapacityMap::Value cap;
+    typename CostMap::Value co;
+    while (is >> c) {
+      switch (c) {
+      case 'c': // comment line
+        getline(is, str);
+        break;
+      case 'p': // problem definition line
+        is >> problem >> n >> m;
+        getline(is, str);
+        if (problem != "min") return;
+        nodes.resize(n + 1);
+        for (int k = 1; k <= n; ++k) {
+          nodes[k] = g.addNode();
+          supply.set(nodes[k], 0);
+        }
+        break;
+      case 'n': // node definition line
+        is >> i >> sup;
+        getline(is, str);
+        supply.set(nodes[i], sup);
+        break;
+      case 'a': // arc (arc) definition line
+        is >> i >> j >> low >> cap >> co;
+        getline(is, str);
+        e = g.addArc(nodes[i], nodes[j]);
+        lower.set(e, low);
+        if (cap >= 0)
+          capacity.set(e, cap);
+        else
+          capacity.set(e, -1);
+        cost.set(e, co);
+        break;
+      }
+    }
+  }
+
+  /// DIMACS max flow reader function.
+  ///
+  /// This function reads a max flow instance from DIMACS format,
+  /// i.e. from DIMACS files having a line starting with
+  /// \code
+  ///   p max
+  /// \endcode
+  /// At the beginning \c g is cleared by \c g.clear(). The arc
+  /// capacities are written to \c capacity and \c s and \c t are
+  /// set to the source and the target nodes.
+  template<typename Digraph, typename CapacityMap>
+  void readDimacs(std::istream& is, Digraph &g, CapacityMap& capacity,
+                  typename Digraph::Node &s, typename Digraph::Node &t) {
+    g.clear();
+    std::vector<typename Digraph::Node> nodes;
+    typename Digraph::Arc e;
+    std::string problem;
+    char c, d;
+    int n, m;
+    int i, j;
+    typename CapacityMap::Value _cap;
+    std::string str;
+    while (is >> c) {
+      switch (c) {
+      case 'c': // comment line
+        getline(is, str);
+        break;
+      case 'p': // problem definition line
+        is >> problem >> n >> m;
+        getline(is, str);
+        nodes.resize(n + 1);
+        for (int k = 1; k <= n; ++k)
+          nodes[k] = g.addNode();
+        break;
+      case 'n': // node definition line
+        if (problem == "sp") { // shortest path problem
+          is >> i;
+          getline(is, str);
+          s = nodes[i];
+        }
+        if (problem == "max") { // max flow problem
+          is >> i >> d;
+          getline(is, str);
+          if (d == 's') s = nodes[i];
+          if (d == 't') t = nodes[i];
+        }
+        break;
+      case 'a': // arc (arc) definition line
+        if (problem == "max" || problem == "sp") {
+          is >> i >> j >> _cap;
+          getline(is, str);
+          e = g.addArc(nodes[i], nodes[j]);
+          capacity.set(e, _cap);
+        } else {
+          is >> i >> j;
+          getline(is, str);
+          g.addArc(nodes[i], nodes[j]);
+        }
+        break;
+      }
+    }
+  }
+
+  /// DIMACS shortest path reader function.
+  ///
+  /// This function reads a shortest path instance from DIMACS format,
+  /// i.e. from DIMACS files having a line starting with
+  /// \code
+  ///   p sp
+  /// \endcode
+  /// At the beginning \c g is cleared by \c g.clear(). The arc
+  /// capacities are written to \c capacity and \c s is set to the
+  /// source node.
+  template<typename Digraph, typename CapacityMap>
+  void readDimacs(std::istream& is, Digraph &g, CapacityMap& capacity,
+                  typename Digraph::Node &s) {
+    readDimacs(is, g, capacity, s, s);
+  }
+
+  /// DIMACS capacitated digraph reader function.
+  ///
+  /// This function reads an arc capacitated digraph instance from
+  /// DIMACS format. At the beginning \c g is cleared by \c g.clear()
+  /// and the arc capacities are written to \c capacity.
+  template<typename Digraph, typename CapacityMap>
+  void readDimacs(std::istream& is, Digraph &g, CapacityMap& capacity) {
+    typename Digraph::Node u;
+    readDimacs(is, g, capacity, u, u);
+  }
+
+  /// DIMACS plain digraph reader function.
+  ///
+  /// This function reads a digraph without any designated nodes and
+  /// maps from DIMACS format, i.e. from DIMACS files having a line
+  /// starting with
+  /// \code
+  ///   p mat
+  /// \endcode
+  /// At the beginning \c g is cleared by \c g.clear().
+  template<typename Digraph>
+  void readDimacs(std::istream& is, Digraph &g) {
+    typename Digraph::Node u;
+    NullMap<typename Digraph::Arc, int> n;
+    readDimacs(is, g, n, u, u);
+  }
+
+  /// DIMACS plain digraph writer function.
+  ///
+  /// This function writes a digraph without any designated nodes and
+  /// maps into DIMACS format, i.e. into DIMACS file having a line
+  /// starting with
+  /// \code
+  ///   p mat
+  /// \endcode
+  template<typename Digraph>
+  void writeDimacs(std::ostream& os, const Digraph &g) {
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::ArcIt ArcIt;
+
+    os << "c matching problem" << std::endl;
+    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
+
+    typename Digraph::template NodeMap<int> nodes(g);
+    int i = 1;
+    for(NodeIt v(g); v != INVALID; ++v) {
+      nodes.set(v, i);
+      ++i;
+    }
+    for(ArcIt e(g); e != INVALID; ++e) {
+      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
+         << std::endl;
+    }
+  }
+
+  /// @}
+
+} //namespace lemon
+
+#endif //LEMON_DIMACS_H
diff -r fc6954b4fce4 -r 50d96f2166d7 tools/Makefile.am
--- a/tools/Makefile.am	Fri Nov 21 10:49:39 2008 +0000
+++ b/tools/Makefile.am	Thu Nov 27 22:04:46 2008 +0000
@@ -1,6 +1,10 @@
 if WANT_TOOLS
 
-bin_PROGRAMS +=
+bin_PROGRAMS += \
+	tools/dimacs-to-lgf
+
 dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh
 
 endif WANT_TOOLS
+
+tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc
diff -r fc6954b4fce4 -r 50d96f2166d7 tools/dimacs-to-lgf.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/dimacs-to-lgf.cc	Thu Nov 27 22:04:46 2008 +0000
@@ -0,0 +1,168 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup tools
+///\file
+///\brief DIMACS to LGF converter.
+///
+/// This program converts various DIMACS formats to the LEMON Digraph Format
+/// (LGF).
+///
+/// See
+/// \verbatim
+///  dimacs-to-lgf --help
+/// \endverbatim
+/// for more info on usage.
+///
+
+#include <iostream>
+#include <fstream>
+#include <cstring>
+
+#include <lemon/smart_graph.h>
+#include <lemon/dimacs.h>
+#include <lemon/lgf_writer.h>
+
+#include <lemon/arg_parser.h>
+
+using namespace std;
+using namespace lemon;
+
+
+int main(int argc, const char *argv[]) {
+  typedef SmartDigraph Digraph;
+
+  typedef Digraph::Arc Arc;
+  typedef Digraph::Node Node;
+  typedef Digraph::ArcIt ArcIt;
+  typedef Digraph::NodeIt NodeIt;
+  typedef Digraph::ArcMap<double> DoubleArcMap;
+  typedef Digraph::NodeMap<double> DoubleNodeMap;
+
+  std::string inputName;
+  std::string outputName;
+  std::string typeName;
+
+  bool mincostflow;
+  bool maxflow;
+  bool shortestpath;
+  bool capacitated;
+  bool plain;
+
+  bool version;
+
+  ArgParser ap(argc, argv);
+  ap.refOption("-input",
+               "use FILE as input instead of standard input",
+               inputName).synonym("i", "-input")
+    .refOption("-output",
+               "use FILE as output instead of standard output",
+               outputName).synonym("o", "-output")
+    .refOption("-mincostflow",
+               "set the type of the digraph to \"mincostflow\" digraph",
+               mincostflow)
+    .optionGroup("type", "-mincostflow").synonym("mcf", "-mincostflow")
+    .refOption("-maxflow",
+               "set the type of the digraph to \"maxflow\" digraph",
+               maxflow)
+    .optionGroup("type", "-maxflow").synonym("mf", "-maxflow")
+    .refOption("-shortestpath",
+               "set the type of the digraph to \"shortestpath\" digraph",
+               shortestpath)
+    .optionGroup("type", "-shortestpath").synonym("sp", "-shortestpath")
+    .refOption("-capacitated",
+               "set the type of the digraph to \"capacitated\" digraph",
+               capacitated)
+    .optionGroup("type", "-capacitated").synonym("cap", "-capacitated")
+    .refOption("-plain",
+               "set the type of the digraph to \"plain\" digraph",
+               plain)
+    .optionGroup("type", "-plain").synonym("pl", "-plain")
+    .onlyOneGroup("type")
+    .mandatoryGroup("type")
+    .refOption("-version", "show version information", version)
+    .synonym("v", "-version")
+    .run();
+
+  ifstream input;
+  if (!inputName.empty()) {
+    input.open(inputName.c_str());
+    if (!input) {
+      cerr << "File open error" << endl;
+      return -1;
+    }
+  }
+  istream& is = (inputName.empty() ? cin : input);
+
+  ofstream output;
+  if (!outputName.empty()) {
+    output.open(outputName.c_str());
+    if (!output) {
+      cerr << "File open error" << endl;
+      return -1;
+    }
+  }
+  ostream& os = (outputName.empty() ? cout : output);
+
+  if (mincostflow) {
+    Digraph digraph;
+    DoubleArcMap lower(digraph), capacity(digraph), cost(digraph);
+    DoubleNodeMap supply(digraph);
+    readDimacs(is, digraph, lower, capacity, cost, supply);
+    DigraphWriter<Digraph>(digraph, os).
+      nodeMap("supply", supply).
+      arcMap("lower", lower).
+      arcMap("capacity", capacity).
+      arcMap("cost", cost).
+      run();
+  } else if (maxflow) {
+    Digraph digraph;
+    Node s, t;
+    DoubleArcMap capacity(digraph);
+    readDimacs(is, digraph, capacity, s, t);
+    DigraphWriter<Digraph>(digraph, os).
+      arcMap("capacity", capacity).
+      node("source", s).
+      node("target", t).
+      run();
+  } else if (shortestpath) {
+    Digraph digraph;
+    Node s;
+    DoubleArcMap capacity(digraph);
+    readDimacs(is, digraph, capacity, s);
+    DigraphWriter<Digraph>(digraph, os).
+      arcMap("capacity", capacity).
+      node("source", s).
+      run();
+  } else if (capacitated) {
+    Digraph digraph;
+    DoubleArcMap capacity(digraph);
+    readDimacs(is, digraph, capacity);
+    DigraphWriter<Digraph>(digraph, os).
+      arcMap("capacity", capacity).
+      run();
+  } else if (plain) {
+    Digraph digraph;
+    readDimacs(is, digraph);
+    DigraphWriter<Digraph>(digraph, os).run();
+  } else {
+    cerr << "Invalid type error" << endl;
+    return -1;
+  }
+  return 0;
+}