Compare commits
6 Commits
3dc85d247b
...
93fc95d70e
Author | SHA1 | Date | |
---|---|---|---|
93fc95d70e | |||
83c9893efd | |||
a3e59c6461 | |||
16aeb1e7e5 | |||
6c14b5942a | |||
2a978bab5f |
@ -31,7 +31,7 @@ public class SecurityConfiguration {
|
||||
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin))
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.authorizeHttpRequests(auth ->
|
||||
auth.requestMatchers("/").permitAll()
|
||||
auth.requestMatchers("/", "get-inference").permitAll()
|
||||
.requestMatchers(permittedUrls).permitAll()
|
||||
.requestMatchers("/swagger-ui.html").hasAuthority(UserRoleConstants.ADMIN)
|
||||
.anyRequest().authenticated())
|
||||
|
@ -6,10 +6,12 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import ru.ulstu.fc.project.service.ProjectRulesService;
|
||||
import ru.ulstu.fc.project.model.RunProjectForm;
|
||||
import ru.ulstu.fc.project.service.ProjectService;
|
||||
import ru.ulstu.fc.project.service.ProjectVariableService;
|
||||
import ru.ulstu.fc.rule.service.FuzzyInferenceService;
|
||||
import ru.ulstu.fc.user.model.UserRoleConstants;
|
||||
|
||||
@Controller
|
||||
@ -18,20 +20,32 @@ import ru.ulstu.fc.user.model.UserRoleConstants;
|
||||
@Secured({UserRoleConstants.ADMIN})
|
||||
public class ProjectRunController {
|
||||
private final ProjectService projectService;
|
||||
private final ProjectRulesService projectRulesService;
|
||||
private final FuzzyInferenceService fuzzyInferenceService;
|
||||
private final ProjectVariableService projectVariableService;
|
||||
|
||||
public ProjectRunController(ProjectService projectService,
|
||||
ProjectRulesService projectRulesService,
|
||||
FuzzyInferenceService fuzzyInferenceService,
|
||||
ProjectVariableService projectVariableService) {
|
||||
this.projectService = projectService;
|
||||
this.projectRulesService = projectRulesService;
|
||||
this.fuzzyInferenceService = fuzzyInferenceService;
|
||||
this.projectVariableService = projectVariableService;
|
||||
}
|
||||
|
||||
@GetMapping("init/{projectId}")
|
||||
public String getProjects(@PathVariable(value = "projectId") Integer projectId, Model model) {
|
||||
model.addAttribute("project", projectService.getById(projectId));
|
||||
model.addAttribute("runProjectForm", new RunProjectForm(projectId));
|
||||
model.addAttribute("variables", projectVariableService.getInputByProjectId(projectId));
|
||||
return "project/init";
|
||||
}
|
||||
|
||||
@PostMapping("run")
|
||||
public String run(RunProjectForm runProjectForm, Model model) {
|
||||
model.addAttribute("projectId", runProjectForm.getProjectId());
|
||||
model.addAttribute("response",
|
||||
fuzzyInferenceService.getProjectFuzzyInference(
|
||||
runProjectForm.getProjectId(),
|
||||
runProjectForm.getVariableValues()));
|
||||
return "project/result";
|
||||
}
|
||||
}
|
||||
|
32
src/main/java/ru/ulstu/fc/project/model/RunProjectForm.java
Normal file
32
src/main/java/ru/ulstu/fc/project/model/RunProjectForm.java
Normal file
@ -0,0 +1,32 @@
|
||||
package ru.ulstu.fc.project.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class RunProjectForm {
|
||||
private Integer projectId;
|
||||
private Map<String, Double> variableValues = new HashMap<>();
|
||||
|
||||
public RunProjectForm() {
|
||||
}
|
||||
|
||||
public RunProjectForm(Integer projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
public Integer getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public void setProjectId(Integer projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
public Map<String, Double> getVariableValues() {
|
||||
return variableValues;
|
||||
}
|
||||
|
||||
public void setVariableValues(Map<String, Double> variableValues) {
|
||||
this.variableValues = variableValues;
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ import ru.ulstu.fc.rule.model.ProjectInferenceData;
|
||||
import ru.ulstu.fc.rule.model.Variable;
|
||||
import ru.ulstu.fc.rule.model.dto.VariableValueDto;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -52,7 +53,7 @@ public class FuzzyInferenceService {
|
||||
}
|
||||
|
||||
private List<String> getDemoRules() {
|
||||
return List.of(
|
||||
return Arrays.asList(
|
||||
String.format(RULE_TEMPLATE, "возраст", "молодой", "доход", "высокий", "средний"),
|
||||
String.format(RULE_TEMPLATE, "возраст", "средний", "доход", "высокий", "большой"),
|
||||
String.format(RULE_TEMPLATE, "возраст", "старый", "доход", "средний", "средний")
|
||||
@ -64,7 +65,7 @@ public class FuzzyInferenceService {
|
||||
input.setName(variable.getName());
|
||||
input.setDescription("");
|
||||
variable.getFuzzyTerms().sort(Comparator.comparing(FuzzyTerm::getCrispValue));
|
||||
input.setRange(0, variable.getFuzzyTerms().get(variable.getFuzzyTerms().size() - 1).getCrispValue());
|
||||
input.setRange(0, variable.getFuzzyTerms().getLast().getCrispValue());
|
||||
input.setEnabled(true);
|
||||
input.setLockValueInRange(false);
|
||||
double prev = 0;
|
||||
@ -83,7 +84,7 @@ public class FuzzyInferenceService {
|
||||
final OutputVariable output = new OutputVariable();
|
||||
output.setName(variable.getName());
|
||||
output.setDescription("");
|
||||
output.setRange(0, variable.getFuzzyTerms().get(variable.getFuzzyTerms().size() - 1).getCrispValue());
|
||||
output.setRange(0, variable.getFuzzyTerms().getLast().getCrispValue());
|
||||
output.setEnabled(true);
|
||||
output.setAggregation(new Maximum());
|
||||
output.setDefuzzifier(new WeightedAverage());
|
||||
@ -117,7 +118,6 @@ public class FuzzyInferenceService {
|
||||
mamdani.setImplication(new AlgebraicProduct());
|
||||
mamdani.setActivation(new General());
|
||||
rules.forEach(r -> mamdani.addRule(Rule.parse(r, engine)));
|
||||
mamdani.addRule(new Rule());
|
||||
return mamdani;
|
||||
}
|
||||
|
||||
@ -141,18 +141,18 @@ public class FuzzyInferenceService {
|
||||
|
||||
public List<OutputValue> getFuzzyInference(Map<String, Double> vals) {
|
||||
return getFuzzyInference(getDemoRules(), vals,
|
||||
List.of(new Variable("возраст", List.of(
|
||||
Arrays.asList(new Variable("возраст", Arrays.asList(
|
||||
new FuzzyTerm("молодой", 35.0),
|
||||
new FuzzyTerm("средний", 60.0),
|
||||
new FuzzyTerm("старый", 100.0))
|
||||
),
|
||||
new Variable("доход", List.of(
|
||||
new Variable("доход", Arrays.asList(
|
||||
new FuzzyTerm("небольшой", 35000.0),
|
||||
new FuzzyTerm("средний", 100000.0),
|
||||
new FuzzyTerm("высокий", 500000.0))
|
||||
)
|
||||
),
|
||||
List.of(new Variable("кредит", List.of(
|
||||
Arrays.asList(new Variable("кредит", Arrays.asList(
|
||||
new FuzzyTerm("небольшой", 20000.0),
|
||||
new FuzzyTerm("средний", 100000.0),
|
||||
new FuzzyTerm("большой", 1000000.0))))
|
||||
@ -188,4 +188,18 @@ public class FuzzyInferenceService {
|
||||
inputVariables,
|
||||
outputVariables);
|
||||
}
|
||||
|
||||
public List<OutputValue> getProjectFuzzyInference(Integer projectId, Map<String, Double> variableValues) {
|
||||
List<String> fuzzyRules = projectRulesService.getByProjectId(projectId)
|
||||
.stream()
|
||||
.map(FuzzyRule::getContent)
|
||||
.toList();
|
||||
List<Variable> inputVariables = projectVariableService.getInputByProjectId(projectId);
|
||||
List<Variable> outputVariables = projectVariableService.getOutputByProjectId(projectId);
|
||||
|
||||
return getFuzzyInference(fuzzyRules,
|
||||
variableValues,
|
||||
inputVariables,
|
||||
outputVariables);
|
||||
}
|
||||
}
|
||||
|
2
src/main/resources/logging.properties
Normal file
2
src/main/resources/logging.properties
Normal file
@ -0,0 +1,2 @@
|
||||
org.apache.tomcat.level=INFO
|
||||
org.apache.tomcat.util.net.level=WARNING
|
@ -48,7 +48,7 @@
|
||||
onclick="return confirm('Удалить запись?')">
|
||||
Удалить
|
||||
</button>
|
||||
<a th:href="@{'/variable/edit/' + ${projectId}+'/' + ${variableId}}" class="btn btn-outline-dark">Отмена</a>
|
||||
<a th:href="@{'/variable/edit/' + ${projectId}+'/' + ${variableId}}" class="btn btn-outline-dark">Назад</a>
|
||||
</form>
|
||||
</div>
|
||||
</html>
|
||||
|
@ -50,12 +50,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" class="btn btn-outline-success m-2" value="Получить результат вывода"/>
|
||||
<div class="row" th:each="out : ${response}">
|
||||
<div class="row" th:each="out : ${response}" th:if="${not #lists.isEmpty(response)}">
|
||||
<div class="col-md-2"> Размер кредита:</div>
|
||||
<div class="col-md-4" th:text="${out.fuzzyTerm}"></div>
|
||||
<div class="col-md-3"> Степень принадлежности:</div>
|
||||
<div class="col-md-1" th:text="${out.degree}"></div>
|
||||
</div>
|
||||
<div class="row" th:if="${response != null && #lists.isEmpty(response)}">
|
||||
Нет результата
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</html>
|
||||
|
@ -21,14 +21,16 @@
|
||||
<label th:text="'Дата создания: ' + ${#dates.format(project.createDate, 'dd.MM.yyyy HH:mm')}"></label>
|
||||
</div>
|
||||
<button name="save" type="submit" class="btn btn-outline-dark">Сохранить</button>
|
||||
<a th:href="@{'/runProject/init/' + ${project.id}}" th:if="${project.id != null && project.id != 0}"
|
||||
class="btn btn-outline-dark">Выполнить</a>
|
||||
<button name="delete" type="submit" class="btn btn-outline-dark" onclick="return confirm('Удалить запись?')">
|
||||
Удалить
|
||||
</button>
|
||||
<a href="/project/list" class="btn btn-outline-dark">Отмена</a>
|
||||
<a href="/project/list" class="btn btn-outline-dark">Назад</a>
|
||||
</form>
|
||||
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="row" th:if="${project.id != null && project.id != 0}">
|
||||
<div class="col col-md-6">
|
||||
<h4> Список переменных</h4>
|
||||
<div class="form-group">
|
||||
|
30
src/main/resources/templates/project/init.html
Normal file
30
src/main/resources/templates/project/init.html
Normal file
@ -0,0 +1,30 @@
|
||||
<!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"/>
|
||||
<script></script>
|
||||
</head>
|
||||
<div class="container" layout:fragment="content">
|
||||
<h3>Ввод переменных:</h3>
|
||||
<form th:action="@{/runProject/run}" th:object="${runProjectForm}" method="post">
|
||||
<input type="hidden" id="projectId" th:field="*{projectId}">
|
||||
<div class="form-group" th:each="v : ${variables}">
|
||||
<label th:text="${v.name}"> </label>
|
||||
<select class='selectpicker inputVar m-2' data-live-search='true' data-width='70%'
|
||||
th:field="*{variableValues[__${v.name}__]}">
|
||||
<option th:each="t : ${v.fuzzyTerms}"
|
||||
th:value="${t.crispValue}"
|
||||
th:utext="${t.description}">
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-outline-dark">Выполнить</button>
|
||||
<a th:href="@{'/project/edit/' + ${projectId}}" class="btn btn-outline-dark">Назад</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</html>
|
26
src/main/resources/templates/project/result.html
Normal file
26
src/main/resources/templates/project/result.html
Normal file
@ -0,0 +1,26 @@
|
||||
<!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"/>
|
||||
<script></script>
|
||||
</head>
|
||||
<div class="container" layout:fragment="content">
|
||||
<h3>Результат нечеткого логического вывода:</h3>
|
||||
<div class="row" th:each="out : ${response}" th:if="${not #lists.isEmpty(response)}">
|
||||
<div class="col-md-2" th:text="${out.variable}"></div>
|
||||
<div class="col-md-4" th:text="${out.fuzzyTerm}"></div>
|
||||
<div class="col-md-3"> Степень принадлежности:</div>
|
||||
<div class="col-md-1" th:text="${out.degree}"></div>
|
||||
</div>
|
||||
<div class="row" th:if="${response != null && #lists.isEmpty(response)}">
|
||||
Нет результата
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<a th:href="@{'/runProject/init/' + ${projectId}}"
|
||||
class="btn btn-outline-dark">Назад</a>
|
||||
</div>
|
||||
</div>
|
||||
</html>
|
@ -46,7 +46,7 @@
|
||||
onclick="return confirm('Удалить запись?')">
|
||||
Удалить
|
||||
</button>
|
||||
<a th:href="@{'/project/edit/' + ${projectId}}" class="btn btn-outline-dark">Отмена</a>
|
||||
<a th:href="@{'/project/edit/' + ${projectId}}" class="btn btn-outline-dark">Назад</a>
|
||||
</div>
|
||||
<script type="text/javascript" src="/js/fuzzyRule.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
@ -29,10 +29,10 @@
|
||||
onclick="return confirm('Удалить запись?')">
|
||||
Удалить
|
||||
</button>
|
||||
<a th:href="@{'/project/edit/' + ${projectId}}" class="btn btn-outline-dark">Отмена</a>
|
||||
<a th:href="@{'/project/edit/' + ${projectId}}" class="btn btn-outline-dark">Назад</a>
|
||||
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="row" th:if="${variableForm.id != null && variableForm.id != 0}">
|
||||
<div class="col col-md-6">
|
||||
<h4> Список термов</h4>
|
||||
<div class="form-group">
|
||||
|
Loading…
x
Reference in New Issue
Block a user