latex_table.cpp 6.9 KB

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