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

127 lines
3.9 KiB
C++

#include "StdAfx.h"
#include <iostream>
#include <math.h>
#include "AicWeights.h"
using namespace std;
AicWeights::AicWeights(){
delta = 0.5;
N = 0.5;
}
AicWeights::~AicWeights(){
}
double AicWeights::getMinValue(vector<double> AicValues){
double res = AicValues[0];
for (int i = 0; i < AicValues.size(); i++){
if (AicValues[i] < res){
res = AicValues[i];
}
}
return res;
}
vector<double> AicWeights::calculateWeights(vector<double> AicValues){
vector<double> diffs;
double minWeight = getMinValue(AicValues);
double sum = 0;
for (int i = 0; i < AicValues.size(); i++){
diffs.push_back(AicValues[i] - minWeight);
sum += exp(-0.5 * (AicValues[i] - minWeight));
}
vector<double> res;
for (int i = 0; i < AicValues.size(); i++){
res.push_back(exp(-0.5 *diffs[i]) / sum);
}
double check = 0;
for (int i = 0; i < res.size(); i++){
check += res[i];
}
return res;
}
//timeSeria - Real process time seria value vector.
//forecastedSeries - Vector of vectors of the forecasted values.
//Inner vectors must have the same length that timeSeria. Usually need cut timeSeria.
double AicWeights::alpha(vector<double> timeSeria, vector<vector<double>> forecastedSeries){
double alphaRes = abs(timeSeria[0] - forecastedSeries[0][0]);
for (int j = 0; j < forecastedSeries.size(); j++){
for (int i = 0; i < forecastedSeries[j].size(); i++){
if (alphaRes < abs(timeSeria[i] - forecastedSeries[j][i])){
alphaRes = abs(timeSeria[i] - forecastedSeries[j][i]);
}
}
}
return alphaRes;
}
double AicWeights::beta(vector<double> timeSeria, vector<vector<double>> forecastedSeries){
double betaRes = abs(timeSeria[0] - forecastedSeries[0][0]);
for (int j = 0; j < forecastedSeries.size(); j++){
for (int i = 0; i < forecastedSeries[j].size(); i++){
if (betaRes > abs(timeSeria[i] - forecastedSeries[j][i])){
betaRes = abs(timeSeria[i] - forecastedSeries[j][i]);
}
}
}
return betaRes;
}
double AicWeights::grayBasicWeight(double relativeError, vector<double> timeSeria, vector<vector<double>> forecastedSeries){
return (alpha(timeSeria, forecastedSeries) + beta(timeSeria, forecastedSeries) * delta) / abs(relativeError)
+ beta(timeSeria, forecastedSeries) * delta;
}
double AicWeights::grayTendency(double forecastedTendency, vector<double> timeSeria, vector<vector<double>> forecastedSeries){
return (alpha(timeSeria, forecastedSeries) + beta(timeSeria, forecastedSeries) * delta) / abs(forecastedTendency)
+ beta(timeSeria, forecastedSeries) * delta;
}
double AicWeights::delta;
double AicWeights::N;
//e(i)
double AicWeights::relativeError(double value, double forecastedValue){
return (value - forecastedValue) / value;
}
//c(i)
double AicWeights::forecastedTendency(vector<double> realSeria){
double sum = 0;
for (int i = 0; i < realSeria.size() - 1; i++){
sum += realSeria[i];
}
return (realSeria[realSeria.size() - 1] - (1 / (realSeria.size() - 2)) * sum) / realSeria[realSeria.size() - 1];
}
//n - positive number,usually n = 0.5
//i - forecasted value number
double AicWeights::adaptiveControlCoefficient(int i){
double acc = 0;
acc = 1 - pow(((i - 1) / i), N);
return acc;
}
vector<double> AicWeights::calculateFuzzyAdaptiveWeights(vector<double> timeSeria, vector<vector<double>> forecastedSeries){
vector<double> fweights;
for (int i = 0; i < forecastedSeries.size(); i++){
fweights.push_back(adaptiveControlCoefficient(timeSeria.size())* grayBasicWeight(relativeError(timeSeria[timeSeria.size() - 1], forecastedSeries[i][forecastedSeries[i].size() - 1]), timeSeria, forecastedSeries)
+ (1 - adaptiveControlCoefficient(timeSeria.size())) * grayTendency(forecastedTendency(timeSeria), timeSeria, forecastedSeries));
}
//normalization
double sum = 0;
for (int i = 0; i < fweights.size(); i++){
sum += fweights[i];
}
for (int i = 0; i < fweights.size(); i++){
fweights[i] = fweights[i] / sum;
}
double check = 0;
for (int i = 0; i < fweights.size(); i++){
check += fweights[i];
}
return fweights;
}