python
复制代码
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'] = 20
cloth_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 = 30
wind_test = 5
temp_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)
# vis
plt.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()