蚁群算法【一篇文章搞懂思路/步骤/示例/拓展/代码!!】
蚂蚁k : 从第i个城市不断进行选择,依据就是我们的选择概率:(为了防止收敛速度过慢,搜索范围过大,我们将d也纳入到选 择概率考虑的一部分)对于每一只蚂蚁的一条满足条件的路径就是一个可行解,我们开始比较可行解的优劣并(以信息素浓度的形式)反馈到下一次寻找过程当中。一直蚂蚁的信息素总量视为有限的常数,蚂蚁走过的路径(这里重点是全程而不是本小段路径长度)越短,留在路径上的信息素浓度越高。求出本轮每只蚂
文章目录
一、问题引入
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问题的限制,范围更广,不一定在多项式内可以验证

二、算法框架
- 蚁群活动
- 信息素挥发
- 信息素增强
核心: 转移概率公式+信息素更新公式
一直蚂蚁的信息素总量视为有限的常数,蚂蚁走过的路径(这里重点是全程而不是本小段路径长度)越短,留在路径上的信息素浓度越高
三、算法步骤
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 df初始化蚂蚁数量m,城市数量nt时刻,i和j路径上的信息素浓度τ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=1∑mΔτij(t)k, 0<ρ<1τij(t)k={LkQ,第k只蚂蚁曾经过i到j0 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 结果

更多推荐



所有评论(0)