子句判斷、啟動強度和去模糊化--AForge.NET框架的使用(三)


使用AForge.NET進行模糊運算

上一篇說來一些模糊運算的數學問題,用AForge.NET做相關運算就很簡單了。

1.聯集運算中的標准聯集

數學:s (p,q) = max (p,q)

程序:

public class MaximumCoNorm : ICoNorm 
{
public float Evaluate( float membershipA, float membershipB )
{
return Math.Max( membershipA, membershipB );
}
}

2.交集運算中的標准交集

數學:t (p,q) = min (p,q)

程序:

public class MinimumNorm : INorm 
{
public float Evaluate( float membershipA, float membershipB )
{
return Math.Min( membershipA, membershipB );
}
}

3.交集運算中的代數乘積:

數學:t (p,q) = pq

程序:

public class ProductNorm : INorm 
{
public float Evaluate( float membershipA, float membershipB )
{
return membershipA * membershipB;
}
}

 

4.邏輯非

數學:t(p)=1-p

程序:

public class NotOperator : IUnaryOperator 
{
public float Evaluate( float membership )
{
return ( 1 - membership );
}
}

我比較好奇AForge.NET沒有實現徹底聯集和徹底交集,只有自己補上了。

子句判斷(Clause)

這個嚴格來說只是一個輔助用的類,它可以判斷特定的子句是否可以構建。

依舊用溫度舉例,語意變量temperature的hot隸屬度0.4,warm隸屬度0.6。那么temperature is hot和temperature is warm都可以構建。

LinguisticVariable lvTemperature = new LinguisticVariable("Temperature", 0, 50);

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);

Clause fuzzyClause1 = new Clause(lvTemperature, fsHot);
lvTemperature.NumericInput = 35;
float result1 = fuzzyClause1.Evaluate();
Console.WriteLine("temperature is hot ====> {0}", result1.ToString());

Clause fuzzyClause2 = new Clause(lvTemperature, fsCold);
lvTemperature.NumericInput = 35;
float result2 = 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

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

至此大部分知識准備就完成了,下一篇會給出一個完整一些的示例。

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM