数学建模 1 层次分析法(上机篇)

学习资源声明:大师兄数学建模 第二讲 层次分析法

通过学习,加以个人思考整理得此篇笔记,含大量实操图片记录。


1 MATLAB基础操作语句(实用版)

快速查询网站:MATLAB命令快速查询网站     我们只需要掌握基本的语法即可,在实际比赛和科研中,即查即用,养成查工具资料和帮助文档的习惯。

1.变量赋值

x = 5;  % 给变量x赋值5
y = 'Hello';  % 给变量y赋值字符串'Hello'

2.矩阵创建

A = [1 2 3; 4 5 6; 7 8 9];  % 创建一个3x3的矩阵

3.基本数学运算

result = 2 * x + y;  % 执行数学运算

4. 条件语句

if x > 10
    disp('x is greater than 10');
elseif x == 10
    disp('x is equal to 10');
else
    disp('x is less than 10');
end

5.循环

  • for循环
for i = 1:5
    disp(i);
end
  • while循环
i = 1;
while i <= 5
    disp(i);
    i = i + 1;
end

6.函数定义

function y = myFunction(x)
    y = x^2;  % 定义一个简单的函数,返回x的平方
end

7.绘图

x = 0:0.1:10;  % 创建一个向量
y = sin(x);     % 计算x的正弦值
plot(x, y);     % 绘制x和y的图形

8.文件读写

  • 写入文件
data = [1 2; 3 4; 5 6];
writematrix(data, 'filename.txt');
  • 读取文件
data = readmatrix('filename.txt');

9.使用MATLAB内置函数

sumData = sum(A);  % 计算矩阵A的元素总和
meanData = mean(A);  % 计算矩阵A的元素平均值

10.注释

% 这是单行注释
% 你可以在这行注释中写多行文本

alternative versions:

%% Matlab常用操作
% (1)赋值语句
a = 1;
a = 2

% % (2)多行注释,选中语句,快捷键Ctrl+R
% a = 1;
% a = 2

% (3)取消注释:选中语句,快捷键Ctrl+T

% 清除工作区的所有变量
clear

% 清屏
clc

% 这两条一起使用,起到“初始化”的作用
clear;clc   % 分号也用于区分行。


%% 输出和输入函数(disp 和 input)
% disp函数
disp('大家好,我是大师兄,欢迎一键三连')
a = [1,2,3]    %矩阵的同一行中间用逗号或空格分隔
a = [1 2 3]    %空格分隔
disp(a) 

%% 判断语句
a = input('请输入考试分数:')
if a >= 85  
    disp('成绩优秀')
elseif a >= 60 
    disp('成绩合格')
else
    disp('成绩挂科')
end

%% 字符串
% 合并几个字符串
% (1)方法一:strcat(str1,str2……,strn) 
 strcat('字符串1','字符串2') 
% (2)方法二:[str 1,str 2,……, str n]或[str1  str2  ……  strn]
['字符串1'  '字符串2']
['字符串1','字符串2']
% 转换字符串
c = 100
num2str(c)
disp(['c的取值为' num2str(c)])
disp(strcat('c的取值为', num2str(c)))

%% sum求和函数
% (1)如果是向量(无论是行向量还是列向量),都是直接求和
E = [1,2,3]
sum(E)
E = [1;2;3]
sum(E)
% (2)如果是矩阵,则需要指明是按行还是按列求和
clc
E = [1,2;3,4;5,6]
a = sum(E)
a = sum(E,1)%按列求和(得到一个行向量)
a = sum(E,2)%按行求和(得到一个列向量)
%对整个矩阵求和
a = sum(sum(E))
a = sum(E(:))

%% 矩阵的查询
% (1)取指定行和列的一个元素(输出的是一个值)
A=[1 2 5; 1/2 1 2; 1/5 1/2 1];
A
A(2,1)
A(3,2)
% (2)取指定的某一行的全部元素(返回的是一个行向量)
A(1,:)
A(2,:)
% (3)取指定的某一列的全部元素(返回的是一个列向量)
A(:,1)
A(:,3)
% (4)取指定的某些行的全部元素(返回的是一个矩阵)
A([1,3],:)      % 只取第一行和第三行
A(1:3,:)        % 取第一行到第三行
A(1:2:3,:)     % 取第一行和第三行 (从一开始,每次递增2个行,到3结束)
% 递增语法
1:3:10
10:-1:1
A(1:end,:)      % 取第一行到最后一行
A(1:end-1,:)    % 取第一行到倒数第二行

% (5)取全部元素(按列拼接的,最终输出的是一个列向量)
A(:)

%% size函数
clc;
A = [1,2,3;4,5,6]
B = [1,2,3,4,5,6]
size(A)
size(B)
% size(A)函数是用来求矩阵A的大小的,它返回一个行向量,第一个元素是矩阵的行数,第二个元素是矩阵的列数
[r,c] = size(A)
% 指定返回行数或列数
r = size(A,1)  %返回行数
c = size(A,2) %返回列数

%% repmat函数
% B = repmat(A,m,n):将矩阵A复制m×n块,即把A作为B的元素,B由m×n个A平铺而成。
% 就是先创建一个m×n的矩阵,然后把A作为元素填充进去
A = [1,2,3;4,5,6]
B = repmat(A,2,1)
B = repmat(A,3,2)

%% 矩阵的运算
% MATLAB在矩阵的运算中,“*”号和“/”号代表矩阵之间的乘法与除法(A/B = A*inv(B))
A = [1,2;3,4]
B = [1,0;1,1]
A * B
inv(B)  % 求B的逆矩阵
B * inv(B)
A * inv(B)
A / B

% 两个形状相同的矩阵对应元素之间的乘除法需要使用“.*”和“./”
A = [1,2;3,4]
B = [1,0;1,1]
A .* B
A ./ B

% 每个元素同时乘或除相同的倍数
A = [1,2;3,4]
A * 2
A .* 2
A / 2 
A ./ 2

% 每个元素同时乘方时只能用 .^
A = [1,2;3,4]
A .^ 2 %将各个元素平方
A ^ 2 
A * A

%% 求特征值和特征向量
A = [1 2 3 ;2 2 1;2 0 3]
% 求矩阵A的全部特征值,返回一个由特征值构成的向量
E=eig(A)
% 求矩阵A的全部特征值,构成对角阵D,并求A的特征向量构成V的列向量。(V的每一列都是D中与之相同列的特征值的特征向量)
[V,D]=eig(A)

2 对例题的MATLAB求解过程

2.1 获取判断矩阵

disp('请输入判断矩阵A')
A=input('A=');
[n,n] = size(A);

在这里我们输入上一篇文章需要处理的数据:

(上一篇文章链接:数学建模 1 层次分析法

查看我们输入的矩阵A(见下图),即上述4个矩阵中的第一个。很明显,我们这个矩阵不满足我们一致矩阵的条件(详见上篇),我们需要进行一次性检验。这里为方便讲解(要使用解题方法),我们将一次性检验放在后面详细说明。

2.2 法一:算术平均法求权重

Sum_A = sum(A); %将A矩阵按列求和
SUM_A = repmat(Sum_A,n,1);
Stand_A = A ./ SUM_A;

disp('算术平均法求权重的结果为:');
w1 = sum(Stand_A,2)./n;
disp(w1)

参考算术平均法的讲解方法,我们需要计算每一列的权重(第一行代码);第二行代码,使用repmat函数将Sum_A重复n次,形成一个新的矩阵SUM_Arepmat函数的用法是repmat(A, m, n),表示将矩阵A沿着第一个维度(行)重复m次,沿着第二个维度(列)重复n次。第三行代码,将矩阵A的每一列元素除以相应的SUM_A中的元素,得到标准化后的矩阵Stand_A。这里的.表示元素级的除法。  这三行代码就完成了我们下面计算每一行权重并且得到算术平均值的全部计算。

得到结果如下:(右侧工作区内容在自己操作的时候点开可以看到每一个过程量的具体值!)

2.3 法二:特征值法求权重

[V,D] = eig(A);
Max_eig = max(max(D));% 先按列求最大值,得到行向量,再从这个向量里面求最大值
[r,c]=find(D == Max_eig , 1);
disp('特征值法求权重的结果为:');
w2 = V(:,c) ./ sum(V(:,c));
disp(w2)
disp('两种方法的平均权值为:');% 将我们刚才用算术平均法求得权重与用特征值法求的权重取平均值
disp((w1 + w2) ./ 2);

附上原理:

代码详解看这里(逐行讲解):

1 使用eig函数计算矩阵A特征值特征向量。函数返回两个输出:V是包含特征向量的矩阵,D是对角矩阵,其对角线上的元素是对应的特征值。

2 首先使用max函数按列求矩阵D最大值,得到一个行向量,然后再次使用max函数在这个行向量中找到最大值,即最大特征值,并将其存储在变量Max_eig中。

3 使用find函数查找矩阵D中等于Max_eig的最大特征值的位置。这里使用第二个参数1表示只返回第一个匹配项的索引。

4 显示提示信息,表示接下来将显示特征值法求得的权重。

5 计算特征向量V中对应于最大特征值的特征向量(即第c列),然后将其每个元素除以该特征向量的和,得到权重向量w2

6 ~ 8 (用于输出结果的都很容易懂)

得到结果如下:

2.4 计算一致性比例CR

CI = (Max_eig - n) / (n-1);
RI=[0 0.0001 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];  %这里的RI最多支持 n = 15,注意检查!
% 这里n=2时,RI=0,我们为了避免分母为0,将这里的第二个元素改为了很接近0的正数
CR=CI/RI(n);
disp('最大特征值为:');
disp(Max_eig);
disp('一致性指标CI=');disp(CI);
disp('一致性比例CR=');disp(CR);
if CR<0.10
    disp('CR<0.10,该判断矩阵A的一致性可以接受!');
else
    disp('注意:CR >= 0.10,该判断矩阵需要进行修改!');
end

附上原理:

代码详解看这里(逐行讲解):

1 计算一致性指标CI。CI的计算公式是:CI=\frac{Max eig-n}{n-1}。这里Max_eig是矩阵的最大特征值,n是矩阵的阶数(即行数或列数)。

2 定义随机一致性指标(Random Index, RI)数组。这个数组包含了不同阶数的随机一致性指标的值。由于这里只提供了到15阶的RI值,所以注释中提到“这里的RI最多支持 n = 15”。

3 注释见上

4 计算一致性比例CR。CR的计算公式是:CR=\frac{CI}{RI(n)}。这里CI是一致性指标,RI(n)是与矩阵阶数n对应的随机一致性指标的值。

5~13 用于输出,加以if语句做了一个简单的判断


3 处理结果汇总&Execl汇总计算

运行以上程序,输入下面这四个矩阵的数据。

得到运行结果如下:

最后来处理一下我们的权重指标的判断矩阵:

将信息汇入我们的Excel表格中:

回顾一下我们的计算公式:

这个处理的时候可以直接使用我们的Excel公式!

=$B$2*C2+$B$3*C3+$B$4*C4+$B$5*C5

处理完这一格之后然后我们往后拉即可。

得到如下:


4 代码汇总

MATLAB代码:

disp('请输入判断矩阵A')
A=input('A=');
[n,n] = size(A);
Sum_A = sum(A); %将A矩阵按列求和
SUM_A = repmat(Sum_A,n,1);
Stand_A = A ./ SUM_A;

disp('算术平均法求权重的结果为:');
w1 = sum(Stand_A,2)./n;
disp(w1)

[V,D] = eig(A);
Max_eig = max(max(D));% 先按列求最大值,得到行向量,再从这个向量里面求最大值
[r,c]=find(D == Max_eig , 1);
disp('特征值法求权重的结果为:');
w2 = V(:,c) ./ sum(V(:,c));
disp(w2)
disp('两种方法的平均权值为:');
disp((w1 + w2) ./ 2);

CI = (Max_eig - n) / (n-1);
RI=[0 0.0001 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];  %这里的RI最多支持 n = 15,注意检查!
% 这里n=2时,RI=0,我们为了避免分母为0,将这里的第二个元素改为了很接近0的正数
CR=CI/RI(n);
disp('最大特征值为:');
disp(Max_eig);
disp('一致性指标CI=');disp(CI);
disp('一致性比例CR=');disp(CR);
if CR<0.10
    disp('CR<0.10,该判断矩阵A的一致性可以接受!');
else
    disp('注意:CR >= 0.10,该判断矩阵需要进行修改!');
end

输入的矩阵数据:

[1 2 5; 1/2 1 2; 1/5 1/2 1]

[1 1 3; 1 1 2; 1/3 1/2 1]

[1 2 3; 1/2 1 2; 1/3 1/2 1]

[1 3 5; 1/3 1 4; 1/5 1/4 1]

[1 1/2 4 3; 2 1 5 5; 1/4 1/5 1 1/4; 1/3 1/5 4 1]

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值