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 problem solver.
23 /// This program solves various problems given in DIMACS format.
27 /// dimacs-solver --help
29 /// for more info on usage.
36 #include <lemon/smart_graph.h>
37 #include <lemon/dimacs.h>
38 #include <lemon/lgf_writer.h>
39 #include <lemon/time_measure.h>
41 #include <lemon/arg_parser.h>
42 #include <lemon/error.h>
44 #include <lemon/dijkstra.h>
45 #include <lemon/preflow.h>
46 #include <lemon/max_matching.h>
48 using namespace lemon;
49 typedef SmartDigraph Digraph;
50 DIGRAPH_TYPEDEFS(Digraph);
51 typedef SmartGraph Graph;
54 void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
55 DimacsDescriptor &desc)
57 bool report = !ap.given("q");
60 Digraph::ArcMap<Value> len(g);
63 readDimacsSp(is, g, len, s, desc);
64 if(report) std::cerr << "Read the file: " << t << '\n';
66 Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
67 if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
70 if(report) std::cerr << "Run Dijkstra: " << t << '\n';
74 void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
75 Value infty, DimacsDescriptor &desc)
77 bool report = !ap.given("q");
80 Digraph::ArcMap<Value> cap(g);
83 readDimacsMax(is, g, cap, s, t, infty, desc);
84 if(report) std::cerr << "Read the file: " << ti << '\n';
86 Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
87 if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
90 if(report) std::cerr << "Run Preflow: " << ti << '\n';
91 if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
94 void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
95 DimacsDescriptor &desc)
97 bool report = !ap.given("q");
101 readDimacsMat(is, g, desc);
102 if(report) std::cerr << "Read the file: " << ti << '\n';
104 MaxMatching<Graph> mat(g);
105 if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
108 if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
109 if(report) std::cerr << "\nCardinality of max matching: "
110 << mat.matchingSize() << '\n';
114 template<class Value>
115 void solve(ArgParser &ap, std::istream &is, std::ostream &os,
116 DimacsDescriptor &desc)
118 std::stringstream iss(ap["infcap"]);
123 std::cerr << "Cannot interpret '"
124 << static_cast<std::string>(ap["infcap"]) << "' as infinite"
131 case DimacsDescriptor::MIN:
133 "\n\n Sorry, the min. cost flow solver is not yet available.\n";
135 case DimacsDescriptor::MAX:
136 solve_max<Value>(ap,is,os,infty,desc);
138 case DimacsDescriptor::SP:
139 solve_sp<Value>(ap,is,os,desc);
141 case DimacsDescriptor::MAT:
142 solve_mat(ap,is,os,desc);
149 int main(int argc, const char *argv[]) {
150 typedef SmartDigraph Digraph;
152 typedef Digraph::Arc Arc;
154 std::string inputName;
155 std::string outputName;
157 ArgParser ap(argc, argv);
158 ap.other("[INFILE [OUTFILE]]",
159 "If either the INFILE or OUTFILE file is missing the standard\n"
160 " input/output will be used instead.")
161 .boolOption("q", "Do not print any report")
162 .boolOption("int","Use 'int' for capacities, costs etc. (default)")
163 .optionGroup("datatype","int")
164 #ifdef HAVE_LONG_LONG
165 .boolOption("long","Use 'long long' for capacities, costs etc.")
166 .optionGroup("datatype","long")
168 .boolOption("double","Use 'double' for capacities, costs etc.")
169 .optionGroup("datatype","double")
170 .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
171 .optionGroup("datatype","ldouble")
172 .onlyOneGroup("datatype")
173 .stringOption("infcap","Value used for 'very high' capacities","0")
177 std::ofstream output;
179 switch(ap.files().size())
182 output.open(ap.files()[1].c_str());
184 throw IoError("Cannot open the file for writing", ap.files()[1]);
187 input.open(ap.files()[0].c_str());
189 throw IoError("File cannot be found", ap.files()[0]);
194 std::cerr << ap.commandName() << ": too many arguments\n";
197 std::istream& is = (ap.files().size()<1 ? std::cin : input);
198 std::ostream& os = (ap.files().size()<2 ? std::cout : output);
200 DimacsDescriptor desc = dimacsType(is);
204 std::cout << "Problem type: ";
207 case DimacsDescriptor::MIN:
210 case DimacsDescriptor::MAX:
213 case DimacsDescriptor::SP:
215 case DimacsDescriptor::MAT:
222 std::cout << "\nNum of nodes: " << desc.nodeNum;
223 std::cout << "\nNum of arcs: " << desc.edgeNum;
227 if(ap.given("double"))
228 solve<double>(ap,is,os,desc);
229 else if(ap.given("ldouble"))
230 solve<long double>(ap,is,os,desc);
231 #ifdef HAVE_LONG_LONG
232 else if(ap.given("long"))
233 solve<long long>(ap,is,os,desc);
235 else solve<int>(ap,is,os,desc);