(1)穗椅、題目
題目:評(píng)價(jià)下表中20條河流的水質(zhì)情況蔓倍。
注:含氧量越高越好(極大型指標(biāo)),PH值越接近7越好(中間型指標(biāo))敞咧,細(xì)菌總數(shù)越少越好(極小型指標(biāo))棘捣,植物性營養(yǎng)物量介于10~20之間最佳,超過20或低于10均不好(范圍型指標(biāo))休建。
(2)乍恐、讀取Excel表中的數(shù)據(jù)
def read(file):
wb = xlrd.open_workbook(filename=file)#打開文件
sheet = wb.sheet_by_index(0)#通過索引獲取表格
rows = sheet.nrows # 獲取行數(shù)
all_content = [] #存放讀取的數(shù)據(jù)
for j in range(1, 5): #取第1~第4列對(duì)的數(shù)據(jù)
temp = []
for i in range(1,rows) :
cell = sheet.cell_value(i, j) #獲取數(shù)據(jù)
temp.append(cell)
all_content.append(temp) #按列添加到結(jié)果集中
temp = []
return np.array(all_content)
(3)、將不同的指標(biāo)轉(zhuǎn)換為極大型指標(biāo)
#極小型指標(biāo) -> 極大型指標(biāo)
def dataDirection_1(datas):
return np.max(datas)-datas #套公式
#中間型指標(biāo) -> 極大型指標(biāo)
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
#區(qū)間型指標(biāo) -> 極大型指標(biāo)
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)测砂、正向化矩陣標(biāo)準(zhǔn)化
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] #套用矩陣標(biāo)準(zhǔn)化的公式
return datas
(5)茵烈、計(jì)算得分并歸一化
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個(gè)評(píng)價(jià)對(duì)象與最大值的距離
min_list = [] #存放第i個(gè)評(píng)價(jià)對(duì)象與最小值的距離
answer_list=[] #存放評(píng)價(jià)對(duì)象的未歸一化得分
for k in range(0,np.size(answer2,axis = 1)): #遍歷每一列數(shù)據(jù)
max_sum = 0
min_sum = 0
for q in range(0,4): #有四個(gè)指標(biāo)
max_sum += np.power(answer2[q,k]-list_max[q],2) #按每一列計(jì)算Di+
min_sum += np.power(answer2[q,k]-list_min[q],2) #按每一列計(jì)算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])) #套用計(jì)算得分的公式 Si = (Di-) / ((Di+) +(Di-))
max_sum = 0
min_sum = 0
answer = np.array(answer_list) #得分歸一化
return (answer / np.sum(answer))
(6)、主函數(shù)
def main():
file = 'C:\\Users\\lenovo\Desktop\\數(shù)學(xué)建模\\TOPSIS法\\第2講.TOPSIS法(優(yōu)劣解距離法)7.17\\代碼和例題數(shù)據(jù)\\20條河流的水質(zhì)情況數(shù)據(jù).xlsx'
answer1 = read(file) #讀取文件
answer2 = []
for i in range(0, 4): #按照不同的列砌些,根據(jù)不同的指標(biāo)轉(zhuǎn)換為極大型指標(biāo)瞧毙,因?yàn)橹挥兴牧? answer = None
if(i == 0): #本來就是極大型指標(biāo),不用轉(zhuǎn)換
answer = answer1[0]
elif(i == 1): #中間型指標(biāo)
answer = dataDirection_2(answer1[1],7)
elif(i==2): #極小型指標(biāo)
answer = dataDirection_1(answer1[2])
else: #范圍型指標(biāo)
answer = dataDirection_3(answer1[3],10,20)
answer2.append(answer)
answer2 = np.array(answer2) #將list轉(zhuǎn)換為numpy數(shù)組
answer3 = temp2(answer2) #數(shù)組正向化
answer4 = temp3(answer3) #標(biāo)準(zhǔn)化處理去鋼
data = pd.DataFrame(answer4) #計(jì)算得分
#將得分輸出到excel表格中
writer = pd.ExcelWriter('C:\\Users\\lenovo\Desktop\\數(shù)學(xué)建模\\TOPSIS法\\第2講.TOPSIS法(優(yōu)劣解距離法)7.17\\代碼和例題數(shù)據(jù)\\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文件中讀取數(shù)據(jù)
def read(file):
wb = xlrd.open_workbook(filename=file)#打開文件
sheet = wb.sheet_by_index(0)#通過索引獲取表格
rows = sheet.nrows # 獲取行數(shù)
all_content = [] #存放讀取的數(shù)據(jù)
for j in range(1, 5): #取第1~第4列對(duì)的數(shù)據(jù)
temp = []
for i in range(1,rows) :
cell = sheet.cell_value(i, j) #獲取數(shù)據(jù)
temp.append(cell)
all_content.append(temp) #按列添加到結(jié)果集中
temp = []
return np.array(all_content)
#極小型指標(biāo) -> 極大型指標(biāo)
def dataDirection_1(datas):
return np.max(datas)-datas #套公式
#中間型指標(biāo) -> 極大型指標(biāo)
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
#區(qū)間型指標(biāo) -> 極大型指標(biāo)
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)
#正向化矩陣標(biāo)準(zhǔn)化
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] #套用矩陣標(biāo)準(zhǔn)化的公式
return datas
#計(jì)算得分并歸一化
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個(gè)評(píng)價(jià)對(duì)象與最大值的距離
min_list = [] #存放第i個(gè)評(píng)價(jià)對(duì)象與最小值的距離
answer_list=[] #存放評(píng)價(jià)對(duì)象的未歸一化得分
for k in range(0,np.size(answer2,axis = 1)): #遍歷每一列數(shù)據(jù)
max_sum = 0
min_sum = 0
for q in range(0,4): #有四個(gè)指標(biāo)
max_sum += np.power(answer2[q,k]-list_max[q],2) #按每一列計(jì)算Di+
min_sum += np.power(answer2[q,k]-list_min[q],2) #按每一列計(jì)算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])) #套用計(jì)算得分的公式 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\\數(shù)學(xué)建模\\TOPSIS法\\第2講.TOPSIS法(優(yōu)劣解距離法)7.17\\代碼和例題數(shù)據(jù)\\20條河流的水質(zhì)情況數(shù)據(jù).xlsx'
answer1 = read(file) #讀取文件
answer2 = []
for i in range(0, 4): #按照不同的列宙彪,根據(jù)不同的指標(biāo)轉(zhuǎn)換為極大型指標(biāo)矩动,因?yàn)橹挥兴牧? answer = None
if(i == 0): #本來就是極大型指標(biāo),不用轉(zhuǎn)換
answer = answer1[0]
elif(i == 1): #中間型指標(biāo)
answer = dataDirection_2(answer1[1],7)
elif(i==2): #極小型指標(biāo)
answer = dataDirection_1(answer1[2])
else: #范圍型指標(biāo)
answer = dataDirection_3(answer1[3],10,20)
answer2.append(answer)
answer2 = np.array(answer2) #將list轉(zhuǎn)換為numpy數(shù)組
answer3 = temp2(answer2) #數(shù)組正向化
answer4 = temp3(answer3) #標(biāo)準(zhǔn)化處理去鋼
data = pd.DataFrame(answer4) #計(jì)算得分
#將得分輸出到excel表格中
writer = pd.ExcelWriter('C:\\Users\\lenovo\Desktop\\數(shù)學(xué)建模\\TOPSIS法\\第2講.TOPSIS法(優(yōu)劣解距離法)7.17\\代碼和例題數(shù)據(jù)\\A.xlsx') # 寫入Excel文件
data.to_excel(writer, 'page_1', float_format='%.5f') # ‘page_1’是寫入excel的sheet名
writer.save()
writer.close()
main()
(8)释漆、計(jì)算結(jié)果
計(jì)算出結(jié)果后可通過excel表對(duì)得分進(jìn)行手動(dòng)排序