Fuzzinator:模糊逻辑控制器
基于 mamdani 推理引擎的模糊逻辑控制器 C# 库 + Windows 窗体 GUI
介绍
本文介绍了一个基于 Mamdani 推理引擎的模糊逻辑控制器。模糊逻辑是一个近似过程,其中使用语言变量、一组规则和提供的推理引擎将精确输入转换为模糊值。例如
我有一列火车,我将火车的语言变量“速度”考虑为具有两个隶属函数:低和高。“低”的范围是从 0 mph 到 10 mph,而“高”的范围是从 10 mph 到 20 mph。
所以,如果我的精确输入是 5 -> 它的模糊值是“低”。
设想一下,如果 0-10 的范围不是一个常量,而是一个最大高度为 1 的三角形图,并且“低”是一个具有 3 个不同点 0, 5, 10 的三角形图。
现在,对于一个单点输入 4,模糊值 = y = (4-0)/(5-0) = 0.8,因此我们的模糊输入 = 0.8 “低”,设想一下语言变量是相交的,这样单个输入可以定义为 (0.8 “低” 0.4 “高”)。
这个过程称为模糊化……
在得到模糊输入后,我们将其与规则库进行比较。规则库是一组负责最终输出的规则。
例如,如果我说我的规则是
规则 1:如果速度很高,则刹车被踩下
规则 2:如果速度很低,则刹车被释放
那么现在使用我们的推理引擎,该引擎将比较并推导出我们的模糊输出,对于模糊输入 (0.8 “低”,0.4 “高”),我们可以根据上述规则说刹车将被踩下 (0.4 “踩下” 0.8 “释放”) --> 模糊输出。
这是使用 Mamdani 概念的规则库和推理引擎过程……
然后,模糊输出进入去模糊化方法,这是一种加权模糊输出并返回施加到刹车上的精确输出力的方法。
图 1-1
Using the Code
在本文附带的项目中,包含 3 个子项目
- 一个 C# 类库,其中包含实现上述示例中所述步骤的引擎。
- 一个名为
FuzzyLogicUI
的 Windows 窗体项目,它是为此模糊逻辑控制器构建的用户界面,您可以添加语言变量、隶属函数、规则以及结果面板来向您展示系统的不同步骤。 - 一个基于控制台的模糊逻辑控制器测试,以更好地理解系统。
模糊库 (DLL)
类图

步骤
1- 配置您的模糊控制器
该系统允许的配置是(AND 逻辑连接)和蕴含。
对于规则:如果 X1 低 且 X2 高 -> Y1 低。
如何计算最终激活强度,如果 X1 -> 0.8,X2 -> 0.4,那么 Y1 -> ?
如果我们在此系统中使用(AND 连接),您可以定义 AND 方法是乘积或最小值,因此对于 Y1 = min(0.8, 0.4) = 0.4,因为 X1 和 X2 之间存在“AND”连接。
Config configure = new Config(ImpMethod.Prod,ConnMethod.Min);
2- 创建您的语言变量及其隶属函数
使用上述火车示例:我们定义火车有速度作为输入。对于速度:高、中、低;对于输出(结果)刹车:释放、踩下。
LingVariable speed = new LingVariable("Speed", VarType.Input); //declare new lingustic variable
speed.setRange(0, 35); // set max - min range for our variables 0 mph -35 mph
speed.addMF(new Trapmf("Low", -10, 0, 10, 15)); // trapmf: trapazoid shape behaviour
speed.addMF(new Trimf("Medium", 10, 20, 30)); // trimf: triangle shape behaviour
speed.addMF(new Trapmf("High", 25, 30, 35, 40));
LingVariable brake = new LingVariable("Brake", VarType.Output);
brake.setRange(0, 65); // Brake Force
brake.addMF(new Trapmf("Released", -10, 0, 20, 41));
brake.addMF(new Trapmf("Pushed", 41, 60, 65, 70));
3- 精确输入和模糊化过程
模糊化是通过针对语言变量“速度”的隶属函数来评估精确输入的过程。membershipfunction
是一个抽象类,带有一个抽象方法“getOutput
”,任何继承该类的对象都需要定义其 getOutput(double)
函数,例如在 Trimf
和 Trapmf
中。基于此特性,可以实现更多的 membershipfunction
来扩展模糊控制器的功能。
Fuzzification
方法然后返回一个模糊数列表,每个模糊数由函数名和来自 getOutput(double)
的激活强度组成。
例如:fuzzynumber(0.8,"Low") FuzzyNumber(0.4,"High")
模糊数列表随后被添加到一个模糊集合中,该集合包含模糊数列表和语言变量名,以供进一步处理。
FLC c = new FLC(conf);
double speedCrispVal = 30;
FuzzySet fuzzy_speed = new FuzzySet(c.Fuzzification(speedCrispVal,speed), speed.Name);
在模糊化了我们所有的输入后,将其添加到模糊集合列表中。
List<FuzzySet> input_sets = new List<FuzzySet>();
input_sets.Add(fuzzy_speed);
4- 制定规则!
定义规则库,即我们系统用于近似的规则。
对于规则 1,根据上述示例
“如果速度很高,则刹车被踩下。”
List<ruleitem> rule1in = new List<ruleitem>();
List<ruleitem> rule1out = new List<ruleitem>();
// the if part of the Rule, add more than one if X1 and X2,
// add another RuleItem in the list
rule1in.AddRange(new RuleItem[1] { new RuleItem("Speed", "High") } );
// the then part in the Rule
rule1out.AddRange(new RuleItem[1] { new RuleItem("Brake", "Pushed") } );
// List of rules "RuleBase" passed to the Inference Engine
List<rule> rules = new List<rule>();
rules.Add(new Rule(rule1in, rule1out, Connector.And));
5- 评估规则
在推理系统中进行规则评估期间,输出的激活强度确定如下例所示:
模糊输入:X1 = 0.8 低,X2 = 0.5 高。
规则:“如果 X1 低 且 X2 高,则 Y1 低。”
配置:AND 连接通过 min(X1, X2) 进行评估。
评估:min(X1, X2) => min(0.8, 0.5) = Y1 = 0.5 低。
模糊输出:Y1 = 0.5 低。
如果更多规则重叠,例如“如果 X1 高,则 Y1 低”,其中 Y1 是 0.7 低,则取 Y1 激活强度的最大值,在这种情况下为 (0.7)。
InferEngine engine = new InferEngine(configure, rules, input_sets);
List<FuzzySet> fuzzy_out = engine.evaluateRules();
6- 去模糊化和精确输出
Defuzzification
方法是一种将模糊输出转换为精确值的方法。在此系统中,使用了两种去模糊化方法,您可以在配置中选择它们。
质心 Defuzzification
,改进型最大值 Defuzzification
。
double crisp_brake_force = c.DeFuzzification(fuzzy_out, brake);
关注点
该项目已被做得非常灵活和可扩展,以便于未来的开发和升级。GUI 是为了实现模糊逻辑控制器并进行尝试而构建的,它主要用于教育目的。提供了 FuzzySet
和 FuzzyNumber
类,以提供对模糊过程更深入的理解。
有关更多测试和示例,请尝试 GUI 项目的预定义测试,或基于控制台的测试项目“FuzzyTest
”。