mihaild

Untitled

Feb 17th, 2015
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.01 KB | None | 0 0
  1. #include <chrono>
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <functional>
  6. #include <map>
  7. #include <string>
  8.  
  9. using std::vector;
  10. using std::cin;
  11. using std::cout;
  12. using std::chrono::steady_clock;
  13. using std::map;
  14. using std::string;
  15.  
  16. using TElement = int;
  17.  
  18. using test_set = map<string, vector<int>>;
  19.  
  20. template<class T1>inline std::ostream& operator<< (std::ostream& s, const std::vector<T1> container) {
  21. for (typename std::vector<T1>::const_iterator i = container.begin(); i != container.end(); i++) s << *i << " ";
  22. return s;
  23. }
  24.  
  25. unsigned long long int get_random() {
  26. constexpr unsigned long long int a = 12005053;
  27. constexpr unsigned long long int b = 123456789;
  28. constexpr unsigned long long int m = 1000000007;
  29. static unsigned long long int x = 0;
  30. x = (a * x + b) % m;
  31. return x;
  32. }
  33.  
  34. test_set get_tests(size_t size) {
  35. test_set result;
  36. result["sorted"].resize(size);
  37. std::iota(result["sorted"].begin(), result["sorted"].end(), 0);
  38. result["reversed"] = result["sorted"];
  39. std::reverse(result["reversed"].begin(), result["reversed"].end());
  40. result["random"].resize(size);
  41. std::generate(result["random"].begin(), result["random"].end(), get_random);
  42. return result;
  43. }
  44.  
  45. const size_t N = 10000000;
  46. const size_t M = 100000;
  47. /*const size_t N = 20;
  48. const size_t M = 5;*/
  49.  
  50. static_assert(!(N % M), "N % M != 0");
  51.  
  52. vector<TElement> with_heap(vector<TElement>& a) {
  53. vector<TElement> heap(a.begin(), a.begin() + M);
  54. std::make_heap(heap.begin(), heap.end());
  55. heap.resize(heap.size() + 1);
  56. for (auto i = a.begin() + M; i != a.end(); ++i) {
  57. heap.back() = *i;
  58. std::push_heap(heap.begin(), heap.end());
  59. std::pop_heap(heap.begin(), heap.end());
  60. }
  61. heap.pop_back();
  62. return heap;
  63. }
  64.  
  65. vector<TElement> with_merge(vector<TElement>& a) {
  66. for (auto i = a.begin(); i != a.end(); i += M) {
  67. std::sort(i, i + M);
  68. }
  69. vector<TElement> result(a.begin(), a.begin() + M);
  70. vector<TElement> tmp(M);
  71. for (auto i = a.begin() + M; i != a.end(); i += M) {
  72. auto a = i;
  73. auto b = result.begin();
  74. for (auto j = tmp.begin(); j != tmp.end(); ++j) {
  75. if (*a < *b) {
  76. *j = *a;
  77. ++a;
  78. }
  79. else {
  80. *j = *b;
  81. ++b;
  82. }
  83. }
  84. result.swap(tmp);
  85. }
  86. return result;
  87. }
  88.  
  89. template<class T> void partition_order_stat(T first, T last, size_t stat) {
  90. auto element = *(first + get_random() % (last - first));
  91. auto p = std::partition(first, last, std::bind(std::less<decltype(*first)>(), std::placeholders::_1, element));
  92. if (p > first + stat) {
  93. return partition_order_stat(first, p, stat);
  94. }
  95. if (p < first + stat) {
  96. return partition_order_stat(p, last, stat - (p - first));
  97. }
  98. }
  99.  
  100. vector<TElement> with_random(vector<TElement>& a) {
  101. partition_order_stat(a.begin(), a.end(), M);
  102. return vector<TElement>(a.begin(), a.begin() + M);
  103. }
  104.  
  105. int main(int, char *argv[]) {
  106. map<string, std::function<vector<TElement>(vector<TElement>&)>> methods;
  107. methods["heap"] = with_heap;
  108. methods["merge"] = with_merge;
  109. methods["random"] = with_random;
  110.  
  111. auto method = methods[argv[1]];
  112. auto size = N;
  113. for (const auto& test : get_tests(size)) {
  114. int times = 0;
  115. double time = 0;
  116. while (time < .3) {
  117. ++times;
  118. auto data = test.second;
  119. //std::cout << data << std::endl;
  120. steady_clock::time_point start = steady_clock::now();
  121. auto answer = method(data);
  122. //std::cout << answer << std::endl;
  123. time += std::chrono::duration_cast<std::chrono::duration<double>>(steady_clock::now() - start).count();
  124. break;
  125. }
  126. std::cout << argv[1] << ' ' << test.first << ' ' << size << "; seconds per iteration: " << (time / times) << std::endl;
  127. }
  128. std::cout << std::endl;
  129. return 0;
  130. }
Advertisement
Add Comment
Please, Sign In to add comment