// ===================================================================================== // // Filename: latex_table.cpp // // Description: generate latex table // // Version: 1.0 // Created: 2018年 02月 19日 星期一 16:42:17 CST // Revision: none // Compiler: g++ // // Author: Jinkun Lin, jkunlin@gmail.com // Organization: School of EECS, Peking University // // ===================================================================================== #include #include #include #include #include #include using namespace std; bool SMALL_BETTER = false; int FAILED_SIZE = numeric_limits::min(); double PENALTY_TIME = 100; double DELTA = 0.0001; string basename(string name) { size_t begin = name.find_last_of('/'); return name.substr(begin + 1, name.size() - begin); } bool equal_for_double(double d1, double d2, double delta = DELTA) { return fabs(d1 - d2) < delta; } template bool better(T1 a, T2 b) { return SMALL_BETTER ? a < b : a > b; } int main(int argc, char const *argv[]) { int solver_count = argc - 1; // ===================================================================================== // read data from file // ===================================================================================== vector> size_matrix(solver_count); vector> time_matrix(solver_count); vector> exact_matrix(solver_count); for (int i = 0; i < solver_count; ++i) { ifstream in_file(argv[i + 1]); in_file.seekg(0, in_file.end); int length = in_file.tellg(); in_file.seekg(0, in_file.beg); if (!in_file || length == 0) { std::cout << argv[i + 1] << '\t' << i + 1 << " file error" << std::endl; for (int j = 0; j < 10; ++j) { size_matrix[i].push_back(FAILED_SIZE); time_matrix[i].push_back(PENALTY_TIME); exact_matrix[i].push_back('h'); } continue; } int seed, size; double solver_time; char exact; while (in_file >> seed >> size >> solver_time >> exact) { if (size == 0) { size_matrix[i].push_back(FAILED_SIZE); time_matrix[i].push_back(PENALTY_TIME); exact_matrix[i].push_back('h'); } else { size_matrix[i].push_back(size); time_matrix[i].push_back(solver_time); exact_matrix[i].push_back(exact); } } in_file.close(); } // ===================================================================================== // caculate data // ===================================================================================== vector best_size(solver_count); vector avg_size(solver_count); vector avg_time(solver_count); vector is_exact(solver_count, 0); int g_best_size = FAILED_SIZE; double g_avg_best_size = FAILED_SIZE; double g_min_avg_t = std::numeric_limits::max(); for (int i = 0; i < solver_count; ++i) { int okay_count = 0; int best_s = FAILED_SIZE; double avg_s = 0; double avg_t = 0; for (int j = 0; j < size_matrix[i].size(); j++) { if (size_matrix[i][j] != FAILED_SIZE) { if (best_s == FAILED_SIZE || better(size_matrix[i][j], best_s)) { best_s = size_matrix[i][j]; } avg_s += size_matrix[i][j]; avg_t += time_matrix[i][j]; if (exact_matrix[i][j] == 'x') { is_exact[i] = 1; } okay_count++; } else { avg_t += PENALTY_TIME; } } if (okay_count != 0) { best_size[i] = best_s; avg_size[i] = round(avg_s / okay_count * 100) / 100; avg_time[i] = round(avg_t / size_matrix[i].size() * 100) / 100; if (better(best_size[i], g_best_size)) { g_best_size = best_size[i]; } if (better(avg_size[i], g_avg_best_size)) { g_avg_best_size = avg_size[i]; } if (g_min_avg_t > avg_time[i]) { g_min_avg_t = avg_time[i]; } } else { best_size[i] = FAILED_SIZE; avg_size[i] = FAILED_SIZE; avg_time[i] = PENALTY_TIME; } } // ===================================================================================== // generate latex table // ===================================================================================== ofstream out_latex("bold_table.tex", ios::app); if (!out_latex) { std::cout << "out file error" << std::endl; return 1; } auto bf_write = [&](double d, bool is_bf) { if (is_bf) { out_latex << "\\textbf{" << d << "}"; } else { out_latex << d; } }; auto bf_write_time = [&](double d, bool is_bf) { if (is_bf) { if (d < 0.01) { out_latex << "\\boldmath{$<$}\\textbf{0.01}"; } else { out_latex << "\\textbf{" << d << "}"; } } else { if (d < 0.01) { out_latex << "$<$0.01"; } else { out_latex << d; } } }; out_latex << basename(argv[1]) << " & "; bool has_double_winner = false; int s_win_count = 0; int avg_s_win_count = 0; int avg_t_win_count = 0; for (int i = 0; i < solver_count; ++i) { if (best_size[i] == g_best_size) { s_win_count++; } if (equal_for_double(avg_size[i], g_avg_best_size)) { avg_s_win_count++; } if (equal_for_double(avg_time[i], g_min_avg_t)) { avg_t_win_count++; } if (best_size[i] == g_best_size && equal_for_double(avg_size[i], g_avg_best_size)) { has_double_winner = true; } } for (int i = 0; i < solver_count; ++i) { if (best_size[i] == FAILED_SIZE) { out_latex << "N/A" << " & " << "N/A"; if (i == solver_count - 1) { out_latex << " \\\\" << std::endl; } else { out_latex << " & "; } continue; } // size if (equal_for_double(best_size[i], avg_size[i])) { if (has_double_winner) { if ((s_win_count != solver_count || avg_s_win_count != solver_count) && best_size[i] == g_best_size && equal_for_double(avg_size[i], g_avg_best_size)) { bf_write(best_size[i], true); } else { bf_write(best_size[i], false); } } else { bf_write(best_size[i], best_size[i] == g_best_size || equal_for_double(avg_size[i], g_avg_best_size)); } } else { // max size dosen't equal to avg size if (has_double_winner) { if ((s_win_count != solver_count || avg_s_win_count != solver_count) && (best_size[i] == g_best_size && equal_for_double(avg_size[i], g_avg_best_size))) { bf_write(best_size[i], true); out_latex << "("; bf_write(avg_size[i], true); out_latex << ")"; } else { bf_write(best_size[i], false); out_latex << "("; bf_write(avg_size[i], false); out_latex << ")"; } } else { if (s_win_count != solver_count) { bf_write(best_size[i], best_size[i] == g_best_size); } else { bf_write(best_size[i], false); } out_latex << "("; if (avg_s_win_count != solver_count) { bf_write(avg_size[i], equal_for_double(avg_size[i], g_avg_best_size)); } else { bf_write(avg_size[i], false); } out_latex << ")"; } } if (is_exact[i]) { out_latex << "$^*$"; } out_latex << " & "; // time if (s_win_count == solver_count && avg_s_win_count == solver_count && avg_t_win_count != solver_count) { bf_write_time(avg_time[i], equal_for_double(avg_time[i], g_min_avg_t)); } else { bf_write_time(avg_time[i], false); } if (i == solver_count - 1) { out_latex << " \\\\" << std::endl; } else { out_latex << " & "; } } out_latex.close(); // ===================================================================================== // generate compare file // ===================================================================================== vector win(solver_count, false); // if (s_win_count != solver_count || avg_s_win_count != solver_count) { for (int i = 0; i < solver_count; ++i) { if (best_size[i] == g_best_size && equal_for_double(avg_size[i], g_avg_best_size)) { // if (best_size[i] == g_best_size) { win[i] = true; } } // } ofstream out_arch("arch.result", ios::app); if (!out_arch) { std::cout << "arch file error" << std::endl; return 1; } // win out_arch << (win[0] ? 1 : 0); for (int i = 1; i < solver_count; ++i) { out_arch << '\t' << (win[i] ? 1 : 0); } out_arch << std::endl; // time out_arch << avg_time[0]; for (int i = 1; i < solver_count; ++i) { out_arch << '\t' << avg_time[i]; } out_arch << std::endl; // okay solver out_arch << (best_size[0] != FAILED_SIZE ? 1 : 0); for (int i = 1; i < solver_count; ++i) { out_arch << '\t' << (best_size[i] != FAILED_SIZE ? 1 : 0); } out_arch << endl; // exact out_arch << (is_exact[0] != 0 ? 1 : 0); for (int i = 1; i < solver_count; ++i) { out_arch << '\t' << (is_exact[i] != 0 ? 1 : 0); } out_arch << endl; out_arch.close(); return 0; }