学习数模自用,方便队友复制粘贴写论文
1.主函数
%topsis法
%清空之前工作区和命令行窗口
clc;clear
%先在右侧工作区建立X的原始矩阵,将excel数据粘贴至X,
%再保存为mat文件,下次直接load,不用粘贴
%data_water.mat为原始数据,后续将对其进行分析
load data_water.mat;
%获取需要正向化的列数
ToPositive=input('请输入需要转化为极大型指标的列号,格式为[2 3 4]:')
%ToPositive=[2 3 4];
%获取需要正向化所在列的指标类型
disp('请输入以上列指标类型,1:极小型,2:中间型,3:区间型')
types=input('例如需要处理的第一列为中间型,第二列为极小型,第三列为区间型,格式为[2 1 3]:')
%types=[2 1 3];
%需要正向化的列数
c=size(ToPositive,2)
%原始矩阵的行数
r=size(X,1)
%将原始矩阵正向化
for i=1:c
switch(types(i))
case 1
disp(['正在将第' num2str(ToPositive(i)) '列极小型指标转化为极大型指标'])
X(:,ToPositive(i))=MinToMax(X(:,ToPositive(i)));
case 2
disp(['正在将第' num2str(ToPositive(i)) '列中间型指标转化为极大型指标'])
X(:,ToPositive(i))=MidToMax(X(:,ToPositive(i)));
case 3
disp(['正在将第' num2str(ToPositive(i)) '列区间型指标转化为极大型指标'])
X(:,ToPositive(i))=RangeToMax(X(:,ToPositive(i)));
end
end
%展示正向化后的矩阵
disp('正向化后的矩阵为:')
X
xlswrite('D:\建模\自己写的代码\topsis.X.xls',X)
%正向矩阵标准化
disp('标准化后的矩阵为:')
Z=X./((repmat(sum(X.^2),r,1))).^0.5
%计算得分归一化
%先计算每列中最小和最大的元素组成的行向量
min_z=min(Z);
max_z=max(Z);
%括号内是输出归一化后的正向矩阵,以excel格式存储
xlswrite('D:\建模\自己写的代码\topsis.Z.xls',Z)
%输入各项指标权重,并检验权重之和是否输入正确,不正确就一直循环,直到输入正确
disp(['现在一共有' num2str(size(X,2)) '个指标'])
w=input('请输入各项指标权重,例如四个指标权重相等,则输入[0.25 0.25 0.25 0.25]:');
while sum(w)~=1
disp('权重之和不等于1,请重新输入权重!')
w=input('请输入各项指标权重,例如四个指标权重相等,则输入[0.25 0.25 0.25 0.25]:');
end
w=repmat(w,r,1);
%计算r个评价对象和最小值的距离(带权重的)
d_n=(sum((Z-repmat(min_z,r,1)).^2.*w,2)).^0.5;
d_p=(sum((Z-repmat(max_z,r,1)).^2.*w,2)).^0.5;
%计算实际得分
S=d_n./(d_p+d_n);
%计算归一化后的得分,将右方结果复制粘贴到excel里进行绘图
disp('归一化后各项指标的得分为:')
stand_S=S/sum(S)
2.极小型指标转化为极大型指标
%极小型指标转化为极大型指标
function positive_x=MinToMax(x)
positive_x=max(x)-x;
3.中间型指标转化为极大型指标
%中间型指标转化为极大型指标
function positive_x=MidToMax(x)
best=input('请输入最好的特定值:');
M=max(abs(x-best));
positive_x=1-abs(x-best)./M;
4.区间型指标转化为极大型指标
%区间型指标转化为极大型指标
function positive_x=RangeToMax(x)
positive_x=x;
%输入区间
a=input('请输入最佳区间的下界:');
b=input('请输入最佳区间的上界:');
%该列的最小值和最大值
min_x=min(x);
max_x=max(x);
%计算M
M=max([a-min_x max_x-b]);
%计算出x有多少行
rows=size(x,1);
%对每一行的数据进行判断
for i=1:rows
if x(i)<a
positive_x(i)=1-(a-x(i))/M;
elseif(x(i)>b)
positive_x(i)=1-(x(i)-b)/M;
else
positive_x(i)=1;
end
end