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 DimacsDescriptor &desc)
77 bool report = !ap.given("q");
80 Digraph::ArcMap<Value> cap(g);
83 readDimacsMax(is, g, cap, s, t, 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)
120 case DimacsDescriptor::MIN:
122 "\n\n Sorry, the min. cost flow solver is not yet available.\n";
124 case DimacsDescriptor::MAX:
125 solve_max<Value>(ap,is,os,desc);
127 case DimacsDescriptor::SP:
128 solve_sp<Value>(ap,is,os,desc);
130 case DimacsDescriptor::MAT:
131 solve_mat(ap,is,os,desc);
138 int main(int argc, const char *argv[]) {
139 typedef SmartDigraph Digraph;
141 typedef Digraph::Arc Arc;
143 std::string inputName;
144 std::string outputName;
146 ArgParser ap(argc, argv);
147 ap.other("[INFILE [OUTFILE]]",
148 "If either the INFILE or OUTFILE file is missing the standard\n"
149 " input/output will be used instead.")
150 .boolOption("q", "Do not print any report")
151 .boolOption("int","Use 'int' for capacities, costs etc. (default)")
152 .optionGroup("datatype","int")
153 #ifdef HAVE_LONG_LONG
154 .boolOption("long","Use 'long long' for capacities, costs etc.")
155 .optionGroup("datatype","long")
157 .boolOption("double","Use 'double' for capacities, costs etc.")
158 .optionGroup("datatype","double")
159 .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
160 .optionGroup("datatype","ldouble")
161 .onlyOneGroup("datatype")
165 std::ofstream output;
167 switch(ap.files().size())
170 output.open(ap.files()[1].c_str());
172 throw IoError("Cannot open the file for writing", ap.files()[1]);
175 input.open(ap.files()[0].c_str());
177 throw IoError("File cannot be found", ap.files()[0]);
182 std::cerr << ap.commandName() << ": too many arguments\n";
185 std::istream& is = (ap.files().size()<1 ? std::cin : input);
186 std::ostream& os = (ap.files().size()<2 ? std::cout : output);
188 DimacsDescriptor desc = dimacsType(is);
192 std::cout << "Problem type: ";
195 case DimacsDescriptor::MIN:
198 case DimacsDescriptor::MAX:
201 case DimacsDescriptor::SP:
203 case DimacsDescriptor::MAT:
210 std::cout << "\nNum of nodes: " << desc.nodeNum;
211 std::cout << "\nNum of arcs: " << desc.edgeNum;
215 if(ap.given("double"))
216 solve<double>(ap,is,os,desc);
217 else if(ap.given("ldouble"))
218 solve<long double>(ap,is,os,desc);
219 #ifdef HAVE_LONG_LONG
220 else if(ap.given("long"))
221 solve<long long>(ap,is,os,desc);
223 else solve<int>(ap,is,os,desc);