1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2009
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
21 ///\brief DIMACS to LGF converter.
23 /// This program converts various DIMACS formats to the LEMON Digraph Format
28 /// dimacs-solver --help
30 /// for more info on usage.
37 #include <lemon/smart_graph.h>
38 #include <lemon/dimacs.h>
39 #include <lemon/lgf_writer.h>
40 #include <lemon/time_measure.h>
42 #include <lemon/arg_parser.h>
43 #include <lemon/error.h>
45 #include <lemon/dijkstra.h>
46 #include <lemon/preflow.h>
47 #include <lemon/max_matching.h>
49 using namespace lemon;
50 typedef SmartDigraph Digraph;
51 DIGRAPH_TYPEDEFS(Digraph);
52 typedef SmartGraph Graph;
55 void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
56 DimacsDescriptor &desc)
58 bool report = !ap.given("q");
61 Digraph::ArcMap<Value> len(g);
64 readDimacsSp(is, g, len, s, desc);
65 if(report) std::cerr << "Read the file: " << t << '\n';
67 Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
68 if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
71 if(report) std::cerr << "Run Dijkstra: " << t << '\n';
75 void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
76 DimacsDescriptor &desc)
78 bool report = !ap.given("q");
81 Digraph::ArcMap<Value> cap(g);
84 readDimacsMax(is, g, cap, s, t, desc);
85 if(report) std::cerr << "Read the file: " << ti << '\n';
87 Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
88 if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
91 if(report) std::cerr << "Run Preflow: " << ti << '\n';
92 if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
95 void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
96 DimacsDescriptor &desc)
98 bool report = !ap.given("q");
102 readDimacsMat(is, g, desc);
103 if(report) std::cerr << "Read the file: " << ti << '\n';
105 MaxMatching<Graph> mat(g);
106 if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
109 if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
110 if(report) std::cerr << "\nCardinality of max matching: "
111 << mat.matchingSize() << '\n';
115 template<class Value>
116 void solve(ArgParser &ap, std::istream &is, std::ostream &os,
117 DimacsDescriptor &desc)
121 case DimacsDescriptor::MIN:
123 "\n\n Sorry, the min. cost flow solver is not yet available.\n"
126 case DimacsDescriptor::MAX:
127 solve_max<Value>(ap,is,os,desc);
129 case DimacsDescriptor::SP:
130 solve_sp<Value>(ap,is,os,desc);
132 case DimacsDescriptor::MAT:
133 solve_mat(ap,is,os,desc);
140 int main(int argc, const char *argv[]) {
141 typedef SmartDigraph Digraph;
143 typedef Digraph::Arc Arc;
144 typedef Digraph::Node Node;
145 typedef Digraph::ArcIt ArcIt;
146 typedef Digraph::NodeIt NodeIt;
147 typedef Digraph::ArcMap<double> DoubleArcMap;
148 typedef Digraph::NodeMap<double> DoubleNodeMap;
150 std::string inputName;
151 std::string outputName;
153 ArgParser ap(argc, argv);
154 ap.other("[INFILE [OUTFILE]]",
155 "If either the INFILE or OUTFILE file is missing the standard\n"
156 " input/output will be used instead.")
157 .boolOption("q", "Do not print any report")
158 .boolOption("int","Use 'int' for capacities, costs etc. (default)")
159 .optionGroup("datatype","int")
160 #ifdef HAVE_LONG_LONG
161 .boolOption("long","Use 'long long' for capacities, costs etc.")
162 .optionGroup("datatype","long")
164 .boolOption("double","Use 'double' for capacities, costs etc.")
165 .optionGroup("datatype","double")
166 .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
167 .optionGroup("datatype","ldouble")
168 .onlyOneGroup("datatype")
172 std::ofstream output;
174 switch(ap.files().size())
177 output.open(ap.files()[1].c_str());
179 throw IoError("Cannot open the file for writing", ap.files()[1]);
182 input.open(ap.files()[0].c_str());
184 throw IoError("File cannot be found", ap.files()[0]);
189 std::cerr << ap.commandName() << ": too many arguments\n";
192 std::istream& is = (ap.files().size()<1 ? std::cin : input);
193 std::ostream& os = (ap.files().size()<2 ? std::cout : output);
195 DimacsDescriptor desc = dimacsType(is);
199 std::cout << "Problem type: ";
202 case DimacsDescriptor::MIN:
205 case DimacsDescriptor::MAX:
208 case DimacsDescriptor::SP:
210 case DimacsDescriptor::MAT:
217 std::cout << "\nNum of nodes: " << desc.nodeNum;
218 std::cout << "\nNum of arcs: " << desc.edgeNum;
219 std::cout << '\n' << std::endl;
222 if(ap.given("double"))
223 solve<double>(ap,is,os,desc);
224 else if(ap.given("ldouble"))
225 solve<long double>(ap,is,os,desc);
226 #ifdef HAVE_LONG_LONG
227 else if(ap.given("long"))
228 solve<long long>(ap,is,os,desc);
230 else solve<int>(ap,is,os,desc);