#14 -- Add forecast stub

This commit is contained in:
Anton Romanov 2025-03-19 15:39:18 +04:00
parent 58a59e1d03
commit 34db9f6018
3 changed files with 50 additions and 39 deletions

View File

@ -10,7 +10,7 @@ import ru.ulstu.method.MethodParamValue;
import ru.ulstu.method.MethodParameter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.List;
@Component
@ -24,35 +24,54 @@ public class PlainFuzzy extends Method {
protected Model getModelOfValidTimeSeries(TimeSeries timeSeries, List<MethodParamValue> parameters) {
PlainFuzzyModel model = new PlainFuzzyModel(timeSeries, parameters);
List<Triangle> fuzzySets = generateFuzzySets(timeSeries, model.getNumberOfFuzzyTerms().getIntValue());
return null;
for (TimeSeriesValue tsVal : timeSeries.getValues()) {
model.getTimeSeriesModel().addValue(new TimeSeriesValue(
tsVal.getDate(),
getMaxMembership(fuzzySets, tsVal).getTop()));
model.getFuzzyTimeSeries().add(getMaxMembership(fuzzySets, tsVal));
}
return model;
}
private List<Triangle> generateFuzzySets(TimeSeries timeSeries, Integer numberOfFuzzyTerms) {
List<Triangle> fuzzySets = new ArrayList<Triangle>();
double min = timeSeries.getValues()
// Universum
DoubleSummaryStatistics stat = timeSeries.getValues()
.stream()
.min(Comparator.comparing(TimeSeriesValue::getValue))
.map(TimeSeriesValue::getValue)
.orElseThrow(() -> new RuntimeException("Минимальное значение не найдено"));
double max = timeSeries.getValues()
.stream()
.max(Comparator.comparing(TimeSeriesValue::getValue))
.map(TimeSeriesValue::getValue)
.orElseThrow(() -> new RuntimeException("Максимальное значение не найдено"));
.mapToDouble(TimeSeriesValue::getValue)
.summaryStatistics();
double min = stat.getMin();
double max = stat.getMax();
// Generate fuzzy sets
List<Triangle> fuzzySets = new ArrayList<>();
double delta = ((max - min) / (numberOfFuzzyTerms - 1));
for (int i = 0; i < numberOfFuzzyTerms; i++) {
fuzzySets.add(new Triangle(min + i * delta - delta,
min + i * delta,
min + i * delta + delta));
min + i * delta + delta, i));
}
return fuzzySets;
}
private Triangle getMaxMembership(List<Triangle> fuzzySets, TimeSeriesValue tsVal) {
Triangle maxTriangle = fuzzySets.get(0);
double membersip = 0;
for (Triangle triangle : fuzzySets) {
if (membersip < triangle.getValueAtPoint(tsVal.getValue())) {
maxTriangle = triangle;
membersip = triangle.getValueAtPoint(tsVal.getValue());
}
}
return maxTriangle;
}
@Override
protected TimeSeries getForecastWithValidParams(Model model, TimeSeries forecast) throws ModelingException {
return null;
for (TimeSeriesValue tsVal : forecast.getValues()) {
tsVal.setValue(0.0);
}
return forecast;
}
@Override

View File

@ -11,14 +11,11 @@ import java.util.Collections;
import java.util.List;
public class PlainFuzzyModel extends Model {
private final static String PREFIX_OF_FUZZY_LABEL = "X";
private final MethodParamValue numberOfFuzzyTerms = new MethodParamValue(NumberOfFuzzyTerms.getInstance(), 2);
private List<String> fuzzyTimeSeries = new ArrayList<>();
private TimeSeries defuzzyfiedTimeSeries;
private final List<Triangle> fuzzyTimeSeries = new ArrayList<>();
protected PlainFuzzyModel(TimeSeries ts, List<MethodParamValue> parameters) {
super(ts);
defuzzyfiedTimeSeries = new TimeSeries("Defuzzified time series of ", ts.getKey());
for (MethodParamValue parameter : parameters) {
if (parameter.getParameter() instanceof NumberOfFuzzyTerms) {
numberOfFuzzyTerms.setValue(parameter.getValue());
@ -34,19 +31,7 @@ public class PlainFuzzyModel extends Model {
return numberOfFuzzyTerms;
}
public List<String> getFuzzyTimeSeries() {
public List<Triangle> getFuzzyTimeSeries() {
return fuzzyTimeSeries;
}
public void setFuzzyTimeSeries(List<String> fuzzyTimeSeries) {
this.fuzzyTimeSeries = fuzzyTimeSeries;
}
public TimeSeries getDefuzzyfiedTimeSeries() {
return defuzzyfiedTimeSeries;
}
public void setDefuzzifiedTimeSeries(TimeSeries defuzzifiedTimeSeries) {
this.defuzzyfiedTimeSeries = defuzzifiedTimeSeries;
}
}

View File

@ -1,6 +1,8 @@
package ru.ulstu.method.fuzzy;
public class Triangle {
private final static String FUZZY_LABEL_TEMPLATE = "X%s";
private String label;
private double start; // левая граница треугольника
private double end; // правая граница треугольника
private double top; // вершина треугольника
@ -9,10 +11,11 @@ public class Triangle {
return start;
}
public Triangle(double start, double top, double end) {
public Triangle(double start, double top, double end, int number) {
this.start = start;
this.top = top;
this.end = end;
this.label = String.format(FUZZY_LABEL_TEMPLATE, number);
}
public void setStart(int start) {
@ -36,16 +39,20 @@ public class Triangle {
this.top = top;
}
public double getValueAtPoint(int pointIndex) {
if (pointIndex == this.getTop()) {
public double getValueAtPoint(double crispValue) {
if (crispValue == this.getTop()) {
return 1;
} else if ((pointIndex >= this.getEnd()) || (pointIndex <= this.getStart())) {
} else if ((crispValue >= this.getEnd()) || (crispValue <= this.getStart())) {
return 0;
} else if (pointIndex < this.getTop()) {
return (pointIndex - this.getStart()) / (this.getTop() - this.getStart());
} else if (pointIndex > this.getTop()) {
return -(pointIndex - this.getEnd()) / (this.getEnd() - this.getTop());
} else if (crispValue < this.getTop()) {
return (crispValue - this.getStart()) / (this.getTop() - this.getStart());
} else if (crispValue > this.getTop()) {
return -(crispValue - this.getEnd()) / (this.getEnd() - this.getTop());
}
return 0;
}
public String getLabel() {
return label;
}
}