C# 和模糊逻辑入门
本文以集装箱起重机控制为例,简要介绍了基于规则的模糊逻辑系统的基本技术。

引言
容器(黄色)已经从船(红色)上被吊起。它必须被放置在卡车(绿色)上方。Angle
(角度)和 Distance
(距离)的值由过程模拟计算得出,而 Power
(功率)是控制变量,可以手动设置或由模糊逻辑控制器设置。模糊逻辑控制器使用人类操作员的经验。人类操作员能够在没有微分方程的情况下控制起重机。
实现语言控制
起重机头部位置的传感器(Distance
,距离)和集装箱摇摆角度的传感器(Angle
,角度)被用于自动控制这台起重机。使用这些输入来描述起重机的当前状态,例如:
IF Distance = medium AND Angle = neg_small THEN Power = pos_high
下图显示了模糊逻辑控制器的完整结构

模糊化
必须为 if
-then
规则中使用的所有变量定义语言变量。对于起重机控制器,术语是:
Distance
(距离):{neg_close
(负近),zero
(零),close
(近),medium
(中),far
(远)}Angle
(角度):{neg_big
(负大),neg_small
(负小),zero
(零),pos_small
(正小),pos_big
(正大)}Power
(功率):{neg_high
(负高),neg_medium
(负中),zero
(零),pos_medium
(正中),pos_high
(正高)}
对于每个语言变量,每个术语都由其隶属函数定义。

考虑起重机的一种可能情况,起重机头部到目标位置的 Distance
(距离)是 12 码,集装箱的 Angle
(角度)是 -30 度。
12 码的 Distance
(距离)属于以下模糊集合的成员:
medium
(中)的隶属度为 0.83far
(远)的隶属度为 0.17- 其他术语的隶属度为 0.00
-30 度的 Angle
(角度)属于以下模糊集合的成员:
neg_big
(负大)的隶属度为 0.4neg_small
(负小)的隶属度为 0.6- 其他术语的隶属度为 0.00
模糊推理
使用 If
-Then
规则。现在所有输入变量都已转换为语言变量值,模糊推理步骤可以识别适用于当前情况的规则,并计算输出语言变量的值。 考虑以上例子
IF
部分组合了两个条件:Distance = medium
(距离 = 中)和 Angle = neg_small
(角度 = 负小)。IF
部分定义了该规则在当前情况下是否有效。 在传统逻辑中,两个条件的组合可以通过布尔 AND
来计算,如下图所示:

对于模糊逻辑,布尔 AND
不能使用,因为它无法处理或多或少为真的条件。 因此,必须为模糊逻辑定义新的运算符来表示逻辑连接词,例如 AND
、OR
和 NOT
。

上述示例的 IF
部分可以计算如下:
min{ 0,83; 0.6} = 0.6
去模糊化
在模糊推理结束时,Power
(功率)的结果以语言变量的值给出。 为了使用它来设置电机功率,必须将其转换为实际值。 语言值和相应实际值之间的关系始终由隶属函数定义给出。 下图绘制了语言变量 Power 的隶属函数。

我使用一种称为最大中心法的去模糊化方法,它与使用单例隶属函数的重心法相同。 这些去模糊化方法用于大多数模糊逻辑实现中。
代码示例
该应用程序由许多函数和对象组成,但我在此应用程序中最喜欢的是模糊逻辑。 我通过以上隶属函数和模糊逻辑的概念编写了模糊函数。 这是模糊函数:
//Fuzzy function to produce optimized power
public double fuzzy()
{
//Fuzzification of variables, distance and angle
if((angle<-60)&&(angle>=-90))
neg_small=0;
else if((angle<-10)&&(angle>=-60))
neg_small=(0.02*angle+1.2);
else if((angle<0)&&(angle>=-10))
neg_small=(-0.1*angle);
else if((angle<=90)&&(angle>=0))
neg_small=0;
if((angle<-60)&&(angle>=-90))
neg_big=1;
else if((angle>=-60)&&(angle<-10))
neg_big=(-0.02*angle-0.2);
else if((angle>=-10)&&(angle<=90))
neg_big=0;
if((distance<5)&&(distance>=-10))
medium=0;
else if((distance<10)&&(distance>=5))
medium=(0.2*distance-1);
else if((distance<22)&&(distance>=10))
medium=((-1/12)*distance+(11/6));
else if((distance<=30)&&(distance>=22))
medium=0;
if((distance<10)&&(distance>=-10))
far=0;
else if((distance<22)&&(distance>=10))
far=((1/12)*distance-(5/6));
else if((distance<=30)&&(distance>=22))
far=1;
//... other if_ then_else clauses for other terms of distance and angle to be
// continued .
//Defuzzification of variable, power
return
System.Math.Round(System.Math.Max(System.Math.Min(pos_small,zerodis),
System.Math.Min(pos_small,close))*neg_medium_pow+System.Math.Max(
System.Math.Min(zero,zerodis),System.Math.Min(zero,close))*zero_pow+System.Math.Max(
System.Math.Max(System.Math.Min(neg_small,close),System.Math.Min(neg_big,medium)),
System.Math.Min(zero,far))*pos_medium_pow+System.Math.Max(System.Math.Min(neg_small,
medium),System.Math.Min(neg_small,far))*pos_high_pow,2);
}
结论
请注意,我的模拟程序不是科学模拟。 我的应用程序不是很漂亮,因为我还是个初学者,但我认为它几乎可以正常工作。 你觉得怎么样?
祝你愉快。
历史
- 2008 年 2 月 2 日:初始发布