Compare commits

..

No commits in common. "1dc44f79889eae29b0f0bbb36e5abb5f0965304e" and "d03cb194ee0ef081af66d40fd63081155a68def7" have entirely different histories.

4 changed files with 79 additions and 20 deletions

View File

@ -30,6 +30,7 @@ public class AssessmentController {
model.addAttribute("branches", branchService.findAllValid()); model.addAttribute("branches", branchService.findAllValid());
if (branchId.isPresent()) { if (branchId.isPresent()) {
model.addAttribute("assessments", assessmentService.getAssessments(branchId.get())); model.addAttribute("assessments", assessmentService.getAssessments(branchId.get()));
model.addAttribute("singleAssessment", assessmentService.getSingleAssessment(branchId.get()));
model.addAttribute("filterBranchForm", new FilterBranchForm(branchId.get())); model.addAttribute("filterBranchForm", new FilterBranchForm(branchId.get()));
} else { } else {
model.addAttribute("filterBranchForm", new FilterBranchForm()); model.addAttribute("filterBranchForm", new FilterBranchForm());

View File

@ -2,6 +2,7 @@ package ru.ulstu.extractor.assessment.service;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.ulstu.extractor.assessment.model.Assessment; import ru.ulstu.extractor.assessment.model.Assessment;
import ru.ulstu.extractor.rule.model.AssessmentException;
import ru.ulstu.extractor.rule.model.DbRule; import ru.ulstu.extractor.rule.model.DbRule;
import ru.ulstu.extractor.rule.service.AntecedentValueService; import ru.ulstu.extractor.rule.service.AntecedentValueService;
import ru.ulstu.extractor.rule.service.DbRuleService; import ru.ulstu.extractor.rule.service.DbRuleService;
@ -9,9 +10,12 @@ import ru.ulstu.extractor.rule.service.FuzzyInferenceService;
import ru.ulstu.extractor.ts.model.TimeSeries; import ru.ulstu.extractor.ts.model.TimeSeries;
import ru.ulstu.extractor.ts.service.TimeSeriesService; import ru.ulstu.extractor.ts.service.TimeSeriesService;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
@Service @Service
public class AssessmentService { public class AssessmentService {
@ -33,10 +37,44 @@ public class AssessmentService {
public List<Assessment> getAssessments(Integer branchId) { public List<Assessment> getAssessments(Integer branchId) {
List<TimeSeries> timeSeries = timeSeriesService.getByBranch(branchId); List<TimeSeries> timeSeries = timeSeriesService.getByBranch(branchId);
List<DbRule> dbRules = ruleService.getList(); List<DbRule> dbRules = ruleService.getList();
try {
return getAssessments(dbRules, timeSeries);
} catch (AssessmentException ex) {
ex.printStackTrace();
return new ArrayList<>();
}
}
public List<Assessment> getSingleAssessment(Integer branchId) throws AssessmentException {
List<TimeSeries> timeSeries = timeSeriesService.getByBranch(branchId);
List<DbRule> dbRules = ruleService.getList();
return getSingleAssessment(dbRules, timeSeries);
}
private List<Assessment> getSingleAssessment(List<DbRule> dbRules, List<TimeSeries> timeSeries) throws AssessmentException {
Map<String, Double> variableValues = new HashMap<>(); Map<String, Double> variableValues = new HashMap<>();
timeSeries.forEach(ts -> variableValues.put(ts.getTimeSeriesType().name(), timeSeriesService.getLastTimeSeriesTendency(ts))); timeSeries.forEach(ts -> variableValues.put(ts.getTimeSeriesType().name(), timeSeriesService.getLastTimeSeriesTendency(ts)));
return fuzzyInferenceService.getFuzzyInference(dbRules, return fuzzyInferenceService.getFuzzyInference(dbRules,
antecedentValueService.getList(), antecedentValueService.getList(),
variableValues); variableValues);
} }
private List<Assessment> getAssessments(List<DbRule> dbRules, List<TimeSeries> timeSeries) {
return dbRules
.stream()
.flatMap(dbRule -> {
Map<String, Double> variableValues = new HashMap<>();
timeSeries
.stream()
.filter(ts -> ts.getTimeSeriesType() == dbRule.getFirstAntecedent()
|| ts.getTimeSeriesType() == dbRule.getSecondAntecedent())
.forEach(ts -> variableValues.put(ts.getTimeSeriesType().name(), timeSeriesService
.getLastTimeSeriesTendency(ts)));
return fuzzyInferenceService.getFuzzyInference(List.of(dbRule),
antecedentValueService.getList(),
variableValues).stream();
})
.sorted(Comparator.comparing(Assessment::getDegree))
.collect(Collectors.toList());
}
} }

View File

@ -8,7 +8,6 @@ import com.fuzzylite.norm.t.AlgebraicProduct;
import com.fuzzylite.norm.t.Minimum; import com.fuzzylite.norm.t.Minimum;
import com.fuzzylite.rule.Rule; import com.fuzzylite.rule.Rule;
import com.fuzzylite.rule.RuleBlock; import com.fuzzylite.rule.RuleBlock;
import com.fuzzylite.term.Activated;
import com.fuzzylite.term.Triangle; import com.fuzzylite.term.Triangle;
import com.fuzzylite.variable.InputVariable; import com.fuzzylite.variable.InputVariable;
import com.fuzzylite.variable.OutputVariable; import com.fuzzylite.variable.OutputVariable;
@ -58,11 +57,20 @@ public class FuzzyInferenceService {
input.setName(key); input.setName(key);
input.setDescription(""); input.setDescription("");
input.setEnabled(true); input.setEnabled(true);
double delta = antecedentValues.size() > 1
? 2.0 / (antecedentValues.size() - 1)
: 2.0;
input.setRange(-1, 1); input.setRange(-1, 1);
input.setLockValueInRange(false); input.setLockValueInRange(false);
input.addTerm(new Triangle("спад", -1, 0)); for (int i = 0; i < antecedentValues.size(); i++) {
input.addTerm(new Triangle("стабильно", -0.1, 0.1)); input.addTerm(
input.addTerm(new Triangle("рост", 0, 1)); new Triangle(
antecedentValues.get(i).getAntecedentValue(),
-1 + i * delta - 0.5 * delta,
-1 + i * delta + delta + 0.5 * delta
)
);
}
engine.addInputVariable(input); engine.addInputVariable(input);
}); });
@ -106,23 +114,18 @@ public class FuzzyInferenceService {
List<AntecedentValue> antecedentValues, List<AntecedentValue> antecedentValues,
Map<String, Double> variableValues) { Map<String, Double> variableValues) {
validateVariables(variableValues, dbRules); validateVariables(variableValues, dbRules);
variableValues.entrySet().forEach(e -> System.out.println(e.getKey() + " " + e.getValue()));
Engine engine = getFuzzyEngine(); Engine engine = getFuzzyEngine();
List<Integer> consequentValues = dbRules.stream().map(DbRule::getId).collect(Collectors.toList()); List<Integer> consequentValues = dbRules.stream().map(DbRule::getId).collect(Collectors.toList());
engine.addRuleBlock(getRuleBlock(engine, dbRules, variableValues, antecedentValues, consequentValues)); engine.addRuleBlock(getRuleBlock(engine, dbRules, variableValues, antecedentValues, consequentValues));
Map<String, Double> consequents = getConsequent(engine, variableValues); Map.Entry<String, Double> consequent = getConsequent(engine, variableValues);
if (consequents.containsKey(NO_RESULT)) { if (consequent.getKey().equals(NO_RESULT)) {
return new ArrayList<>(); return new ArrayList<>();
} }
List<Assessment> assessments = new ArrayList<>(); return dbRules
for (Map.Entry<String, Double> consequent : consequents.entrySet()) { .stream()
for (DbRule dbRule : dbRules) { .filter(r -> r.getId().equals(Integer.valueOf(consequent.getKey())))
if (dbRule.getId().equals(Integer.valueOf(consequent.getKey()))) { .map(r -> new Assessment(r, consequent.getValue()))
assessments.add(new Assessment(dbRule, consequent.getValue())); .collect(Collectors.toList());
}
}
}
return assessments;
} }
@ -139,7 +142,7 @@ public class FuzzyInferenceService {
} }
} }
private Map<String, Double> getConsequent(Engine engine, Map<String, Double> variableValues) { private Map.Entry<String, Double> getConsequent(Engine engine, Map<String, Double> variableValues) {
OutputVariable outputVariable = engine.getOutputVariable(OUTPUT_VARIABLE_NAME); OutputVariable outputVariable = engine.getOutputVariable(OUTPUT_VARIABLE_NAME);
for (Map.Entry<String, Double> variableValue : variableValues.entrySet()) { for (Map.Entry<String, Double> variableValue : variableValues.entrySet()) {
InputVariable inputVariable = engine.getInputVariable(variableValue.getKey()); InputVariable inputVariable = engine.getInputVariable(variableValue.getKey());
@ -149,8 +152,8 @@ public class FuzzyInferenceService {
if (outputVariable != null) { if (outputVariable != null) {
LOG.info("Output: {}", outputVariable.getValue()); LOG.info("Output: {}", outputVariable.getValue());
} }
return Double.isNaN(outputVariable.getValue()) return (outputVariable == null || Double.isNaN(outputVariable.getValue()))
? Map.of(NO_RESULT, 0.0) ? Map.entry(NO_RESULT, 0.0)
: outputVariable.fuzzyOutput().getTerms().stream().collect(Collectors.toMap(t -> t.getTerm().getName(), Activated::getDegree)); : Map.entry(outputVariable.highestMembershipTerm(outputVariable.getValue()).getName(), outputVariable.getValue());
} }
} }

View File

@ -46,5 +46,22 @@
<div th:if="${assessments != null && #lists.size(assessments) == 0}"> <div th:if="${assessments != null && #lists.size(assessments) == 0}">
<h5>Нет результатов</h5> <h5>Нет результатов</h5>
</div> </div>
<hr/>
<div th:if="${singleAssessment != null && #lists.size(assessments) > 0}">
<h5>Состояние репозитория по лидирующему правилу описывается следующими выражениями:</h5>
<div th:each="assessment: ${singleAssessment}">
<span th:text="${assessment.consequent}"></span>
вследствие тенденции '<span th:text="${assessment.firstAntecedentTendency}"></span>' показателя '<span
th:text="${assessment.firstAntecedent.description}"></span>'
и тенденции '<span th:text="${assessment.secondAntecedentTendency}"></span>' показателя '<span
th:text="${assessment.secondAntecedent.description}"></span>';
<span class="badge badge-warning" th:text="${assessment.degree}"></span>
</div>
</div>
<div th:if="${singleAssessment != null && #lists.size(singleAssessment) == 0}">
<h5>Нет результатов</h5>
</div>
</div> </div>
</html> </html>