python实现直觉模糊的TOPSIS方法

这是李登峰老师《直觉模糊集决策与对策分析方法》第三章的topsis方法,对于给出的算例进行独立重复实验。
相比实数域上的topsis方法,我们可以通过拆分矩阵,拼接矩阵对齐运算等方式实现直觉模糊下的矩阵运算。贴出来供大家学习参考。
关键环节有注释解释,代码如下

import pandas as pd
import numpy as np
from matplotlib.cbook import flatten
def finpis(df):#寻找正负理想解
        df1=df.iloc[:,::2]
        df2=df.iloc[:,1::2]
        df3=df1.max()
        df4=df1.min()
        df5=df2.max()
        df6=df2.min()#准备工作,用很多个切片操作为之后做准备,其实可以优化,看起来确实不美观

        df7=list(flatten(zip(df3,df6)))       #这里是百度到的如何奇偶项交错插入数列方法
        df8=list(flatten(zip(df4,df5)))
        df11 = df7[0::2]
        df12 = df7[1::2]
        c1 = [1-df11[i] - df12[i] for i in range(len(df11))]
        c1= pd.Series(c1)
        df7= pd.Series(df7)
        df13 = df8[0::2]
        df14 = df8[1::2]
        c2 = [1-df13[i] - df14[i] for i in range(len(df13))]
        c2= pd.Series(c2)#c1,c2就是寻找到的正负理想解,考虑到矩阵运算的时候需要犹豫度运算,因此还要找到犹豫度连接到数列头部

        df8= pd.Series(df8)
        zheng = pd.concat([c1,df7])
        fu= pd.concat([c2,df8])
        return zheng,fu#带有犹豫度的正负理想解,但并不是需要的

def normalize_matrix(df):#矩阵也需要犹豫度参与运算,因此把犹豫度拼接到头部,只要位置和正负理想解对齐,线性运算就不会出错
        df2=df.iloc[:,1::2]
        df1=df.iloc[:,::2]
        pai=1-df1.values-df2.values
        pai =pd.DataFrame(pai)
        f=[pai,df]
        f= pd.concat(f,axis=1)
        return f
def ranks(df,pis,nis):#排名方法,原封不动可以使用实数域的方法代码
    pistemp = df.sub(pis, axis=1)
    pistempsum = (pistemp ** 2).sum(axis=1)
    nistemp = df.sub(nis, axis=1)
    nistempsum = (nistemp ** 2).sum(axis=1)
    return np.sqrt(nistempsum)/(np.sqrt(pistempsum)+np.sqrt(nistempsum))
if __name__ == '__main__':#主函数列出需要的矩阵,没有使用excel导入
        df = [[0.1875, 0.325, 0.21, 0.55, 0.24, 0.72],
              [0.20, 0.3625, 0.238, 0.52, 0.135, 0.825],
              [0.1, 0.5875, 0.2625, 0.43, 0.18, 0.755]]
        df = pd.DataFrame(df)
        pis,nis=finpis(df)#一个方法返回两个结果,方便使用
        f= normalize_matrix(df)
        print('方案收益值为\n ',ranks(f, pis,nis))

10.25进行代码优化。三个函数分别实现寻找正负理想解,计算犹豫度和计算排名的功能。

def finpn(df):
        df=df
        pis = df.max()
        nis = df.min()
        for i in range(1,df.shape[1],2):
                temp = pis[i]
                pis[i] = nis[i]
                nis[i] = temp
        return pis, nis
def add_matrix(df):
        df=df
        df2=df.iloc[:,1::2].T.reset_index(drop=True).T
        df1=df.iloc[:,::2].T.reset_index(drop=True).T
        df3=1-df1-df2
        df4= pd.concat([df,df3],axis=1).T.reset_index(drop=True).T
        return df4

def ranks(df,pis,nis):#排名方法
        df=df
        pis=pis
        nis=nis
        pis1=1-pis[0::2].reset_index(drop=True)-pis[1::2].reset_index(drop=True)
        nis1=1-nis[0::2].reset_index(drop=True)-nis[1::2].reset_index(drop=True)
        pis2=pis.tolist()+pis1.tolist()
        nis2=nis.tolist()+nis1.tolist()
        print(pis2,nis2)
        pistemp = df.sub(pis2, axis=1)
        pistempsum = (pistemp ** 2).sum(axis=1)
        nistemp = df.sub(nis2, axis=1)
        nistempsum = (nistemp ** 2).sum(axis=1)
        return np.sqrt(nistempsum) / (np.sqrt(pistempsum) + np.sqrt(nistempsum))

if __name__ == '__main__':#主函数列出需要的矩阵,没有使用excel导入
        df = [[0.1875, 0.325, 0.21, 0.55, 0.24, 0.72],
              [0.20, 0.3625, 0.238, 0.52, 0.135, 0.825],
              [0.1, 0.5875, 0.2625, 0.43, 0.18, 0.755]]
        df = pd.DataFrame(df)

        pis,nis=finpn(df)
        df=add_matrix(df)
        print(df)
        print('方案收益值为\n ',ranks(df, pis,nis))

github仓库在https://github.com/rivendelltom/decision-making-study

你可能感兴趣的:(python,开发语言,后端)