分为最高层、中间层(可以有多层)和最底层。
最高层:决策目的,要解决的问题中间层:考虑的因素,决策准则最底层:决策的备选方案打分依据(两两比较打分,来减少主观的影响):
打分程度1同样重要3稍微重要5明显重要7强烈重要9极端重要2,4,6,8处于对应程度中间单排序,对应于中间层对最高层的判断矩阵(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 为 修正因子,具体数值为
矩阵阶数123456789101112131415RI000.520.891.121.261.361.411.461.491.521.541.561.581.59若 R I < 0.1 RI < 0.1 RI<0.1,那么说明该矩阵一致性可以接受
总排序,对应于最底层对于中间层(一般有多个) 排序:见程序 一致性检验:
C R = c r ∗ w 0 CR = cr * w0 CR=cr∗w0
cr:该层每个判断矩阵的CR组成的矩阵 w0:矩阵对应的决策项权重的矩阵(步骤三排序结果)
在一致性检验时,如果一致性检验通过,则直接计算权重,如果一致性检验未通过,则需修正判断矩阵后才计算权重。 修正方式参考论文:[点击这里](https://wenku.baidu.com/view/147d31315a8102d276a22f18.html)
根据景色、费用、居住、饮食、旅途等条件从三个景点中选取最佳的一个
构建层次结构模型 选择一个目的地 景色 a1 费用 a2 居住 a3 饮食 a4 旅途 a5 目的地1 b1 目的地2 b2 目的地3 b3 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 enddata.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运行结果: