| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- // =====================================================================================
- //
- // 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 <algorithm>
- #include <fstream>
- #include <iostream>
- #include <limits>
- #include <sstream>
- #include <vector>
- using namespace std;
- bool SMALL_BETTER = false;
- int FAILED_SIZE = numeric_limits<int>::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 <class T1, class T2> 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<vector<int>> size_matrix(solver_count);
- vector<vector<double>> time_matrix(solver_count);
- vector<vector<char>> 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<int> best_size(solver_count);
- vector<double> avg_size(solver_count);
- vector<double> avg_time(solver_count);
- vector<int> 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<double>::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<bool> 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;
- }
|