commit
c29650935c
@ -0,0 +1,35 @@
|
||||
package ru.ulstu.extractor.generation.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import ru.ulstu.extractor.generation.model.GenerationForm;
|
||||
import ru.ulstu.extractor.generation.service.GenerationService;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import static ru.ulstu.extractor.core.Route.GENERATION;
|
||||
|
||||
@Controller
|
||||
@ApiIgnore
|
||||
public class GenerationController {
|
||||
private final GenerationService generationService;
|
||||
|
||||
public GenerationController(GenerationService generationService) {
|
||||
this.generationService = generationService;
|
||||
}
|
||||
|
||||
@GetMapping(GENERATION)
|
||||
public String getGenerationsPage(Model model) {
|
||||
model.addAttribute("generationForm", new GenerationForm());
|
||||
return GENERATION;
|
||||
}
|
||||
|
||||
@PostMapping(GENERATION)
|
||||
public String setGenerationParams(Model model, @ModelAttribute GenerationForm generationForm) {
|
||||
model.addAttribute("generationForm", generationForm);
|
||||
generationService.generate(generationForm);
|
||||
return GENERATION;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package ru.ulstu.extractor.generation.model;
|
||||
|
||||
public class GenerationForm {
|
||||
private int tsLength;
|
||||
private double min;
|
||||
private double max;
|
||||
private double base;
|
||||
private double baseTendency;
|
||||
private double tendencyDynamic;
|
||||
private double randomWeight;
|
||||
|
||||
public int getTsLength() {
|
||||
return tsLength;
|
||||
}
|
||||
|
||||
public void setTsLength(int tsLength) {
|
||||
this.tsLength = tsLength;
|
||||
}
|
||||
|
||||
public double getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
public void setMin(double min) {
|
||||
this.min = min;
|
||||
}
|
||||
|
||||
public double getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public void setMax(double max) {
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public double getBase() {
|
||||
return base;
|
||||
}
|
||||
|
||||
public void setBase(double base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public double getBaseTendency() {
|
||||
return baseTendency;
|
||||
}
|
||||
|
||||
public void setBaseTendency(double baseTendency) {
|
||||
this.baseTendency = baseTendency;
|
||||
}
|
||||
|
||||
public double getTendencyDynamic() {
|
||||
return tendencyDynamic;
|
||||
}
|
||||
|
||||
public void setTendencyDynamic(double tendencyDynamic) {
|
||||
this.tendencyDynamic = tendencyDynamic;
|
||||
}
|
||||
|
||||
public double getRandomWeight() {
|
||||
return randomWeight;
|
||||
}
|
||||
|
||||
public void setRandomWeight(double randomWeight) {
|
||||
this.randomWeight = randomWeight;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package ru.ulstu.extractor.generation.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.ulstu.extractor.branch.model.Branch;
|
||||
import ru.ulstu.extractor.branch.service.BranchService;
|
||||
import ru.ulstu.extractor.generation.model.GenerationForm;
|
||||
import ru.ulstu.extractor.ts.model.TimeSeriesType;
|
||||
import ru.ulstu.extractor.ts.model.TimeSeriesValue;
|
||||
import ru.ulstu.extractor.ts.service.TimeSeriesService;
|
||||
import ru.ulstu.extractor.ts.util.DateUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class GenerationService {
|
||||
private final TimeSeriesService timeSeriesService;
|
||||
private final BranchService branchService;
|
||||
|
||||
public GenerationService(TimeSeriesService timeSeriesService,
|
||||
BranchService branchService) {
|
||||
this.timeSeriesService = timeSeriesService;
|
||||
this.branchService = branchService;
|
||||
}
|
||||
|
||||
public void generate(GenerationForm generationForm) {
|
||||
Branch branch = branchService.findByBranchId(Branch.GENERATED_BRANCH_ID).orElseThrow();
|
||||
Date startDate = DateUtils.addDays(-generationForm.getTsLength());
|
||||
Arrays.stream(TimeSeriesType.values()).forEach(tsType -> {
|
||||
List<TimeSeriesValue> tsValues = new ArrayList<>();
|
||||
for (int i = 0; i < generationForm.getTsLength(); i++) {
|
||||
tsValues.add(new TimeSeriesValue(DateUtils.addDays(startDate, i),
|
||||
getNextAdditiveValue(tsValues, generationForm)));
|
||||
}
|
||||
final String tsName = "Генерированный " + tsType.getDescription();
|
||||
timeSeriesService.save(tsName, branch, tsType, tsValues);
|
||||
});
|
||||
}
|
||||
|
||||
private double getNextAdditiveValue(List<TimeSeriesValue> timeSeriesValues, GenerationForm generationForm) {
|
||||
double newValue;
|
||||
int maxTryCount = 10;
|
||||
do {
|
||||
double oneStepDiff = generationForm.getRandomWeight() * (Math.random() - 0.5) * (generationForm.getMax() - generationForm.getMin()) / (generationForm.getTsLength() + 10);
|
||||
if (timeSeriesValues.isEmpty()) {
|
||||
if (generationForm.getBaseTendency() > 0) {
|
||||
newValue = 0.1 * (generationForm.getRandomWeight() > 0.0 ? oneStepDiff : 1.0) * (generationForm.getMax() - generationForm.getMin());
|
||||
} else if (generationForm.getBaseTendency() < 0) {
|
||||
newValue = generationForm.getMax() - 0.1 * (generationForm.getRandomWeight() > 0.0 ? oneStepDiff : 1.0) * (generationForm.getMax() - generationForm.getMin());
|
||||
} else {
|
||||
newValue = generationForm.getBase();
|
||||
}
|
||||
} else {
|
||||
newValue = timeSeriesValues.get(timeSeriesValues.size() - 1).getValue()
|
||||
+ (generationForm.getRandomWeight() > 0.0 ? oneStepDiff : 1.0) * generationForm.getBaseTendency()
|
||||
* ((generationForm.getMax() - generationForm.getMin()) / (generationForm.getTsLength() + 10))
|
||||
* generationForm.getTendencyDynamic();
|
||||
}
|
||||
maxTryCount--;
|
||||
} while (((newValue <= generationForm.getMin())
|
||||
|| (newValue >= generationForm.getMax()))
|
||||
&& (maxTryCount > 0));
|
||||
return newValue;
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
|
||||
<html
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
|
||||
layout:decorate="~{default}">
|
||||
<head>
|
||||
<title>Генерация</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
<div class="container" layout:fragment="content">
|
||||
<form action="#" th:action="${@route.GENERATION}" th:object="${generationForm}" method="post">
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-sm-12">
|
||||
Длина временных рядов
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<input type="text" class="form-control m-1" th:field="*{tsLength}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-sm-12">
|
||||
Минимум
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<input type="text" class="form-control m-1" th:field="*{min}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-sm-12">
|
||||
Максимум
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<input type="text" class="form-control m-1" th:field="*{max}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-sm-12">
|
||||
Основное значение
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<input type="text" class="form-control m-1" th:field="*{base}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-sm-12">
|
||||
Основная тенденция
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<input type="text" class="form-control m-1" th:field="*{baseTendency}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-sm-12">
|
||||
Динамика тенденции
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<input type="text" class="form-control m-1" th:field="*{tendencyDynamic}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-sm-12">
|
||||
Величина шума
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<input type="text" class="form-control m-1" th:field="*{randomWeight}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-sm-12">
|
||||
<input type="submit" class="btn btn-outline-success form-control" value="Сгенерировать временные ряды"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</html>
|
Loading…
Reference in New Issue