先说一下,为什么题目是简单实现,因为我实在没有弄出好的例子。
我原来用AForge.net做的项目中的模糊系统融入了神经网络和向量机,没法抽出来当例子,就用了个最老的自动车辆的例子。
模糊系统(Fuzzy System)架构
前面零零散散说来一下有关模糊系统和模糊理论的东西,这里来个总结。
模煳系统的基本架构如图8.1所示,其中主要的功能方块包括:(1)模煳化机构、(2)模煳规则库、(3)模煳推论引擎、以及(4)去模煳化机构。
模糊化机构是有关模糊集合和隶属度函数的内容。
模糊规则前文也有提及,去模糊化只涉及了重心法一种,这里简单说一下模糊推理引擎。
模糊推理引擎是模煳系统的核心,它可以藉由近似推论或模煳推论的进行,来模拟人类的思考决策模式,以达到解决问题的目地。
比如:
前提(premise)一:x is A’
前提(premise)二:if x is A,y is B
结论:y is B’
模糊推理系统的简单实现
在AForge.Net中的对应类是InferenceSystem。
在程序实现中一个模糊推理系统(Fuzzy Inference System )由数据库(Database)和规则库(Rulebase)组成,一般操作如下:
1.获取数值输入
2.通过数据库(Database)将数值输入转为语意含义
3.验证规则库(Rulebase)中的哪些规则被输入激活
4.组合被激活的规则,得到模糊输出(Fuzzy Output)
5.去模糊化(实现IDefuzzifier接口)
下面看看例子,这个例子是关于控制车辆避免正面冲撞的系统。
输入为距离,论域[0,120],隶属度函数
输出为角度,论域[-10,50],隶属度函数
核心代码:
// 隶属度函数(距离)
FuzzySet fsNear =
new FuzzySet(
"Near",
new TrapezoidalFunction(
15,
50, TrapezoidalFunction.EdgeType.Right));
FuzzySet fsMedium =
new FuzzySet(
"Medium",
new TrapezoidalFunction(
15,
50,
60,
100));
FuzzySet fsFar =
new FuzzySet(
"Far",
new TrapezoidalFunction(
60,
100, TrapezoidalFunction.EdgeType.Left));
//绘制图像
int length1 =(
int) (chart1.RangeX.Max - chart1.RangeX.Min);
double[,] NearValues =
new double[length1,
2];
for (
int i = (
int)chart1.RangeX.Min; i < chart1.RangeX.Max; i++)
{
NearValues[i,
0] = i;
NearValues[i,
1] = fsNear.GetMembership(i);
}
double[,] MediumValues =
new double[length1,
2];
for (
int i = (
int)chart1.RangeX.Min; i < chart1.RangeX.Max; i++)
{
MediumValues[i,
0] = i;
MediumValues[i,
1] = fsMedium.GetMembership(i);
}
double[,] FarValues =
new double[length1,
2];
for (
int i = (
int)chart1.RangeX.Min; i < chart1.RangeX.Max; i++)
{
FarValues[i,
0] = i;
FarValues[i,
1] = fsFar.GetMembership(i);
}
chart1.UpdateDataSeries(
"Near", NearValues);
chart1.UpdateDataSeries(
"Medium", MediumValues);
chart1.UpdateDataSeries(
"Far", FarValues);
// 距离(输入)
LinguisticVariable lvFront =
new LinguisticVariable(
"FrontalDistance",
0,
120);
lvFront.AddLabel(fsNear);
lvFront.AddLabel(fsMedium);
lvFront.AddLabel(fsFar);
// 隶属度函数
FuzzySet fsZero =
new FuzzySet(
"Zero",
new TrapezoidalFunction(-
10,
5,
5,
10));
FuzzySet fsLP =
new FuzzySet(
"LittlePositive",
new TrapezoidalFunction(
5,
10,
20,
25));
FuzzySet fsP =
new FuzzySet(
"Positive",
new TrapezoidalFunction(
20,
25,
35,
40));
FuzzySet fsVP =
new FuzzySet(
"VeryPositive",
new TrapezoidalFunction(
35,
40, TrapezoidalFunction.EdgeType.Left));
//绘制图像
int length2 = (
int)(chart2.RangeX.Max - chart2.RangeX.Min);
double[,] ZeroValues =
new double[length2,
2];
for (
int i = (
int)chart2.RangeX.Min; i < chart2.RangeX.Max; i++)
{
ZeroValues[i +
10,
0] = i;
ZeroValues[i +
10,
1] = fsZero.GetMembership(i);
}
double[,] LittlePositiveValues =
new double[length2,
2];
for (
int i = (
int)chart2.RangeX.Min; i < chart2.RangeX.Max; i++)
{
LittlePositiveValues[i +
10,
0] = i;
LittlePositiveValues[i +
10,
1] = fsLP.GetMembership(i);
}
double[,] PositiveValues =
new double[length2,
2];
for (
int i = (
int)chart2.RangeX.Min; i < chart2.RangeX.Max; i++)
{
PositiveValues[i +
10,
0] = i;
PositiveValues[i +
10,
1] = fsP.GetMembership(i);
}
double[,] VeryPositiveValues =
new double[length2,
2];
for (
int i = (
int)chart2.RangeX.Min; i < chart2.RangeX.Max; i++)
{
VeryPositiveValues[i +
10,
0] = i;
VeryPositiveValues[i +
10,
1] = fsVP.GetMembership(i);
}
chart2.UpdateDataSeries(
"Zero", ZeroValues);
chart2.UpdateDataSeries(
"LittlePositive", LittlePositiveValues);
chart2.UpdateDataSeries(
"Positive", PositiveValues);
chart2.UpdateDataSeries(
"VeryPositive", VeryPositiveValues);
//角度
LinguisticVariable lvAngle =
new LinguisticVariable(
"Angle", -
10,
50);
lvAngle.AddLabel(fsZero);
lvAngle.AddLabel(fsLP);
lvAngle.AddLabel(fsP);
lvAngle.AddLabel(fsVP);
//设置数据库
Database fuzzyDB =
new Database();
fuzzyDB.AddVariable(lvFront);
fuzzyDB.AddVariable(lvAngle);
// 创建模糊推理系统
InferenceSystem IS =
new InferenceSystem(fuzzyDB,
new CentroidDefuzzifier(
1000));
// 直行规则
IS.NewRule(
"Rule 1",
"IF FrontalDistance IS Far THEN Angle IS Zero");
// 左转规则
IS.NewRule(
"Rule 2",
"IF FrontalDistance IS Near THEN Angle IS Positive");
//开始推理
// 设定输入
IS.SetInput(
"FrontalDistance",
float.Parse(inputBox.Text));
//打印输出
try {
float newAngle = IS.Evaluate(
"Angle");
outputBox.Text = newAngle.ToString();
}
catch (Exception ex)
{
MessageBox.Show(
"error ===> "+ex.Message);
}
效果:
如果要输出模糊结论可以使用:
FuzzyOutput fuzzyOutput = IS.ExecuteInference(
"Angle");
foreach (FuzzyOutput.OutputConstraint oc
in fuzzyOutput.OutputList)
{
Console.WriteLine(oc.Label +
" - " + oc.FiringStrength.ToString());
}
模糊推理系统的扩展和完善
借助AForge.Net我们可以很快构建一个系统,但是AForge.Net也不是十全十美的。
首先它的合成运算子没有实现完全,有些常用的,比如最大边界算子就没有。
其次其去模糊化的实现只有一种,可以考虑实现自己补充一下算法:
1.最大平均法 (modified mean of maxima defuzzifier)
2.修正型最大平均法 (modified mean of maxima defuzzifier)
3.中心平均法 (modified center average defuzzifier)
4.修正型重心法 (modified center average defuzzifier)
5.权重式平均法(weighted average method)结合了启动强度,使用更为广泛
不过AForge.Net的接口和设计比较好,扩展也是很方便的。
其实模糊系统的话,matlab也是可以做到的,但是一来matlab不开源,二来扩展确实不方便,所以没有使用,如果确实没有替代品,可以考虑混编。
模糊系统的使用本身也有一些不方便,主要是规则库的建立。
第一种也是最直接的方式就是经由询问人类专家而得。但是人类专家往往无法完整地提供所有必需的语意式模煳规则,以致于规则库的不完全。
而模糊系统的效果主要受规则和隶属度函数影响,所以有时候规则库的不全对系统的效果是毁灭性伤害。
第二种取得语意式模煳规则的方式,则是经由训练法则,从数值型资料(numerical data)中取得模煳规则,此种作法往往牵涉如何分割输入及输出变数空间。常用的就是神经网络。
AForge.Net也有神经网络相关的东西,所以使用起来很方便的。
最后附上整个项目的下载地址:
http://www.ctdisk.com/file/4512079