步骤
1. 建立层次结构模型
分为最高层、中间层(可以有多层)和最底层。
- 最高层:决策目的,要解决的问题
- 中间层:考虑的因素,决策准则
- 最底层:决策的备选方案
2. 构造判断矩阵
打分依据(两两比较打分,来减少主观的影响):
打分 | 程度 |
---|---|
1 | 同样重要 |
3 | 稍微重要 |
5 | 明显重要 |
7 | 强烈重要 |
9 | 极端重要 |
2,4,6,8 | 处于对应程度中间 |
3. 层次单排序及其一致性检验
单排序,对应于中间层对最高层的判断矩阵(1个)
排序:见程序
一致性检验:
(n为判断矩阵的维度)
C I = ( λ m a x − n ) ( n − 1 ) CI = \frac {(\lambda_{max} - n)} {(n - 1)} CI=(n−1)(λmax−n)
C R = C I R I CR = \frac {CI} {RI} CR=RICI
其中 RI 为 修正因子,具体数值为
矩阵阶数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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 |
若 R I < 0.1 RI < 0.1 RI<0.1,那么说明该矩阵一致性可以接受
4. 层次总排序及其一致性检验
总排序,对应于最底层对于中间层(一般有多个)
排序:见程序
一致性检验:
C R = c r ∗ w 0 CR = cr * w0 CR=cr∗w0
cr:该层每个判断矩阵的CR组成的矩阵
w0:矩阵对应的决策项权重的矩阵(步骤三排序结果)
在一致性检验时,如果一致性检验通过,则直接计算权重,如果一致性检验未通过,则需修正判断矩阵后才计算权重。
修正方式参考论文:[点击这里](https://wenku.baidu.com/view/147d31315a8102d276a22f18.html)
实例
根据景色、费用、居住、饮食、旅途等条件从三个景点中选取最佳的一个
- 构建层次结构模型
- matlab程序
file = fopen('D:/DD/数学建模/层次分析法/data.txt'); % 此处修改路径
x= input('请输入决策量数目和方案数目:');
m = x(1);
n = x(2);
a = [];
% 获取中间层判断矩阵
for i = 1:m
tmp = str2num(fgetl(file));
a = [a;tmp];
end
for i = 1:m
str1 = char(['b', num2str(i), '=[]']);
str2 = char(['b', num2str(i), '=[b', num2str(i), ';tmp]']);
eval(str1);
% 获取方案层判断矩阵
for i = 1:n
tmp = str2num(fgetl(file));
eval(str2);
end
end
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]; % 一致性修正参数
% 对中间层
disp('中间层:');
[tz, C] = get_feature(a);
% 一致性检验
CI0 = (tz - m)/(m - 1);
CR0 = CI0/RI(m);
W0 = zeros(m, 1);
if CR0 < 0.1
for i = 1:m
W0(i, 1) = C(i, 1)/sum(C(:, 1)); %特征向量标准化
end
disp('W0:');
disp(W0);
disp('此矩阵一致性可以接受。');
else
disp('此矩阵一致性不可以接受。');
disp('即将进行修正');
a = correction(a, m);
[tz, C] = get_feature(a);
CI0 = (tz - m)/(m - 1);
CR0 = CI0/RI(m);
W0 = zeros(m, 1);
for i = 1:m
W0(i, 1) = C(i, 1)/sum(C(:, 1)); %特征向量标准化
end
disp(eval(char(["'", 'W', num2str(i), "'"])));
disp(W1(:, i));
disp('修正完毕');
end
% 对方案层
disp('方案层:');
W1= zeros(n, m);
for i = 1:m
[tz, C] = get_feature(eval(char(['b', num2str(i)])));
CI1 = (tz - n)/(n - 1);
CR1(i) = CI1/RI(n);
if CR1(i) < 0.1
W1(:, i) = zeros(n, 1);
for j = 1:n
W1(j, i) = C(j, 1)/sum(C(:, 1)); %特征向量标准化
end
disp(eval(char(["'", 'W', num2str(i), "'"])));
disp(W1(:, i));
disp('此矩阵一致性可以接受。');
else
disp('此矩阵一致性不可以接受。');
disp('即将进行修正');
switch i
case 1
b1(:, :) = correction(b1, n);
case 2
b2(:, :) = correction(b2, n);
case 3
b3(:, :) = correction(b3, n);
case 4
b4(:, :) = correction(b3, n);
case 5
b5(:, :) = correction(b3, n);
case 6
b6(:, :) = correction(b3, n);
case 7
b7(:, :) = correction(b3, n);
case 8
b8(:, :) = correction(b3, n);
case 9
b9(:, :) = correction(b3, n);
case 10
b10(:, :) = correction(b3, n);
end
[tz, C] = get_feature(eval(char(['b', num2str(i)])));
CI1 = (tz - n)/(n - 1);
CR0 = CI1/RI(n);
W1(:, i) = zeros(n, 1);
for j = 1:n
W1(j, i) = C(j, 1)/sum(C(:, 1)); %特征向量标准化
end
disp(eval(char(["'", 'W', num2str(i), "'"])));
disp(W1(:, i));
disp('修正完毕');
end
end
disp(W1);
% 结果
ts = W1 * W0;
CR = CR1 * W0;
disp('CR:');
disp(CR);
disp('最终方案层的权重:');
disp(ts);
function [tz, C] = get_feature(a)
% 求特征向量和最大特征值
[V, D] = eig(a); %获取特征值V,特征向量D
tz = max(diag(D)); %最大特征值
[~, col] = find(D == tz); %寻找最大特征值的位置
C = V(:, col); %对应特征向量
end
function A = correction(a, m)
% 判断矩阵一致性修正
% a:判断矩阵
% m:判断矩阵维数
b = a;
[~, C] = get_feature(a);
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]; % 一致性修正参数
while 1
% 列向量归一化
for i = 1:m
for j = 1:m
b(j, i) = a(j, i)/sum(a(:, i));
end
end
% 寻找最小夹角余弦(最大误差的列)
min = 1; % 存储最小夹角余弦
r = 1;
for i = 1:m
tmp = dot(C, b(:, i))/abs((norm(b(:, i)) * norm(C)));
if tmp < min
min = tmp;
r = i;
end
end
% 修正值
lambda = 0.95; % 经验数值,0.9-1之间最好
% 列
for i = 1:m
a(i, r) = a(i, r).^lambda * (C(i)/C(r)).^(1-lambda);
end
% 行
for j = 1:m
a(r, j) = a(r, j).^lambda * (C(r)/C(j)).^(1-lambda);
end
% 验证
[tz, C] = get_feature(a);
CI = (tz - m)/(m - 1);
CR = CI/RI(m);
disp(CR);
if CR < 0.1
A = a;
break
end
end
end
data.txt文件内容:
1 1/2 4 3 3
2 1 7 5 5
1/4 1/7 1 1/2 1/3
1/3 1/5 2 1 1
1/3 1/5 3 1 1
1 2 5
1/2 1 2
1/5 1/2 1
1 1/3 1/8
3 1 1/3
8 3 1
1 1 3
1 1 3
1/3 1/3 1
1 3 4
1/3 1 1
1/4 1 1
1 1 1/4
1 1 1/4
4 4 1
运行结果: