层次分析法

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

层次分析法(AHP)

层次分析法(The analytic hierarchy process),主要用于解决数学建模中评价类问题。

评价类问题是数学建模中较为常见的一类问题,解决这一类问题的途径有很多,但我认为最简单而又高效的方式是以“评分”来解决。

但是评分的标准是什么呢?又该以怎样的方式评分?这就引申出了这一关键算法——层次分析法。

层次分析法的步骤:

Step 1:分析系统中各因素之间的关系,建立系统的“递阶层次结构”

逻辑图演示
这里需要说明的是,不同问题中,对于某一方案,对于决定的它的影响因素的个数可能是不一样的

例如上图,影响方案1的因素有因素1,2,3…,但是影响方案2的因素只有因素1,3…,以此类推。

但是解决办法的核心思想是一致的,不一样只是最后求“总得分”的方式。

Step 2:对于同一层次的各元素关于上一层次中某一准则的重要性,进行两两比较,构造“判断矩阵”

在这一步骤中,我们需要思考,如何确定“对于同一层次的各元素”关于“上一层次中某一准则”的重要性,这里就要引入标度的概念。

“分而治之”的思想

问题:一次性考虑N个指标之间的关系,往往考虑不周
解决方法:每两个指标进行比较,最终根据两两比较的结果推算最终权重
标度图
进行全部的比较之后,便可以得到这样一个矩阵:
判断矩阵
我们称这样的矩阵为判断矩阵,不难看出,这是一个“n×n”的方阵,记为A,对应元素为aij

判断矩阵的特点:

1、aij表示的意义是,与j指标相比,i的重要程度;
2、当i=j时,两个指标相同,因而一样重要,记为1;
3、aij>0且满足aij×aji=1。

Matlab中的代码实现:

%判断矩阵
%判断一个矩阵是否为判断矩阵 正互反矩阵

a=0;   %初始化矩阵的行数
b=0;   %初始化矩阵的列数
a=input('请输入矩阵的行数:');
b=input('请输入矩阵的列数:');

if(a ~= b)
        disp('不是判断矩阵!');
else
        %初始化判断矩阵
        c=zeros(a,b);
        c=input('请依次输入矩阵的元素:');
       
        k=0;
        for i=1:a
            for j=1:a
                if(c(i,j) ~= c(j,i))
                    k=1;
                end
            end
        end  
        
        if(k==0)
            disp('是判断矩阵!');
        else
            disp('不是判断矩阵!');
        end   
end

Step 3:根据判断矩阵计算被比较元素对于该准则的相对权重,并进行一致性检验(一致性检验合格后,所求权重才可使用)

这里我们先引入一致矩阵的概念:
若判断矩阵满足aij×ajk=aik,则我们称其为“一致矩阵”

例如:
非一致矩阵
一致矩阵
可以发现,一致矩阵的每一行(列)的元素成比例
(在实际的数学建模中,我们往往是以此来判断是否为“一致矩阵”)。

Matlab中的代码实现:

%一致矩阵
%判断一个“判断矩阵”是否为“一致矩阵”

a=0;
a=input('请输入判断矩阵的阶数:');

b=zeros(a,a);
b=input('请依次输入判断矩阵的每个元素:');

%判断变量 设定初始值为0
c=0;

% Step1 a(ij)>0
for i=1:a
    for j=1:a
        if(b(i,j) <= 0)
            c=1;
        end
    end
end

% Step2 a(11)=a(22)=...a(nn)=1
for i=1:a
    if(b(a,a) ~= 1)
        c=1;
    end
end

% Step3 [a(i1),a(i2)...a(in)]=k[a(11),a(22)...a(nn)]
for i=1:(a-2)
    d=b(i,1)/b(i+1,1);
    e=b(i+1,1)/b(i+2,1);
    if(d ~= e)
        c=1;
    end
end

if(c==0)
    disp('该判断矩阵为一致矩阵!');
else
    disp('该判断矩阵不是一致矩阵!');
end
一致性检验的步骤:

一致性检验步骤

注:

1、λmax是判断矩阵的最大特征值;

2、n是判断矩阵的迹;

Matlab中的代码实现:

%一致性检验
%一致矩阵为方阵“ 且r(A)=1” “ A有一个特征值为tr(A)” “ 其余全为0%前提准备
a=0;
a=input('请输入判断矩阵的阶数:');

b=zeros(a,a);
b=input('请输入判断矩阵的各个元素:');

% 计算判断矩阵的最大特征值
[x,y]=eig(b);
z=diag(y);
m=max(z);

%计算矩阵的迹 即tr(A) 函数trace(A)
t=trace(b);


%正式步骤 

%Step1 计算“一致性指标 CI”
CI=(m-t)/(t-1);

%Step2 查找对应的“平均随机一致性指标RI”
if t==1
    RI=0;
    
elseif t==2
    RI=0;
    
elseif t==3
    RI=0.52;
    
elseif t==4
    RI=0.89;
    
elseif t==5
    RI=1.12;
    
elseif t==6
    RI=1.26;
    
elseif t==7
    RI=1.36;
    
elseif t==8
    RI=1.41;
    
elseif t==9
    RI=1.46;
    
elseif t==10
    RI=1.49;
    
elseif t==11
    RI=1.52;
    
elseif t==12
    RI=1.54;
    
elseif t==13
    RI=1.56;
    
elseif t==14
    RI=1.58;
    
elseif t==15
    RI=1.59;
end

%Step3 计算一致性比例“CR” CR=CI/RI
CR=CI/RI;


if(CR<0.1)
    disp('一致性比例CR:');
    disp(CR);
    disp('一致性可以接受');
else
    disp('一致性比例CR:'); 
    disp(CR);
    disp('判断矩阵偏差过大,需要修改!');
end
如果判断矩阵的CR偏大,该如何修改呢?

答:根据“一致矩阵”的定义,修改个别数据。

计算“一致矩阵”中的权重:

例如:
一致矩阵中的计算权重
Matlab中的代码实现:

%计算一致矩阵的权重
%进行归一化处理便可实现

a=0;
a=input('请输入一致矩阵的阶数:');

b=zeros(a,a);
b=input('请输入一致矩阵的各个元素:');

%原则上任何一行/列都可以实现
%我这里用第一列
s=0;
for i=1:a
    s=s+b(i,1);
end

for i=1:a
    c(i)=b(i,1)/s;
end

计算“判断矩阵”中的权重:

这里以这样的一个矩阵为例子:
判断矩阵

方法1:算术平均法

Step1. 将判断矩阵按照列(行)进行归一化(每一个元素除以其所在列(行)的和);

Step2. 将归一化的各列相加(按行求和);

Step3. 将相加后得到的向量中每个元素除以n即可以得到权重。

例如:
方法1
Matlab中的代码实现:

%计算判断矩阵的权重

%第一种方法 “算术平均法求权重”

%分别根据第1-n列/行的权重,求平均值。

a=0;
a=input('请输入判断矩阵的阶数:');

b=zeros(a,a);
b=input('请输入判断矩阵的各个元素:');

%Step1 计算每一列的总和
for i=1:a
    c(i)=0;
    for j=1:a
        c(i)=c(i)+b(j,i);
    end
end

%Step2 计算每一列的权重
for i=1:a
    for j=1:a
        d(j,i)=b(j,i)/c(i);
    end
end

%Step3 计算算术平均权重
for i=1:a
    e(i)=0;
    for j=1:a
        e(i)=e(i)+d(i,j);
    end
    f(i)=e(i)/a;
end
方法2:几何平均法

Step1. 将判断矩阵的元素按照行相乘得到一个新的列向量;

Step2. 将新的向量每个分量开n次方;

Step3. 对该列向量进行归一化即可得到权重向量。

例如:
方法2
Matlab中的代码实现:

%计算判断矩阵的权重

%第二种方法 几何平均法求权重

a=0;
a=input('请输入判断矩阵的阶数:');

b=zeros(a,a);
b=input('请输入判断矩阵的各个元素:');

%Step1 将A的元素按照行相乘得到一个新的列向量
for i=1:a
    c(i)=1;
    for j=1:a
        c(i)=b(i,j)*c(i);
    end
end

%Step2 将新的列向量的每个分量开n次方 (n为A的阶数)
for i=1:a
    c(i)=power(c(i),1/a);
end

%Step3 进行归一化处理
s=0;
for i=1:a
    s=c(i)+s;
end

for i=1:a
    d(i)=c(i)/s;
end
方法3:特征值法

Step1. 求出判断矩阵的特征向量;

Step2. 对求出的特征向量进行归一化处理即可得到权重向量。

例如:
方法3
Matlab中的代码实现:

%计算判断矩阵的权重

%第三种方法 特征值法求权重(使用最多)

a=0;
a=input('请输入判断矩阵的阶数:');

b=zeros(a,a);
b=input('请输入判断矩阵的各个元素:');

%Step1 求出A对应的特征向量
[x,y]=eig(b);
%x为对应的特征向量 y为对应的特征值

%Step2 对求出的特征向量进行归一化处理
s=0;
for i=1:a
   s=s+x(i);
end

for i=1:a
    t(i)=x(i)/s;
end
对比3种方法求得的结果:

对比结果

Step 4:计算各层元素元素对系统目标的合成权重,并进行排序

将最终所得的结果填入表中,然后进行“算分”,便实现了用“层次分析法”实现评价问题。

例如:
得分

层次分析方法的局限性:

1、评价的决策层不能太多,太多的话,导致n会很大,因而判断矩阵和一致矩阵的差异可能会很大;

2、如果决策层中指标的数据是已知的,那么便不能用“层次分析法”来评价,需要用TOPSIS法来评价。

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>我们被要算法时间复杂度简化到O(log n),这通常意味着我们需要利用分而治之、二分查找或者数学变换等方法。O(log n)的时间复杂度通常出现在每次操作将问题规模减半的情况下。 参考引用[1]和[2]中关于时间复杂度的描述,我们知道O(log n)的效率是非常高的,仅次于常数时间O(1)。那么如何设计一个O(log n)的算法呢? 常见方法: 1. 二分查找(Binary Search):在有序数组中查找元素,每次比较后搜索范围减半。 2. 分治算法(Divide and Conquer):如快速幂算法(计算a的n次方)、归并排序(虽然归并排序是O(n log n))等,其中快速幂就是典型的O(log n)算法。 3. 使用平衡二叉搜索树(如AVL树、红黑树)进行操作(查找、插入、删除)可以达到O(log n)。 4. 欧几里得算法最大公约数)也是O(log n)的。 5. 一些数学问题,例如解斐波那契数列的矩阵快速幂方法。 下面以几个例子说明: 例1:二分查找 在有序数组中查找一个数,每次将搜索范围缩小一半,因此时间复杂度为O(log n)。 例2:快速幂算法 计算a的n次方,我们可以将n用二进制表示,然后通过不断平方和乘以对应的位来将时间复杂度从O(n)降低到O(log n)。 例3:欧几里得算法 两个数的最大公约数(GCD): gcd(a, b) = gcd(b, a mod b) 每次递归调用,问题规模至少减半,因此时间复杂度为O(log(min(a, b))),即O(log n)。 但是,不是所有问题都能降低到O(log n)。我们需要分析问题是否具有某种可以每次将规模减半的性质。 另外,引用[2]提到,当输入规模较小时,低复杂度算法的常数因子可能使得它不如简单的高复杂度算法。因此,在实际应用中,我们有时会结合使用,例如在快速排序中,当子数组长度小于某个阈值时改用插入排序。 总结步骤: 1. 分析问题,看是否可以通过分治策略(每次将问题规模减半)解决。 2. 考虑数据结构,如使用树结构(二叉搜索树、堆)来优化操作。 3. 检查问题是否具有数学特性,如快速幂、欧几里得算法等。 4. 如果问题允许,使用预处理(如构建索引、排序等)来支持后续的O(log n)操作。 注意:O(log n)通常要问题具有某种有序性或可分割性,并且每次操作能排除一半的数据。 相关问题: 1. 二分查找算法具体如何实现? 2. 快速幂算法的具体步骤是什么? 3. 在什么情况下,算法的时间复杂度不能降低到O(log n)? 4. 如何通过数据结构(如堆、平衡树)来达到O(log n)的操作复杂度? </think>### 如何将算法时间复杂度优化至 $O(\log n)$ 将算法时间复杂度优化到 $O(\log n)$ 的核心在于**利用问题规模 $n$ 的指数级缩减**。以下是具体方法和示例: --- #### 一、核心优化策略 1. **分治策略(Divide and Conquer)** 每次操作将问题规模**减半**(或按固定比例分割),递归处理子问题后合并结果。 - **数学依据**:$T(n) = T(n/2) + O(1) \rightarrow T(n) = O(\log n)$ 2. **二分搜索(Binary Search)** 适用于**有序数据**的查找操作,每一步丢弃一半无效数据。 - **时间复杂度**:$O(\log n)$ 3. **数学变换** 利用指数/对数的数学特性(如快速幂、GCD 算法)。 4. **树形结构优化** 平衡二叉树(如 AVL 树、红黑树)的查找/插入操作天然满足 $O(\log n)$。 --- #### 二、典型案例 1. **二分查找(有序数组)** ```python def binary_search(arr, target): low, high = 0, len(arr) - 1 while low <= high: mid = (low + high) // 2 if arr[mid] == target: return mid elif arr[mid] < target: low = mid + 1 # 丢弃左半部分 else: high = mid - 1 # 丢弃右半部分 return -1 ``` **关键**:每次迭代搜索范围减半 → $O(\log n)$ [^1][^2]。 2. **快速幂算法(计算 $a^n$)** ```python def fast_power(a, n): res = 1 while n: if n & 1: # 奇数次幂额外乘a res *= a a *= a # 底数平方 n //= 2 # 指数减半 return res ``` **关键**:指数 $n$ 每次减半 → $O(\log n)$ [^2]。 3. **欧几里得算法(GCD)** ```python def gcd(a, b): while b: a, b = b, a % b # 问题规模指数级缩减 return a ``` **数学证明**:$a \mod b \leq a/2$ → 最坏 $O(\log(\min(a,b)))$ [^3]。 4. **平衡二叉树操作** - 红黑树的查找、插入、删除均保证 $O(\log n)$(树高 $\log n$)。 --- #### 三、适用条件与注意事项 1. **必要条件**: - 问题需具备**可分割性**(如有序性、可递归分解)。 - 子问题合并代价需控制在 $O(1)$ 或 $O(\log n)$ 内。 2. **局限场景**: - 无序数据需先排序($O(n \log n)$ 预处理成本)[^2]。 - 小规模数据可能不如 $O(n)$ 算法高效(常数因子影响)[^2]。 3. **验证方法**: 通过**主定理(Master Theorem)** 分析递归式,例如 $T(n) = T(n/2) + O(1)$ 的解为 $O(\log n)$。 --- #### 四、优化步骤总结 1. 分析问题是否满足**可分割性**(如有序、可递归)。 2. 设计分治/二分策略,确保每步规模**指数级缩减**。 3. 控制子问题合并复杂度为 $O(1)$ 或更低。 4. 对树形结构优先采用平衡二叉树。 > 提示:若问题无法直接分割,可尝试转换为等价形式(如将乘积问题取对数变为和问题)。 --- ### 相关问题 1. 二分查找能否应用于链表?为什么? 2. 快速幂算法如何处理大数取模运算? 3. 哪些排序算法能实现 $O(n \log n)$ 复杂度?它们的分治逻辑有何区别? 4. 如何证明欧几里得算法的时间复杂度是 $O(\log n)$? [^1]: 常见时间复杂度等级中 $O(\log n)$ 效率远高于 $O(n)$ 和 $O(n^2)$。 [^2]: 实际应用中需权衡数据规模和常数因子,小规模数据可能选择更低阶复杂度的算法。 [^3]: 最坏情况分析是时间复杂度评估的重要原则。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rayme629

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值