TOPSIS优劣解距离法–代码部分
下面要介绍的是TOPSIS的代码书写方法,TOPSIS总体分为三步:
1、矩阵正向化
2、正向化矩阵标准化
3、计算评分并归一化
下面根据这三步开始我们的代码编写:
第一步:导入数据
把数据复制到工作区,并将这个矩阵命名为x
① 在工作区右键,点击新建(ctrl+n),输入变量名称X
② 在Excel中复制数据,再回到X变量中粘贴数据
③ 右键X另存为,保存为mat文件,以后调用X只需要用load命令即可加载数据(这里我保存的mat文件命名为X.mat)
④ 代码和数据需要放在同一个目录下哦
第二步:判断是否需要正向化,并进行正向化
[n,m]=size(X);
disp(['共有num2str(n)'个评价对象'个评价对象'num2str(m)'个评价指标']
%用向量的方法拼接并输出字符串
Judge=input(['这'num2str(m)'个指标是否经过正向化处理,需要请输入1,不需要请输入0:']);
%使用input函数,来给Judge赋值
if Judge==1
Position=input('请输入需要正向化处理的指标所在的列,例如第2、3、6三列需要处理,那么你输入[2,3,6]:');
%使用input函数确定需要正向化处理的位置
disp('请输入需要处理的这些列的标准类型(1:极小型,2:中间型,3:区间型)')
Type=input('例如:第2列是极小型,第3列是区间型,第6列是中间型,就输入[1,3,2]:');
%使用intput函数确定需要处理列的指标类型
%需要注意的是Position和Type是相同维度的行向量
for i=1:size(Position,2)%这里得出的是循环次数,也就是每一个需要正向化的列都做一次循环
X(:,Position(i))=Positivization(X(:,Position(i)),Type(i),Position(i));
%Positivization是我们自己定义的函数,其作用是进行正向化,一共接受3个参数
%第一个参数就是要正向化处理的那一列向量X(:,Position(i))
%第二个参数是对应的这一列的指标类型(1:极小型,2:中间型,3:区间型)
%第三个参数是告诉函数我们正在处理的是原始矩阵中的哪一列
%该函数有一个返回值,它返回正向化之后的指标那一列,我们可以直接给我们原始要处理的列向量进行赋值
end
disp('正向化后的矩阵X=')
disp(X)
end
接下来开始定义我们的Positivization函数,函数不可以直接放在主函数中,和大多数语言不同,函数需要在matlab中单独定义一个m文件,并且函数文件需要和主函数放在同一个目录,也就是同一个文件夹当中。首先定义三种指标的转化函数:
极小型转化为极大型:Min2Max
m
a
x
−
x
max-x
max−x
%function[输出变量]=函数名(输入变量)
%函数最后需要用end结尾
function[posit_x]=Min2Max(x)
posit_x=max(x)-x;
end
中间型转化为极大型:Mid2Max
M
=
m
a
x
∣
x
i
−
x
b
e
s
t
∣
,
x
i
∗
=
1
−
∣
x
i
−
x
b
e
s
t
∣
M
M=max{|x_i-x_{best}|} , x_i^*=1-\frac{|x_i-x_{best}|}{M}
M=max∣xi−xbest∣,xi∗=1−M∣xi−xbest∣
function[posit_x]=Mid2Max(x,best)
M=max(abs(x-best));
posit_x=1-abs(x-best)/M;
end
区间型指标转化为极大型指标:Inter2Max
M=max{a-min{xi},max{xi}-b}
X
i
∗
=
{
1
−
a
−
x
M
x
<
a
1
a
≤
x
≤
b
1
−
x
−
b
M
x
>
b
X^{*}_i=\left\{ \begin{array}{rcl} 1-\frac{a-x}{M} & & {x < a}\\ 1 & & {a \leq x \leq b}\\ 1-\frac{x-b}{M} & & {x>b} \end{array} \right.
Xi∗=⎩⎨⎧1−Ma−x11−Mx−bx<aa≤x≤bx>b
function[posit_x]=Inter2Max(x,a,b)
r_x=size(x,1);%表示列向量的行数(row of x),来找到循环的次数
M=max([a-min(x),max(x)-b]);
posit_x=zeros(r_x,1) %将posit_x初始化为一个全为0的列向量
for i=1:r_x
if x(i)<a
posit_x(i)=1-(a-x(i)/M;
elseif x(i)>b
posit_x(i)=1-(x(i)-b)/M;
else
posit_x(i)=1;
end
end
end
接下来开始写Positivization函数:
%function[输出变量]=函数名(输入变量)
%函数最后需要用end结尾
%输出变量和输入变量可以有多个,中间用逗号隔开
function[posit_x]=Positivization(x,type,i)%这里定义函数参数,其中均为形参
%posit_x表示正向化后的列向量
%x表示需要正向化处理的指标对应的原始列向量
%type表示指标的类型(1:极小型,2:中间型,3:区间型)
%i表示正在处理的是原矩阵中的哪一列
if type==1 %极小型
disp(['第'num2str(i)'列是极小型,正在正向化'])
posit_x=Min2Max(x);%调用Min2Max函数来进行正向化
disp(['第'num2str(i)'列极小型正向化处理完毕'])
disp('~~~~~~~~~~~~~~~~~~~分界线~~~~~~~~~~~~~~~~~~~')
elseif type==2%中间型
disp(['第'num2str(i)'列是中间型'])
best=input('请输入最佳的值:');
posit_x=Mid2Max(x,best);
disp(['第'num2str(i)'列中间型正向化处理完毕'])
disp('~~~~~~~~~~~~~~~~~~~分界线~~~~~~~~~~~~~~~~~~~')
elseif type==3 %区间型
disp(['第'num2str(i)'列是区间型'])
a=input('请输入区间的上界');
b=input('请输入区间的下界');
posit_x=Inter2Max(x,a,b);
disp(['第'num2str(i)'列区间型正向化处理完毕'])
disp('~~~~~~~~~~~~~~~~~~~分界线~~~~~~~~~~~~~~~~~~~')
end
end
第三步:对正向化后的矩阵进行标准化
Z=X./repmat(sum(X.*X).^0.5,n,1);
disp('标准化矩阵Z=')
disp(Z)
第四步:计算与最大值的距离和与最小值的距离,并计算出得分
D_P=sum([(Z-repmat(max(Z),n,1)).^2],2).^0.5;%D+与最大值的距离
D_N=sum([(Z-repmat(min(Z),n,1)).^2],2).^0.5;%D-与最小值的距离
S=D_N./(D_P+D_N);%未归一化的得分
disp('最后的得分为:')
stand_S=S/sum(S)
[sortde_s,index]=sort(stand_S,'descend')
%这里使用sort函数进行排序,sort函数默认升序排列,加入参数'descend'为降序排列
%返回值sortde_s为降序排列后的矩阵,index为排列后的序号。