b站大学  链接:https://www.bilibili.com/video/BV1p14y1U7Nr/?spm_id_from=333.337.search-card.all.click

层次分析法

介绍

矩阵的一致性

不一致 a12=2  a13=5   (预计)a23=a21 x a13 = 5/2

实际上 a23 = 2  矛盾  ---->矩阵不一致

一致:aij * ajk = aik

性质:

  • 1.A的秩1,A的唯一非零特征根为n;
  • 2.A的任一列向量都是对于特征根n的特征向量.

用来检查判断矩阵“矛盾”的问题,所以在使用判断矩阵之前要先检验其一致性

一致性检验方法

权重的计算方法:

1.对于一致性矩阵  只需要算一列的就行

非一致性矩阵  需要算每一列 然后求平均值

对于判断矩阵A ,先将其归一化,再将其归一化,再将归一化的矩阵案列相加,并将每个元素除以n得到权重向量,即

2.特征值法求权重  (更常用)

根据A  计算特征值和特征向量 然后用CR 通过一致性检验   然后α 是最大特征值对应的特征向量  归一化成ω

最后一步:

层次总排序的一致性检验

用层次分级法的套路

解决评价类问题

  1. 画出层级结构图(目标层,准则层,方案层)
  2. 构造判断矩阵
  3. 依照评价指标对各个方案进行打分
  4. 求出权重,填表,求得最后得分
  5. 层次总排序一致性检验

实践

Mathlab的基本用法

a = 1;   (有;不输出语句  没有;会结果)

注释/取消注释:ctrl + R(ctrl + T)

clear清除工作区的所有变量

clc  清屏   ( 常用的用法:clear;clc)

输出 输入函数  disp  和 input  disp('输出的内容')  disp(变量)

if 判断语句

% 判断语句
a = input('请输入考试分数:'); % 获取输入,input 函数在 MATLAB 里获取数值输入可直接用于后续数值比较
if a >= 85
    disp('成绩优秀')
elseif a >= 60
    disp('成绩合格')
else
    disp('成绩挂科')
end

字符串:   合并字符串:  strcat(str1,str2,...,strn)   或者 [str1,str2,...,strn]  或者 [str1  str2   ...   strn]

转换字符串:num2str()    在disp中必须要把数字转成字符串才能正常输出

sum求和函数  E  =  [1,2,3] (行向量)   a = sum(E)   E[1;2;3]列向量    sum(E,1)默认按列求和   sum(E,2)   则为按行求和

全部求和(2种方法)sum(sum(E))   或者  sum(E(:))

模糊综合评价

模糊集合的隶属函数

确定各因素的权重

对于权重的确定方法,如果题目没有给出数据则用层次分析法,如果给出了数据则用熵权法的TOPSiS,
(这个方法我们下一讲学习)也可以不确定权重.

一级模糊综合评价

评语集带有评价色彩型

评语集不带有评价色彩型

多级模糊综合评价

模糊综合评价总结

  1. 解决评价类问题
  2. 确定因素集(如果因素过多可考虑用多级,可以用主成分分析法,确定各因素权重,注意每一级权重之和为1)
  3. 确定评语集(有无评价色彩)
  4. 从最后一层开始主机确定每级因素对评语集的隶属度(逐级打分)
  5. 根据隶属度确定相关评语(注意画图)

熵权法

步骤:

第一步:正向化处理

极小型转极大型  max-x  或者(1/x)(x>0)

中间型转极大型 M = max(|xi - xmax|)  再令xi转化后的结果 = 1- (xi - xbest)/M

区间型转 极大值

xi  最佳区间为[a,b]  可以这样正向化

M = max{a-min(xi),max(xi)-b},再令各元素xi转化后的结果

第二步 标准化处理

第三步:计算信息熵和熵权

TOPSIS

优劣解距离法-介绍

正向化 标准化

指标正向化

标准化

用优劣解打分

熵权法 + TOPSIS练习

题目:

思路整理:

  1. 正向化
  2. 标准化
  3. 归一化
  4. 熵权法
  5. TOPSIS练习

我的代码仅供参考

% 熵权法 Entropy.m
w = [];  % 最后储存的结果
X = [];  % 从blind date.xlsx中读取
X = readmatrix("blind date.xlsx");
X = X(:,2:end);

lst = input("请输入要正向化处理的数据的列数,比如[1,2,3]:");

function [res] = Min2Max(X)
    res = max(X)-X;
end

function [res] = Mid2Max(X,best)
    maxNum = max(abs(X-best));
    res = 1 - (abs(X-best))/maxNum;
end

function [res] = int2Max(X, a, b)
    % 检查输入是否为列向量
    if size(X, 2) > 1
        X = X(:); % 转换为列向量
    end
  
    % 初始化结果向量
    res = zeros(size(X));
    
    % 计算每个元素到区间的距离
    for i = 1:length(X)
        if X(i) < a
            % 元素在区间左侧,距离为 a - X(i)
            res(i,1) = a - X(i,1);
        elseif X(i) > b
            % 元素在区间右侧,距离为 X(i) - b
            res(i,1) = X(i,1) - b;
        else
            % 元素在区间内,距离为 0
            res(i,1) = 0;
        end
    end
    
    % 计算最大距离
    M = max(res);
    
    % 避免除零错误
    if M > 0
        % 正向化转换:距离越大,得分越低
        res = 1 - res / M;
    else
        % 所有元素都在区间内,直接返回全1向量
        res = ones(size(X));
    end
end                              

lst_size = size(lst);

% 正向化
for i=1:lst_size(1,2)
    flag1 = input(sprintf("请输入第%d列的类型 极小型为1 中间型为2 区间型为3:",lst(i)));
    if flag1 == 1
        X(:,lst(1,i)) = Min2Max(X(:,lst(1,i)));
    elseif flag1 == 2
        best = input("请输入中间型最合适的值:");
        X(:,lst(1,i)) = Mid2Max(X(:,lst(1,i)),best);
    elseif flag1 == 3
        arr= input("请输入区间 比如[1,2]:");
        X(:,lst(1,i)) = int2Max(X(:,lst(1,i)),arr(1),arr(2));
    end
end

disp("转换完成");

% 标准化(消除量纲)
X_row = size(X,1);
X_col = size(X,2);
X_pow = X .^ 2;
X_pow_sum = sum(X_pow);
X_pow_2 = X_pow_sum .^ 0.5;
X = X ./ repmat(X_pow_2,X_row,1);

% 归一化
res2 = X./repmat(sum(X),X_row,1);

% 计算熵值
% ln0 没有定义需要指定一个接近0的值
for i=1:X_row
    for j=1:X_col
        if (res2(i,j)==0)
            res2(i,j)=0.00001;
        end
    end
end

res3 = log(res2);
sum2 = sum(-res2 .* res3);
e = sum2 * (1/log(X_row));
d = 1-e;
w = d ./ repmat(sum(d),1,X_col);

w

下面是求解过程 其中w为上一个的权重

% Topsis.m
% 初始化权重变量
w = [];
% 从 Excel 文件读取数据(需确保文件路径正确,且文件存在)
X = readmatrix("blind date.xlsx");
% 截取从第 2 列开始的数据(去掉可能的标识列)
X = X(:, 2:end);

% 让用户输入需要正向化处理的列数
lst = input("请输入要正向化处理的数据的列数,比如[1,2,3]: ");

% 极小型指标转极大型函数
function [res] = Min2Max(X)
    res = max(X) - X;
end

% 中间型指标转极大型函数
function [res] = Mid2Max(X, best)
    maxNum = max(abs(X - best));
    res = 1 - (abs(X - best)) / maxNum;
end

% 区间型指标转极大型函数
function [res] = int2Max(X, a, b)
    % 检查输入是否为列向量,若不是则转换为列向量
    if size(X, 2) > 1
        X = X(:); 
    end
    % 初始化结果向量
    res = zeros(size(X));
    % 遍历计算每个元素到区间的距离
    for i = 1:length(X)
        if X(i) < a
            % 元素在区间左侧,距离为 a - X(i)
            res(i, 1) = a - X(i, 1);
        elseif X(i) > b
            % 元素在区间右侧,距离为 X(i) - b
            res(i, 1) = X(i, 1) - b;
        else
            % 元素在区间内,距离为 0
            res(i, 1) = 0;
        end
    end
    % 计算最大距离
    M = max(res);
    % 避免除零错误,进行正向化转换
    if M > 0
        res = 1 - res / M;
    else
        % 所有元素都在区间内,直接返回全 1 向量
        res = ones(size(X));
    end
end

% 获取输入列数向量的尺寸
lst_size = size(lst);
% 正向化处理循环
for i = 1:lst_size(1, 2)
    % 让用户输入每列的指标类型
    flag1 = input(sprintf("请输入第%d列的类型 极小型为1 中间型为2 区间型为3: ", lst(i)));
    if flag1 == 1
        % 极小型转极大型处理
        X(:, lst(1, i)) = Min2Max(X(:, lst(1, i)));
    elseif flag1 == 2
        % 中间型转极大型处理,需输入最合适值
        best = input("请输入中间型最合适的值: ");
        X(:, lst(1, i)) = Mid2Max(X(:, lst(1, i)), best);
    elseif flag1 == 3
        % 区间型转极大型处理,需输入区间
        arr = input("请输入区间 比如[1,2]: ");
        X(:, lst(1, i)) = int2Max(X(:, lst(1, i)), arr(1), arr(2));
    end
end
disp("转换完成");

% 标准化处理(消除量纲影响)
X_row = size(X, 1);
X_col = size(X, 2);
X_pow = X .^ 2;
X_pow_sum = sum(X_pow);
X_pow_2 = X_pow_sum .^ 0.5;
X = X ./ repmat(X_pow_2, X_row, 1);

% 基于熵权法的 TOPSIS 优劣解距离法
XStandard = X;
% 求每一列的最大值
X_max = max(XStandard, [], 1); 
% 求每一列的最小值
X_min = min(XStandard, [], 1); 

% 询问是否考虑指标权重
is_w_true = input("是否考虑各个指标的权重,考虑按1,不考虑按0: ");

if is_w_true == 1
    % 考虑权重且权重未设置时,让用户输入权重
    if isempty(w)
        w = input("请输入权重: ");
    end
else
    % 不考虑权重时,权重设为全 1 矩阵
    w = ones(X_row, X_col);
end

% 计算到正理想解的距离 d2
d2 = repmat(X_max, X_row, 1);
d2 = (d2 - X) .^ 2;
d2 = d2 .* repmat(w, X_row, 1);
d2 = sum(d2, 2);
d2 = d2 .^ 0.5;

% 计算到负理想解的距离 d3
d3 = repmat(X_min, X_row, 1);
d3 = (d3 - X) .^ 2;
d3 = d3 .* repmat(w, X_row, 1);
d3 = sum(d3, 2);
d3 = d3 .^ 0.5;

% 计算贴近度 s
s = d3 ./ (d2 + d3);
s = s ./ sum(s);
% 输出最终结果
s

灰色关联分析

  1. 先进行数据预处理、正向化、标准化;
  2. 确定母序列和子序列,如果有多个母序列则需要分别进行灰色关联分析;
  3. 将母序列与子序列两两相减,并计算两级最小差和两极最大差:
  4. 对每个元素计算灰色关联系数了,注意这里p一般取值为0.5;
  5. 将各指标的灰色关联系数求平均值作为灰色关联度;
  6. 根据灰色关联度大小下结论

线性规划

[x,val] = linprog(f,A, b, Aeq, beq, lb, ub);
符号 / 表达式 含义说明
f 目标函数的系数列向量
A,b 不等式的系数矩阵和常数向量
Aeq, beq 等式的系数矩阵和常数向量
lb, ub 决策变量的最小值和最大值
x 取得目标函数最小值时 x 的取值
val 目标函数的最小值
[] 如果不存在某项约束则在对应位置填 []
+inf-inf 若某个 x 无上下界则在对应矩阵上填此项

整数规划

[x,val] = intlinprog(f,intcon,A, b, Aeq, beq, lb, ub);

intcon=[1,2];%x1和x2限定为整数

苏州大学软件工程专业—希望提升自己算法水平
最后更新于 2025-07-06