Topsis即优劣解距离法,数学建模中应用,这里大概写个代码,具体在使用的时候根据自己所需去优化
import numpy as np
'''
第一步,
先写正向化函数,传入两个个参数,注意这里把矩阵定义成全局变量,所以不用再向函数中传入矩阵
第一个参数是所需要正向化的列数
第二个参数是哪种类型的正向化,1.极小性 2.中间型 3.区间型
注:如果是中间型的话会提示输入最佳值,区间型会输入两个,x_best 和 y_best 分别存最佳区间的左右两端点
'''
a = np.array([[1, 1 / 4, 2, 1 / 3], [4, 1, 8, 2], [1 / 2, 1 / 8, 1, 1 / 5], [3, 1 / 2, 5, 1]])
def positiveTrend(column,key):
global M #这里不先定义成全局变量系统会报错,具体原理还不明白
if(key == 1):
#先找最大值
M = max(a[:, column])
a[:,column] = M - a[:,column]
elif(key == 2):
x_best = float(input("请输入x_best的值:"))
M = max(a[:,column]-x_best)
a[:,column] = 1 -(abs(a[:,column]-x_best)/M)
elif(key == 3):
x_best = float(input("请输入x_best的值:"))
y_best = float(input("请输入y_best的值:"))
M = max(x_best - min(a[:,column]),max(a[:,column]) - y_best)
for i in range(a.shape[0]):
if(a[i][column]<x_best):
a[i][column] = 1 - (x_best - a[i][column])/M
elif(x_best<=a[i][column]<=y_best):
a[i][column] = 1
elif(a[i][column]>y_best):
a[i][column] = 1 - (a[i][column]-y_best)/M
positiveTrend(1,2)
'''
第二步,
将矩阵标准化,每一列除以对应列的所有元素的和
'''
def normalize(a):
for i in range(a.shape[1]):
sum = 0
for j in range(a.shape[0]):
sum += a[j][i]
a[:,i] = a[:,i]/sum
normalize(a)
print(a)
'''
第三步
计算得分
先算每一列的最大值和最小值与并保存起来,
算每个人的每一个指标与最大值和与最小值的距离平方和得出D+和D-
由公式求出最终得分s,s = D- / (D+ + D-)
'''
def getScore(a):
#先求出这个矩阵的列数,方便后续操作
column = a.shape[1]
#定义两个数组来存放即将求的最大值和最小值
big = np.zeros((1,column))
small = np.zeros((1,column))
#求出每一列的最大值和最小值,为后续求D+和D-做准备
for i in range(column): #range函数默认从零开始,这一点注意下
big[0][i] = max(a[:,i])
small[0][i] = min(a[:,i])
score = np.zeros((a.shape[0],1)) #定义一个数组存每个人的得分
for i in range(a.shape[0]):
# ↑这个循环指的是每一个人都得算得分
sum_1 = 0
sum_2 = 0 # 定义两个变量sum作为媒介来求D+和D-
for j in range(column):
# ↑ 这个循环是指的每个列都得计算
#下面先算这个人的每一列与其对应列最大值和最小值的距离,最后在开方
sum_1 += (big[0][j] - a[i][j])**2
sum_2 += (a[i][j] - small[0][j])**2
#循环过后对两个sum开方即是所找的D+和D-,直接求得分存到数组中
score[i][0] = np.sqrt(sum_2)/(np.sqrt(sum_1)+np.sqrt(sum_2))
print("得分的情况为:",score)
getScore(a)
如果想直接用的话,就把a矩阵改成自己需要的矩阵,然后根据我所写的矩阵的功能直接传入参数使用即可