文章 "种群优化算法:树苗播种和成长(SSG)算法" - 页 12

 
Andrey Dik #:

是的,一个非常有趣的生物体。)

但是,蛞蝓只使用 2 维空间,即使是最简单的 AO 也能应对 2 维空间。它在 1000 维空间中的表现如何是个大问题,因为问题的复杂性会随着维数的增加而非线性增长。

蚂蚁算法也是如此,但他们将其推广到了多维情况下

在这里,chattgpt 问到了,不知道是不是:)

粘菌算法是一种基于粘菌行为的启发式优化方法。该算法由 Chiaro D'Ambrosio 开发,属于 "自然 "优化算法。


该算法的本质是将 "蛞蝓 "放在一个特定的点上,然后观察它如何围绕该点扩散,以寻找最多的食物。在这一算法的过程中,蛞蝓会留下痕迹并逐渐蒸发。在某一区域留下的痕迹越多,另一只 "蛞蝓 "就越有可能将该痕迹作为通往更多食物的路径。


在优化过程中,这种蛞蝓行为被用来寻找参数空间中的最优解。例如,我们可以使用这种算法在给定的参数范围内找到函数的最小值。


这种算法的优点是简单,能够在多维空间中快速收敛到最优解。不过,在更复杂的非线性问题中,该算法在收敛到最优解时也会遇到问题。

 
Maxim Dmitrievsky #:
蚂蚁算法是一样的,但它被推广到了多维情况下。

蚂蚁算法的收敛性会随着维度的增加而降低,而且会迅速降低。所有算法的行为一般都是一样的,这取决于搜索策略,而我们并不知道鼻涕虫的策略。)

随着维度的增加,收敛性的下降速度慢于复杂性的增长速度--我认为这是 AO 的可扩展性。可扩展性取决于函数的类型,不同的算法在不同的函数上有不同的扩展性。

 
Maxim Dmitrievsky #:

这里是 chattgpt 问的,不知道是不是 :)

粘菌算法是一种基于粘菌行为的启发式优化方法。该算法由 Chiaro D'Ambrosio 开发,属于 "自然 "优化算法。

该算法的本质是将 "蛞蝓 "放在一个特定的点上,然后观察它如何围绕该点扩散,以寻找最多的食物。在这一算法的过程中,蛞蝓会留下痕迹并逐渐蒸发。在某一区域留下的痕迹越多,另一只 "蛞蝓 "就越有可能将该痕迹作为通往更多食物的路径。

在优化过程中,这种蛞蝓行为被用来寻找参数空间中的最优解。例如,我们可以使用这种算法在给定的参数范围内找到函数的最小值。

这种算法的优点是简单,能够在多维空间中快速收敛到最优解。不过,在更复杂的非线性问题中,该算法在收敛到最优解时也会遇到问题。

哇,太有趣了。我会找找这个算法的,当然,把它拆开也很有趣。而且,组装)))))))

 
我一拿到它,就会把所有已知算法的收敛性与问题的维度、三类问题的收敛性进行比较。
 
Andrey Dik #:

哇,太有趣了。我会找找这个算法,当然,把它拆开来也很有趣。然后组装))))))

下面是一个用 MQL 编程语言实现 slug 算法的例子:


```

double slimeMouldAlgorithm(double(*f)(double[]), double x[], int n, double LB[], double UB[], int maxIter, int N)

{

常量 double k = 0.1; // 追踪蒸发系数

const double stepSize = 0.001; // "弹头 "移动步长的大小

double trail[N]; // 每个粒子的轨迹数组

double bestTrail[N]; // 最佳轨迹数组

double bestFitness = DBL_MAX; // 最佳适应度函数的初始值

double bestX[N]; // 与最佳轨迹相对应的参数值数组

for (int i = 0; i < N; i++) {

for (int j = 0; j < n; j++) {

x[j] = LB[j] + (UB[j] - LB[j]) * (double)rand() / RAND_MAX; // 在指定的参数范围内随机放置 "插头"

}

trail[i] = f(x); // 计算这些参数的适应度函数值

if (trail[i] < bestFitness) { // 如果适配函数值优于当前最佳值,则将其存储为新的最佳值

bestFitness = trail[i];

memcpy(bestX, x, sizeof(bestX)); // 将找到的参数值复制到最佳值数组中

memcpy(bestTrail, trail, sizeof(bestTrail)); // 将找到的参数的函数值复制到最佳函数值数组中

}

}

for (int iter = 0; iter < maxIter; iter++) { // 循环迭代次数

for (int i = 0; i < N; i++) {

double r[n], d[n];

for (int j = 0; j < n; j++) {

r[j] = (double)rand() / RAND_MAX - 0.5; // 随机增量向量

d[j] = r[j] * stepSize * (UB[j] - LB[j]); // 计算步宽

x[j] += d[j]; // 给参数增加一个步长

if (x[j] < LB[j]) { // 如果参数超出范围,则将其保留在边界上

x[j] = LB[j];

}else if (x[j] > UB[j]) {

x[j] = UB[j];

}

}

double newTrail = f(x); // 根据新参数计算函数值

if (newTrail <= trail[i]) { // 如果函数值有所改善或没有变化,则保存新参数和函数值

memcpy(bestX, x, sizeof(bestX)); // 将新参数复制到最佳参数值数组中

memcpy(bestTrail, &newTrail, sizeof(newTrail)); // 将新函数值复制到最佳函数值数组中

trail[i] = newTrail; // 将新参数的函数值保存到所有 "短语 "的函数值数组中

if (bestTrail[i] < bestFitness) { // 检查当前最佳解决方案是否优于当前最佳解决方案

bestFitness = bestTrail[i];

}

}else { // 如果函数值变差,则返回旧参数

memcpy(x, bestX, sizeof(bestX));

trail[i] = bestTrail[i];

}

}

for (int i = 0; i < N; i++) {

trail[i] *= (1.0 - k); // 蒸发蛞蝓轨迹,以避免卡在局部最大值中

}

}

return bestFitness;

}

```


这段代码使用所选参数的随机值作为起点,然后按顺序处理每个粒子。对于每个粒子,它会生成一个随机增量向量,计算步长并将其添加到每个参数中。然后计算新参数的函数值,如果数值减少或保持不变,则将其存储起来。在每个周期结束时,它会蒸发蛞蝓轨迹,以避免陷入局部最大值。


您可能需要在这里进行调整 😀 gpt 已发布

 
更正:

你是对的,MQL 中没有 `memcpy` 函数。要将值从一个变量复制到另一个变量,可以使用赋值操作符`=`。下面是一个不使用 `memcpy` 函数的修改代码示例:


```

double slimeMouldAlgorithm(double(*f)(double[]), double x[], int n, double LB[], double UB[], int maxIter, int N)

{

常量 double k = 0.1; // 追踪蒸发系数

const double stepSize = 0.001; // "弹头 "移动步长的大小

double trail[N]; // 每个粒子的轨迹数组

double bestTrail[N]; // 最佳轨迹数组

double bestFitness = DBL_MAX; // 最佳适应度函数的初始值

double bestX[N]; // 与最佳轨迹相对应的参数值数组

for (int i = 0; i < N; i++) {

for (int j = 0; j < n; j++) {

x[j] = LB[j] + (UB[j] - LB[j]) * (double)rand() / RAND_MAX; // 在指定的参数范围内随机放置 "插头"

}

trail[i] = f(x); // 计算这些参数的适应度函数值

if (trail[i] < bestFitness) { // 如果适配函数值优于当前最佳值,则将其存储为新的最佳值

bestFitness = trail[i];

for (int j = 0; j < n; j++) {

bestX[j] = x[j]; // 将找到的参数值复制到最佳值数组中

}

bestTrail[i] = trail[i]; // 将找到的参数的函数值复制到最佳函数值数组中

}

}

for (int iter = 0; iter < maxIter; iter++) { // 循环迭代次数

for (int i = 0; i < N; i++) {

double r[n], d[n];

for (int j = 0; j < n; j++) {

r[j] = (double)rand() / RAND_MAX - 0.5; // 随机增量向量

d[j] = r[j] * stepSize * (UB[j] - LB[j]); // 计算步宽

x[j] += d[j]; // 给参数增加一个步长

if (x[j] < LB[j]) { // 如果参数超出范围,则将其保留在边界上

x[j] = LB[j];

}else if (x[j] > UB[j]) {

x[j] = UB[j];

}

}

double newTrail = f(x); // 计算新参数的函数值

if (newTrail <= trail[i]) { // 如果函数值有所改善或没有变化,则保存新参数和函数值

for (int j = 0; j < n; j++) {

bestX[j] = x[j]; // 将新参数复制到最佳参数值数组中

}

bestTrail[i] = newTrail; // 将新函数值复制到最佳函数值数组中

trail[i] = newTrail; // 将新参数的函数值存储到所有 "短语 "的函数值数组中

if (bestTrail[i] < bestFitness) { // 检查当前最佳解决方案是否优于当前最佳解决方案

bestFitness = bestTrail[i];

}

}else { // 如果函数值变差,则返回旧参数

for (int j = 0; j < n; j++) {

x[j] = bestX[j];

}

trail[i] = bestTrail[i];

}

}

for (int i = 0; i < N; i++) {

trail[i] *= (1.0 - k); // 气化弹头轨迹,以避免卡在局部最大值中

}

}

return bestFitness;

}

```


正如您所看到的,我们只是使用循环来逐个元素复制数组值。

 


这块铁什么都知道......))))

在一般情况下,你也许可以相信硬件会为任务选择合适的算法,但我宁愿看看我的评级表)) ))

 
Maxim Dmitrievsky #:

```

double slimeMouldAlgorithm(double(*f)(double[]), double x[], int n, double LB[], double UB[], int maxIter, int N)

正如文章中的所有算法一样,有必要将其分解为一个方案。

 
Andrey Dik #:

有必要根据方案进行分解,因为文章中的所有算法都是这样做的。

通过聊天试试吧,不知道它是否能处理这样的任务:)我没有代币了,所以有时会掺和一下。给他提供一个文章示例,并保持风格。顺便说一句,一个伟大的初创公司只需一分钱就能在购物车中安装这样一个机器人。
 
Maxim Dmitrievsky #:
通过聊天试试看,不知道它是否会处理这样的任务:)我的代币用完了,所以有时会掺和一下。给它提供一篇范文,让它跟上风格。顺便说一句,花一分钱就能在购物车里买到这样一个机器人,真是个不错的创业公司。

不幸的是,或者说幸运的是,机器人不会产生新的信息,而公开的信息往往是失真的。我认为这是由于信息插值机制造成的。它说谎,编造不存在的算法缩写,甚至临时编造作者姓名和算法出现的日期))))。

作为文本编辑、文体修正和撰写文章时的参考助手--是的,不可或缺的助手。