参考文献: 一种快速的时间序列线性拟合算法 杜奕 卢德唐 李道伦 赵亦朋
#include "iostream"
#include "set"
#include "cmath"
#include "iterator"
#include "fstream"
#include "vector"
using namespace std;
double *x; //数据
double *m; //中位数
int n;
set<int> IE; //极值点初始集合,存储数据的下标
set<int> T; //转折点集合,存储数据的下标
set<int> E; //去除IE中噪音中极值点集合,存储数据下标
vector<int> K; //集合T、E的并集,存储数据下标
void mid()
{
int i;
m[1] = x[1];
int temp;
for(i=2; i<n; i++)
{
temp = (x[i-1] + x[i] + x[i+1]) / 3;
if(abs(temp - x[i]) > 3)
m[i] = temp;
else
m[i] = x[i];
}
m[n] = x[n];
}
void KPSegmentation(double error, double maxTime)
{
IE.insert(1); //第一个数据点放入极值点初始集合
int i;
for(i=2; i<n; i++)
{
if((x[i]>x[i-1] && x[i]>x[i+1]) || (x[i]<x[i-1] && x[i]<x[i+1]))
{
//cout << i << endl;
IE.insert(i); //将第i个数据点放入极值点初始集合
}
if(fabs( x[i] - ((x[i+1]+x[i-1])/2) ) > error)
{
//cout << i << endl;
T.insert(i);
}
}
E.insert(1); //第一个数据放入极值点集合
set<int>::iterator it1;
set<int>::iterator it2;
it1 = it2 = IE.begin();
it2++;
while(it2 != IE.end())
{
if((*it2 - *it1) > maxTime) //如果该极值点保持的时间段>maxTime,相当于两个数据下标的差值
{
cout << *it2 << endl;
E.insert(*it2);
}
it1++;
it2++;
}
set<int>::iterator it;
it = T.begin();
while(it != T.end()) //合并集合E, T
{
E.insert(*it);
it++;
}
}
int main()
{
ifstream fin("小区.txt");
ofstream fout("关键点.txt"); //存储关键点的下标和值
ofstream fout1("x.txt"); //存储关键点下标
ofstream fout2("y.txt"); //存储关键的值
ofstream fout3("m.txt"); //中位数滤波后的值
int i;
double error = 4.5;
double maxTime = 3;
fin >> n;
x = new double[n+1];
m = new double[n+1];
for(i=1; i<=n; i++)
{
fin >> x[i];
}
mid();
for(i=1; i<=n; i++)
{
fout3 << m[i] << endl;
x[i] = m[i];
}
KPSegmentation(error, maxTime);
set<int>:: iterator it;
it = E.begin();
while(it != E.end())
{
fout << *it << " " << x[*it] << "\n";
fout1 << *it << endl;
fout2 << x[*it] << endl;
it++;
}
return 0;
}