#ifndef __MONKEY_FIT__ #define __MONKEY_FIT__ #include #include #include #include #include #include "base_data.h" struct monkey_fit { virtual ~monkey_fit(){} template static double get_probab_max(T it,T ite,int sum,int N=3) { sum/=5; sum=std::max(3,sum); std::vector> p; if(N==0) { auto it0=it; for(int i=0;it0!=ite;++it0,++i) { if(i%10==0) printf("\n"); printf("%5d:%2d,",it0->first,it0->second); } printf("\n"); } int s=0; for(auto i1=it;it!=ite;) { for(;ssecond; if(sfirst-it->first+1))); s-=it->second; ++it; } if(p.empty()) return 0; std::sort(p.begin(),p.end(),[](const std::tuple&l,const std::tuple&r){ return 1.*std::get<2>(l) > 1.*std::get<2>(r); }); int i=1; auto it1=std::get<0>(p[0]); auto it2=std::prev(std::get<1>(p[0])); for(;i<(int)p.size();++i) { if(std::get<2>(p[i])!=std::get<2>(p[i-1])) break; if(std::get<0>(p[i])->first < it1->first) it1=std::get<0>(p[i]); if(std::prev(std::get<1>(p[i]))->second > it2->second) it2=std::prev(std::get<1>(p[i])); } ++it2; double rc=0; int cc=0; int x=0; for(;it1!=it2;++it1) { rc+=it1->first*it1->second; cc+=it1->second; if(N==0) { if(x++%10==0) printf("\n"); printf("%5d:%2d,",it1->first,it1->second); } } if(N==0) printf("\n"); return rc/cc; } int round(double value) { return (value > 0.0)?floor(value + 0.5):ceil(value - 0.5); } virtual void reset(double monkey_speed = 0){} virtual void push(double time_second,double dist_meter) {} virtual double get_K() = 0; }; struct monkey_fit_b :monkey_fit { static const int min_points = 60; static const int BN = 20; double k_init_; int count_; std::map probab_b; monkey_fit_b() :k_init_(0) ,count_(0) {} monkey_fit_b(double s) :k_init_(s) ,count_(0) {} virtual void reset(double monkey_speed/*=0*/) { k_init_=monkey_speed; count_=0; probab_b.clear(); } virtual void push(double time_second,double dist_meter) { double k=k_init_; ++count_; double b=(dist_meter-k*time_second)*BN; ++probab_b[round(b)]; } double get_dist(double time_second)const { return k_init_*time_second + get_B(); } double get_K() { return k_init_; } double get_B()const { if(count_ probab_k; std::deque m_points; monkey_fit_k() :step_(0) ,count_(0) {} virtual void reset(double speed /*=0*/) { probab_k.clear(); m_points.clear(); step_=0; count_ = 0; } virtual void push(double time_second,double dist_meter) { int cc=m_points.size(); if(cc<60) { m_points.push_back(point_2(time_second,dist_meter)); } else if(step_++>2) { m_points.push_back(point_2(time_second,dist_meter)); step_=0; } if(cc<10) return; cc*=9./10; for(int i=0;i<3;i++) { int index=rand()%cc; double k=(dist_meter-m_points[index].y_)/(time_second-m_points[index].x_); if((1