diff --git a/lab12/FuzzyRule.py b/lab12/FuzzyRule.py new file mode 100644 index 0000000..e741219 --- /dev/null +++ b/lab12/FuzzyRule.py @@ -0,0 +1,20 @@ +class FuzzyRule: + def __init__(self): + self.condition: dict[str, str] = {} + self.resout: (str, str) = None + + def add_condition(self, variable: str, value: str): + self.condition[variable] = value + return self + + def add_resout(self, variable: str, value: str): + self.resout = (variable, value) + return self + + def calculate_res(self, variables: dict[str, dict[str, float]]) -> (str, str, float): + res = 1 + + for i in self.condition: + res = min(res, variables[i][self.condition[i]]) + + return self.resout[0], self.resout[1], res diff --git a/lab12/FuzzySet.py b/lab12/FuzzySet.py new file mode 100644 index 0000000..3ed9237 --- /dev/null +++ b/lab12/FuzzySet.py @@ -0,0 +1,21 @@ +class FuzzySet: + def __init__(self, name: str, a: float, b: float, c: float, d: float): + self.name = name + self.a = a + self.b = b + self.c = c + self.d = d + + def affiliation(self, x: float) -> float: + if x <= self.a or x >= self.d: + return 0 + if self.b <= x <= self.c: + return 1 + + if x <= self.b: + return (x - self.a) / (self.b - self.a) + else: + return (self.d - x) / (self.d - self.c) + + def defuzzification(self) -> float: + return (self.c + self.b) / 2 diff --git a/lab12/LinguisticVariable.py b/lab12/LinguisticVariable.py new file mode 100644 index 0000000..17ff695 --- /dev/null +++ b/lab12/LinguisticVariable.py @@ -0,0 +1,24 @@ +from FuzzySet import FuzzySet + + +class LinguisticVariable: + def __init__(self, name: str): + self.name = name + self.fuzzy_sets: dict[str, FuzzySet] = {} + + def add_fuzzy_set(self, name: str, a: float, b: float, c: float, d: float): + if not (a <= b <= c <= d): + return + + if name in self.fuzzy_sets: + fuzzy = self.fuzzy_sets[name] + fuzzy.a = a + fuzzy.b = b + fuzzy.c = c + fuzzy.d = d + else: + self.fuzzy_sets[name] = FuzzySet(name, a, b, c, d) + return self + + def get_all_supplies(self, x: float) -> dict[str, float]: + return {i: self.fuzzy_sets[i].affiliation(x) for i in self.fuzzy_sets} diff --git a/lab12/main.py b/lab12/main.py new file mode 100644 index 0000000..57a5c91 --- /dev/null +++ b/lab12/main.py @@ -0,0 +1,105 @@ +from FuzzyRule import FuzzyRule +from LinguisticVariable import LinguisticVariable + + +def get_linguistic_data(vars: list[LinguisticVariable], x: dict[str, float]) -> dict[str, dict[str, float]]: + return {i.name: i.get_all_supplies(x[i.name]) for i in vars} + + +def get_rule_table_res(rules: list[FuzzyRule], vars: list[LinguisticVariable], x: dict[str, float]) \ + -> (str, str, float): + res = [i.calculate_res(get_linguistic_data(vars, x)) for i in rules] + + return sorted(res, key=lambda y: -y[2])[0] + + +if __name__ == '__main__': + variables: list[LinguisticVariable] = [ + LinguisticVariable("Часы эксплуатации") + .add_fuzzy_set("мало", 0, 0, 100, 200) + .add_fuzzy_set("средне", 100, 300, 500, 700) + .add_fuzzy_set("много", 500, 800, 1000, 1000), + + LinguisticVariable("Срок последней проверки") + .add_fuzzy_set("недавно", 0, 0, 3, 6) + .add_fuzzy_set("давно", 3, 6, 12, 18) + .add_fuzzy_set("очень давно", 12, 18, 24, 24), + + LinguisticVariable("Риск поломки") + .add_fuzzy_set("низкий", 0, 0, 20, 40) + .add_fuzzy_set("средний", 20, 40, 60, 80) + .add_fuzzy_set("высокий", 60, 80, 100, 100) + ] + + rules: list[FuzzyRule] = [ + FuzzyRule() + .add_condition("Часы эксплуатации", 'мало') + .add_condition("Срок последней проверки", 'недавно') + .add_resout("Риск поломки", 'низкий'), + + FuzzyRule() + .add_condition("Часы эксплуатации", 'мало') + .add_condition("Срок последней проверки", 'давно') + .add_resout("Риск поломки", 'низкий'), + + FuzzyRule() + .add_condition("Часы эксплуатации", 'мало') + .add_condition("Срок последней проверки", 'очень давно') + .add_resout("Риск поломки", 'средний'), + + FuzzyRule() + .add_condition("Часы эксплуатации", 'средне') + .add_condition("Срок последней проверки", 'недавно') + .add_resout("Риск поломки", 'низкий'), + + FuzzyRule() + .add_condition("Часы эксплуатации", 'средне') + .add_condition("Срок последней проверки", 'давно') + .add_resout("Риск поломки", 'средний'), + + FuzzyRule() + .add_condition("Часы эксплуатации", 'средне') + .add_condition("Срок последней проверки", 'очень давно') + .add_resout("Риск поломки", 'высокий'), + + FuzzyRule() + .add_condition("Часы эксплуатации", 'много') + .add_condition("Срок последней проверки", 'недавно') + .add_resout("Риск поломки", 'средний'), + + FuzzyRule() + .add_condition("Часы эксплуатации", 'много') + .add_condition("Срок последней проверки", 'давно') + .add_resout("Риск поломки", 'высокий'), + + FuzzyRule() + .add_condition("Часы эксплуатации", 'много') + .add_condition("Срок последней проверки", 'очень давно') + .add_resout("Риск поломки", 'высокий'), + + FuzzyRule() + .add_condition("Часы эксплуатации", 'мало') + .add_condition("Срок последней проверки", 'недавно') + .add_resout("Риск поломки", 'низкий'), + + FuzzyRule() + .add_condition("Часы эксплуатации", 'много') + .add_condition("Срок последней проверки", 'недавно') + .add_resout("Риск поломки", 'средний') + ] + + input_data: dict[str, float] = { + "Часы эксплуатации": 550, + "Срок последней проверки": 15 + } + + varz = [] + for i in variables: + if i.name in input_data: + varz.append(i) + + name, value, confidence = get_rule_table_res(rules, varz, input_data) + print(name, value) + for i in variables: + if i.name == name: + print(i.fuzzy_sets[value].defuzzification())