latex_table.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. // =====================================================================================
  2. //
  3. // Filename: latex_table.cpp
  4. //
  5. // Description: generate latex table
  6. //
  7. // Version: 1.0
  8. // Created: 2018年 02月 19日 星期一 16:42:17 CST
  9. // Revision: none
  10. // Compiler: g++
  11. //
  12. // Author: Jinkun Lin, jkunlin@gmail.com
  13. // Organization: School of EECS, Peking University
  14. //
  15. // =====================================================================================
  16. #include <iostream>
  17. #include <fstream>
  18. #include <sstream>
  19. #include <vector>
  20. #include <algorithm>
  21. #include <limits>
  22. using namespace std;
  23. bool small = true;
  24. string basename(string name) {
  25. size_t begin = name.find_last_of('/');
  26. return name.substr(begin + 1, name.size() - begin);
  27. }
  28. template<class T1, class T2>
  29. bool better(T1 a, T2 b) {
  30. return small ? a < b : a > b;
  31. }
  32. int main(int argc, char const *argv[]) {
  33. int solver_count = argc - 1;
  34. // =====================================================================================
  35. // read data from file
  36. // =====================================================================================
  37. vector<vector<int>> size_matrix (solver_count);
  38. vector<vector<double>> time_matrix (solver_count);
  39. vector<vector<char>> exact_matrix (solver_count);
  40. for (int i = 0; i < solver_count; ++i) {
  41. ifstream in_file(argv[i + 1]);
  42. if (!in_file) {
  43. std::cout << argv[i + 1] << '\t' << i + 1 << " file error" << std::endl;
  44. return 1;
  45. }
  46. int seed, size;
  47. double solver_time;
  48. char exact;
  49. while (in_file >> seed >> size >> solver_time >> exact) {
  50. size_matrix[i].push_back(size);
  51. time_matrix[i].push_back(solver_time);
  52. exact_matrix[i].push_back(exact);
  53. }
  54. in_file.close();
  55. }
  56. // =====================================================================================
  57. // caculate data
  58. // =====================================================================================
  59. vector<int> best_size (solver_count);
  60. vector<double> avg_size (solver_count);
  61. vector<double> avg_time (solver_count);
  62. vector<int> is_exact (solver_count, 0);
  63. int g_best_size = small ? std::numeric_limits<int>::max() : 0;
  64. double g_avg_best_size = small ? std::numeric_limits<double>::max() : 0;
  65. double g_min_avg_t = std::numeric_limits<double>::max();
  66. for (int i = 0; i < solver_count; ++i) {
  67. int okay_count = 0;
  68. int best_s = size_matrix[i][0];
  69. double avg_s = size_matrix[i][0];
  70. double avg_t = time_matrix[i][0];
  71. if (size_matrix[i][0] != 0) {
  72. okay_count++;
  73. }
  74. for (size_t j = 1; j < size_matrix[i].size(); ++j) {
  75. if (better(size_matrix[i][j], best_s)) {
  76. best_s = size_matrix[i][j];
  77. }
  78. avg_s += size_matrix[i][j];
  79. avg_t += time_matrix[i][j];
  80. if (exact_matrix[i][j] == 'x') {
  81. is_exact[i] = 1;
  82. }
  83. if (size_matrix[i][j] != 0) {
  84. okay_count++;
  85. }
  86. }
  87. best_size[i] = best_s;
  88. if (okay_count != 0) {
  89. avg_size[i] = round(avg_s / okay_count * 100) / 100;
  90. avg_time[i] = round(avg_t / okay_count * 100) / 100;
  91. }
  92. else {
  93. avg_size[i] = 0;
  94. avg_time[i] = 0;
  95. }
  96. if (okay_count == 0) {
  97. continue;
  98. }
  99. if (better(best_size[i], g_best_size)) {
  100. g_best_size = best_size[i];
  101. }
  102. if (better(avg_size[i], g_avg_best_size)) {
  103. g_avg_best_size = avg_size[i];
  104. }
  105. if (g_min_avg_t > avg_time[i]) {
  106. g_min_avg_t = avg_time[i];
  107. }
  108. }
  109. // =====================================================================================
  110. // generate latex table
  111. // =====================================================================================
  112. ofstream out_latex("bold_table.tex", ios::app);
  113. if (!out_latex) {
  114. std::cout << "out file error" << std::endl;
  115. return 1;
  116. }
  117. auto bf_write = [&](double d, bool is_bf) {
  118. if (is_bf) {
  119. out_latex << "\\textbf{" << d << "}";
  120. }
  121. else {
  122. out_latex << d;
  123. }
  124. };
  125. auto bf_write_time = [&](double d, bool is_bf) {
  126. if (is_bf) {
  127. if (d < 0.01) {
  128. out_latex << "\\boldmath{$<$}\\textbf{0.01}";
  129. }
  130. else {
  131. out_latex << "\\textbf{" << d << "}";
  132. }
  133. }
  134. else {
  135. if (d < 0.01) {
  136. out_latex << "$<$0.01";
  137. }
  138. else {
  139. out_latex << d;
  140. }
  141. }
  142. };
  143. out_latex << basename(argv[1]) << " & ";
  144. int s_win_count = 0;
  145. int avg_s_win_count = 0;
  146. int avg_t_win_count = 0;
  147. for (int i = 0; i < solver_count; ++i) {
  148. if (best_size[i] == g_best_size) {
  149. s_win_count++;
  150. }
  151. if (avg_size[i] == g_avg_best_size) {
  152. avg_s_win_count++;
  153. }
  154. if (avg_time[i] == g_min_avg_t) {
  155. avg_t_win_count++;
  156. }
  157. }
  158. for (int i = 0; i < solver_count; ++i) {
  159. if (best_size[i] == 0) {
  160. out_latex << "N/A" << " & " << "N/A";
  161. if (i == solver_count - 1) {
  162. out_latex << " \\\\" << std::endl;
  163. }
  164. else {
  165. out_latex << " & ";
  166. }
  167. continue;
  168. }
  169. // size
  170. if (best_size[i] != avg_size[i]) { // max size dosen't equal to avg size
  171. if (s_win_count != solver_count) {
  172. bf_write(best_size[i], best_size[i] == g_best_size);
  173. }
  174. else {
  175. bf_write(best_size[i], false);
  176. }
  177. out_latex << "(";
  178. if (avg_s_win_count != solver_count) {
  179. bf_write(avg_size[i], avg_size[i] == g_avg_best_size);
  180. }
  181. else {
  182. bf_write(avg_size[i], false);
  183. }
  184. out_latex << ")";
  185. }
  186. else {
  187. if (s_win_count != solver_count || avg_s_win_count != solver_count) {
  188. bf_write(best_size[i], best_size[i] == g_best_size || avg_size[i] == g_avg_best_size);
  189. }
  190. else {
  191. bf_write(best_size[i], false);
  192. }
  193. }
  194. if (is_exact[i]) {
  195. out_latex << "$^*$";
  196. }
  197. out_latex << " & ";
  198. // time
  199. if (s_win_count == solver_count && avg_s_win_count == solver_count &&
  200. avg_t_win_count != solver_count) {
  201. bf_write_time(avg_time[i], avg_time[i] == g_min_avg_t);
  202. }
  203. else {
  204. bf_write_time(avg_time[i], false);
  205. }
  206. if (i == solver_count - 1) {
  207. out_latex << " \\\\" << std::endl;
  208. }
  209. else {
  210. out_latex << " & ";
  211. }
  212. }
  213. out_latex.close();
  214. // =====================================================================================
  215. // generate compare file
  216. // =====================================================================================
  217. vector<bool> win (solver_count, false);
  218. // if (s_win_count != solver_count || avg_s_win_count != solver_count) {
  219. for (int i = 0; i < solver_count; ++i) {
  220. if (best_size[i] == g_best_size && avg_size[i] == g_avg_best_size) {
  221. // if (best_size[i] == g_best_size) {
  222. win[i] = true;
  223. }
  224. }
  225. // }
  226. ofstream out_arch("arch.result", ios::app);
  227. if (!out_arch) {
  228. std::cout << "arch file error" << std::endl;
  229. return 1;
  230. }
  231. // win
  232. out_arch << (win[0] ? 1 : 0);
  233. for (int i = 1; i < solver_count; ++i) {
  234. out_arch << '\t' << (win[i] ? 1 : 0);
  235. }
  236. out_arch << std::endl;
  237. // time
  238. out_arch << avg_time[0];
  239. for (int i = 1; i < solver_count; ++i) {
  240. out_arch << '\t' << avg_time[i];
  241. }
  242. out_arch << std::endl;
  243. // okay solver
  244. out_arch << (best_size[0] != 0 ? 1 : 0);
  245. for (int i = 1; i < solver_count; ++i) {
  246. out_arch << '\t' << (best_size[i] != 0 ? 1 : 0);
  247. }
  248. out_arch << endl;
  249. // exact
  250. out_arch << (is_exact[0] != 0 ? 1 : 0);
  251. for (int i = 1; i < solver_count; ++i) {
  252. out_arch << '\t' << (is_exact[i] != 0 ? 1 : 0);
  253. }
  254. out_arch << endl;
  255. out_arch.close();
  256. return 0;
  257. }