【数学建模】模糊数学运算——python实现各类运算

目录

一、模糊矩阵及其运算

① 并集计算

② 交集计算

③ 余集计算

④ 矩阵的合成

⑤ 矩阵的转置

⑥ 矩阵的λ-截矩阵计算

二、总结


一、模糊矩阵及其运算

        此处不再重复模糊矩阵R的含义了

        首先需要先读取数据,这里是将excel导入Python中进行的。读者可自行在EXCEL中使用该函数:=RANDARRAY(col,row,min,max,interger),分别是列数、行数、最小值、最大值以及输出区域,便可随机得到一个矩阵。使min=0,max=1,使之随机矩阵符合模糊矩阵元素值取值范围在[0,1]的要求。

import xlrd as xr
file_location="/Users/lifangjian/Desktop/CSDN/模糊识别运算.xls"
data=xr.open_workbook(file_location)
sheet=data.sheet_by_index(0)#第一个sheet是矩阵A
A=[[round(sheet.cell_value(r,c),2) for c in range(0,sheet.ncols)] for r in range(0,sheet.nrows)]#列表推导式,round取两位小数方便看
sheet=data.sheet_by_index(1)#第二个sheet是矩阵B
B=[[round(sheet.cell_value(r,c),2) for c in range(0,sheet.ncols)] for r in range(0,sheet.nrows)]#列表推导式,round取两位小数方便看
print(A)
print(B)

##输出结果为
[[0.81, 0.22, 0.6, 0.25], [0.06, 0.15, 0.41, 0.43], [0.37, 0.28, 0.66, 0.02], [0.56, 0.5, 0.05, 0.69]]
[[0.99, 0.64, 0.82, 0.82], [0.08, 0.3, 0.66, 0.39], [0.3, 0.89, 0.13, 0.63], [0.02, 0.17, 0.25, 0.18]]

① 并集计算

A \cup B= (a_i_j \vee b_i_j)_m_ \times_ _n

        比如 R12 就应该是 a12 和 b12 中的最大值。事实上就是两个矩阵每行每列对应的元素取最大值。通过手算比较,即取两个矩阵对应元素的最大值成之为模糊矩阵的元素值:

0.99 0.640.820.82
0.080.30.660.43
0.370.890.660.63
0.560.50.250.69

        利用 python验证手算结果,定义arbj函数,(取名就是array并集):

def arbj(A,B):
    R=[]
    for i in range(len(A)):
        a=A[i]
        b=B[i]
        r=[]
        for j in range(0,len(a)):
            if a[j]>b[j]:
                r.append(a[j])
            elif A[j]<B[j]:
                r.append(b[j])
            else:
                r.append(b[j])
        R.append(r)
    return R
print("并集运算结果为:{0}".format(arbj(A,B)))
并集运算结果为:[[0.99, 0.64, 0.82, 0.82], [0.08, 0.3, 0.66, 0.43], [0.37, 0.89, 0.66, 0.63], [0.56, 0.5, 0.25, 0.69]]

② 交集计算

A \cup B= (a_i_j \wedge b_i_j)_m_ \times_ _n

比如 R12 就应该是 a12 和 b12 中的最小值。事实上就是两个矩阵每行每列对应的元素取最小值。通过手算比较,即取两个矩阵对应元素的最小值成之为模糊矩阵的元素值:

0.81

0.220.60.25
0.060.150.410.39
0.30.280.130.02
0.020.170.050.18

这里代码只需要上面简单改动就可以实现了:

def arjj(A,B):
    R=[]
    for i in range(len(A)):
        a=A[i]
        b=B[i]
        r=[]
        for j in range(0,len(a)):
            if a[j]>b[j]:
                r.append(b[j])
            elif a[j]<b[j]:
                r.append(a[j])
            else:
                r.append(b[j])
        R.append(r)
    return R
print("交集运算结果为:{0}".format(arjj(A,B)))

##输出结果为:
交集运算结果为:[[0.81, 0.22, 0.6, 0.25], [0.06, 0.15, 0.41, 0.39], [0.3, 0.28, 0.13, 0.02], [0.02, 0.17, 0.05, 0.18]]

③ 余集计算

A^{c}=(1-a_i_j)_m_n

这里就不单独说手算结果了,直接上代码吧:

def aryj(A):
    R=[]
    for i in range(len(A)):
        a=A[i]
        r=[]
        for j in range(len(a)):
            b=round(1-a[j],2) #这里要注意计算机二进制算法的问题,给round避免一下
            r.append(b)
        R.append(r)
    return R
print("余集运算结果为:{0}".format(aryj(A)))    

余集运算结果为:[[0.19, 0.78, 0.4, 0.75], [0.94, 0.85, 0.59, 0.57], [0.63, 0.72, 0.34, 0.98], [0.44, 0.5, 0.95, 0.31]]

④ 矩阵的合成

        A=(aij)mxs, B=(bij)sxn,称模糊矩阵A o B = (cij)mxn为A和B的合成.

        其中cij=max{(aik)^(bkj)}

        这是行列对应的关系,以下列几个式子做例子来判定

A=[0.81, 0.22, 0.6, 0.25], [0.06, 0.15, 0.41, 0.43], [0.37, 0.28, 0.66, 0.02], [0.56, 0.5, 0.05, 0.69]
B=[0.99, 0.64, 0.82, 0.82], [0.08, 0.3, 0.66, 0.39], [0.3, 0.89, 0.13, 0.63], [0.02, 0.17, 0.25, 0.18]

        c11=max(0.81,0.08,0.3,0.02)=0.81,0.81和0.99比较,0.22和0.08比较,0.6和0.3比较

        c12=max(0.64,0.22,0.6,0.17)=0.64,0.81和0.64比较,0.22和0.3作比较

        c13=max(0.81,0.22,0.13,0.25)=0.81

        c14=max(0.81,0.22,0.6,0.18)=0.81

        c23=max(0.06,0.15,0.13,,0.25)=0.25,0.06和0.82作比较,0.15和0.66作比较

##导入numpy库实现转置
import numpy as np
def jzhc(M,N):
    R=[]
    N=np.stack(N,axis=1)#实现转置
    for i in range(len(M)):
        mr=[]
        for j in range(len(N)):
            r=(arjj([M[i]],[N[j]]))[0]
            mr.append(max(r))
        R.append(mr)
    return R
print(jzhc(A,B)) 
输出结果为:
[[0.81, 0.64, 0.81, 0.81],
[0.3, 0.41, 0.25, 0.41],
[0.37, 0.66, 0.37, 0.63],
[0.56, 0.56, 0.56, 0.56]]

⑤ 矩阵的转置

结合模糊矩阵合成的代码可知

import numpy as np
#数据导入看最前面
print(A)
At=np.stack(A,axis=1)
print(At)
#输出结果
A:
[[0.81, 0.22, 0.6, 0.25],
[0.06, 0.15, 0.41, 0.43],
[0.37, 0.28, 0.66, 0.02],
[0.56, 0.5, 0.05, 0.69]]
At:
[[0.81 0.06 0.37 0.56]
 [0.22 0.15 0.28 0.5 ]
 [0.6  0.41 0.66 0.05]
 [0.25 0.43 0.02 0.69]]

关于stack,hstack,vstack可以参照这里:

import numpy as np
##np.vstack(()):实现数组的堆砌,类似矩阵的输出形式
a=np.array([[1,2,3]])
b=np.array([[1,4,6]])
print(np.shape(a),np.shape(b))
#np.shape:输出列表或矩阵有几行几列
print(np.vstack((a,b)))

##np.hstack(()):实现两个数组的合并,如果有多个就不能全部输出
print(np.shape(a),np.shape(b))
print(np.hstack((a,b)))

##np.stack函数:
a=[[1,2,3],
   [4,5,6],
   [7,8,9]]
print("列表a如下:")
print(a)
print("增加一维,新维度的下标为0")
c=np.stack(a,axis=0)
print(c)

print("增加一维,新维度的下标为1") #可以实现转置
c=np.stack(a,axis=1)
print(c)
print(c[1])

 ⑥ 矩阵的λ-截矩阵计算

        大于等于λ,元素赋值=1;小于等于λ,元素赋值为0;该矩阵又称模糊布尔矩阵。

        代码实现:

def lamdajie(A,λ):
    Alamda=[]
    for i in range(len(A)):
        a=A[i]
        for j in range(len(a)):
            if a[j]>=λ:
                a[j]=1
            else:
                a[j]=0
        Alamda.append(a)
    return Alamda
print(lamdajie(A,0.5)) ##0.5截,这里可以任意设置+调用函数

结果对比:
A:
[[0.81, 0.22, 0.6, 0.25],
[0.06, 0.15, 0.41, 0.43],
[0.37, 0.28, 0.66, 0.02],
[0.56, 0.5, 0.05, 0.69]]

λ截:
[[1, 0, 1, 0],
[0, 0, 0, 0],
[0, 0, 1, 0],
[1, 1, 0, 1]]

二、总结

        ①  看完且看懂上面这些内容之后,基本上对模糊数学的矩阵计算就过了个遍了。后面有关模糊矩阵自反性、对称性和传递性的判断,即模糊等价矩阵、模糊相似矩阵、传递闭包矩阵的算法实质上基本上遵循了上述基本操作了。用python代码很容易实现。

        ② 代码只是帮助计算的工具而已,从根本上自己要明确理论方法!不然光看代码是学不会的计算的。当然如果能够自己写出来代码我觉得基本上就没什么问题了,以上都是博主花了一个晚上写出来的代码,也是小白边学边看,在合成那块卡了半天因为没有理解理论公式怎么算的。希望我写的对大家有帮助!大家加油~

        ③ 代码总结

import xlrd as xr
import numpy as np
file_location="/Users/lifangjian/Desktop/CSDN/模糊识别运算.xls"
data=xr.open_workbook(file_location)
sheet=data.sheet_by_index(0)
A=[[round(sheet.cell_value(r,c),2) for c in range(0,sheet.ncols)] for r in range(0,sheet.nrows)]
sheet=data.sheet_by_index(1)
B=[[round(sheet.cell_value(r,c),2) for c in range(0,sheet.ncols)] for r in range(0,sheet.nrows)]
At=np.stack(A,axis=1)
Bt=np.stack(B,axis=1)

def arbj(A,B): #并集
    R=[]
    for i in range(len(A)):
        a=A[i]
        b=B[i]
        r=[]
        for j in range(0,len(a)):
            if a[j]>b[j]:
                r.append(a[j])
            elif a[j]<b[j]:
                r.append(b[j])
            else:
                r.append(b[j])
        R.append(r)
    return R
print("并集运算结果为:{0}".format(arbj(A,B)))

def arjj(A,B): #交集
    R=[]
    for i in range(len(A)):
        a=A[i]
        b=B[i]
        r=[]
        for j in range(0,len(a)):
            if a[j]>b[j]:
                r.append(b[j])
            elif a[j]<b[j]:
                r.append(a[j])
            else:
                r.append(b[j])
        R.append(r)
    return R
print("交集运算结果为:{0}".format(arjj(A,B)))

def aryj(A): #余集
    R=[]
    for i in range(len(A)):
        a=A[i]
        r=[]
        for j in range(len(a)):
            b=round(1-a[j],2)
            r.append(b)
        R.append(r)
    return R
print("余集运算结果为:{0}".format(aryj(A)))

def jzhc(M,N):#必须是m*s,s*n的矩阵输入
    R=[]
    N=np.stack(N,axis=1)#实现转置
    for i in range(len(M)):
        mr=[]
        for j in range(len(N)):
            r=(arjj([M[i]],[N[j]]))[0]
            mr.append(max(r))
        R.append(mr)
    return R
print(jzhc(A,B))

def lamdajie(A,λ):
    Alamda=[]
    for i in range(len(A)):
        a=A[i]
        for j in range(len(a)):
            if a[j]>=λ:
                a[j]=1
            else:
                a[j]=0
        Alamda.append(a)
    return Alamda
print(lamdajie(A,0.5))
  • 10
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fonsi-

没饭吃了,帮帮孩子

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值