子句判断、启动强度和去模糊化–AForge.NET框架的使用(三)

5 2月

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2012/02/05/aforge_3/

使用AForge.NET进行模糊运算

上一篇说来一些模糊运算的数学问题,用AForge.NET做相关运算就很简单了。

1.联集运算中的标准联集

数学:s (p,q) = max (p,q)

程序:

publicclass MaximumCoNorm : ICoNorm {publicfloatEvaluate(float membershipA,float membershipB ) {return Math.Max( membershipA, membershipB ); } }

2.交集运算中的标准交集

数学:t (p,q) = min (p,q)

程序:

publicclass MinimumNorm : INorm {publicfloatEvaluate(float membershipA,float membershipB ) {return Math.Min( membershipA, membershipB ); } }

3.交集运算中的代数乘积:

数学:t (p,q) = pq

程序:

publicclass ProductNorm : INorm {publicfloatEvaluate(float membershipA,float membershipB ) {return membershipA * membershipB; } }

 

4.逻辑非

数学:t(p)=1-p

程序:

publicclass NotOperator : IUnaryOperator {publicfloatEvaluate(float membership ) {return (1 - membership ); } }

我比较好奇AForge.NET没有实现彻底联集和彻底交集,只有自己补上了。

子句判断(Clause)

这个严格来说只是一个辅助用的类,它可以判断特定的子句是否可以构建。

依旧用温度举例,语意变量temperature的hot隶属度0.4,warm隶属度0.6。那么temperature is hot和temperature is warm都可以构建。

LinguisticVariablelvTemperature = new LinguisticVariable("Temperature",0,50);TrapezoidalFunctionfunction1 = new TrapezoidalFunction(10,15, TrapezoidalFunction.EdgeType.Right); FuzzySetfsCold = new FuzzySet("Cold", function1); TrapezoidalFunctionfunction2 = new TrapezoidalFunction(10,15,20,25); FuzzySetfsCool = new FuzzySet("Cool", function2); TrapezoidalFunctionfunction3 = new TrapezoidalFunction(20,25,30,35); FuzzySetfsWarm = new FuzzySet("Warm", function3); TrapezoidalFunctionfunction4 = new TrapezoidalFunction(30,35, TrapezoidalFunction.EdgeType.Left); FuzzySetfsHot = new FuzzySet("Hot", function4);lvTemperature.AddLabel(fsCold); lvTemperature.AddLabel(fsCool); lvTemperature.AddLabel(fsWarm); lvTemperature.AddLabel(fsHot);ClausefuzzyClause1 = new Clause(lvTemperature, fsHot); lvTemperature.NumericInput =35; floatresult1 = fuzzyClause1.Evaluate(); Console.WriteLine("temperature is hot ====> {0}", result1.ToString());ClausefuzzyClause2 = new Clause(lvTemperature, fsCold); lvTemperature.NumericInput =35; floatresult2 = fuzzyClause2.Evaluate(); Console.WriteLine("temperature is cold ====> {0}", result2.ToString());

效果:

fuzzy3-1

很明显在35度时,temperature is hot 可以构建,temperature is cold则不行。

这个类在自己写东西的时候一般用不上,但是如果要编写泛用性的或者拿给别人用的系统,那么最后每个子句都检查一下。

启动强度(Firing Strength)

启动强度(Firing Strength)是衡量规则和输入的匹配度的量。

举个例子,语意变量Steel为Cold 的隶属度是0.6,Stove为Hot的隶属度为0.4。

那么规则R1:IF Steel is Cold and Stove is Hot then Pressure is Low 的Firing Strength=min(x,y)=0.4

规则R2:IF Steel is Cold and not (Stove is Warm or Stove is Hot) then Pressure is Medium”的Firing Strength=0.4

(以上算法只是这里采用的而已,不同的运算规则会有不同结果,比如0.24之类的)

       

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); LinguisticVariable lvSteel =new LinguisticVariable("Steel",0,80); lvSteel.AddLabel(fsCold); lvSteel.AddLabel(fsCool); lvSteel.AddLabel(fsWarm); lvSteel.AddLabel(fsHot); LinguisticVariable lvStove =new LinguisticVariable("Stove",0,80); lvStove.AddLabel(fsCold); lvStove.AddLabel(fsCool); lvStove.AddLabel(fsWarm); lvStove.AddLabel(fsHot); 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); LinguisticVariable lvPressure =new LinguisticVariable("Pressure",0,100); lvPressure.AddLabel(fsLow); lvPressure.AddLabel(fsMedium); lvPressure.AddLabel(fsHigh); Database db =new Database(); db.AddVariable(lvSteel); db.AddVariable(lvStove); db.AddVariable(lvPressure); Rule r1 =new Rule(db,"R1","IF Steel is Cold and Stove is Hot then Pressure is Low"); Rule r2 =new Rule(db,"R2","IF Steel is Cold and not (Stove is Warm or Stove is Hot) then Pressure is Medium"); Rule r3 =new Rule(db,"R3","IF Steel is Cold and Stove is Warm or Stove is Hot then Pressure is High"); lvSteel.NumericInput =12; lvStove.NumericInput =32;float result1 = lvSteel.GetLabelMembership("Cold", lvSteel.NumericInput); Console.WriteLine("membership of Cold ===> {0}", result1);float result2 = lvStove.GetLabelMembership("Hot", lvStove.NumericInput); Console.WriteLine("membership of Hot ===> {0}", result2);float result3 = r1.EvaluateFiringStrength(); Console.WriteLine(r1.GetRPNExpression()); Console.WriteLine("firing strength of R1 ===> {0}",result3);float result4 = r2.EvaluateFiringStrength(); Console.WriteLine(r2.GetRPNExpression()); Console.WriteLine("firing strength of R2 ===> {0}", result4);

 

 

fuzzy3-2

去模糊化(defuzzification )

这可以说是模糊系统的最后一步,将经过模糊推理之后产生的结论,转换为一明确数值,称之为“去模糊化”。

至于这一步骤的必要性,一般有两个原因:

1.不同的模糊规则产生的结果不一致,有的是集合,有的是具体的数据,需要一个统一。

2.模糊系统一般不单独使用,它和其他系统(如神经网络)等搭配时,输出值必须是数值。

去模糊化常用方法有最大隶属度法、取中位数法和重心法。

AForge.Net的实现是CentroidDefuzzifier,即重心法。

当论域为连续时:

fuzzy3-3

当论域为离散时:

fuzzy3-4

InferenceSystemIS =new InferenceSystem( fuzzyDB,new CentroidDefuzzifier(1000 ) );

至此大部分知识准备就完成了,下一篇会给出一个完整一些的示例。

最后找到一个有关模糊集合的PPT,大家可以参考一下:
http://www.ctdisk.com/file/4496068

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2012/02/05/aforge_3/

发表评论

您的电子邮箱地址不会被公开。