ts-aggregator/project_template/Tsaur.cpp
2022-12-13 12:36:06 +04:00

271 lines
7.5 KiB
C++

#include "StdAfx.h"
#include "Tsaur.h"
#include "Param.h"
#include "float.h"
#include <iostream>
Tsaur::Tsaur(vector<double> timeSeries, int countPointForecast){
this->countPointForecast = countPointForecast;
this->trendType = trendType;
this->seasonType = seasonType;
this->x = timeSeries;
this->partition();
}
void Tsaur::init() {
S.clear();
T.clear();
T.push_back(fuzzyfication(x[1]-x[0]));
S.push_back(fuzzyfication(x[0]));
fuzzyForecast.push_back(plusSet(S[0], T[0]));
}
// îïðåäåëèòü óíèâåðñóì äëÿ âðåìåííîãî ðÿäà
// èùåì ìàêñèìóì, ìèíèìóì, ïðîèçâîäèì ðàçáèåíèå íà çàäàííûå èíòåðâàëû
void Tsaur::defineUniversum() {
this->universumMax = x[0];
this->universumMin = x[0];
for (int i = 1; i < x.size(); i++) {
if (universumMax < x[i]) {
universumMax = x[i];
}
if (universumMin > x[i]) {
universumMin = x[i];
}
}
// ñîçäàåì ôóíêöèè ïðèíàäëåæíîñòè
// ïðèíèìàåì ïî óìîë÷àíèþ, ÷òî ñîñåäíèå ïåðåêðûâàþòñÿ íà ïîëîâèíó ìåæäó ñîáîé
// ðàç åñòü êîëè÷åñòâî èíòåðâàëîâ, òî âû÷èñëÿåì ðàçìåð îñíîâàíèÿ òðåóãîëüíèêà
double baseSize = (universumMax - universumMin) / countFuzzyParts;
a.resize(countFuzzyParts + 1);
for (int i=0; i < countFuzzyParts + 1;i++){
a[i] = (A(universumMin + (i-1) * baseSize, universumMin + (i+1)*baseSize));
}
}
// îïåðàöèÿ âû÷èòàíèÿ ìíîæåñòâ
A Tsaur::minusSet(A a, A b) {
//if ((a.getLeft()- b.getLeft()) < (a.getRight() - b.getRight())) {
return A(a.getLeft()- b.getLeft(), a.getRight() - b.getRight());
//} else {
// return A(a.getRight() - b.getRight(), a.getLeft()- b.getLeft());
//}
}
// îïåðàöèÿ âû÷èòàíèÿ ìíîæåñòâ
A Tsaur::numMinusSet(double num, A a) {
//if ((num - a.getLeft()) < (num - a.getRight())) {
return A(num - a.getLeft(), num - a.getRight());
//} else {
// return A(num - a.getRight(), num - a.getLeft());
//}
}
// îïåðàöèÿ äåëåíèÿ ìíîæåñòâ
A Tsaur::divSet(A a, A b) {
return A(a.getLeft()/b.getLeft(), a.getRight()/b.getRight());
}
// îïåðàöèÿ äåëåíèÿ ìíîæåñòâ
A Tsaur::divSet(A a, double b) {
return A(a.getLeft()/b, a.getRight()/b);
}
// îïåðàöèÿ óìíîæåíèå ìíîæåñòâà íà ÷èñëî
A Tsaur::multSetNum(double num, A a) {
//if ((a.getLeft() * num) < (a.getRight() * num)) {
return A(a.getLeft() * num, a.getRight() * num);
//} else {
// return A(a.getRight() * num, a.getLeft() * num);
//}
}
// îïåðàöèÿ ñëîæåíèÿ ìíîæåñòâ
A Tsaur::plusSet(A a, A b) {
return A(a.getLeft()+ b.getLeft(), a.getRight() + b.getRight());
}
// îïåðàöèÿ óìíîæåíèÿ ìíîæåñòâ
A Tsaur::multSet(A a, A b) {
//if ((a.getLeft()* b.getLeft()) < (a.getRight() * b.getRight())) {
return A(a.getLeft()* b.getLeft(), a.getRight() * b.getRight());
//} else {
// return A(a.getLeft()* b.getLeft(), a.getRight() * b.getRight());
//}
}
// ôàççèôèöèðîâàòü òîëüêî îäíó òî÷êó
// âîçâðàùàåò èíäåêñ ôóíêöèè ïðèíàäëåæíîñòè ñ ìàêñèìàëüíûì çíà÷åíèåì
A Tsaur::fuzzyfication(double value) {
// ïåðåáèðàåì âñå ôóíêöèè ïðèíàäëåæíîñòè,
// åñëè íàøëè íàèáîëüøóþ ñòåïåíü ïðèíàäëåæíîñòè, òî ôèêñèðóåì èíäåêñ ôóíêöèè
A aMax = a[0];
for (int j = 0; j < a.size(); j++) {
if (a[j].getValue(value) > aMax.getValue(value)) {
aMax = a[j];
}
}
return aMax;
}
void Tsaur::createModelForEstimation() {
defineUniversum();
A fuzzyBetta0 = fuzzyfication(xLearning[1]- xLearning[0]);
A fuzzyBetta1 = A(lb1,rb1);
A fuzzyBetta2 = A(lb2,rb2);
A fuzzyAlpha = A(0, 1);
fuzzyTs.clear();
fuzzyForecast.clear();
// ôàççèôèêàöèÿ
fuzzyTs.resize(xLearning.size());
init();
A e;
//âûïîëíÿåòñÿ ïðîõîä ìîäåëè ïî ñãëàæèâàíèþ è ïðîãíîçèðîâàíèþ countPointForecast òî÷åê
for (unsigned int t = 0; t < xLearning.size()-1+this->countPointForecast; t++) {
if (t < xLearning.size()) {
e = minusSet(fuzzyfication(xLearning[t]), fuzzyForecast[t]);
} else {
e = A(0,0);
}
S.push_back(plusSet(S[t], multSet(e, fuzzyAlpha)));
T.push_back(plusSet(plusSet(fuzzyBetta0, multSetNum(t, fuzzyBetta1)), multSetNum(t*t, fuzzyBetta2)));
fuzzyForecast.push_back(plusSet(multSetNum(alpha, S[t+1]), multSetNum((1-alpha), T[t+1])));
//fuzzyForecast.push_back(S[t+1]);
}
forecast.clear();
forecast.resize(fuzzyForecast.size());
for (unsigned int i = 0; i < fuzzyForecast.size(); i++) {
if (_finite(defuzzyfication(fuzzyForecast[i])) == 0){
forecast[i] = (x[x.size()-1]);
} else {
forecast[i] = (defuzzyfication(fuzzyForecast[i]));
}
}
}
void Tsaur::createModel() {
defineUniversum();
A fuzzyBetta0 = fuzzyfication(x[1]- x[0]);
A fuzzyBetta1 = A(lb1,rb1);
A fuzzyBetta2 = A(lb2,rb2);
A fuzzyAlpha = A(0, 1);
fuzzyTs.clear();
fuzzyForecast.clear();
// ôàççèôèêàöèÿ
fuzzyTs.resize(x.size());
init();
A e;
//âûïîëíÿåòñÿ ïðîõîä ìîäåëè ïî ñãëàæèâàíèþ è ïðîãíîçèðîâàíèþ countPointForecast òî÷åê
for (unsigned int t = 0; t < x.size()-1+this->countPointForecast; t++) {
if (t < x.size()) {
e = minusSet(fuzzyfication(x[t]), fuzzyForecast[t]);
} else {
e = A(0,0);
}
S.push_back(plusSet(S[t], multSet(e, fuzzyAlpha)));
T.push_back(plusSet(plusSet(fuzzyBetta0, multSetNum(t, fuzzyBetta1)), multSetNum(t*t, fuzzyBetta2)));
fuzzyForecast.push_back(plusSet(multSetNum(alpha, S[t+1]), multSetNum((1-alpha), T[t+1])));
//fuzzyForecast.push_back(S[t+1]);
}
forecast.clear();
forecast.resize(fuzzyForecast.size());
for (unsigned int i = 0; i < fuzzyForecast.size(); i++) {
if (_finite(defuzzyfication(fuzzyForecast[i])) == 0){
forecast[i] = (x[x.size()-1]);
} else {
forecast[i] = (defuzzyfication(fuzzyForecast[i]));
}
}
}
// ìåòîä ïîëó÷åíèÿ îöåíêè ìîäåëè
double Tsaur::calcEstimation(Aic *aic) {
return aic->getValue(3, this->xEstimation, this->forecast);
}
Tsaur::~Tsaur(void) {
}
double Tsaur::defuzzyfication(A a) {
return a.getValueAtTop();
}
vector<double> Tsaur::defuzzyfication(vector<A> fuz) {
vector<double> result;
for (int i =0; i < fuz.size(); i++) {
result.push_back(defuzzyfication(fuz[i]));
}
return result;
}
vector<double> Tsaur::getForecast() {
vector<double> result;
for (unsigned int i = forecast.size() - countPointForecast; i < forecast.size(); i++) {
result.push_back(forecast[i]);
}
return result;
}
void Tsaur::setParam(string paramName, double value) {
if (paramName.compare("countFuzzyParts") == 0) {
this->countFuzzyParts = value;
} else if (paramName.compare("alpha") == 0) {
this->alpha = value;
} else if (paramName.compare("lb1") == 0) {
this->lb1 = value;
} else if (paramName.compare("rb1") == 0) {
this->rb1 = value;
} else if (paramName.compare("lb2") == 0) {
this->lb2 = value;
} else if (paramName.compare("rb2") == 0) {
this->rb2 = value;
}
}
// ìåòîä ïîëó÷åíèÿ îïòèìèçèðîâàííîãî çíà÷åíèÿ îäíîãî ïàðàìåòðà
// TODO: ðåàëèçîâàòü
Param* Tsaur::optimize(Estimation *est) {
Param *optimal = new Param();
double minSmape = 99999;
for (double a = 0; a < 1; a+= 0.1) {
cout << "TSAUR " << a << " èç 1" <<"\n";;
for (double _lb1 = -10; _lb1 < 1; _lb1 += 0.2) {
for (double _rb1 = _lb1; _rb1 < 1; _rb1 += 0.2) {
for (double _lb2 = -1; _lb2 < 1; _lb2 += 0.2) {
for (double _rb2 = _lb2; _rb2 < 1; _rb2 += 0.2) {
for (double cfp = 2; cfp < 20;cfp+= 1) {
this->setParam("countFuzzyParts", cfp);
this->setParam("alpha", a);
this->setParam("lb1", _lb1);
this->setParam("rb1", _rb1);
this->setParam("lb2", _lb2);
this->setParam("rb2", _rb2);
this->createModelForEstimation();
double smapeValue = est->getValue(getXEstimation(), getForecast());
if (minSmape > smapeValue) {
minSmape = smapeValue;
optimal->countFuzzyParts = cfp;
optimal->alpha = a;
optimal->lb1 = _lb1;
optimal->lb2 = _lb2;
optimal->rb1 = _rb1;
optimal->rb2 = _rb2;
}
}
}
}
}
}
}
return optimal;
}