monkey_fit.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #ifndef __MONKEY_FIT__
  2. #define __MONKEY_FIT__
  3. #include <cmath>
  4. #include <iterator>
  5. #include <map>
  6. #include <deque>
  7. #include <algorithm>
  8. #include "base_data.h"
  9. struct monkey_fit
  10. {
  11. virtual ~monkey_fit(){}
  12. template<typename T> static double get_probab_max(T it,T ite,int sum,int N=3)
  13. {
  14. sum/=5;
  15. sum=std::max(3,sum);
  16. std::vector<std::tuple<T,T,float>> p;
  17. if(N==0)
  18. {
  19. auto it0=it;
  20. for(int i=0;it0!=ite;++it0,++i)
  21. {
  22. if(i%10==0) printf("\n");
  23. printf("%5d:%2d,",it0->first,it0->second);
  24. }
  25. printf("\n");
  26. }
  27. int s=0;
  28. for(auto i1=it;it!=ite;)
  29. {
  30. for(;s<sum && i1!=ite;++i1)
  31. s+=i1->second;
  32. if(s<sum) break;
  33. p.push_back(std::make_tuple(it,i1,1.*s/(std::prev(i1)->first-it->first+1)));
  34. s-=it->second; ++it;
  35. }
  36. if(p.empty())
  37. return 0;
  38. std::sort(p.begin(),p.end(),[](const std::tuple<T,T,int>&l,const std::tuple<T,T,int>&r){
  39. return 1.*std::get<2>(l) > 1.*std::get<2>(r);
  40. });
  41. int i=1;
  42. auto it1=std::get<0>(p[0]);
  43. auto it2=std::prev(std::get<1>(p[0]));
  44. for(;i<(int)p.size();++i)
  45. {
  46. if(std::get<2>(p[i])!=std::get<2>(p[i-1]))
  47. break;
  48. if(std::get<0>(p[i])->first < it1->first)
  49. it1=std::get<0>(p[i]);
  50. if(std::prev(std::get<1>(p[i]))->second > it2->second)
  51. it2=std::prev(std::get<1>(p[i]));
  52. }
  53. ++it2;
  54. double rc=0;
  55. int cc=0;
  56. int x=0;
  57. for(;it1!=it2;++it1)
  58. {
  59. rc+=it1->first*it1->second;
  60. cc+=it1->second;
  61. if(N==0)
  62. {
  63. if(x++%10==0) printf("\n");
  64. printf("%5d:%2d,",it1->first,it1->second);
  65. }
  66. }
  67. if(N==0)
  68. printf("\n");
  69. return rc/cc;
  70. }
  71. int round(double value)
  72. {
  73. return (value > 0.0)?floor(value + 0.5):ceil(value - 0.5);
  74. }
  75. virtual void reset(double monkey_speed = 0){}
  76. virtual void push(double time_second,double dist_meter) {}
  77. virtual double get_K() = 0;
  78. };
  79. struct monkey_fit_b :monkey_fit
  80. {
  81. static const int min_points = 60;
  82. static const int BN = 20;
  83. double k_init_;
  84. int count_;
  85. std::map<int,int> probab_b;
  86. monkey_fit_b()
  87. :k_init_(0)
  88. ,count_(0)
  89. {}
  90. monkey_fit_b(double s)
  91. :k_init_(s)
  92. ,count_(0)
  93. {}
  94. virtual void reset(double monkey_speed/*=0*/)
  95. {
  96. k_init_=monkey_speed;
  97. count_=0;
  98. probab_b.clear();
  99. }
  100. virtual void push(double time_second,double dist_meter)
  101. {
  102. double k=k_init_;
  103. ++count_;
  104. double b=(dist_meter-k*time_second)*BN;
  105. ++probab_b[round(b)];
  106. }
  107. double get_dist(double time_second)const
  108. {
  109. return k_init_*time_second + get_B();
  110. }
  111. double get_K()
  112. {
  113. return k_init_;
  114. }
  115. double get_B()const
  116. {
  117. if(count_<min_points)
  118. return 0;
  119. if(probab_b.size()<3)
  120. return 0;
  121. return 1.*get_probab_max(probab_b.begin(),probab_b.end(),count_)/BN;
  122. }
  123. };
  124. struct monkey_fit_k:monkey_fit
  125. {
  126. static const int min_points=60;
  127. static const int KN=50;
  128. int step_;
  129. uint32_t count_;
  130. std::map<int,int> probab_k;
  131. std::deque<point_2> m_points;
  132. monkey_fit_k()
  133. :step_(0)
  134. ,count_(0)
  135. {}
  136. virtual void reset(double speed /*=0*/)
  137. {
  138. probab_k.clear();
  139. m_points.clear();
  140. step_=0;
  141. count_ = 0;
  142. }
  143. virtual void push(double time_second,double dist_meter)
  144. {
  145. int cc=m_points.size();
  146. if(cc<60)
  147. {
  148. m_points.push_back(point_2(time_second,dist_meter));
  149. }
  150. else if(step_++>2)
  151. {
  152. m_points.push_back(point_2(time_second,dist_meter));
  153. step_=0;
  154. }
  155. if(cc<10)
  156. return;
  157. cc*=9./10;
  158. for(int i=0;i<3;i++)
  159. {
  160. int index=rand()%cc;
  161. double k=(dist_meter-m_points[index].y_)/(time_second-m_points[index].x_);
  162. if((1<k && k<3) || (-3<k && k<-1))
  163. {
  164. count_++;
  165. ++probab_k[round(k*KN)];
  166. }
  167. }
  168. }
  169. double get_K()
  170. {
  171. if(m_points.size()<min_points)
  172. return 0;
  173. return round(get_probab_max(probab_k.begin(),probab_k.end(),count_)/KN*10000)/10000.;
  174. }
  175. };
  176. #endif