Topsis法(Technique for Order Preferece by Similarity to Ideal Solution)可翻译为逼近理想解排序法,国内常称为优劣解距离法,Topsis法是一种常用的综合评价方法,其能充分利用原始数据的信息,其结果能精确的反映各评价方案之间的差距

层次分析法的主观性太强,且决策层不能太多,如果太多判断矩阵和一致矩阵差异可能会很大,但是如果决策层中指标的数据是已知的,我们可以使用topsis来使得评价更加准确。

基本过程:先将原始数据矩阵统一指标类型(一般正向化处理)得到正向化矩阵,再对正向化的矩阵进行标准化处理以消除各指标量纲的影响,并找到有限个方案中的最有方案和最劣方案,然后分别计算各评价对象与最优方案的相对接近程度,获得各评价对象与最优方案的相对接近程度,以此作为评价优劣的依据。

matlab语法

1、load xx.mat 可将统一文件下的mat数据文件直接引用到工作区。


2、sort(A),A中的每列按升序排列;如果有第二个参数,如果第二个参数是1,表示列,2表示按行来排。如果需要降序,后面再加一个参数'descend'。


3、如果要保留sort函数的索引可以用[SA , index] = sort(A , 'descend') SA是排序好的向量,index是SA中的元素在A中的元素的索引。


4、matlab中的函数要单独放在一个文件里面,与主函数放在同一目录下。

function [输出变量] = 函数名称(传入参数)
    function_body
end

5、zeros函数的用法,zeros(3) 表示构造一个3*3的0矩阵;zeros(3,1)表示构造一个3*1的0矩阵

代码

%topsis , 主函数代码
clear;clc
load C:\Users\22978\Desktop\清风数学建模\我整理的代码\Topsis\data_water_quality.mat
%%
[r,c] = size(X)
disp(['当前共有' num2str(r) '个评价对象和' num2str(c) '个指标'])
%%  正向化
judge = input('是否需要正向化处理,需要按1,不需要按0:')
if judge == 1
    Position = input('需要对哪几个指标进行正向化?')
    Type = input('分别对应的类型, 输入1表示极小型,2表示中间型,3表示区间型:')
    
    for i = 1:size(Position , 2)
        X(:,Position(i)) = Positivition(X(:,Position(i)),Type(i),Position(i));
    end 
    
    disp('正向化矩阵后的结果为:');
    disp(X);    
end
%%  标准化
n = size(X,1)
Z = X./repmat(sum(X.*X).^0.5 , n , 1)
disp('标准化矩阵 Z = ')
disp(Z)
%% 计算得分

D_P = sum((repmat(max(Z) , n , 1) - Z).^ 0.5 , 2)
D_N = sum((repmat(min(Z) , n , 1) - Z).^ 0.5 , 2)

S = D_N / (D_P + D_N)
Stand_s = S/sum(S)   %  归一化
[sorted_s , index] = sort(Stand_s , 'descend')

%positivation函数代码,额,我这个单词写错了,应该是positivization,懒得改了
function [posit_x] = Positivition(x,type,i)
    if type == 1
        disp(['~~~~~~第' num2str(i) '列是极小型,正在正向化~~~~~~'])
        posit_x = min2max(x)
        disp(['~~~~~~第' num2str(i) '列极小型正向化完成~~~~~~'])
    elseif type == 2
        disp(['~~~~~~第' num2str(i) '列是中间型,正在正向化~~~~~~'])
        posit_x = mid2max(x)
        disp(['~~~~~~第' num2str(i) '列中间型正向化完成~~~~~~'])
    elseif type == 3
        disp(['~~~~~~第' num2str(i) '列是区间型,正在正向化~~~~~~'])
        posit_x = inter2max(x)
        disp(['~~~~~~第' num2str(i) '列区间型正向化完成~~~~~~'])
    else
        disp('没有这种类型的指标')
    end
end
%min2max函数代码
function [output] = min2max(x)
    output = max(x) - x
end
%mid2max函数代码
function [output] = mid2max(x)
    best = input('请输入最佳指标的数值:')
    M = max(abs(x - best))    
    output = 1 - abs(x - best)/M
end
%inter2max函数代码
function [output] = inter2max(x)
    a = input('输入区间的左端点')
    b = input('输入区间的右端点')
    r_x = size(x,1)  % row of x
    M= max(a - min(x) , max(x) - b)
    output = zeros(r_x , 1)
    for i = 1:r_x
        if x<a
            output(i) = 1 - (a - x(i))/M;
        elseif x>b
            output(i) = 1 - (x(i) - b)/M;
        else
          output(i) = 1;
        end
    end
end

立志成为一名攻城狮