AForge.Fuzzy 提供了大量的模糊集操作。
FuzzySet:模糊集是模糊应用的基础,也是理解模糊应用的关键,我们通过一个例子理解模糊集的概念:在现实生活中我们以冷暖来直观的描述温度,例如我们直观认定20摄氏度左右为冷,30摄氏度左右为暖。但是在对温度进行数字型描述时,我们会发现很难确定临界点,这一临界点决定突破某一温度值为暖,低于某一温度值为冷。因此我们引入了模糊集概念,即假设我们确定25摄氏度为临界点,当温度大于25摄氏度时,气温偏暖(数值大于0.5),当温度低于25摄氏度,气温偏冷(数值低于0.5)。在AForge中我们通过不规则四边形对模糊集进行数学描述。
CentroidDefuzzifier:模糊推理系统通常用于进行语义运算,但是在运算结束时我们需要获得运算期间产生的大量值,这不是意味着我们的运算需要高精度,而是说我们需要获得这些运算值,因为在很多情况下,这些运算值可以用来控制其他系统的运行,为了获得这些值,我们引入去模糊化概念。CentroidDefuzzifier类正是用来完成重心去模糊化方法,模糊推理系统的输出形式为一系列的行为规则,这些规则包含大于零的触发强度。而这些触发强度则用来对顺向模糊集规则实施约束,当我们将所有模糊集归类即会产生一种形状,这一形状即是语义含义的输出形式。本类的具体应用我们后面会通过代码进行介绍。
Clause:模糊语句用来确认在某以特定时刻是否一种语义变量可被作为某一特定值进行理解,处理,为了避免概念过于抽象,我们通过下面的代码示例进行理解。
实例: // 通过创建语言变量表示温度,范围为【0,80】
LinguisticVariable lvTemperature = new LinguisticVariable("Temperature", 0, 80);
// 通过创建语言标签构成温度
//[【10,15】的不规则四边形构成的折线表示Cold,依次类似
TrapezoidalFunction function1 = new TrapezoidalFunction(10, 15, TrapezoidalFunction.EdgeType.Right);
FuzzySet fsCold = new FuzzySet("Cold", function1);
TrapezoidalFunction function2 = new TrapezoidalFunction(10, 15, 20, 25);
FuzzySet fsCool = new FuzzySet("Cool", function2);
TrapezoidalFunction function3 = new TrapezoidalFunction(20, 25, 30, 35);
FuzzySet fsWarm = new FuzzySet("Warm", function3);
TrapezoidalFunction function4 = new TrapezoidalFunction(30, 35, TrapezoidalFunction.EdgeType.Left);
FuzzySet fsHot = new FuzzySet("Hot", function4);
// 将语言标签添加到语言变量中
lvTemperature.AddLabel(fsCold);
lvTemperature.AddLabel(fsCool);
lvTemperature.AddLabel(fsWarm);
lvTemperature.AddLabel(fsHot);
//为chart添加Series
chart.RangeX = new Range(0, 45);//指定Chart的X显示范围
chart.AddDataSeries("COLD", Color.CornflowerBlue, Chart.SeriesType.Line, 3, true);
chart.AddDataSeries("COOL", Color.LightBlue, Chart.SeriesType.Line, 3, true);
chart.AddDataSeries("WARM", Color.LightCoral, Chart.SeriesType.Line, 3, true);
chart.AddDataSeries("HOT", Color.Firebrick, Chart.SeriesType.Line, 3, true);
// 为显示语言变量,我们创建Chart数组
double[][,] chartValues = new double[4][,];
for (int i = 0; i < 4; i++)//4代表了语言变量数目
chartValues[i] = new double[160, 2];
int j = 0;
for (float x = 0; x < 80; x += 0.5f, j++)
{
//获取语言变量值
double y1 = lvTemperature.GetLabelMembership("Cold", x);
double y2 = lvTemperature.GetLabelMembership("Cool", x);
double y3 = lvTemperature.GetLabelMembership("Warm", x);
double y4 = lvTemperature.GetLabelMembership("Hot", x);
//为数组添加新值
chartValues[0][j, 0] = x;
chartValues[0][j, 1] = y1;
chartValues[1][j, 0] = x;
chartValues[1][j, 1] = y2;
chartValues[2][j, 0] = x;
chartValues[2][j, 1] = y3;
chartValues[3][j, 0] = x;
chartValues[3][j, 1] = y4;
}
//显示
chart.UpdateDataSeries("COLD", chartValues[0]);
chart.UpdateDataSeries("COOL", chartValues[1]);
chart.UpdateDataSeries("WARM", chartValues[2]);
chart.UpdateDataSeries("HOT", chartValues[3]);
运行结果:
语言变量的使用比较简单,首先我们创建一个语言变量(如温度),同时指定变量范围。再创建模糊集并为模糊集指定变量区间,最后我们将,模糊集加入到语言变量当中。
MaximumCoNorm:获取或操作最大值
MinimumNorm:获取与操作值。
NotOperator:如果模糊集成员值为m,该操作返回值为1-m,既获取非操作值。
// 创建两个模糊集 Cool (Temperature) and Near (Distance)
TrapezoidalFunction function1 = new TrapezoidalFunction(13, 18, 23, 28);
FuzzySet fsCool = new FuzzySet("Cool", function1);
TrapezoidalFunction function2 = new TrapezoidalFunction(23, 28, 33, 38);
FuzzySet fsNear = new FuzzySet("Near", function2);
// 获取成员值
float m1 = fsCool.GetMembership(15);
float m2 = fsNear.GetMembership(35);
// 计算或操作值
MaximumCoNorm OR = new MaximumCoNorm();
float result = OR.Evaluate(m1, m2);
//计算与操作值
MinimumNorm AND = new MinimumNorm();
float result1 = AND.Evaluate(m1, m2);
//计算非操作值
NotOperator NOT = new NotOperator();
float result2 = NOT.Evaluate(m1);
// 结果显示
richTextBox1.Text += " 温度成员值: " + m1.ToString()+"\r\n";
richTextBox1.Text += " 距离成员值: " + m2.ToString() + "\r\n";
richTextBox1.Text += " 或操作值: " + result.ToString() + "\r\n";
richTextBox1.Text += " 与操作值: " + result1.ToString() + "\r\n";
richTextBox1.Text += "距离非操作值: " + result2.ToString() + "\r\n";
运行结果:
Rule:模糊推理系统规则,使用如下面示例。
// create the linguistic labels (fuzzy sets) that compose the temperature
TrapezoidalFunction function1 = new TrapezoidalFunction(
10, 15, TrapezoidalFunction.EdgeType.Right);
FuzzySet fsCold = new FuzzySet("Cold", function1);
TrapezoidalFunction function2 = new TrapezoidalFunction(10, 15, 20, 25);
FuzzySet fsCool = new FuzzySet("Cool", function2);
TrapezoidalFunction function3 = new TrapezoidalFunction(20, 25, 30, 35);
FuzzySet fsWarm = new FuzzySet("Warm", function3);
TrapezoidalFunction function4 = new TrapezoidalFunction(
30, 35, TrapezoidalFunction.EdgeType.Left);
FuzzySet fsHot = new FuzzySet("Hot", function4);
// create a linguistic variable to represent steel temperature
LinguisticVariable lvSteel = new LinguisticVariable("Steel", 0, 80);
// adding labels to the variable
lvSteel.AddLabel(fsCold);
lvSteel.AddLabel(fsCool);
lvSteel.AddLabel(fsWarm);
lvSteel.AddLabel(fsHot);
// create a linguistic variable to represent stove temperature
LinguisticVariable lvStove = new LinguisticVariable("Stove", 0, 80);
// adding labels to the variable
lvStove.AddLabel(fsCold);
lvStove.AddLabel(fsCool);
lvStove.AddLabel(fsWarm);
lvStove.AddLabel(fsHot);
// create the linguistic labels (fuzzy sets) that compose the pressure
TrapezoidalFunction function5 = new TrapezoidalFunction(
20, 40, TrapezoidalFunction.EdgeType.Right);
FuzzySet fsLow = new FuzzySet("Low", function5);
TrapezoidalFunction function6 = new TrapezoidalFunction(20, 40, 60, 80);
FuzzySet fsMedium = new FuzzySet("Medium", function6);
TrapezoidalFunction function7 = new TrapezoidalFunction(
60, 80, TrapezoidalFunction.EdgeType.Left);
FuzzySet fsHigh = new FuzzySet("High", function7);
// create a linguistic variable to represent pressure
LinguisticVariable lvPressure = new LinguisticVariable("Pressure", 0, 100);
// adding labels to the variable
lvPressure.AddLabel(fsLow);
lvPressure.AddLabel(fsMedium);
lvPressure.AddLabel(fsHigh);
// create a linguistic variable database
Database db = new Database();
db.AddVariable(lvSteel);
db.AddVariable(lvStove);
db.AddVariable(lvPressure);
// sample rules just to test the expression parsing
AForge.Fuzzy.Rule r1 = new AForge.Fuzzy.Rule(db, "Test1", "IF Steel is not Cold and Stove is Hot then Pressure is High");
AForge.Fuzzy.Rule r2 = new AForge.Fuzzy.Rule(db, "Test2", "IF Steel is Cold and not (Stove is Warm or Stove is Hot) then Pressure is Medium");
AForge.Fuzzy.Rule r3 = new AForge.Fuzzy.Rule(db, "Test3", "IF Steel is Cold and Stove is Warm or Stove is Hot then Pressure is High");
// testing the firing strength
lvSteel.NumericInput = 12;
lvStove.NumericInput = 35;
float result = r1.EvaluateFiringStrength();
上述代码通过规则的语句描述,如:"IF Steel is not Cold and Stove is Hot then Pressure is High"基于输入值计算规则成立(压强强度)的可能性。