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.
35 #include <lemon/smart_graph.h>
36 #include <lemon/dimacs.h>
37 #include <lemon/lgf_writer.h>
38 #include <lemon/time_measure.h>
40 #include <lemon/arg_parser.h>
41 #include <lemon/error.h>
43 #include <lemon/dijkstra.h>
44 #include <lemon/preflow.h>
45 #include <lemon/matching.h>
47 using namespace lemon;
48 typedef SmartDigraph Digraph;
49 DIGRAPH_TYPEDEFS(Digraph);
50 typedef SmartGraph Graph;
53 void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
54 DimacsDescriptor &desc)
56 bool report = !ap.given("q");
59 Digraph::ArcMap<Value> len(g);
62 readDimacsSp(is, g, len, s, desc);
63 if(report) std::cerr << "Read the file: " << t << '\n';
65 Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
66 if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
69 if(report) std::cerr << "Run Dijkstra: " << t << '\n';
73 void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
74 Value infty, DimacsDescriptor &desc)
76 bool report = !ap.given("q");
79 Digraph::ArcMap<Value> cap(g);
82 readDimacsMax(is, g, cap, s, t, infty, desc);
83 if(report) std::cerr << "Read the file: " << ti << '\n';
85 Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
86 if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
89 if(report) std::cerr << "Run Preflow: " << ti << '\n';
90 if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
93 void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
94 DimacsDescriptor &desc)
96 bool report = !ap.given("q");
100 readDimacsMat(is, g, desc);
101 if(report) std::cerr << "Read the file: " << ti << '\n';
103 MaxMatching<Graph> mat(g);
104 if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
107 if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
108 if(report) std::cerr << "\nCardinality of max matching: "
109 << mat.matchingSize() << '\n';
113 template<class Value>
114 void solve(ArgParser &ap, std::istream &is, std::ostream &os,
115 DimacsDescriptor &desc)
117 std::stringstream iss(static_cast<std::string>(ap["infcap"]));
122 std::cerr << "Cannot interpret '"
123 << static_cast<std::string>(ap["infcap"]) << "' as infinite"
130 case DimacsDescriptor::MIN:
132 "\n\n Sorry, the min. cost flow solver is not yet available.\n";
134 case DimacsDescriptor::MAX:
135 solve_max<Value>(ap,is,os,infty,desc);
137 case DimacsDescriptor::SP:
138 solve_sp<Value>(ap,is,os,desc);
140 case DimacsDescriptor::MAT:
141 solve_mat(ap,is,os,desc);
148 int main(int argc, const char *argv[]) {
149 typedef SmartDigraph Digraph;
151 typedef Digraph::Arc Arc;
153 std::string inputName;
154 std::string outputName;
156 ArgParser ap(argc, argv);
157 ap.other("[INFILE [OUTFILE]]",
158 "If either the INFILE or OUTFILE file is missing the standard\n"
159 " input/output will be used instead.")
160 .boolOption("q", "Do not print any report")
161 .boolOption("int","Use 'int' for capacities, costs etc. (default)")
162 .optionGroup("datatype","int")
163 #ifdef HAVE_LONG_LONG
164 .boolOption("long","Use 'long long' for capacities, costs etc.")
165 .optionGroup("datatype","long")
167 .boolOption("double","Use 'double' for capacities, costs etc.")
168 .optionGroup("datatype","double")
169 .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
170 .optionGroup("datatype","ldouble")
171 .onlyOneGroup("datatype")
172 .stringOption("infcap","Value used for 'very high' capacities","0")
176 std::ofstream output;
178 switch(ap.files().size())
181 output.open(ap.files()[1].c_str());
183 throw IoError("Cannot open the file for writing", ap.files()[1]);
186 input.open(ap.files()[0].c_str());
188 throw IoError("File cannot be found", ap.files()[0]);
193 std::cerr << ap.commandName() << ": too many arguments\n";
196 std::istream& is = (ap.files().size()<1 ? std::cin : input);
197 std::ostream& os = (ap.files().size()<2 ? std::cout : output);
199 DimacsDescriptor desc = dimacsType(is);
203 std::cout << "Problem type: ";
206 case DimacsDescriptor::MIN:
209 case DimacsDescriptor::MAX:
212 case DimacsDescriptor::SP:
214 case DimacsDescriptor::MAT:
221 std::cout << "\nNum of nodes: " << desc.nodeNum;
222 std::cout << "\nNum of arcs: " << desc.edgeNum;
226 if(ap.given("double"))
227 solve<double>(ap,is,os,desc);
228 else if(ap.given("ldouble"))
229 solve<long double>(ap,is,os,desc);
230 #ifdef HAVE_LONG_LONG
231 else if(ap.given("long"))
232 solve<long long>(ap,is,os,desc);
234 else solve<int>(ap,is,os,desc);