美文网首页Python办公
Python实现TOPSIS分析法(优劣解距离法)

Python实现TOPSIS分析法(优劣解距离法)

作者: XHHP | 来源:发表于2019-07-28 10:10 被阅读0次

    (1)、题目

    在这里插入图片描述

    题目:评价下表中20条河流的水质情况。
    注:含氧量越高越好(极大型指标),PH值越接近7越好(中间型指标),细菌总数越少越好(极小型指标),植物性营养物量介于10~20之间最佳,超过20或低于10均不好(范围型指标)。

    (2)、读取Excel表中的数据

    def read(file):
        wb = xlrd.open_workbook(filename=file)#打开文件
        sheet = wb.sheet_by_index(0)#通过索引获取表格
        rows = sheet.nrows # 获取行数
        all_content = []        #存放读取的数据
        for j in range(1, 5):       #取第1~第4列对的数据
            temp = []
            for i in range(1,rows) :
                cell = sheet.cell_value(i, j)   #获取数据 
                temp.append(cell)           
            all_content.append(temp)    #按列添加到结果集中
            temp = []
        return np.array(all_content)
    

    (3)、将不同的指标转换为极大型指标

    #极小型指标 -> 极大型指标
    def dataDirection_1(datas):         
            return np.max(datas)-datas     #套公式
    
    #中间型指标 -> 极大型指标
    def dataDirection_2(datas, x_best):
        temp_datas = datas - x_best
        M = np.max(abs(temp_datas))
        answer_datas = 1 - abs(datas - x_best) / M     #套公式
        return answer_datas
        
    #区间型指标 -> 极大型指标
    def dataDirection_3(datas, x_min, x_max):
        M = max(x_min - np.min(datas), np.max(datas) - x_max)
        answer_list = []
        for i in datas:
            if(i < x_min):
                answer_list.append(1 - (x_min-i) /M)      #套公式
            elif( x_min <= i <= x_max):
                answer_list.append(1)
            else:
                answer_list.append(1 - (i - x_max)/M)
        return np.array(answer_list)   
    
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    (4)、正向化矩阵标准化

    def temp2(datas):
        K = np.power(np.sum(pow(datas,2),axis =1),0.5)
        for i in range(0,K.size):
            for j in range(0,datas[i].size):
                datas[i,j] = datas[i,j] / K[i]      #套用矩阵标准化的公式
        return datas 
    
    在这里插入图片描述

    (5)、计算得分并归一化

    def temp3(answer2):
        list_max = np.array([np.max(answer2[0,:]),np.max(answer2[1,:]),np.max(answer2[2,:]),np.max(answer2[3,:])])  #获取每一列的最大值
        list_min = np.array([np.min(answer2[0,:]),np.min(answer2[1,:]),np.min(answer2[2,:]),np.min(answer2[3,:])])  #获取每一列的最小值
        max_list = []       #存放第i个评价对象与最大值的距离
        min_list = []       #存放第i个评价对象与最小值的距离
        answer_list=[]      #存放评价对象的未归一化得分
        for k in range(0,np.size(answer2,axis = 1)):        #遍历每一列数据
            max_sum = 0
            min_sum = 0
            for q in range(0,4):                                #有四个指标
                max_sum += np.power(answer2[q,k]-list_max[q],2)     #按每一列计算Di+
                min_sum += np.power(answer2[q,k]-list_min[q],2)     #按每一列计算Di-
            max_list.append(pow(max_sum,0.5))
            min_list.append(pow(min_sum,0.5))
            answer_list.append(min_list[k]/ (min_list[k] + max_list[k]))    #套用计算得分的公式 Si = (Di-) / ((Di+) +(Di-))
            max_sum = 0
            min_sum = 0
        answer = np.array(answer_list)      #得分归一化
        return (answer / np.sum(answer))
    
    在这里插入图片描述

    (6)、主函数

    def main():
        file = 'C:\\Users\\lenovo\Desktop\\数学建模\\TOPSIS法\\第2讲.TOPSIS法(优劣解距离法)7.17\\代码和例题数据\\20条河流的水质情况数据.xlsx'
        answer1 = read(file)        #读取文件
        answer2 = []
        for i in range(0, 4):       #按照不同的列,根据不同的指标转换为极大型指标,因为只有四列
            answer = None
            if(i == 0):             #本来就是极大型指标,不用转换
                answer = answer1[0]             
            elif(i == 1):                   #中间型指标
                answer = dataDirection_2(answer1[1],7)
            elif(i==2):                     #极小型指标
                answer = dataDirection_1(answer1[2])
            else:                           #范围型指标
                answer = dataDirection_3(answer1[3],10,20)
            answer2.append(answer)
        answer2 = np.array(answer2)         #将list转换为numpy数组
        answer3 = temp2(answer2)            #数组正向化
        answer4 = temp3(answer3)            #标准化处理去钢
        data = pd.DataFrame(answer4)        #计算得分
        
        #将得分输出到excel表格中
        writer = pd.ExcelWriter('C:\\Users\\lenovo\Desktop\\数学建模\\TOPSIS法\\第2讲.TOPSIS法(优劣解距离法)7.17\\代码和例题数据\\A.xlsx')       # 写入Excel文件
        data.to_excel(writer, 'page_1', float_format='%.5f')        # ‘page_1’是写入excel的sheet名
        writer.save()
        writer.close()
    

    (7)、完整代码部分

    # -*- coding: utf-8 -*-
    """
    Created on Sat Jul 27 21:36:55 2019
    
    @author: lenovo
    """
    import numpy as np
    import xlrd
    import pandas as pd
    
    #从excel文件中读取数据
    def read(file):
        wb = xlrd.open_workbook(filename=file)#打开文件
        sheet = wb.sheet_by_index(0)#通过索引获取表格
        rows = sheet.nrows # 获取行数
        all_content = []        #存放读取的数据
        for j in range(1, 5):       #取第1~第4列对的数据
            temp = []
            for i in range(1,rows) :
                cell = sheet.cell_value(i, j)   #获取数据 
                temp.append(cell)           
            all_content.append(temp)    #按列添加到结果集中
            temp = []
        return np.array(all_content)
    
    #极小型指标 -> 极大型指标
    def dataDirection_1(datas):         
            return np.max(datas)-datas     #套公式
    
    #中间型指标 -> 极大型指标
    def dataDirection_2(datas, x_best):
        temp_datas = datas - x_best
        M = np.max(abs(temp_datas))
        answer_datas = 1 - abs(datas - x_best) / M     #套公式
        return answer_datas
        
    #区间型指标 -> 极大型指标
    def dataDirection_3(datas, x_min, x_max):
        M = max(x_min - np.min(datas), np.max(datas) - x_max)
        answer_list = []
        for i in datas:
            if(i < x_min):
                answer_list.append(1 - (x_min-i) /M)      #套公式
            elif( x_min <= i <= x_max):
                answer_list.append(1)
            else:
                answer_list.append(1 - (i - x_max)/M)
        return np.array(answer_list)   
     
    #正向化矩阵标准化
    def temp2(datas):
        K = np.power(np.sum(pow(datas,2),axis =1),0.5)
        for i in range(0,K.size):
            for j in range(0,datas[i].size):
                datas[i,j] = datas[i,j] / K[i]      #套用矩阵标准化的公式
        return datas
    
    #计算得分并归一化
    def temp3(answer2):
        list_max = np.array([np.max(answer2[0,:]),np.max(answer2[1,:]),np.max(answer2[2,:]),np.max(answer2[3,:])])  #获取每一列的最大值
        list_min = np.array([np.min(answer2[0,:]),np.min(answer2[1,:]),np.min(answer2[2,:]),np.min(answer2[3,:])])  #获取每一列的最小值
        max_list = []       #存放第i个评价对象与最大值的距离
        min_list = []       #存放第i个评价对象与最小值的距离
        answer_list=[]      #存放评价对象的未归一化得分
        for k in range(0,np.size(answer2,axis = 1)):        #遍历每一列数据
            max_sum = 0
            min_sum = 0
            for q in range(0,4):                                #有四个指标
                max_sum += np.power(answer2[q,k]-list_max[q],2)     #按每一列计算Di+
                min_sum += np.power(answer2[q,k]-list_min[q],2)     #按每一列计算Di-
            max_list.append(pow(max_sum,0.5))
            min_list.append(pow(min_sum,0.5))
            answer_list.append(min_list[k]/ (min_list[k] + max_list[k]))    #套用计算得分的公式 Si = (Di-) / ((Di+) +(Di-))
            max_sum = 0
            min_sum = 0
        answer = np.array(answer_list)      #得分归一化
        return (answer / np.sum(answer))
    
    
    def main():
        file = 'C:\\Users\\lenovo\Desktop\\数学建模\\TOPSIS法\\第2讲.TOPSIS法(优劣解距离法)7.17\\代码和例题数据\\20条河流的水质情况数据.xlsx'
        answer1 = read(file)        #读取文件
        answer2 = []
        for i in range(0, 4):       #按照不同的列,根据不同的指标转换为极大型指标,因为只有四列
            answer = None
            if(i == 0):             #本来就是极大型指标,不用转换
                answer = answer1[0]             
            elif(i == 1):                   #中间型指标
                answer = dataDirection_2(answer1[1],7)
            elif(i==2):                     #极小型指标
                answer = dataDirection_1(answer1[2])
            else:                           #范围型指标
                answer = dataDirection_3(answer1[3],10,20)
            answer2.append(answer)
        answer2 = np.array(answer2)         #将list转换为numpy数组
        answer3 = temp2(answer2)            #数组正向化
        answer4 = temp3(answer3)            #标准化处理去钢
        data = pd.DataFrame(answer4)        #计算得分
        
        #将得分输出到excel表格中
        writer = pd.ExcelWriter('C:\\Users\\lenovo\Desktop\\数学建模\\TOPSIS法\\第2讲.TOPSIS法(优劣解距离法)7.17\\代码和例题数据\\A.xlsx')       # 写入Excel文件
        data.to_excel(writer, 'page_1', float_format='%.5f')        # ‘page_1’是写入excel的sheet名
        writer.save()
        writer.close()
    
    main()
    
    

    (8)、计算结果

    在这里插入图片描述

    计算出结果后可通过excel表对得分进行手动排序

    相关文章

      网友评论

        本文标题:Python实现TOPSIS分析法(优劣解距离法)

        本文链接:https://www.haomeiwen.com/subject/exsurctx.html