| 1 | 1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
| 2 | 2 |
* |
| 3 | 3 |
* This file is a part of LEMON, a generic C++ optimization library. |
| 4 | 4 |
* |
| 5 | 5 |
* Copyright (C) 2003-2009 |
| 6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
| 7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
| 8 | 8 |
* |
| 9 | 9 |
* Permission to use, modify and distribute this software is granted |
| 10 | 10 |
* provided that this copyright notice appears in all copies. For |
| 11 | 11 |
* precise terms see the accompanying LICENSE file. |
| 12 | 12 |
* |
| 13 | 13 |
* This software is provided "AS IS" with no warranty of any kind, |
| 14 | 14 |
* express or implied, and with no claim as to its suitability for any |
| 15 | 15 |
* purpose. |
| 16 | 16 |
* |
| 17 | 17 |
*/ |
| 18 | 18 |
|
| 19 | 19 |
///\ingroup tools |
| 20 | 20 |
///\file |
| 21 |
///\brief DIMACS |
|
| 21 |
///\brief DIMACS problem solver. |
|
| 22 | 22 |
/// |
| 23 |
/// This program converts various DIMACS formats to the LEMON Digraph Format |
|
| 24 |
/// (LGF). |
|
| 23 |
/// This program solves various problems given in DIMACS format. |
|
| 25 | 24 |
/// |
| 26 | 25 |
/// See |
| 27 | 26 |
/// \verbatim |
| 28 | 27 |
/// dimacs-solver --help |
| 29 | 28 |
/// \endverbatim |
| 30 | 29 |
/// for more info on usage. |
| 31 | 30 |
/// |
| 32 | 31 |
|
| 33 | 32 |
#include <iostream> |
| 34 | 33 |
#include <fstream> |
| 35 | 34 |
#include <cstring> |
| 36 | 35 |
|
| 37 | 36 |
#include <lemon/smart_graph.h> |
| 38 | 37 |
#include <lemon/dimacs.h> |
| 39 | 38 |
#include <lemon/lgf_writer.h> |
| 40 | 39 |
#include <lemon/time_measure.h> |
| 41 | 40 |
|
| 42 | 41 |
#include <lemon/arg_parser.h> |
| 43 | 42 |
#include <lemon/error.h> |
| 44 | 43 |
|
| 45 | 44 |
#include <lemon/dijkstra.h> |
| 46 | 45 |
#include <lemon/preflow.h> |
| 47 | 46 |
#include <lemon/max_matching.h> |
| 48 | 47 |
|
| ... | ... |
@@ -99,135 +98,129 @@ |
| 99 | 98 |
Graph g; |
| 100 | 99 |
Timer ti; |
| 101 | 100 |
ti.restart(); |
| 102 | 101 |
readDimacsMat(is, g, desc); |
| 103 | 102 |
if(report) std::cerr << "Read the file: " << ti << '\n'; |
| 104 | 103 |
ti.restart(); |
| 105 | 104 |
MaxMatching<Graph> mat(g); |
| 106 | 105 |
if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n'; |
| 107 | 106 |
ti.restart(); |
| 108 | 107 |
mat.run(); |
| 109 | 108 |
if(report) std::cerr << "Run MaxMatching: " << ti << '\n'; |
| 110 | 109 |
if(report) std::cerr << "\nCardinality of max matching: " |
| 111 | 110 |
<< mat.matchingSize() << '\n'; |
| 112 | 111 |
} |
| 113 | 112 |
|
| 114 | 113 |
|
| 115 | 114 |
template<class Value> |
| 116 | 115 |
void solve(ArgParser &ap, std::istream &is, std::ostream &os, |
| 117 | 116 |
DimacsDescriptor &desc) |
| 118 | 117 |
{
|
| 119 | 118 |
switch(desc.type) |
| 120 | 119 |
{
|
| 121 | 120 |
case DimacsDescriptor::MIN: |
| 122 | 121 |
std::cerr << |
| 123 |
"\n\n Sorry, the min. cost flow solver is not yet available.\n" |
|
| 124 |
<< std::endl; |
|
| 122 |
"\n\n Sorry, the min. cost flow solver is not yet available.\n"; |
|
| 125 | 123 |
break; |
| 126 | 124 |
case DimacsDescriptor::MAX: |
| 127 | 125 |
solve_max<Value>(ap,is,os,desc); |
| 128 | 126 |
break; |
| 129 | 127 |
case DimacsDescriptor::SP: |
| 130 | 128 |
solve_sp<Value>(ap,is,os,desc); |
| 131 | 129 |
break; |
| 132 | 130 |
case DimacsDescriptor::MAT: |
| 133 | 131 |
solve_mat(ap,is,os,desc); |
| 134 | 132 |
break; |
| 135 | 133 |
default: |
| 136 | 134 |
break; |
| 137 | 135 |
} |
| 138 | 136 |
} |
| 139 | 137 |
|
| 140 | 138 |
int main(int argc, const char *argv[]) {
|
| 141 | 139 |
typedef SmartDigraph Digraph; |
| 142 | 140 |
|
| 143 | 141 |
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; |
|
| 149 | 142 |
|
| 150 | 143 |
std::string inputName; |
| 151 | 144 |
std::string outputName; |
| 152 | 145 |
|
| 153 | 146 |
ArgParser ap(argc, argv); |
| 154 | 147 |
ap.other("[INFILE [OUTFILE]]",
|
| 155 | 148 |
"If either the INFILE or OUTFILE file is missing the standard\n" |
| 156 | 149 |
" input/output will be used instead.") |
| 157 | 150 |
.boolOption("q", "Do not print any report")
|
| 158 | 151 |
.boolOption("int","Use 'int' for capacities, costs etc. (default)")
|
| 159 | 152 |
.optionGroup("datatype","int")
|
| 160 | 153 |
#ifdef HAVE_LONG_LONG |
| 161 | 154 |
.boolOption("long","Use 'long long' for capacities, costs etc.")
|
| 162 | 155 |
.optionGroup("datatype","long")
|
| 163 | 156 |
#endif |
| 164 | 157 |
.boolOption("double","Use 'double' for capacities, costs etc.")
|
| 165 | 158 |
.optionGroup("datatype","double")
|
| 166 | 159 |
.boolOption("ldouble","Use 'long double' for capacities, costs etc.")
|
| 167 | 160 |
.optionGroup("datatype","ldouble")
|
| 168 | 161 |
.onlyOneGroup("datatype")
|
| 169 | 162 |
.run(); |
| 170 | 163 |
|
| 171 | 164 |
std::ifstream input; |
| 172 | 165 |
std::ofstream output; |
| 173 | 166 |
|
| 174 | 167 |
switch(ap.files().size()) |
| 175 | 168 |
{
|
| 176 | 169 |
case 2: |
| 177 | 170 |
output.open(ap.files()[1].c_str()); |
| 178 | 171 |
if (!output) {
|
| 179 | 172 |
throw IoError("Cannot open the file for writing", ap.files()[1]);
|
| 180 | 173 |
} |
| 181 | 174 |
case 1: |
| 182 | 175 |
input.open(ap.files()[0].c_str()); |
| 183 | 176 |
if (!input) {
|
| 184 | 177 |
throw IoError("File cannot be found", ap.files()[0]);
|
| 185 | 178 |
} |
| 186 | 179 |
case 0: |
| 187 | 180 |
break; |
| 188 | 181 |
default: |
| 189 | 182 |
std::cerr << ap.commandName() << ": too many arguments\n"; |
| 190 | 183 |
return 1; |
| 191 |
} |
|
| 184 |
} |
|
| 192 | 185 |
std::istream& is = (ap.files().size()<1 ? std::cin : input); |
| 193 | 186 |
std::ostream& os = (ap.files().size()<2 ? std::cout : output); |
| 194 | 187 |
|
| 195 | 188 |
DimacsDescriptor desc = dimacsType(is); |
| 196 | 189 |
|
| 197 | 190 |
if(!ap.given("q"))
|
| 198 | 191 |
{
|
| 199 | 192 |
std::cout << "Problem type: "; |
| 200 | 193 |
switch(desc.type) |
| 201 | 194 |
{
|
| 202 | 195 |
case DimacsDescriptor::MIN: |
| 203 | 196 |
std::cout << "min"; |
| 204 | 197 |
break; |
| 205 | 198 |
case DimacsDescriptor::MAX: |
| 206 | 199 |
std::cout << "max"; |
| 207 | 200 |
break; |
| 208 | 201 |
case DimacsDescriptor::SP: |
| 209 | 202 |
std::cout << "sp"; |
| 210 | 203 |
case DimacsDescriptor::MAT: |
| 211 | 204 |
std::cout << "mat"; |
| 212 | 205 |
break; |
| 213 | 206 |
default: |
| 214 | 207 |
exit(1); |
| 215 | 208 |
break; |
| 216 | 209 |
} |
| 217 | 210 |
std::cout << "\nNum of nodes: " << desc.nodeNum; |
| 218 | 211 |
std::cout << "\nNum of arcs: " << desc.edgeNum; |
| 219 |
std::cout << |
|
| 212 |
std::cout << "\n\n"; |
|
| 220 | 213 |
} |
| 221 | 214 |
|
| 222 | 215 |
if(ap.given("double"))
|
| 223 | 216 |
solve<double>(ap,is,os,desc); |
| 224 | 217 |
else if(ap.given("ldouble"))
|
| 225 | 218 |
solve<long double>(ap,is,os,desc); |
| 226 | 219 |
#ifdef HAVE_LONG_LONG |
| 227 | 220 |
else if(ap.given("long"))
|
| 228 | 221 |
solve<long long>(ap,is,os,desc); |
| 229 | 222 |
#endif |
| 230 | 223 |
else solve<int>(ap,is,os,desc); |
| 231 | 224 |
|
| 232 | 225 |
return 0; |
| 233 | 226 |
} |
0 comments (0 inline)