OKlibrary
0.2.1.6
|
00001 // Oliver Kullmann, 5.5.2005 (Swansea) 00002 /* Copyright 2005 - 2007 Oliver Kullmann 00003 This file is part of the OKlibrary. OKlibrary is free software; you can redistribute 00004 it and/or modify it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation and included in this library; either version 3 of the 00006 License, or any later version. */ 00007 00015 #include <iostream> 00016 #include <vector> 00017 #include <algorithm> 00018 #include <set> 00019 #include <stdexcept> 00020 #include <string> 00021 #include <iterator> 00022 #include <cstdlib> 00023 #include <fstream> 00024 #include <cassert> 00025 00026 #include <boost/lexical_cast.hpp> 00027 00028 namespace Analyse { 00029 00030 typedef unsigned int CountSolved; 00031 typedef unsigned int NumberSolver; 00032 typedef double Time; 00033 00034 struct FormatError : std::runtime_error { 00035 FormatError(const std::string& m) : std::runtime_error(m) {} 00036 }; 00037 00038 struct mean_time { 00039 void set_NaN() { is_NaN = true; } 00040 void set_time(const Time t) { is_NaN = false; time = t; } 00041 bool is_NaN; 00042 Time time; 00043 }; 00044 00045 std::istream& operator >>(std::istream& in, mean_time& t) { 00046 if (not in) 00047 throw FormatError("operator >>(std::istream& in, mean_time& t): stream unreadable from the beginning"); 00048 std::string time; 00049 in >> time; 00050 if (not in) 00051 throw FormatError("operator >>(std::istream& in, mean_time& t): can't read time"); 00052 if (time == "NaN") 00053 t.set_NaN(); 00054 else { 00055 try { 00056 t.set_time(boost::lexical_cast<Time>(time)); 00057 } 00058 catch(const boost::bad_lexical_cast& e) { 00059 throw FormatError(std::string("operator >>(std::istream& in, mean_time& t): can't convert time; message from boost::bad_lexical_cast is\n") + e.what()); 00060 } 00061 } 00062 return in; 00063 } 00064 00065 std::ostream& operator <<(std::ostream& out, const mean_time& t) { 00066 if (t.is_NaN) 00067 return out << "NaN"; 00068 else 00069 return out << t.time; 00070 } 00071 00072 bool operator <(const mean_time& a, const mean_time& b) { 00073 if (b.is_NaN) 00074 return false; 00075 else 00076 if (a.is_NaN) 00077 return true; 00078 else 00079 return b.time < a.time; 00080 } 00081 00082 struct SolverResult { 00083 NumberSolver num_solver; 00084 typedef std::vector<CountSolved> vector_numbers; 00085 typedef std::vector<mean_time> vector_times; 00086 unsigned int ncolumns; 00087 vector_numbers solved; 00088 vector_times times; 00089 }; 00090 00091 bool operator <(const SolverResult& a, const SolverResult& b) { 00092 const bool a_l_b = std::lexicographical_compare(a.solved.rbegin(), a.solved.rend(), b.solved.rbegin(), b.solved.rend()); 00093 if (a_l_b) return true; 00094 const bool b_l_a = std::lexicographical_compare(b.solved.rbegin(), b.solved.rend(), a.solved.rbegin(), a.solved.rend()); 00095 if (b_l_a) return false; 00096 return std::lexicographical_compare(a.times.rbegin(), a.times.rend(), b.times.rbegin(), b.times.rend()); 00097 } 00098 00099 std::ostream& operator <<(std::ostream& out, const SolverResult& r) { 00100 if (not out) 00101 throw FormatError("operator >>(std::ostream& in, SolverResult& R): stream unwritable from the beginning"); 00102 out << r.num_solver << "\n"; 00103 std::copy(r.solved.begin(), r.solved.end(), std::ostream_iterator<CountSolved>(out, " ")); 00104 out << "\n"; 00105 std::copy(r.times.begin(), r.times.end(), std::ostream_iterator<mean_time>(out, " ")); 00106 out << "\n"; 00107 return out; 00108 } 00109 00110 typedef std::set<SolverResult> SolverResults; 00111 00112 std::istream& operator >> (std::istream& in, SolverResults& R) { 00113 if (not in) 00114 throw FormatError("operator >>(std::istream& in, SolverResults& R): stream unreadable from the beginning"); 00115 unsigned int number_results; 00116 unsigned int number_columns; 00117 in >> number_results >> number_columns; 00118 if (not in) 00119 throw FormatError("operator >>(std::istream& in, SolverResults& R): can't read number_results, number_columns"); 00120 00121 for (unsigned int i = 0; i < number_results; ++i) { 00122 SolverResult r; 00123 in >> r.num_solver; 00124 if (not in) 00125 throw FormatError(std::string("operator >>(std::istream& in, SolverResults& R): can't read solver number for result number ") + boost::lexical_cast<std::string>(i + 1)); 00126 r.solved.reserve(number_columns); 00127 for (unsigned int j = 0; j < number_columns; ++j) { 00128 CountSolved c; 00129 in >> c; 00130 if (not in) 00131 throw FormatError(std::string("operator >>(std::istream& in, SolverResults& R): can't read number of instances solved for result number ") + boost::lexical_cast<std::string>(i + 1) + " and column number " + boost::lexical_cast<std::string>(j + 1)); 00132 r.solved.push_back(c); 00133 } 00134 r.times.reserve(number_columns); 00135 for (unsigned int j = 0; j < number_columns; ++j) { 00136 mean_time t; 00137 in >> t; 00138 if (not in) 00139 throw FormatError(std::string("operator >>(std::istream& in, SolverResults& R): can't read mean time for result number ") + boost::lexical_cast<std::string>(i + 1) + " and column number " + boost::lexical_cast<std::string>(j + 1)); 00140 r.times.push_back(t); 00141 } 00142 R.insert(r); 00143 assert(R.size() == i+1); 00144 } 00145 return in; 00146 } 00147 00148 std::ostream& operator <<(std::ostream& out, const SolverResults& R) { 00149 std::copy(R.rbegin(), R.rend(), std::ostream_iterator<SolverResult>(out, "\n")); 00150 return out; 00151 } 00152 00153 } 00154 00155 int main(const int argc, const char* const argv[]) { 00156 if (argc != 2) { 00157 std::cerr << "ERROR[Analyse]: Exactly one argument expected, the name of the file with the data.\n"; 00158 return EXIT_FAILURE; 00159 } 00160 std::ifstream file(argv[1]); 00161 Analyse::SolverResults R; 00162 file >> R; 00163 std::cout << R; 00164 }