一、问题引入

1.1 TSP问题

遍历34个省级行政区,每个城市访问1次并最终回到起始城市,且总路径最短。

1.2 问题分析

  • 模型假设:遍历过程中,两两城市直线距离为路径距离,每个目的地为节点,图论问题

  • 可行解:34!种可行方案

    数量级在10^38次

补充:P/NP/NP-C/NP-H问题

首先我们要知道,这些问题的划分是基于算法能否在多项式时间内验证的、解决的,这让我们对算法的效率和问题的难易做了一个等级划分。

**NP:**Non deterministic polynominal,非确定性多项式

  • P问题:多项式时间内可以解决的
  • NP问题:多项式时间内可以验证的(所以我们看出,这是一定包含P问题的)
  • NP-Complete:它比较特殊,既属于NP-Hard又属于NP问题
  • NP-Hard:所有NP问题可以约化为的问题
理解:
  • TSP问题就是著名的一个NP类问题,也就是我们可以在多项式的时间内验证并得出问题的正确解,但是就像上文所说,我们不知道是否有一个多项式时间的算法,每次解决它(当然不一定不存在,但是我们完全不知道)
  • 约化是具有传递性的,如A约化到B,B约化到C,A就可以约化到C,同时不断约化下去,我们会发现一个很惊人的特性,就是他一定会存在一个最大的问题,而我们只需要解决了这个问题,那其下的所有问题也就解决了。所以说同样的,存在这样一个NP问题,所有的NP问题都可以约化成它,解决了这个问题,所有的NP问题都解决了。
  • NP-Hard就没有NP问题的限制,范围更广,不一定在多项式内可以验证

P、NP、NPC和NP-Hard问题详解_np-hard 问题的复杂度-CSDN博客

二、算法框架

  • 蚁群活动
  • 信息素挥发
  • 信息素增强

核心: 转移概率公式+信息素更新公式

一直蚂蚁的信息素总量视为有限的常数,蚂蚁走过的路径(这里重点是全程而不是本小段路径长度)越短,留在路径上的信息素浓度越高

三、算法步骤

3.1 参数初始化:

d f 初 始 化 蚂 蚁 数 量 m , 城 市 数 量 n t 时 刻 , i 和 j 路 径 上 的 信 息 素 浓 度 τ i j ( t ) 初 始 化 信 息 素 浓 度 为 τ i j ( 0 ) = τ 0 挥 发 速 率 ρ 浓 度 因 素 重 要 性 α 和 路 径 长 度 重 要 性 β {df } 初始化蚂蚁数量m,城市数量n\\t时刻,i和j路径上的信息素浓度\tau_{ij}(t)\\ 初始化信息素浓度为\tau_{ij}(0)=\tau_0\\挥发速率\rho\\ 浓度因素重要性\alpha和路径长度重要性\beta dfmntijτij(t)τij(0)=τ0ραβ

3.2 计算概率:

对于每一个蚂蚁k : 从第i个城市不断进行选择,依据就是我们的选择概率:(为了防止收敛速度过慢,搜索范围过大,我们将d也纳入到选 择概率考虑的一部分)
KaTeX parse error: No such environment: split at position 31: …n{cases} \begin{̲s̲p̲l̲i̲t̲}̲ \frac{\tau_{ij…
!!!!:此时此刻我们的i是确定的,不变的,只需要看j(未访问过的城市)

分析:

α = 0 , 为 根 据 d i j 来 的 贪 心 算 法 , 可 能 陷 入 局 部 最 优 解 β = 0 , 则 完 全 由 信 息 素 浓 度 决 定 , 为 正 反 馈 的 启 发 式 算 法 , 可 能 收 敛 速 度 太 快 \alpha=0,为根据d_{ij}来的贪心算法,可能陷入局部最优解\\ \beta=0,则完全由信息素浓度决定,为正反馈的启发式算法,可能收敛速度太快 α=0,dijβ=0,

3.3 更新信息素浓度:

对于每一只蚂蚁的一条满足条件的路径就是一个可行解,我们开始比较可行解的优劣并(以信息素浓度的形式)反馈到下一次寻找过程当中。

对于每一条路径ij:(取决于原有的t时刻新增的
τ i j ( t + 1 ) = ( 1 − ρ ) τ i j ( t ) + ∑ k = 1 m Δ τ i j ( t ) k ,     0 < ρ < 1 τ i j ( t ) k = { Q L k , 第 k 只 蚂 蚁 曾 经 过 i 到 j 0      e l s e \tau_{ij}(t+1)=(1-\rho)\tau_{ij}(t)+\sum_{k=1}^m\Delta\tau_{ij}(t)^k,~~~0\lt\rho<1\\ \tau_{ij}(t)^k= \begin{cases} \frac{Q}{L_k},第k只蚂蚁曾经过i到j\\ 0 ~~~~else \end{cases} τij(t+1)=(1ρ)τij(t)+k=1mΔτij(t)k,   0<ρ<1τij(t)k={LkQ,kij0    else
注意这里:更新某条路径的信息素和第k个蚂蚁的优劣相关,所以一定是Q/Lk,其中L是整个路径长度(也就是一个完整的可行解)

求出本轮每只蚂蚁的总路径的最小值,与上一轮最优解相比,最小的记为当前最优解

3.4判断是否终止:

  • 达到最大迭代次数
  • 最优解差值小于阈值

3.5 未终止则下一次迭代

清空本轮蚂蚁走过的路径,信息素保持更新后的不变,返回3.2

四、示例图解

在这里插入图片描述
在这里插入图片描述

五、拓展解决背包问题

5.1 问题描述

有10件货物要从甲地运送到乙地,每件货物重量和利润如下表所示:

物品 1 2 3 4 5 6 7 8 9 10
重量(吨) 6 3 4 5 1 2 3 5 4 2
利润 (元) 510 220 150 340 70 160 290 430 320 110

由于只有一辆最大载重为30吨的货车来运算货物,只能选择部分货物运送。要求确定运算哪些货物可以是总利润最大。

5.2 问题建模

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

5.3 代码附上

function ant_colony_knapsack()  
    % 物品的重量和利润  
    weights = [6, 3, 4, 5, 1, 2, 3, 5, 4, 2];  % 重量  
    profits = [510, 220, 150, 340, 70, 160, 290, 430, 320, 110];  % 利润  
    max_weight = 30;  % 最大承载重量  
    num_items = length(weights);  % 物品数量  

    % 蚁群算法参数  
    num_ants = 50;     % 蚂蚁数量  
    max_iterations = 500; % 迭代次数  
    alpha = 1;        % 信息素重要性  
    beta = 2;         % 启发函数重要性  
    evaporation_rate = 0.1; % 信息素挥发率  

    % 初始化信息素矩阵  
    pheromone = ones(num_items, 1);  

    best_profit = 0;  
    best_solution = zeros(1, num_items);  

    for iteration = 1:max_iterations  
        solutions = zeros(num_ants, num_items);  
        profits_collected = zeros(num_ants, 1);  

        for ant = 1:num_ants  
            % 蚂蚁选择物品  
            for i = 1:num_items  
                if rand < prob_select(pheromone(i), alpha, beta)  
                    solutions(ant, i) = 1; % 选择该物品  
                end  
            end  
            % 计算总重量和利润  
            total_weight = sum(weights .* solutions(ant, :));  
            if total_weight <= max_weight  
                profits_collected(ant) = sum(profits .* solutions(ant, :));  
            end  
        end  

        % 更新信息素  
        pheromone = (1 - evaporation_rate) * pheromone; % 衰减  
        for ant = 1:num_ants  
            if profits_collected(ant) > best_profit  
                best_profit = profits_collected(ant);  
                best_solution = solutions(ant, :);  
            end  
            % 增加信息素  
            pheromone = pheromone + solutions(ant, :) * profits_collected(ant);  
        end  
    end  

    % 输出结果  
    selected_items = find(best_solution);  % 找到选择的物品  
    fprintf('选择的物品索引: %s\n', num2str(selected_items));  
    fprintf('总利润: %d 元\n', best_profit);  
end  

function p = prob_select(pheromone, alpha, beta)  
    % 计算选择概率  
    p = pheromone ^ alpha;  % 取权重  
end

5.4 结果

在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐