北太天元实现层次分析法-以如何选购汽车为例

%北太天元 层次分析法 可以用来做经济建模
% 美国数学家 T.L.Saaty 于1970年代提出层次分析法
% AHP (Analytic Hierarchy Process)
% 是指将与决策总是有关的元素分解成目标、准则、方案等层次,
% 在此基础之上进行定性和定量分析的决策方法。
% 举例: 我们要采购一辆汽车
% 影响我们采购的有3个因素
% 有3个因素: 价格, 油耗,大小
% 假设有3种汽车 x, y, z
%
% 目标层A 购买汽车的欲望
% 准则层B 价格(B1) 油耗(B2) 大小(B3)
% 方案层C 汽车x(C1) 汽车y(C2) 汽车z(C3)
%% 输入 判断矩阵
% 准则层权重矩阵
A = [ ...
1 1/9 1/3
9 1 5
3 1/5 1
];
%
个数_B = 3;
个数_C = 3;
B = cell(1,个数_B);
% 仅仅考虑价格,选择汽车x,y,z 的判断矩阵
B{1} = [ ...
1 2 9
1/2 1 5
1/9 1/5 1
];
% 仅仅考虑油耗,选择汽车x,y,z 的判断矩阵
B{2} = [ ...
1 2 4
1/2 1 2
1/4 1/2 1
];
% 仅仅考虑大小,选择汽车x,y,z 的判断矩阵
B{3} = [ ...
1 2 1
1/2 1 1/2
1 2 1
];
%% 计算权重
[yes_A, 权重_A ] = 层次分析法求权重(A);
if( ~yes_A )
error("A没有通过一致性检验");
end
权重_B = zeros(个数_C, 个数_B);
for j=1:个数_B
[yes_Bj, 权重_Bj ] = 层次分析法求权重( B{j} );
if( ~yes_Bj )
error(['B' num2str(j) '没有通过一致性检验']);
end
权重_B(:, j) = 权重_Bj;
end
%%总后计算选择汽车x,y,z 的欲望值
欲望值 = 权重_B * 权重_A
% 北太天元 层次分析法的判断矩阵是否通过一致性检验,并且求权重
% 输入: A必须是方阵,而且方阵的阶数n 满足 2<=n<=20
% 输出: 是否通过一种性检验 = true,如果输入的矩阵通过一致性检验
% 输出: 权重是一个列向量,是矩阵的对应最大特征值的向量(按照和为1做了归一化)
% 例:
% A = [ 1 2 5 ;
% 1/2 1 5/2;
% 1/5 2/5 1 ] ;
% [是否, 权重] = 层次分析法求权重(A);
function [是否通过一致性检验, 权重] = 层次分析法求权重(A);
%% 检查参数是否符合要求
if (nargin ~=1)
help 层次分析法求权重;
error("层次分析法求权重的输入参数必须为1");
end
[m,n] = size(A);
if (m~=n)
help 层次分析法求权重;
error("层次分析法求权重的输入参数A必须是方阵");
end
if (n < 2 || n>20)
help 层次分析法求权重;
error("层次分析法求权重的输入参数A必须是方阵");
end
%% 求权重
[V,D] = eig(A); % V 的每一列是A的特征向量, 但是是用2范数归一的
最大特征值 = max(max(D));
[~,c]=find(D == 最大特征值 , 1); % 获得最大特征值所在的列 c
%特征值法求权重
权重 = V(:,c)/ sum(V(:,c)); % 除以 sum(V(:,c)) 的是为了让权重的求和为1
%% 一致性检验
CI = (最大特征值 - n) / (n-1);
RI=[0 0 0.52 0.89 1.12 1.26 1.36 1.41 1.46 1.49 1.52 1.54 1.56 1.58 ...
1.59 1.60 1.61 1.615 1.62 1.63];
%注意,这里的RI最多支持 n = 20
% 这里n=2时,用户输入两种因素的判断矩阵,
% A = [ 1 m; 1/m, 1] ;
% 如果不是 A(1,2) = 1/A(2,1) 就是不一致的。
% 因此检查的要非常严格的, 因此 RI(2) = 0;
CR=CI/RI(n);
if n>2
if CR<0.10
是否通过一致性检验 = true; %因为CR<0.10,所以矩阵A通过一致性检验
else
是否通过一致性检验 = false; %因为CR>=0.10,所以矩阵A没有通过一致性检验
end
else
% 当 n = 2, 即使 CI == 0, 仍然有 CI/RI(2) = 0/0 = Nan , 此事 Nan < 0.10 会返回false
% 而 CI == 0 的情形是一致的
if abs(CI) < eps
是否通过一致性检验 = true; %因为abs(CI) 很小,所以矩阵A通过一致性检验
else
是否通过一致性检验 = false; %因为abs(CI) 很大,所以矩阵A没有通过一致性检验
end
end
end