#include "StdAfx.h" #include "Vovk.h" #include "Dsa.h" #include "Fuzzy.h" #include "FuzzyWithSets.h" #include "NoTrendNoSeasonality.h" #include "NoTrendNoSeasonality.h" #include "NoTrendAddSeasonality.h" #include "NoTrendMultSeasonality.h" #include "AddTrendNoSeasonality.h" #include "AddTrendAddSeasonality.h" #include "AddTrendMultSeasonality.h" #include "MultTrendNoSeasonality.h" #include "MultTrendAddSeasonality.h" #include "MultTrendMultSeasonality.h" #include "DATrendNoSeasonality.h" #include "DATrendAddSeasonality.h" #include "DATrendMultSeasonality.h" #include "DMTrendNoSeasonality.h" #include "DMTrendAddSeasonality.h" #include "DMTrendMultSeasonality.h" #include "TrackingControlSignal.h" #include //Set ts at constructor, get first forecast //add value(update) ts //recalculate weights Vovk::Vovk(vector _timeSeria, int _forecastHorizont, Method **m) { prep = new Preparator(true, true); useSingleTrashhold = false; forecastHorizont = 1; singleTrashhold = 0.35; useModelTrashhold = false; modelTrashhold = 0; activeExpertsCount = 0; beta = 0.5; step = 0; forecast = 0; addWeightFromSleepEx = 0.0; timeSeria = _timeSeria; calculateTimeSeriaDiff(_timeSeria); int n = 29; // количество методов, чтоб лишнего памяти не жрать expertsCount = n; forecastHorizont = _forecastHorizont; /*int p = 1; double alpha = 0.4; double delta = 0.9; double gamma = 0.4; double phi = 0.1;*/ int countRulesIn = 1; int countFuzzyParts = 40; models = m; //models[0] = new NoTrendNoSeasonality(_timeSeria, _forecastHorizont); //models[1] = new NoTrendAddSeasonality(_timeSeria, _forecastHorizont); //models[2] = new NoTrendMultSeasonality(_timeSeria, _forecastHorizont); //models[3] = new AddTrendNoSeasonality(_timeSeria, _forecastHorizont); //models[4] = new MultTrendNoSeasonality(_timeSeria, _forecastHorizont); //models[5] = new DATrendNoSeasonality(_timeSeria, _forecastHorizont); //models[6] = new DMTrendNoSeasonality(_timeSeria, _forecastHorizont); //models[7] = new AddTrendAddSeasonality(_timeSeria, _forecastHorizont); //models[8] = new MultTrendAddSeasonality(_timeSeria, _forecastHorizont); //models[9] = new DATrendAddSeasonality(_timeSeria, _forecastHorizont); //models[10] = new DMTrendAddSeasonality(_timeSeria, _forecastHorizont); //models[11] = new AddTrendMultSeasonality(_timeSeria, _forecastHorizont); //models[12] = new MultTrendMultSeasonality(_timeSeria, _forecastHorizont); //models[13] = new DATrendMultSeasonality(_timeSeria, _forecastHorizont); //models[14] = new DMTrendMultSeasonality(_timeSeria, _forecastHorizont); //models[15] = new Dsa(_timeSeria, _forecastHorizont); //models[16] = new Fuzzy("None", "None", _timeSeria, _forecastHorizont); //models[17] = new Fuzzy("Add", "None", _timeSeria, _forecastHorizont); //models[18] = new Fuzzy("None", "Add", _timeSeria, _forecastHorizont); //models[19] = new Fuzzy("Add", "Add", _timeSeria, _forecastHorizont); //models[20] = new FuzzyWithSets("None", "None", _timeSeria, _forecastHorizont); //models[21] = new FuzzyWithSets("None", "Add", _timeSeria, _forecastHorizont); //models[22] = new FuzzyWithSets("None", "Mult", _timeSeria, _forecastHorizont); //models[23] = new FuzzyWithSets("Add", "None", _timeSeria, _forecastHorizont); //models[24] = new FuzzyWithSets("Add", "Add", _timeSeria, _forecastHorizont); //models[25] = new FuzzyWithSets("Add", "Mult", _timeSeria, _forecastHorizont); //models[26] = new FuzzyWithSets("Mult", "None", _timeSeria, _forecastHorizont); //models[27] = new FuzzyWithSets("Mult", "Add", _timeSeria, _forecastHorizont); //models[28] = new FuzzyWithSets("Mult", "Mult", _timeSeria, _forecastHorizont); ////add models //for (int i = 0; i < 29; i++) { // // создаем модель для тестирования при помощи выбранного метода // // задаем параметры // models[i]->setParam("alpha", alpha); // models[i]->setParam("gamma", gamma); // models[i]->setParam("delta", delta); // models[i]->setParam("p", p); // models[i]->setParam("phi", phi); // models[i]->setParam("countRulesIn", countRulesIn); // models[i]->setParam("countFuzzyParts", countFuzzyParts); // models[i]->setParam("w", 0.5); // // с нужно определять как относительную величину, без привязки к значениям ряда // // лишь потом масштабировать // // например можно рассчитать так: при количестве интервалов разбиения = 20, если задать c = 20 // // то треугольники будут перекрывать друг друга ровно на половину // models[i]->setParam("c", 20); // // создаем модель // models[i]->createModelForEstimation(); //} //push models to Vovks object double check = 0; //set weights at first time for (int i = 0; i < expertsCount; i++) { models[i]->weight = (1.0 / expertsCount); check += models[i]->weight; models[i]->value = models[i]->getForecast()[step]; //cout << models[i]->value << " " << models[i]->weight << " " << forecast << endl; } //check experts representation checkExperts(); //calculate first forecast for (int i = 0; i < expertsCount; i++) { if (models[i]->isActive) forecast += models[i]->value * (models[i]->weight + addWeightFromSleepEx/activeExpertsCount); } getNewExpertsValues(); //step++; } void Vovk::setBeta(double _beta){ beta = _beta; } Vovk::~Vovk() { } void Vovk::calculateTimeSeriaDiff(vector timeSeria){ double diff = 0.0; for (int i = 0; i < timeSeria.size() - 1; i++){ diff += fabs(timeSeria[i] - timeSeria[i + 1]); } timeSeriaDiff = (diff / (timeSeria.size() - 1)) * (1 + singleTrashhold); } void Vovk::checkExperts(){ TrackingControlSignal *tcs = new TrackingControlSignal(); activeExpertsCount = expertsCount; addWeightFromSleepEx = 0.0; vector expertsActivity = tcs->HistoricalExpertControl(models, timeSeriaDiff, expertsCount); for (int i = 0; i < expertsCount; i++) { models[i]->isActive = expertsActivity[i]; if (!expertsActivity[i]){ addWeightFromSleepEx += models[i]->weight; activeExpertsCount--; } } } void Vovk::getNewExpertsValues(){ for (int i = 0; i < expertsCount; i++){ //for 1 scale forecast models[i]->value = models[i]->getForecast()[step]; } step++; } //ret gt(x) double Vovk::recalculateWeights(double nextRealValue){ double weightsSum = 0; for (int i = 0; i < expertsCount; i++){ models[i]->weight = models[i]->weight * pow(beta, fabs(models[i]->value - nextRealValue)); weightsSum += models[i]->weight; } //normalize weights double check = 0.0; for (int i = 0; i < expertsCount; i++){ models[i]->weight = models[i]->weight / weightsSum; check += models[i]->weight; } return log(weightsSum) / log(beta);//beta, weightsSum); } void Vovk::updateTS(double nextRealValue){ //change models weights with new real value double gtx = recalculateWeights(nextRealValue); forecast = 0.0; //create new forecast from experts getNewExpertsValues(); checkExperts(); //create aggregated forecast double check = 0.0; for (int i = 0; i < expertsCount; i++) { /*cout << i << ") "; if (models[i]->isActive){ cout << "true "; } else{ cout << "false "; } cout << " " << models[i]->value << " " << models[i]->weight << endl;*/ if (models[i]->isActive){ check += models[i]->weight; forecast += models[i]->value * (models[i]->weight + addWeightFromSleepEx / activeExpertsCount); } } } double Vovk::getForecast(){ return forecast; } //void Vovk::addMethod(AggModel model){ // models.push_back(model); //}