diff --git a/src/main/java/ru/ulstu/extractor/GitExtractorApplication.java b/src/main/java/ru/ulstu/extractor/GitExtractorApplication.java index 9b10858..0cad8ff 100644 --- a/src/main/java/ru/ulstu/extractor/GitExtractorApplication.java +++ b/src/main/java/ru/ulstu/extractor/GitExtractorApplication.java @@ -20,69 +20,6 @@ import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling public class GitExtractorApplication { public static void main(String[] args) { - Engine engine = new Engine(); - engine.setName("Git rules"); - engine.setDescription(""); - - InputVariable obstacle = new InputVariable(); - obstacle.setName("obstacle"); - obstacle.setDescription(""); - obstacle.setEnabled(true); - obstacle.setRange(0.000, 1.000); - obstacle.setLockValueInRange(false); - obstacle.addTerm(new Trapezoid("left", 0.000, 0.700)); - obstacle.addTerm(new Trapezoid("right", 0.400, 1.000)); - engine.addInputVariable(obstacle); - - OutputVariable mSteer = new OutputVariable(); - mSteer.setName("mSteer"); - mSteer.setDescription(""); - mSteer.setEnabled(true); - mSteer.setRange(0.000, 1.000); - mSteer.setLockValueInRange(false); - mSteer.setAggregation(new Maximum()); - mSteer.setDefuzzifier(new Centroid(100)); - mSteer.setDefaultValue(Double.NaN); - mSteer.setLockPreviousValue(false); - mSteer.addTerm(new Trapezoid("left", 0.000, 0.700)); - mSteer.addTerm(new Trapezoid("right", 0.400, 1.000)); - engine.addOutputVariable(mSteer); - - RuleBlock mamdani = new RuleBlock(); - mamdani.setName("mamdani"); - mamdani.setDescription(""); - mamdani.setEnabled(true); - mamdani.setConjunction(null); - mamdani.setDisjunction(null); - mamdani.setImplication(new AlgebraicProduct()); - mamdani.setActivation(new Highest()); - mamdani.addRule(Rule.parse("if obstacle is left then mSteer is right", engine)); - mamdani.addRule(Rule.parse("if obstacle is right then mSteer is left", engine)); - engine.addRuleBlock(mamdani); - - - StringBuilder status = new StringBuilder(); - if (!engine.isReady(status)) - throw new RuntimeException("[engine error] engine is not ready:n" + status); - - InputVariable obstacle1 = engine.getInputVariable("obstacle"); - OutputVariable steer = engine.getOutputVariable("mSteer"); - - for (int i = 10; i <= 50; ++i) { - double location = obstacle1.getMinimum() + i * (obstacle1.range() / 50); - obstacle1.setValue(location); - engine.process(); - if (Double.isNaN(steer.getValue())) { - System.out.println("no decision"); - continue; - } - FuzzyLite.logger().info(String.format( - "obstacle.input = %s -> steer.output = %s", - Op.str(location), Op.str(steer.getValue()))); - FuzzyLite.logger().info(String.format( - "obstacle.input = %s -> steer.output = %s", - Op.str(location), steer.highestMembership(steer.getValue()).getSecond().getName())); - } SpringApplication.run(GitExtractorApplication.class, args); } } diff --git a/src/main/java/ru/ulstu/extractor/rule/service/FuzzyInferenceService.java b/src/main/java/ru/ulstu/extractor/rule/service/FuzzyInferenceService.java index 4119729..862166c 100644 --- a/src/main/java/ru/ulstu/extractor/rule/service/FuzzyInferenceService.java +++ b/src/main/java/ru/ulstu/extractor/rule/service/FuzzyInferenceService.java @@ -1,25 +1,27 @@ package ru.ulstu.extractor.rule.service; -import com.fuzzylite.Engine; -import com.fuzzylite.activation.Highest; -import com.fuzzylite.norm.t.AlgebraicProduct; -import com.fuzzylite.rule.Rule; -import com.fuzzylite.rule.RuleBlock; -import com.fuzzylite.term.Triangle; -import com.fuzzylite.variable.InputVariable; -import com.fuzzylite.variable.OutputVariable; +import net.sourceforge.jFuzzyLogic.defuzzifier.DefuzzifierCenterOfGravity; +import net.sourceforge.jFuzzyLogic.membership.MembershipFunctionTriangular; +import net.sourceforge.jFuzzyLogic.rule.FuzzyRule; +import net.sourceforge.jFuzzyLogic.rule.FuzzyRuleExpression; +import net.sourceforge.jFuzzyLogic.rule.FuzzyRuleSet; +import net.sourceforge.jFuzzyLogic.rule.FuzzyRuleTerm; +import net.sourceforge.jFuzzyLogic.rule.LinguisticTerm; +import net.sourceforge.jFuzzyLogic.rule.Variable; +import net.sourceforge.jFuzzyLogic.ruleConnection.RuleConnectionMethodAndMin; +import net.sourceforge.jFuzzyLogic.ruleImplication.RuleImplicationMethodMin; import org.springframework.stereotype.Service; import ru.ulstu.extractor.rule.model.AntecedentValue; -import ru.ulstu.extractor.rule.model.DbRule; +import ru.ulstu.extractor.rule.model.Rule; -import java.util.HashMap; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; @Service public class FuzzyInferenceService { - private final static String RULE_TEMPLATE = "if %s is %s AND %s is %s then state is %s"; private final RuleService ruleService; private final AntecedentValueService antecedentValueService; @@ -29,69 +31,118 @@ public class FuzzyInferenceService { this.antecedentValueService = antecedentValueService; } - public List getRulesFromDb() { - List dbDbRules = ruleService.getList(); - return dbDbRules.stream().map(this::getFuzzyRule).collect(Collectors.toList()); + private List getFuzzyRulesFromDb() { + List fuzzyRules = new ArrayList<>(); + //List variables = getFuzzyVariables(); + for (Rule dbRule : ruleService.getList()) { + FuzzyRule fuzzyRule = new FuzzyRule(String.format("Fuzzy rule %s", dbRule.getId())); + // fuzzyRule.setAntecedents(expression); + // fuzzyRule.setConsequents(new LinkedList<>(Collections.singleton(new FuzzyRuleTerm(dbRule.getConsequent(), false)))); + fuzzyRules.add(fuzzyRule); + } + return fuzzyRules; } - private String getFuzzyRule(DbRule dbRule) { - return String.format(RULE_TEMPLATE, - dbRule.getFirstAntecedent().name(), - dbRule.getFirstAntecedentValue().getAntecedentValue(), - dbRule.getSecondAntecedent().name(), - dbRule.getSecondAntecedentValue().getAntecedentValue(), - dbRule.getConsequent()); + private List getFuzzyVariablesWithoutMembership() { + List variables = new ArrayList<>(); + List antecedentValues = antecedentValueService.getList(); + for (AntecedentValue antecedentValue : antecedentValues) { + variables.add(new Variable(antecedentValue.getAntecedentValue())); + } + return variables; } - private RuleBlock getRuleBlock(Engine engine, Map variableValues, List antecedentValues) { - variableValues.forEach((key, value) -> { - InputVariable input = new InputVariable(); - input.setName(key); - input.setDescription(""); - input.setEnabled(true); - input.setRange(0.000, 1.000); - input.setLockValueInRange(false); - for (int i = 0; i < antecedentValues.size(); i++) { - input.addTerm(new Triangle(antecedentValues.get(i).getAntecedentValue(), i, i + 2)); - } - engine.addInputVariable(input); - }); - - - RuleBlock mamdani = new RuleBlock(); - mamdani.setName("mamdani"); - mamdani.setDescription(""); - mamdani.setEnabled(true); - mamdani.setConjunction(null); - mamdani.setDisjunction(null); - mamdani.setImplication(new AlgebraicProduct()); - mamdani.setActivation(new Highest()); - getRulesFromDb().forEach(r -> mamdani.addRule(Rule.parse(r, engine))); - return mamdani; - } +// private FuzzyRuleExpression getFuzzyRulesAntecedents(TimeSeriesType timeSeriesType1, TimeSeriesType timeSeriesType2) { +// return new FuzzyRuleExpression(getFuzzyRuleTerm(), getFuzzyRuleTerm(), new RuleConnectionMethodAndMin()); +// } - private Engine getFuzzyEngine() { - Engine engine = new Engine(); - engine.setName("Git rules"); - engine.setDescription(""); - return engine; + private FuzzyRuleExpression getFuzzyRuleExpression(FuzzyRuleTerm term1, FuzzyRuleTerm term2) { + return new FuzzyRuleExpression(term1, term2, new RuleConnectionMethodAndMin()); } - public String run() { - Engine engine = getFuzzyEngine(); - List antecedentValues = antecedentValueService.getList(); - Map variableValues = new HashMap<>(); - engine.addRuleBlock(getRuleBlock(engine, variableValues, antecedentValues)); - return getConsequent(engine, variableValues); + private FuzzyRuleTerm getFuzzyRuleTerm(Variable variable, String term) { + return new FuzzyRuleTerm(variable, term, false); } - private String getConsequent(Engine engine, Map variableValues) { - OutputVariable outputVariable = engine.getOutputVariable("state"); - for (Map.Entry variableValue : variableValues.entrySet()) { - InputVariable inputVariable = engine.getInputVariable(variableValue.getKey()); - inputVariable.setValue(variableValue.getValue()); - } - engine.process(); - return outputVariable.highestMembership(outputVariable.getValue()).getSecond().getName(); + + public void run() { + FuzzyRule fuzzyRule1 = new FuzzyRule("rule 1"); + FuzzyRule fuzzyRule2 = new FuzzyRule("rule 2"); + FuzzyRule fuzzyRule3 = new FuzzyRule("rule 3"); + + Variable weather = new Variable("Погода"); + weather.getLinguisticTerms().put("солнечно", + new LinguisticTerm("солнечно", new MembershipFunctionTriangular(0, 20, 30))); + weather.getLinguisticTerms().put("мороз", + new LinguisticTerm("мороз", new MembershipFunctionTriangular(-50, -10, 10))); + weather.setDefuzzifier(new DefuzzifierCenterOfGravity(weather)); + + + Variable suit = new Variable("Одежда"); + suit.getLinguisticTerms().put("легко одет", + new LinguisticTerm("легко одет", new MembershipFunctionTriangular(0, 5, 10))); + suit.getLinguisticTerms().put("тепло одет", + new LinguisticTerm("тепло одет", new MembershipFunctionTriangular(5, 10, 20))); + suit.setDefuzzifier(new DefuzzifierCenterOfGravity(suit)); + + Variable feel = new Variable("Ощущение"); + feel.getLinguisticTerms().put("Холодно", + new LinguisticTerm("Холодно", new MembershipFunctionTriangular(0, 5, 10))); + feel.getLinguisticTerms().put("Жарко", + new LinguisticTerm("Жарко", new MembershipFunctionTriangular(5, 10, 20))); + feel.setDefuzzifier(new DefuzzifierCenterOfGravity(feel)); + + FuzzyRuleTerm weatherTerm1 = new FuzzyRuleTerm(weather, "солнечно", false); + FuzzyRuleTerm weatherTerm2 = new FuzzyRuleTerm(weather, "мороз", false); + + FuzzyRuleTerm suitTerm1 = new FuzzyRuleTerm(suit, "легко одет", false); + FuzzyRuleTerm suitTerm2 = new FuzzyRuleTerm(suit, "тепло одет", false); + + FuzzyRuleTerm feelCold = new FuzzyRuleTerm(feel, "Холодно", false); + FuzzyRuleTerm feelWarm = new FuzzyRuleTerm(feel, "Жарко", false); + + FuzzyRuleExpression expression1 = new FuzzyRuleExpression(weatherTerm1, suitTerm2, new RuleConnectionMethodAndMin()); + fuzzyRule1.setAntecedents(expression1); + fuzzyRule1.setConsequents(new LinkedList<>(Collections.singleton(feelWarm))); + + FuzzyRuleExpression expression2 = new FuzzyRuleExpression(weatherTerm2, suitTerm1, new RuleConnectionMethodAndMin()); + fuzzyRule2.setAntecedents(expression2); + fuzzyRule2.setConsequents(new LinkedList<>(Collections.singleton(feelCold))); + + FuzzyRuleExpression expression3 = new FuzzyRuleExpression(weatherTerm1, suitTerm1, new RuleConnectionMethodAndMin()); + fuzzyRule3.setAntecedents(expression3); + fuzzyRule3.setConsequents(new LinkedList<>(Collections.singleton(feelCold))); + + fuzzyRule1.evaluate(new RuleImplicationMethodMin()); + fuzzyRule2.evaluate(new RuleImplicationMethodMin()); + //fuzzyRule3.evaluate(new RuleImplicationMethodMin()); + + FuzzyRuleSet set = new FuzzyRuleSet(); + set.add(fuzzyRule1); + set.add(fuzzyRule2); + set.add(fuzzyRule3); + set.evaluate(); + + set.setVariable("Погода", 25); + set.setVariable("Одежда", 7); + // Evaluate fuzzy set + set.evaluate(); + + // Show output variable's chart + //set.getVariable("Ощущение").chartDefuzzifier(true); + System.out.println(set.getVariable("Ощущение").getLatestDefuzzifiedValue()); + System.out.println(set); + System.out.println(set.getVariable("Ощущение")); + System.out.println( + feel.getLinguisticTerms() + .entrySet() + .stream() + .max(Comparator.comparing(e -> e.getValue() + .getMembershipFunction() + .membership(set.getVariable("Ощущение").getLatestDefuzzifiedValue()))) + .get() + .getValue().getTermName() + ); + set.getVariable("Ощущение").chartDefuzzifier(true); } }