模糊(逻辑)控制

模糊控制经典问题学习总结

参看博客:模糊推理控制系统——python

重在理解

'''
# 参看博客: https://blog.csdn.net/weixin_45902276/article/details/116454201
*原理及说明*
模糊推理所处理的事物自身是模糊的,概念本身没有明确的外延, 一个对象是否符合这个概念难以明确地确定模糊推理是对这种不确定性, 即模糊性的表示与处理。
模糊逻辑推理是基于模糊性知识(模糊规则)的一种近似推理, 一般采用Zadeh提出的语言变量、语言值、模糊集和模糊关系合成的方法进行推理。

*设计洗衣洗涤时间模糊控制*
已知人的操作经验为:
"污泥越多, 油脂越多, 洗涤时间越长";
"污泥适中, 油脂适中, 洗涤时间适中";
"污泥越少, 油脂越少, 洗涤时间越短"。

*模糊控制规则*
1. if (x is SD) and (y is NG) then (z is VS) (1)
2. if (x is SD) and (y is MG) then (z is M)  (1)
3. if (x is SD) and (y is LG) then (z is L)  (1)
4. if (x is MD) and (y is NG) then (z is S)  (1)
5. if (x is MD) and (y is MG) then (z is M)  (1)
6. if (x is MD) and (y is LG) then (z is L)  (1)
7. if (x is LD) and (y is MG) then (z is M)  (1)
8. if (x is LD) and (y is MG) then (z is L)  (1)
9. if (x is LD) and (y is LG) then (z is VL) (1)
其中, SD: 污泥少; MD: 污泥中; LD: 污泥多; 
      NG: 油脂少; MG: 油脂中; LG: 油脂多; 
      VS: 洗涤时间很短; VL: 洗涤时间很长;
      S: 洗涤时间短; M: 洗涤时间中等; L: 洗涤时间长.

*题目分析*
控制对象是洗衣机的洗涤时间, 论域: [0, 60];
输入是被洗衣物的污泥和油脂, 论域: [0, 100].

1. 污泥隶属函数
       | u_{SD}(x)=(50-x)/50        0 <=x <= 50
       |           |   x/50         0 <= x <= 50
u_{泥}=| u_{MD}(x)=|
       |           | (100-x)/50     50 < x <= 100
       | u_{LD}(x)=(x-50)/50        50 < x <= 100

2. 油脂隶属函数
       | u_{NG}(y)=(50-y)/50        0 <= y <= 50
       |           |   y/50         0 <= y <= 50
u_{油}=| u_{MG}(y)=|
       |           | (100-y)/50     50 < y <= 100
       | u_{LG}(y)=(y-50)/50        50 < y <= 100

3. 洗涤时间隶属函数
       | u_{VS}(z)=(10-z)/10        0 <= z <= 10
       |           |   z/10         0 <= z <= 10
u_{洗}=| u_{S}(z)= |
       |           | (25-z)/15      10 < z <= 25
       |           | (z-10)/15      10 < z <= 25
       | u_{M}(z)= |
       |           | (40-z)/15      25 < z <= 40
       |           | (z-25)/15      10 < z <= 25
       | u_{L}(z)= |
       |           | (60-z)/20      40 < z <= 60
       | u_{VL}(z)=(z-40)/20        40 <= z <= 60

4. 规则表
污泥度\油脂度    NG    MG    LG
     SD         VS     M     L
     MD          S     M     L
     LD          M     L     VL
'''
# 做题步骤及相应的代码

# 1. 定义污泥及油脂隶属函数求对应属性值下的隶属度.
# 分别定义一个一维三列的数组依次对应少中多.
def sludge_membership(x): # 污泥
    sludge=[0, 0, 0] # 默认隶属度为0,依次对应SD, MD, LD
    if x < 0 or x > 100:
        return (print("输入值有误."))
    elif 0 <= x <= 50:
        sludge[0] = (50-x)/50
        sludge[1] = x/50
    elif 50 < x <= 100:
        sludge[1] = (100-x)/50
        sludge[2] = (x-50)/50
    print("污泥对应的隶属度: ", sludge)
    return sludge

def grease_membership(y): # 油脂
    grease = [0, 0, 0] # 默认隶属度为0,依次对应SD, MD, LD
    if y < 0 or y > 100:
        return (print("输入值有误."))
    elif 0 <= y <= 50:
        grease[0] = (50-y)/50
        grease[1] = y/50
    elif 50 < y <= 100:
        grease[1] = (100-y)/50
        grease[2] = (y-50)/50
    print("油脂对应的隶属度: ", grease)
    return grease

# 2. 规则匹配与激活及规则前件隶属度聚集
# 将上得到污泥及油脂的隶属度值参考规则表,然后求取最小值。
# 代码思路是按照规则选择最简单的if条件句,判断得到相应属性值的隶属度。
# 一共会得到1个VS,1个S,3个M,3个L,1个VL的隶属度值。
# 所以需要在得到的M和L的隶属度中先去除0再取最小值。
# 这样就可以得到所有洗涤时间的属性值对应的隶属度了
def rules(x, y): # 0为污泥隶属度, b为油脂隶属度
    rules_value = [0, 0, 0, 0, 0, 0, 0, 0, 0] # 依次对应0个规则: VS, M, L, S, M, L, M, L, VL
    if x[0] != 0 and y[0] != 0:
        rules_value[0] = min(x[0], y[0])
    if x[0] != 0 and y[1] != 0:
        rules_value[1] = min(x[0], y[1])
    if x[0] != 0 and y[2] != 0:
        rules_value[2] = min(x[0], y[2])
    if x[1] != 0 and y[0] != 0:
        rules_value[3] = min(x[1], y[0])
    if x[1] != 0 and y[1] != 0:
        rules_value[4] = min(x[1], y[1])
    if x[1] != 0 and y[2] != 0:
        rules_value[5] = min(x[1], y[2])
    if x[2] != 0 and y[0] != 0:
        rules_value[6] = min(x[2], y[0])
    if x[2] != 0 and y[1] != 0:
        rules_value[7] = min(x[2], y[1])
    if x[2] != 0 and y[2] != 0:
        rules_value[8] = min(x[2], y[2])
    print("污泥和油脂对应规则的隶属度: ", rules_value)
    return rules_value

# 每条规则推理输出
def inference(z_rule): # z为9条规则下的结果隶属度
    time_level = [0, 0, 0, 0, 0] # 依次对应9条规则结果VS, S, M, L, VL
    time_level[0] = z_rule[0]
    time_level[1] = z_rule[3]
    if (z_rule[1] != 0 or z_rule[4] != 0 or z_rule[6] != 0): # 去零值然后取剩下的最小值
        list_1 = [z_rule[1], z_rule[4], z_rule[6]]
        for i in range(len(list_1)-1, -1, -1):
            if list_1[i] == 0:
                list_1.remove(0)
        time_level[2] = min(list_1)
    if (z_rule[2] != 0 or z_rule[5] != 0 or z_rule[7] != 0):
        list_2 = [z_rule[2], z_rule[5], z_rule[7]]
        for i in range(len(list_2)-1, -1, -1):
            if list_2[i] == 0:
                list_2.remove(0)
        time_level[3] = min(list_2)
    time_level[4] = z_rule[8]
    print("5个结果的隶属度: ", time_level)
    return time_level

# 面积重心法解模糊
#       \sigma^{m}_{k=1} v_{k}u_{v}(v_{k})
# v_{o}=-----------------------------------
#          \sigma^{m}_{k=1} u_{v}(v_{k})
# 根据公式知道需要根据时间隶属函数的反函数, 用相应的隶属度求出时间论域中对应的值, 
# 最后再根据公式求出最后结果
def area_gravity(res): # res为时间隶属度
    time = [0, 0, 0, 0, 0, 0, 0, 0, 0] # 时间隶属函数8个区间分别对应的时间值
    time[0] = 10 - 10 * res[0]
    time[1] = 10 * res[1]
    time[2] = 25 - 15 * res[1]
    time[3] = 15 * res[2] + 10
    time[4] = 40 - 15 * res[2]
    time[5] = 15 * res[2] + 10
    time[6] = 60 - 20 * res[3]
    time[7] = 20 * res[4] + 40
    sum_1 = (time[0]*res[0] + time[1]*res[1] + time[2]*res[1] + time[3]*res[2] + 
                        time[4]*res[2] + time[5]*res[3] + time[6]*res[3] + time[7]*res[4])
    sum_2 = res[0] + 2*res[1] + 2*res[2] + 2*res[3] + res[4]
    result = sum_1/sum_2
    print("面积重心法解模糊结果: ", result)
    return result # 最后返回预测时间

# 至此可以算是结束了, 不过我最后还添加了通过时间值求属性值(时间长短), 使用最大隶属度法
# 下面我使用的是用上面预测出的时间, 代入时间隶属函数求属性值, 也可以直接通过上面求出的时间隶属度来求时间属性值, 同样用最大隶属度法.
def maximum(z):
    if 0<=z<=10:
        u1 = (10-z)/10
        u2 = z/10
        if (u1>u2):
            time_level = 'VS'
        else:
            time_level = 'S'
    if 10<z<=25:
        u3 = (25-z)/15
        u4 = (z-10)/15
        if (u3>u4):
            time_level = 'S'
        else:
            time_level = 'M'
    if 25<z<=40:
        u5 = (40-z)/15
        u6 = (z-25)/15
        if (u5>u6):
            time_level = 'M'
        else:
            time_level = 'L'
    if 40<z<=60:
        u7 = (60-z)/20
        u8 = (z-40)/20
        if(u7>u8):
            time_level = 'L'
        else:
            time_level = 'VL'
    print("时间长短划分结果: ", time_level)
    return time_level


if __name__ == '__main__':
    sludge_value = int(input("输入污泥指数: "))
    grease_value = int(input("输入油脂指数: "))
    rules_value = rules(sludge_membership(sludge_value), grease_membership(grease_value))
    time_level = inference(rules_value) # 时间隶属度
    result_1 = area_gravity(time_level) # 面积重心法求得的预测时间
    result_2 = maximum(result_1) # 最大隶属度法求得的预测时间长短
    result_3 = {'VS': '很短', 'S': '短', 'M': '中等', 'L': '长', 'VL': '很长'}
    print("模糊推理系统预测洗涤时间{}, 预计洗涤时间{}".format(result_3[result_2], int(result_1+0.5)))
输入污泥指数: 20
输入油脂指数: 15
污泥对应的隶属度:  [0.6, 0.4, 0]
油脂对应的隶属度:  [0.7, 0.3, 0]
污泥和油脂对应规则的隶属度:  [0.6, 0.3, 0, 0.4, 0.3, 0, 0, 0, 0]
5个结果的隶属度:  [0.6, 0.4, 0.3, 0, 0]
面积重心法解模糊结果:  13.3
时间长短划分结果:  S
模糊推理系统预测洗涤时间短, 预计洗涤时间13
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值