参考资料:https: // blog.csdn.net / shelgi / article / details / 126908418
————通过下面这个例子,终于能理解一点模糊理论的应用了,感谢原作。
熟悉简单的skfuzzy构建接近生活事件的模糊控制器
假设下面这样的场景, 我们希望构建一套模糊控制系统, 通过室外温度和风的大小来判断穿几件衣服
室外温度的范围设置为0 - 40度, 虽然今年夏天超过40度在我们这边很平常, 但是我们这里还是以40度为最高界限
风的大小范围0 - 10, 这里不是风的级数, 而是我自己构建的大小.模糊理论奥妙就在于不需要精确的逻辑值,
可以模糊描述.比如小风我设置为1 - 3, 然后有点大的风等等, 都是比较抽象的描述, 但是经过隶属函数可以看出, 往往某个值是在多个状态叠加.
衣服的件数我设置为1 - 6(不能一件衣服不穿), 如果按照本人自己的爱好, 我最多也只穿三件.不过考虑到实际还是设一个大点的范围
常见模糊隶属度函数
import matplotlib.pyplot as plt
import numpy as np
import skfuzzy as fuzz
from skfuzzy import control as ctrl
import matplotlib.pyplot as plt"""scikit-fuzzy模块,它可以实现模糊控制系统1.选择输入输出模糊集2.定义输入输出隶属度函数(不同的隶属度函数,会导致不同的控制特性)3.建立模糊控制表4.建立模糊控制规则5.模糊推理6.反模糊化7.输出结果绘制结果3D图
"""""" 方式一: 调用库函数 """
if 0:temp = ctrl.Antecedent(np.arange(0, 41, 1), 'temp')wind = ctrl.Antecedent(np.arange(0, 11, 1), 'wind')clothes = ctrl.Consequent(np.arange(1, 7, 1), 'clothes')# 自动找成员函数,分为三类temp.automf(3)wind.automf(3)# 设置目标的模糊规则clothes['low'] = fuzz.trimf(clothes.universe, [1, 1, 3])clothes['medium'] = fuzz.trimf(clothes.universe, [1, 3, 6])clothes['high'] = fuzz.trimf(clothes.universe, [3, 6, 6])rule1 = ctrl.Rule(temp['good'] | wind['poor'], clothes['low'])rule2 = ctrl.Rule(temp['average'], clothes['medium'])rule3 = ctrl.Rule(temp['poor'] | wind['good'], clothes['high'])rule1.view()rule2.view()rule3.view()# 创建控制系统,应用编写好的规则cloth_ctrl = ctrl.ControlSystem([rule1, rule2, rule3])# 创建控制仿真器cloth_num = ctrl.ControlSystemSimulation(cloth_ctrl)# 输入测试数据cloth_num.input['temp'] = 20cloth_num.input['wind'] = 2# 设置去模糊方法clothes.defuzzify_method = 'mom'# 计算结果cloth_num.compute()cloth_num_res = cloth_num.output['clothes']print(f"The result of clothes: {cloth_num_res}")# 可视化clothes.view(sim=cloth_num)plt.show()else:""" 方式二: 手动实现模糊规则 """plt.rcParams['font.family'] = 'simhei'x_temp = np.arange(0, 41, 1)x_wind = np.arange(0, 11, 1)x_clothes = np.arange(1, 7, 1)# 将三角隶属度函数对各个量进行隶属度映射temp_cold = fuzz.trimf(x_temp, [0, 0, 15])temp_warm = fuzz.trimf(x_temp, [5, 25, 35])temp_hot = fuzz.trimf(x_temp, [25, 40, 40])plt.figure()plt.title("Temperature")plt.plot(x_temp, temp_cold, 'b', label='cold')plt.plot(x_temp, temp_warm, 'y', label='warm')plt.plot(x_temp, temp_hot, 'r', label='hot')plt.legend()# plt.show()wind_low = fuzz.trimf(x_wind, [0, 0, 5])wind_medium = fuzz.trimf(x_wind, [0, 5, 10])wind_high = fuzz.trimf(x_wind, [5, 10, 10])plt.figure()plt.title("Wind")plt.plot(x_wind, wind_low, 'b', label='low')plt.plot(x_wind, wind_medium, 'y', label='medium')plt.plot(x_wind, wind_high, 'r', label='high')plt.legend()# plt.show()cloth_low = fuzz.trimf(x_clothes, [1, 1, 3])cloth_medium = fuzz.trimf(x_clothes, [1, 3, 6])cloth_high = fuzz.trimf(x_clothes, [3, 6, 6])plt.figure()plt.title("clothes")plt.plot(x_clothes, cloth_low, 'b', label='low')plt.plot(x_clothes, cloth_medium, 'y', label='medium')plt.plot(x_clothes, cloth_high, 'r', label='high')plt.legend()# plt.show()temp_test = 30wind_test = 5temp_level_cold = fuzz.interp_membership(x_temp, temp_cold, temp_test)temp_level_warm = fuzz.interp_membership(x_temp, temp_warm, temp_test)temp_level_hot = fuzz.interp_membership(x_temp, temp_hot, temp_test)wind_level_low = fuzz.interp_membership(x_wind, wind_low, wind_test)wind_level_medium = fuzz.interp_membership(x_wind, wind_medium, wind_test)wind_level_high = fuzz.interp_membership(x_wind, wind_high, wind_test)# 模糊规则# 当风小或者温度高的时候我们穿很少的衣服# 当温度中等, 比较温暖的时候我们穿得稍微多点# 当温度很低或者风很大的时候, 那我们就需要穿很多衣服了rule1 = np.fmax(temp_level_hot, wind_level_low)cloth_res_low = np.fmin(rule1, cloth_low)cloth_res_medium = np.fmin(temp_level_warm, cloth_medium)rule2 = np.fmax(temp_level_cold, wind_level_high)cloth_res_high = np.fmin(rule2, cloth_high)clothes = np.zeros_like(x_clothes)# visplt.figure(figsize=(8, 3))plt.title("结果")plt.plot(x_clothes, cloth_low, 'b')plt.fill_between(x_clothes, 0, cloth_res_low)plt.plot(x_clothes, cloth_medium, 'g')plt.fill_between(x_clothes, 0, cloth_res_medium)plt.plot(x_clothes, cloth_high, 'r')plt.fill_between(x_clothes, 0, cloth_res_high)# plt.show()# 去模糊aggregated = np.fmax(cloth_res_low, np.fmax(cloth_res_medium, cloth_res_high))# 去模糊方法:# 反模糊化方法有很多# centroid面积重心法# bisector面积等分法# mom最大隶属度平均法# som最大隶属度取最小法# lom最大隶属度取最大法cloth = fuzz.defuzz(x_clothes, aggregated, 'mom')cloth_res = fuzz.interp_membership(x_clothes, aggregated, cloth)plt.figure(figsize=(8, 3))plt.title(f"去模糊化结果cloth:{cloth}")plt.plot(x_clothes, cloth_low, 'b')plt.plot(x_clothes, cloth_medium, 'g')plt.plot(x_clothes, cloth_high, 'r')plt.fill_between(x_clothes, 0, aggregated, facecolor='orange')plt.plot([cloth, cloth], [0, cloth_res], 'k')plt.show()
- 测试温度:temp_test = 30;测试风速:wind_test = 5
- 测试温度:temp_test = 10;测试风速:wind_test = 8
- 测试温度:temp_test = 40;测试风速:wind_test = 2