正在加载中...

展开本页目录
算法教程SSA-麻雀搜索

SSA-麻雀搜索

No.208 · 在线教程

本项目实现的是 SSA(Sparrow Search Algorithm,麻雀搜索)单目标优化框架,核心代码位于 SSA-麻雀搜索/core/ssarunner.py 与 core/ssacalculator.py。项目支持三类问题来源:

SSA-麻雀搜索

1. 方法概述

本项目实现的是 SSA(Sparrow Search Algorithm,麻雀搜索)单目标优化框架,核心代码位于 SSA-麻雀搜索/core/ssa_runner.pycore/ssa_calculator.py。项目支持三类问题来源:

  • benchmark:内置目标函数;
  • Custom:用户输入目标表达式与约束;
  • upload_surrogate:上传数据后进行代理优化。

此外,代码支持:

  • runs>1 的多次独立运行;
  • uniform/per_dim 两类边界,其中上传模式强制使用逐维边界;
  • 生产者、跟随者、警觉者三类个体机制。

项目求解的一般单目标问题可写为

$$ \operatorname*{opt}_{\boldsymbol{x}\in\Omega} f(\boldsymbol{x}), \qquad \operatorname*{opt}\in\{\min,\max\} \tag{1} $$

2. 自定义目标与上传代理优化

Custom 模式下,若给定不等式约束 \(g_k(\boldsymbol{x})\le 0\) 和等式约束 \(h_\ell(\boldsymbol{x})=0\),则代码构造罚项

$$ P(\boldsymbol{x}) = \rho\sum_k \max\big(g_k(\boldsymbol{x}),0\big)^p +\rho_{eq}\sum_\ell \max\big(|h_\ell(\boldsymbol{x})|-\varepsilon,0\big)^p \tag{2} $$

于是内部目标为

$$ \tilde f(\boldsymbol{x})= \begin{cases} f(\boldsymbol{x})+P(\boldsymbol{x}), & \text{min}\\ f(\boldsymbol{x})-P(\boldsymbol{x}), & \text{max} \end{cases} \tag{3} $$

在上传代理模式下,项目训练 RandomForestRegressor(n_estimators=300) 得到

$$ \hat f(\boldsymbol{x})=\frac{1}{300}\sum_{b=1}^{300}T_b(\boldsymbol{x}) \tag{4} $$

这里与一些“先做符号翻转”的实现不同,core/ssa_calculator.py 直接令

$$ f_{up}(\boldsymbol{x})=\hat f(\boldsymbol{x}), \qquad \operatorname*{opt}\in\{\min,\max\} \tag{5} $$

并通过 problem.minmax = objective_direction 控制比较规则,而不是修改目标函数本身。上传模式同时强制使用逐维边界:

$$ l_j=\min_n x_j^{(n)}, \qquad u_j=\max_n x_j^{(n)} \tag{6} $$

3. 核心数学模型

3.1 角色划分与初始化

设种群规模为 \(N\),生产者比例为 pd,警觉者比例为 sd,则代码使用

$$ P_N=\max\big(1,\operatorname{round}(N\cdot pd)\big), \qquad A_N=\max\big(1,\operatorname{round}(N\cdot sd)\big) \tag{7} $$

初始化种群与个人历史最优:

$$ \boldsymbol{x}_i^{(0)}\sim U(\boldsymbol{l},\boldsymbol{u}), \qquad \boldsymbol{p}_i^{(0)}=\boldsymbol{x}_i^{(0)} \tag{8} $$

3.2 生产者更新

代码中的安全阈值固定为 st=0.8。若随机数 \(r_2<st\),则前 \(P_N\) 个生产者按

$$ \boldsymbol{x}_{idx} = \boldsymbol{p}_{idx}\exp\!\left(-\frac{i+1}{r_1T}\right) \tag{9} $$

更新,其中 \(r_1\in(0,1)\)。否则采用高斯扰动:

$$ \boldsymbol{x}_{idx} = \boldsymbol{p}_{idx}+\mathcal{N}(0,1)\,\mathbf{1} \tag{10} $$

3.3 跟随者更新

代码先从个人历史最优 p_x 中确定最差位置 worst_x,并从当前 fit 中确定当前最好位置 best_xx。当跟随者排序位置满足 \((i+1)>N/2\) 时,采用

$$ \boldsymbol{x}_{idx} = \boldsymbol{z}\odot \exp\!\left(\frac{\boldsymbol{x}_{worst}-\boldsymbol{p}_{idx}}{(i+1)^2}\right), \qquad \boldsymbol{z}\sim \mathcal{N}(0,1)^d \tag{11} $$

否则采用 MATLAB 风格的标量跟随式:

$$ \boldsymbol{x}_{idx} = \boldsymbol{x}_{best,current} +\frac{\left|\boldsymbol{p}_{idx}-\boldsymbol{x}_{best,current}\right|^\top\boldsymbol{a}}{\boldsymbol{a}^\top\boldsymbol{a}}\mathbf{1}, \qquad \boldsymbol{a}\in\{-1,+1\}^d \tag{12} $$

3.4 警觉者更新

从排序后的种群中随机抽取 \(A_N\) 个警觉者。若其个人最优不优于全局最优,则

$$ \boldsymbol{x}_{idx} = \boldsymbol{x}_{best} +\boldsymbol{z}\odot\left|\boldsymbol{p}_{idx}-\boldsymbol{x}_{best}\right| \tag{13} $$

否则按

$$ \boldsymbol{x}_{idx} = \boldsymbol{p}_{idx} +k\frac{\left|\boldsymbol{p}_{idx}-\boldsymbol{x}_{worst}\right|}{pfit_{idx}-fit_{worst}+\varepsilon}, \qquad k\in[-1,1] \tag{14} $$

更新。

3.5 历史最优与多次运行

每轮结束后,若当前解优于个人历史最优,则更新 p_x/p_fit;若个人历史最优优于全局最优,则同步更新 best_x/best_fit。项目记录的历史量包括

$$ \text{history}(t)=\big(\text{best\_fitness},\ \text{mean\_fitness},\ \text{worst\_fitness},\ P_N,\ A_N,\ r_2\big) \tag{15} $$

若运行 \(R\) 次,则第 \(r\) 次使用随机种子

$$ \mathrm{seed}_r=\mathrm{seed}_0+r-1 \tag{16} $$

最终代表性最佳运行按最终最优值选择:

$$ r^\star= \begin{cases} \operatorname*{arg\,min}_{1\le r\le R} b_r, & \text{min}\\ \operatorname*{arg\,max}_{1\le r\le R} b_r, & \text{max} \end{cases} \tag{17} $$

其中 \(b_r\) 为第 \(r\) 次运行的最终 best_fitness

4. 算法流程

结合 core/ssa_runner.pycore/ssa_calculator.pycore/custom_objective.pyui/upload_widget.pyutils/excel_handler.py,本项目麻雀搜索的流程为:

  1. 选择 benchmarkCustomupload_surrogate
  2. 若为 Custom,则按式(2)和式(3)构造含罚函数的目标。
  3. 若为上传模式,则训练随机森林代理,并强制使用 bounds_mode="per_dim"
  4. 按式(7)和式(8)初始化种群及个人最优。
  5. 生产者按式(9)或式(10)更新。
  6. 跟随者按式(11)或式(12)更新。
  7. 警觉者按式(13)或式(14)更新。
  8. 更新 pbest/gbest,记录所有运行历史,并按式(17)选择代表性最佳运行导出。

5. 关键参数说明

  • pop_size:种群规模。
  • max_iters:最大迭代次数。
  • runs:独立运行次数。
  • seed:基础随机种子。
  • st:安全阈值,默认 0.8
  • pd:生产者比例,默认 0.2
  • sd:警觉者比例,默认 0.1
  • bounds_mode:代码支持 uniform/per_dim,但 benchmark 界面固定传 uniform,上传模式强制改成 per_dim

6. 评价指标与输出结果解释

utils/excel_handler.py 导出的主要工作表包括:

  • Summary:最终目标函数、维度、运行次数、best_fitness 及统计值;
  • ProblemSSA_Params:问题配置与算法参数;
  • Custom_Objective:仅 Custom 模式下出现,保存表达式与约束;
  • Bounds:边界信息;
  • Run_Summary:每次运行的最终最优值;
  • History_Mean:按迭代聚合得到的均值/标准差;
  • History_All:所有运行的完整历史;
  • Best_Solution:代表性最佳运行的最优解;
  • Charts:平均收敛曲线图路径。

上传模式下还会额外导出 UploadedDataSurrogateMetrics

需要特别注意:worst_x 明确取自 p_x[worst_idx],不是当前种群 x[worst_idx];这一点是当前实现与很多简化版 SSA 代码的关键差异。论文中建议以 SummaryRun_Summary 作为统计结果主表,以 History_Mean 展示均值±标准差收敛曲线,并在方法说明里明确 worst_x 的取值来源。若使用 Custom 模式,建议同时报告罚函数系数与约束表达式。

7. 论文写作模板

可在论文方法部分表述为:

“本文采用麻雀搜索算法(SSA)进行单目标优化。算法将种群划分为生产者、跟随者和警觉者三类个体,其中生产者根据安全阈值在指数收缩搜索与随机扰动搜索之间切换,跟随者依据当前最优与最差个体位置更新,警觉者则在风险感知机制下靠近全局最优或远离最差区域。对于自定义问题,本文将约束统一转化为罚函数;对于数据驱动问题,本文进一步训练随机森林代理模型,并在样本逐维边界范围内执行 SSA 搜索。”

7.1 结果部分补充模板

若需把实验结果直接写入论文结果部分,可进一步表述为:

“表X给出了算法在当前问题上的最优目标值、平均最优值和标准差(如有多次独立运行),图X展示了收敛曲线变化。结果表明,该算法在迭代前期能够快速逼近优势区域,并在后期逐步趋于稳定,最终获得最优解 \(\boldsymbol{x}^*\) 及其对应目标值 \(f(\boldsymbol{x}^*)\)。对于上传代理优化场景,结合代理模型误差指标可认为该最优结果具有一定的数据驱动解释性。”

7.2 写作替换提示

为便于直接落稿,正文撰写时可将结果文件中的字段替换为以下论文措辞:

  • best_fitness 或结果汇总表中的最优值,可写为“最优目标函数值”或“最优适应度值”;
  • BestSolutionBestPositionBest_Solution最优解 等工作表,可统一写为“最优决策变量组合 \(\boldsymbol{x}^*\)”;
  • Convergence收敛曲线 等图表,可统一写为“算法收敛曲线图”;
  • SurrogateMetrics 可写为“代理模型训练误差与拟合优度指标”,如 RMSE、MAE、\(R^2\)。

7.3 可直接替换的论文结果段落

若需进一步直接落稿,可按以下模板替换其中的表号、图号和数值:

“由表X可知,该算法在[问题名称]上的最优目标值为 [best_fitness]。若进行了多次独立运行,则其平均最优值与标准差分别为 [mean_best_fitness] 和 [std_best_fitness]。由图X所示收敛曲线可见,算法在迭代前期快速逼近优势区域,后期逐渐趋于平稳,表现出较好的收敛性。最终得到的最优决策变量组合为 \(\boldsymbol{x}^*=[x_1^*,x_2^*,\ldots,x_d^*]\)。若采用上传代理优化模式,则结合 RMSE、MAE 和 \(R^2\) 等代理误差指标,可认为该优化结果具有一定的数据驱动可信度。”

8. 实现说明与注意事项

  • 本实现同时支持 benchmarkCustomupload_surrogate 三类问题来源。
  • 上传模式下没有做目标符号翻转,而是直接利用 minmax 控制“更优”比较规则。
  • benchmark 模式在界面层固定传 bounds_mode="uniform";上传模式则强制改成 per_dim
  • 多次运行时,Summary 中的统计摘要来自 Run_Summary 的后处理统计,不是单轮内部直接产生的量。

9. 单篇终审补充

9.1 图题与表题对齐建议

  • Summary 表可写为:表X SSA 最优值与统计摘要。
  • Run_Summary 表可写为:表X SSA 各次运行最优值汇总。
  • History_Mean 表可写为:表X SSA 均值±标准差收敛曲线。
  • History_All 表可写为:表X SSA 全部运行历史。
  • Best_Solution 表可写为:表X SSA 代表性最佳运行的最优解向量。
  • Charts 中平均收敛图建议写为:图X 麻雀搜索算法均值收敛曲线。

9.2 终审说明

  • 该实现支持多次运行统计,正文可以写稳定性结果,但应明确统计来自 Run_Summary 的后处理汇总。
  • worst_x 取自 p_x[worst_idx] 是实现级关键细节,方法部分若写机制差异应保留这一点。

9.3 全量强化补充

本次全量强化优先绑定更活跃的真实结果目录 具体的算法3/优化与多目标/SSA-麻雀搜索/results/pytest_ui_ssa_test_swarm_improved_ui_flow_of9。该目录中较新的主结果文件可绑定为 SSA_results_20260329_171741.xlsx,实际工作表结构与 smoke 结果一致,为 SummaryProblemSSA_ParamsBoundsRun_SummaryHistory_MeanHistory_AllBest_SolutionCharts;对应主图可引用 SSA_convergence_20260329_171741.png

需要明确的是,这个目录不是单一静态快照,而是长期累计的 UI/回归结果池,内含大量成对时间戳 xlsx + png。本次文档建议固定引用最后一轮 171741 这一组结果,其余文件视作历史复算产物,避免在论文里把同目录多轮输出误写成一轮实验。

repro_ssa.py 的真实口径是 benchmark:problem_mode = 'benchmark'objective_name = 'Sphere'runs = 1seed = 8bounds_mode = 'uniform',只有在 upload_surrogate 时才会尝试拼接 problem_file。因此当前绑定证据属于基准函数复算链路,而不是 repro_inputs 上传链路。若后续要写上传代理版实验,需要单独绑定含 problem_file 或上传副本的目录。

10. 软件实现核查补充(2026-07)

本篇对应的软件源码目录是 具体的算法3/优化与多目标/SSA-麻雀搜索。软件实现支持优化模式和上传数据代理优化模式;上传模式读取数值表并训练代理模型后再运行麻雀搜索。文档中的发现者/跟随者/警戒者更新公式可以保留,但软件结果应以 SSA_ParamsRun_SummaryHistory_MeanHistory_AllBest_SolutionCharts 解释。

当前较新的代表性目录为 results/SSA-麻雀搜索分析结果_20260517_144515-优化模式results/SSA-麻雀搜索分析结果_20260517_144527-上传数据代理优化。主工作簿通常包含 SummaryProblemSSA_ParamsBoundsRun_SummaryHistory_MeanHistory_AllBest_SolutionCharts;上传模式额外包含 UploadedProblemUploadedDataSurrogateMetrics。如果正文讨论多次运行,应以 Run_SummaryHistory_Mean 为主,而不是只写单次最优值。

当前图表稳定输出为 SSA_convergence_时间戳.pngSSA_best_solution_时间戳.png。复现代码位于 复现代码/优化模式/复现代码/上传数据代理优化/,上传模式输入副本为 repro_inputs/ssa_sample.xlsx,复现结果进入 repro_outputs/。这篇文档中的上传代理结果应与代理模型误差一起解释。