146 lines
4.1 KiB
C++
146 lines
4.1 KiB
C++
|
//
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//
|
|||
|
#include "StdAfx.h"
|
|||
|
#include <iostream>
|
|||
|
#include "MultTrendMultSeasonality.h"
|
|||
|
#include <math.h>
|
|||
|
#include "Param.h"
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
MultTrendMultSeasonality::MultTrendMultSeasonality(vector<double> timeSeries, int countPointForecast) {
|
|||
|
this->x = timeSeries;
|
|||
|
this->countPointForecast = countPointForecast;
|
|||
|
this->partition();
|
|||
|
}
|
|||
|
|
|||
|
MultTrendMultSeasonality::~MultTrendMultSeasonality() {
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
std::vector<double> ().swap(S);
|
|||
|
std::vector<double> ().swap(x);
|
|||
|
std::vector<double> ().swap(T);
|
|||
|
std::vector<double> ().swap(I);
|
|||
|
std::vector<double> ().swap(forecast);
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
void MultTrendMultSeasonality::init() {
|
|||
|
S.clear();
|
|||
|
T.clear();
|
|||
|
I.clear();
|
|||
|
forecast.clear();
|
|||
|
|
|||
|
double sumS = 0;
|
|||
|
double sumT = 0;
|
|||
|
for (unsigned int t = 0; t < p; t++) {
|
|||
|
sumS += x[t];
|
|||
|
sumT += x[t+p];
|
|||
|
}
|
|||
|
|
|||
|
S.push_back(sumS / p);
|
|||
|
T.push_back((sumT/ p - S[0]) / p);
|
|||
|
|
|||
|
for (unsigned int t = 0; t < p; t++) {
|
|||
|
I.push_back(x[t] / S[0]);
|
|||
|
}
|
|||
|
|
|||
|
forecast.push_back(S[0] * T[0] * I[0]);
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
void MultTrendMultSeasonality::setParam(string paramName, double value) {
|
|||
|
if (paramName.compare("alpha") == 0) {
|
|||
|
this->alpha = value;
|
|||
|
} else if (paramName.compare("gamma") == 0) {
|
|||
|
this->gamma = value;
|
|||
|
} else if (paramName.compare("p") == 0) {
|
|||
|
this->p = value;
|
|||
|
} else if (paramName.compare("delta") == 0) {
|
|||
|
this->delta = value;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
void MultTrendMultSeasonality::createModel() {
|
|||
|
this->init(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
double e = 0;
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> countPointForecast <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
for (unsigned int t = 0; t < x.size()-1 + this->countPointForecast; t++) {
|
|||
|
// <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (t < x.size()) {
|
|||
|
e = x[t]-forecast[t];
|
|||
|
} else {
|
|||
|
e = 0;
|
|||
|
}
|
|||
|
|
|||
|
S.push_back(S[t] * T[t] + alpha * e / I[t]); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
T.push_back(T[t] + alpha * gamma * e / (I[t] * S[t])); // <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
I.push_back(I[t] + delta * e / (S[t] * T[t])); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
forecast.push_back(S[t+1] * T[t+1] * I[t+1]); // <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
void MultTrendMultSeasonality::createModelForEstimation() {
|
|||
|
this->init(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
double e = 0;
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> countPointForecast <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
for (unsigned int t = 0; t < xLearning.size()-1 + this->countPointForecast; t++) {
|
|||
|
// <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (t < xLearning.size()) {
|
|||
|
e = xLearning[t]-forecast[t];
|
|||
|
} else {
|
|||
|
e = 0;
|
|||
|
}
|
|||
|
|
|||
|
S.push_back(S[t] * T[t] + alpha * e / I[t]); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
T.push_back(T[t] + alpha * gamma * e / (I[t] * S[t])); // <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
I.push_back(I[t] + delta * e / (S[t] * T[t])); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
forecast.push_back(S[t+1] * T[t+1] * I[t+1]); // <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
vector<double> MultTrendMultSeasonality::getForecast() {
|
|||
|
vector<double> result;
|
|||
|
for (unsigned int i = forecast.size() - countPointForecast; i < forecast.size(); i++) {
|
|||
|
result.push_back(forecast[i]);
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
double MultTrendMultSeasonality::calcEstimation(Aic *aic) {
|
|||
|
return aic->getValue(3, this->xEstimation, this->forecast);
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// TODO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Param* MultTrendMultSeasonality::optimize(Estimation *est) {
|
|||
|
Param *optimal = new Param();
|
|||
|
double minSmape = 99999;
|
|||
|
for (double al = 0.1; al < 1; al+= 0.01) {
|
|||
|
for (double gam = 0.1; gam < 1; gam+= 0.01) {
|
|||
|
for (double del = 0.1; del < 1;del+= 0.01) {
|
|||
|
this->setParam("alpha", al);
|
|||
|
this->setParam("gamma", gam);
|
|||
|
this->setParam("delta", del);
|
|||
|
this->createModelForEstimation();
|
|||
|
double smapeValue = est->getValue(getXEstimation(), getForecast());
|
|||
|
if (minSmape > smapeValue) {
|
|||
|
minSmape = smapeValue;
|
|||
|
optimal->alpha = al;
|
|||
|
optimal->gamma = gam;
|
|||
|
optimal->delta = del;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return optimal;
|
|||
|
}
|
|||
|
|