
密码锁算法(CLA)
内容
1. 概述
密码锁,也被称为数字锁或组合锁,是用来控制房间、保险箱、橱柜或其他物品访问权限的安全机制。它们与普通锁的不同之处在于,不是使用钥匙来开启,而是需要输入特定的数字组合。
密码锁通常配备有键盘、特殊圆筒或其他旋转机制,允许用户输入代码序列。一旦输入了正确的组合,密码锁就会激活解锁机制,允许用户打开门或访问保险箱的内容。用户可以设置自己的代码,也可以使用提供的代码来打开锁。
密码锁优势:
- 安全性。密码锁可以提供高度的安全性,尤其是密码需要定期更换的情况。
- 便利性。无需携带钥匙,这使得密码锁使用起来非常方便。
- 可设置多个密码。一些型号的密码锁允许为不同用户或不同时间段设置多个不同的密码。
密码锁被广泛应用于多个领域,包括家庭安全、商业建筑、酒店、学校、办公室以及其他需要访问控制的机构。将密码锁的概念应用于优化算法中可能是一个有趣的想法。密码锁在优化算法中的一种可能应用是创建一个系统,该系统利用密码锁的原理来解决优化问题,例如寻找机器学习问题中的最优参数值,或其他优化问题。
密码锁的操作原理,即输入正确的数字组合以解锁,与优化算法中寻找最优解的机制相似,后者通过迭代改变参数并评估其效率来找到最优解。
例如,可以想象一个使用密码锁原理的优化算法如下:
- 参数组合。待优化的参数可以表示为输入的一个“组合”。
- 验证组合的有效性。算法可以改变参数值并评估其效率,这类似于用户向密码锁输入不同的组合以验证其有效性。
- 最优解即解锁。当算法找到了最优参数值时,这可以视为“解锁”最优解。
因此,密码锁启发了我开发一种优化算法,该算法可用于寻找各种问题中的最优解,包括机器学习和交易系统开发等领域。
2. 算法实现
让我们将一群智能体想象成一群锁,其中每把锁代表一个问题的解决方案。接下来,我们可以为密码锁算法勾勒出一个近似的伪代码框架:
1. 初始化:
创建一个大小为popSize的锁数组。每把锁具有一组coords圆盘,而每组包含lockDiscs个圆盘。
2. 选择锁的组合:
如果这是第一步,则将每把锁的每一组中的每个圆盘初始化为0到9之间的一个随机数。
否则,对于每把锁:
- 如果一个随机数小于copyProb,则从随机选择的一把锁中复制一组圆盘。
- 否则,对于每组圆盘:
- 如果一个随机数小于rotateProb,则将圆盘设置为0到9之间的一个随机数。 - 否则,从随机选择的锁中复制圆盘。
3. 评估锁组合的质量:
更新每个锁组合的质量。
找出组合质量最好的锁,并在必要时更新全局最佳解决方案。
将所有锁复制到公共锁篮中。
按适应度对锁篮中的锁进行排序。
4. 重复步骤2和3,直到达到指定的迭代次数或满足停止准则。
这个概念相当吸引人,但在某些方面仍然存在疑问。特别是,锁中的组合密码如何能够代表一个问题的解决方案,这一点尚不完全明确。为了加深理解,通过一个具体的示例来说明,将会非常有帮助。
让我们想象一下,我们用密码锁的形式来表示一个问题的解决方案,其中我们需要优化一个或多个参数。在这种情况下,每个参数都可以表示为一组数字的组合,每个数字都在一个独立的圆盘上。圆盘的数量可以是任意的。这被视为算法的一个外部参数。因此,每个参数都由一组带有数字标签的圆盘来表示。
例如,如果一个任务参数有一组9个圆盘,每个圆盘上的数字从0到9,那么组合可以是000000000到999999999之间的任何数字。我们将得到的数字缩放到相应参数“最小值”到“最大值”的范围内。因此,如果我们有三个需要优化的参数,那么我们的密码锁将有3 x 9 = 27个数字圆盘。图例1展示了单个参数的编码机制。
图例1. 通过数字代码解码将任务参数变成实际值
在优化算法中,诸如交叉和变异等算子,基于代码锁的思想被整合到CLA优化算法中。
1. 交叉。遗传算法中的交叉操作旨在将两个父本的遗传物质结合起来,从而创造出子代。
- 在密码锁背景下,我们可以将交叉想象成从不同锁的盘值中组合出一种新的编码任务参数组合。
- 这个过程为算法提供了探索参数新组合的可能性,类似于用户可以在密码锁上尝试不同的数字组合,并且仍然可以在不同的锁上使用最成功的数字组合。
2. 变异。遗传算法中的变异是指遗传物质的随机变化,旨在增加种群的多样性。
- 在密码锁背景下,变异可以理解为随机旋转密码锁盘到任意数字位置,从而改变密码锁的组合。
- 这个过程有助于算法在整个解空间中探索新的参数组合,并避免陷入局部最优解。
一般来说,将交叉和突变整合到优化算法中,可以增加解的多样性,加速收敛到最优解,并有助于避免过早收敛。这种方法在处理庞大的搜索空间和复杂目标函数的优化问题时非常有用。事实上,与遗传算子进行类比,我们除了旋转盘之外别无选择。
为了解决这个问题,我们需要选择密码锁上正确的数字组合。我们需要旋转盘以找到能够打开锁的正确密码组合。在遗传算法中,“旋转”基因中的二进制代码值得到某个值的概率是50%(即0或1),与遗传算法不同,在组合锁算法中,我们可以在盘旋转策略中使用概率分布。让我们考虑几种选择。
我们可以使用高斯分布来变异组合参数,即每个参数都变为一个从正态分布(高斯分布)中随机选择的值。这样可以在一定程度上对参数进行随机改变,同时仍然保持其当前值。
使用高斯分布实行变异是有用的,因为它可以控制参数变化的程度。参数可以变为接近当前值的较小值,这有助于保留当前解决方案的良好属性,而变异的随机性则允许算法探索搜索空间内的新区域。
因此,使用高斯分布实行变异可以在探索新解决方案与保持当前解决方案的良好属性之间取得平衡,这将有助于在复杂的参数空间中高效搜索最优解。
我们还可以使用幂律分布来实行变异过程。与高斯分布不同,幂律分布的尾部更重,这意味着出现较大参数变化的可能性更大,这在需要更彻底地探索参数空间的情况下可能是有用的。幂律分布可以帮助算法“跳出”局部陷阱。
我们也可以选择第三种方案——均匀分布,该方案使得选择锁盘上任意数字的概率相等。
现在,我们会从理论部分转向编写代码和实践研究。
在代表问题解决方案的智能体CLA算法中,我们使用S_CLA_Agent结构来描述锁。以下是其主要组成部分:
- f表示一个智能体的适应度。它被初始化为 -DBL_MAX,这是 double 类型所能取到的最小值。
- struct S_Lock是一个嵌套结构,包含了一个名为 lock的数组。这个数组用于存储单个任务参数(正在被优化)的代码组合。
- S_Lock code[]是 S_Lock结构体数组。整个数组构成了一个“锁”。
- void Init (int coords, int lockDiscs)是一个初始化函数。它接受两个参数:coords 定义了参数集的数量,而lockDiscs定义了每个参数集中的盘片数量。在函数内部,初始化code数组。
总体来说,该结构代表了 CLA优化算法中的一个智能体。每个智能体都有自己的适应度和锁组合描述,这些将在执行算法的过程中逐渐优化。
//—————————————————————————————————————————————————————————————————————————————— struct S_CLA_Agent { double f; //fitness struct S_Lock { int lock []; }; S_Lock code []; void Init (int coords, int lockDiscs) { f = -DBL_MAX; ArrayResize (code, coords); for (int i = 0; i < coords; i++) { ArrayResize (code [i].lock, lockDiscs); } } }; //——————————————————————————————————————————————————————————————————————————————
现在,我们来描述从C_AO类派生的C_AO_CLA类。主要类组件如下:
- C_AO_CLA () - 类构造函数,用于初始化类对象。在构造函数内部,诸如 popSize(种群大小)、lockDiscs(锁盘片数量)、copyProb(复制概率)、rotateProb(旋转概率)和 params(参数数组)等参数被初始化。
- SetParams() - 根据params数组中的值设置算法参数。
- Init ()是一个初始化函数,它接受搜索范围和迭代次数作为参数。
- Moving ()和 Revision ()是用于执行算法主要逻辑的函数。
- lockDiscs、copyProb和rotateProb 用于存储算法参数的变量。
- S_CLA_Agent agent[]是智能体的一个数组。每个智能体都是 S_CLA_Agent结构体的一个对象。
- maxLockNumber、S_CLA_Agent parents[]和S_CLA_Agent parTemp[]是在类的内部使用的私有变量和数组。
- ArrayToNumber ()和LockToDouble ()是私有方法,分别用于将代码组合数组转换为数字,以及将锁转换为浮点数。
//—————————————————————————————————————————————————————————————————————————————— class C_AO_CLA : public C_AO { public: //-------------------------------------------------------------------- ~C_AO_CLA () { } C_AO_CLA () { ao_name = "CLA"; ao_desc = "Code Lock Algorithm"; ao_link = "https://www.mql5.com/ru/articles/14878"; popSize = 100; //population size lockDiscs = 8; //lock discs copyProb = 0.8; //copying probability rotateProb = 0.03; //rotate disc probability ArrayResize (params, 4); params [0].name = "popSize"; params [0].val = popSize; params [1].name = "lockDiscs"; params [1].val = lockDiscs; params [2].name = "copyProb"; params [2].val = copyProb; params [3].name = "rotateProb"; params [3].val = rotateProb; } void SetParams () { popSize = (int)params [0].val; lockDiscs = (int)params [1].val; copyProb = params [2].val; rotateProb = params [3].val; } bool Init (const double &rangeMinP [], //minimum search range const double &rangeMaxP [], //maximum search range const double &rangeStepP [], //step search const int epochsP = 0); //number of epochs void Moving (); void Revision (); void Injection (const int popPos, const int coordPos, const double value); //---------------------------------------------------------------------------- int lockDiscs; //lock discs double copyProb; //copying probability double rotateProb; //rotate disc probability S_CLA_Agent agent []; private: //------------------------------------------------------------------- int maxLockNumber; //max lock number S_CLA_Agent parents []; S_CLA_Agent parTemp []; int ArrayToNumber (int &arr []); double LockToDouble (int lockNum, int coordPos); }; //——————————————————————————————————————————————————————————————————————————————
在C_AO_CLA类中定义Init方法。此方法使用给定的搜索范围和迭代次数来初始化算法。各步骤的描述如下:
1. if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false; - 在指定的搜索范围内调用StandardInit函数。如果初始化失败,函数返回'false'。
2. ArrayResize (agent, popSize); - 将'agent'数组调整为popSize种群规模。
3. for (int i = 0; i < popSize; i++) agent [i].Init (coords, lockDiscs); - 该循环使用指定的coords坐标数量和lockDiscs锁盘数量初始化种群中的每个智能体。
4. ArrayResize (parents, popSize * 2); ArrayResize (parTemp, popSize * 2); - 将parents和parTemp数组的大小调整为两个种群的大小。
5. for (int i = 0; i < popSize * 2; i++) { parents [i].Init (coords, lockDiscs); parTemp [i].Init (coords, lockDiscs); } - 该循环用于初始化parents和parTemp数组中的每个父类个体和临时父类个体。
6. maxLockNumber = 0; for (int i = 0; i < lockDiscs; i++) { maxLockNumber += 9 * (int)pow (10, i); } - 该循环使用锁盘数量(lockDiscs)来计算maxLockNumber锁组合中的最大数字。
7. return true; - 如果之前所有操作都成功,该函数返回'true'。
该函数在CLA代码锁优化算法中初始化agent和parent ,并根据锁盘的数量设置锁组合的最大数量。
//—————————————————————————————————————————————————————————————————————————————— bool C_AO_CLA::Init (const double &rangeMinP [], //minimum search range const double &rangeMaxP [], //maximum search range const double &rangeStepP [], //step search const int epochsP = 0) //number of epochs { if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false; //---------------------------------------------------------------------------- ArrayResize (agent, popSize); for (int i = 0; i < popSize; i++) agent [i].Init (coords, lockDiscs); ArrayResize (parents, popSize * 2); ArrayResize (parTemp, popSize * 2); for (int i = 0; i < popSize * 2; i++) { parents [i].Init (coords, lockDiscs); parTemp [i].Init (coords, lockDiscs); } maxLockNumber = 0; for (int i = 0; i < lockDiscs; i++) { maxLockNumber += 9 * (int)pow (10, i); } return true; } //——————————————————————————————————————————————————————————————————————————————
数字组合锁的选择在C_AO_CLA类的Moving 方法中已描述。其遵循如下过程:
- val = 0.0; code = 0; pos = 0; - 初始化该方法中需要使用的变量。
- if (!revision) {...} - 如果revision是'false',执行代码块。在这段代码中,用随机值初始化智能体和父类。
- 然后,为每个智能体和父类计算code 和val值,并使用这些值来更新智能体的坐标。之后,将revision设置为'true',表示函数执行完毕。
- for (int i = 0; i < popSize; i++) {...} - 当revision为'true'时,执行代码块。在该代码块内部,对智能体进行更新。如果生成的随机数小于copyProb,则将其中一个父类的锁代码复制到智能体上。否则,将智能体的锁代码更新为一个随机值或其中一个父类的锁代码。
- 然后,为每个智能体重新计算code和val值。这些值用于更新智能体的坐标。
在CLA优化算法中,用该函数更新智能体。
//—————————————————————————————————————————————————————————————————————————————— void C_AO_CLA::Moving () { double val = 0.0; int code = 0; int pos = 0; //---------------------------------------------------------------------------- if (!revision) { for (int i = 0; i < popSize; i++) { for (int c = 0; c < coords; c++) { for (int l = 0; l < lockDiscs; l++) { agent [i].code [c].lock [l] = u.RNDminusOne (10); } code = ArrayToNumber (agent [i].code [c].lock); val = LockToDouble (code, c); a [i].c [c] = u.SeInDiSp (val, rangeMin [c], rangeMax [c], rangeStep [c]); } } for (int i = 0; i < popSize * 2; i++) { for (int c = 0; c < coords; c++) { for (int l = 0; l < lockDiscs; l++) { parents [i].code [c].lock [l] = u.RNDminusOne (10); } } } revision = true; return; } //---------------------------------------------------------------------------- for (int i = 0; i < popSize; i++) { for (int c = 0; c < coords; c++) { if (u.RNDprobab () < copyProb) { int pos = u.RNDminusOne (popSize); ArrayCopy (agent [i].code [c].lock, parents [pos].code [c].lock, 0, 0, WHOLE_ARRAY); } else { for (int l = 0; l < lockDiscs; l++) { if (u.RNDprobab () < rotateProb) { //pos = u.RNDminusOne (popSize); //agent [i].code [c].lock [l] = (int)round (u.GaussDistribution (agent [i].codePrev [c].lock [l], 0, 9, 8)); //agent [i].code [c].lock [l] = (int)round (u.PowerDistribution (agent [i].codePrev [c].lock [l], 0, 9, 20)); agent [i].code [c].lock [l] = u.RNDminusOne (10); } else { pos = u.RNDminusOne (popSize); agent [i].code [c].lock [l] = parents [pos].code [c].lock [l]; } } } code = ArrayToNumber (agent [i].code [c].lock); val = LockToDouble (code, c); a [i].c [c] = u.SeInDiSp (val, rangeMin [c], rangeMax [c], rangeStep [c]); } } } //——————————————————————————————————————————————————————————————————————————————通常用C_AO_CLA类中的Revision方法更新全局解决方案。该方法执行以下操作:
- ind = -1; - 初始化变量ind,用于追踪具有最优适应度的智能体的索引。
- for (int i = 0; i < popSize; i++) {...} - 循环遍历种群中的每个智能体,并检查其适应度是否超过当前的最优适应度值fB。如果确实如此,则更新fB,并将ind设置为当前索引。
- if (ind != -1) ArrayCopy (cB, a [ind].c, 0, 0, WHOLE_ARRAY); - 如果找到了具有最优适应度的智能体,则将其坐标复制到cB中。
- for (int i = 0; i < popSize; i++) { agent [i].f = a [i].f; } - 循环根据a数组中的当前值更新每个智能体的适应度。
- for (int i = 0; i < popSize; i++) { parents [i + popSize] = agent [i]; } - 该循环从popSize位置开始,将每个智能体复制到parents数组中,即父类种群的第二半部分。
- u.Sorting (parents, parTemp, popSize * 2); - 使用字符串排序方法,将parTemp数组作为临时存储,对parents数组进行排序。
//—————————————————————————————————————————————————————————————————————————————— void C_AO_CLA::Revision () { //---------------------------------------------------------------------------- int ind = -1; for (int i = 0; i < popSize; i++) { if (a [i].f > fB) { fB = a [i].f; ind = i; } } if (ind != -1) ArrayCopy (cB, a [ind].c, 0, 0, WHOLE_ARRAY); //---------------------------------------------------------------------------- for (int i = 0; i < popSize; i++) { agent [i].f = a [i].f; } for (int i = 0; i < popSize; i++) { parents [i + popSize] = agent [i]; } u.Sorting (parents, parTemp, popSize * 2); } //——————————————————————————————————————————————————————————————————————————————
ArrayToNumber方法将代码组合中的字符转换为一个数字。该方法具体如下:
- result = 0; - 初始化用于存储结果的变量。
- for (int i = 0; i < ArraySize (arr); i++) {...} - 循环遍历 arr 数组的每个元素。对于每个 arr[i] 元素,要将当前result值乘以 10 并加上 arr[i]。
- return result; - 方法返回最终的result值。
总体来说,该方法通过将数组中的每个元素解释为数字十进制表示中的一位,从而将一个整数数组转换成为一个单一的整数。
例如,arr 输入数组(代码组合)的值:|0|3|1|5|7|0|。我们需要去掉组合中所有左边的零,并从3的值开始构成数字。所得数字是31570。如果组合中的所有单元格都包含零,则最终数字将为 0。
//—————————————————————————————————————————————————————————————————————————————— int C_AO_CLA::ArrayToNumber (int &arr []) { int result = 0; for (int i = 0; i < ArraySize (arr); i++) { result = result * 10 + arr [i]; } return result; } //——————————————————————————————————————————————————————————————————————————————
C_AO_CLA类中的LockToDouble方法将组合码的数字转换为优化参数。以下是该函数的功能说明:
- LockToDouble (int lockNum, int coordPos) - 该方法需要获取两个参数:lockNum是锁的编号(即特定coordPos位置的锁编号),coordPos是坐标数组中的坐标位置(即优化参数的位置)。
- return u.Scale (lockNum, 0, maxLockNumber, rangeMin [coordPos], rangeMax [coordPos]); - 该字符串返回lockNum 从 [0, maxLockNumber]范围缩放到[rangeMin [coordPos], rangeMax [coordPos]]范围而获得的值。
一般来说,该方法用于根据给定的范围将锁的编号转换为浮点数。换句话说,锁的编号被转换为优化任务的参数值。
//—————————————————————————————————————————————————————————————————————————————— double C_AO_CLA::LockToDouble (int lockNum, int coordPos) { return u.Scale (lockNum, 0, maxLockNumber, rangeMin [coordPos], rangeMax [coordPos]); } //——————————————————————————————————————————————————————————————————————————————
3. 测试结果
CLA优化算法在测试函数上的结果表现优异。达到最大可能值的67.86%是一个极佳的结果。这证明了CLA算法在优化复杂函数方面体现出的高性能。
这些结果表明,CLA算法相当有效,可以成功应用于需要优化多维函数的各种问题中。其可扩展性和处理复杂问题的能力使其成为广泛解决优化问题的一种有效的工具。
CLA|Code Lock Algorithm|100.0|8.0|0.8|0.03|
=============================
5 Hilly's; Func runs: 10000; result: 0.9534490932631814
25 Hilly's; Func runs: 10000; result: 0.8710742215971827
500 Hilly's; Func runs: 10000; result: 0.375900385878165
=============================
5 Forest's; Func runs: 10000; result: 0.9894215656296362
25 Forest's; Func runs: 10000; result: 0.917091907561472
500 Forest's; Func runs: 10000; result: 0.3164221021938828
=============================
5 Megacity's; Func runs: 10000; result: 0.7969230769230768
25 Megacity's; Func runs: 10000; result: 0.693846153846154
500 Megacity's; Func runs: 10000; result: 0.19303076923077062
=============================
总分: 6.10716 (67.86%)
使用该算法在对测试函数操作的可视化过程中,可以注意到在低维函数上的结果存在一定的离散性。然而,随着任务参数数量的增加,结果的离散性逐渐消失。此外,从收敛曲线(红线)的形状可以看出,该算法在处理大规模问题(1000个参数)方面具有显著潜力。这条线以加速的方式增长。如果我们取消对适应度函数运行次数的限制(我们的测试规则),算法将继续逼近全局最优解。
CLA在Hilly测试函数上
CLA在Forest测试函数上
CLA在Megacity测试函数上
代码锁算法在排行榜中位居第二位。在具有10个参数的夏普Forest函数中,CLA甚至能够超越排行榜的领头羊—BGA。所有测试函数的结果单元格颜色均为绿色(与表中列出的所有算法进行比较),这表明它在不同类型的任务上表现非常一致,在个别测试中没有出现明显的失败。”
# | AO | 说明 | Hilly值 | Hilly最终值 | Forest值 | Forest最终值 | Megacity (离散) | Megacity最终值 | 最终结果 | 最大百分比 | ||||||
10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | ||||||||
1 | BGA | 二进制遗传算法 | 0,99989 | 0,99518 | 0,42835 | 2,42341 | 0,96153 | 0,96181 | 0,32027 | 2,24360 | 0,91385 | 0,95908 | 0,24220 | 2,11512 | 6,782 | 75,36 |
2 | CLA | 密码锁算法 | 0.95345 | 0.87107 | 0.37590 | 2.20042 | 0.98942 | 0.91709 | 0.31642 | 2.22294 | 0.79692 | 0.69385 | 0.19303 | 1.68380 | 6.107 | 67.86 |
3 | (P+O)ES | (P+O) 进化策略 | 0.92256 | 0.88101 | 0.40021 | 2.20379 | 0.97750 | 0.87490 | 0.31945 | 2.17185 | 0.67385 | 0.62985 | 0.18634 | 1.49003 | 5.866 | 65.17 |
4 | CTA | 彗星尾算法 | 0.95346 | 0.86319 | 0.27770 | 2.09435 | 0.99794 | 0.85740 | 0.33949 | 2.19484 | 0.88769 | 0.56431 | 0.10512 | 1.55712 | 5.846 | 64.96 |
5 | SDSm | 随机扩散搜索 M | 0.93066 | 0.85445 | 0.39476 | 2.17988 | 0.99983 | 0.89244 | 0.19619 | 2.08846 | 0.72333 | 0.61100 | 0.10670 | 1.44103 | 5.709 | 63.44 |
6 | ESG | 社会群体的进化 | 0.99906 | 0.79654 | 0.35056 | 2.14616 | 1.00000 | 0.82863 | 0.13102 | 1.95965 | 0.82333 | 0.55300 | 0.04725 | 1.42358 | 5.529 | 61.44 |
7 | SIA | 模拟退火算法 | 0.95784 | 0.84264 | 0.41465 | 2.21513 | 0.98239 | 0.79586 | 0.20507 | 1.98332 | 0.68667 | 0.49300 | 0.09053 | 1.27020 | 5.469 | 60.76 |
8 | TSEA | 龟壳演化算法 | 0.96798 | 0.64480 | 0.29672 | 1.90949 | 0.99449 | 0.61981 | 0.22708 | 1.84139 | 0.69077 | 0.42646 | 0.13598 | 1.25322 | 5.004 | 55.60 |
9 | DE | 差分进化 | 0.95044 | 0.61674 | 0.30308 | 1.87026 | 0.95317 | 0.78896 | 0.16652 | 1.90865 | 0.78667 | 0.36033 | 0.02953 | 1.17653 | 4.955 | 55.06 |
10 | BSA | 鸟群算法 | 0.89306 | 0.64900 | 0.26250 | 1.80455 | 0.92420 | 0.71121 | 0.24939 | 1.88479 | 0.69385 | 0.32615 | 0.10012 | 1.12012 | 4.809 | 53.44 |
11 | HS | 和声搜索 | 0.86509 | 0.68782 | 0.32527 | 1.87818 | 0.99999 | 0.68002 | 0.09590 | 1.77592 | 0.62000 | 0.42267 | 0.05458 | 1.09725 | 4.751 | 52.79 |
12 | SSG | 树苗播种和生长 | 0.77839 | 0.64925 | 0.39543 | 1.82308 | 0.85973 | 0.62467 | 0.17429 | 1.65869 | 0.64667 | 0.44133 | 0.10598 | 1.19398 | 4.676 | 51.95 |
13 | (PO)ES | (PO) 进化策略 | 0.79025 | 0.62647 | 0.42935 | 1.84606 | 0.87616 | 0.60943 | 0.19591 | 1.68151 | 0.59000 | 0.37933 | 0.11322 | 1.08255 | 4.610 | 51.22 |
14 | BSO | 头脑风暴优化 | 0.93736 | 0.57616 | 0.29688 | 1.81041 | 0.93131 | 0.55866 | 0.23537 | 1.72534 | 0.55231 | 0.29077 | 0.11914 | 0.96222 | 4.498 | 49.98 |
15 | WOAm | 鲸鱼优化算法M | 0.84521 | 0.56298 | 0.26263 | 1.67081 | 0.93100 | 0.52278 | 0.16365 | 1.61743 | 0.66308 | 0.41138 | 0.11357 | 1.18803 | 4.476 | 49.74 |
16 | ACOm | 蚁群优化 M | 0.88190 | 0.66127 | 0.30377 | 1.84693 | 0.85873 | 0.58680 | 0.15051 | 1.59604 | 0.59667 | 0.37333 | 0.02472 | 0.99472 | 4.438 | 49.31 |
17 | BFO-GA | 细菌觅食优化 - ga | 0.89150 | 0.55111 | 0.31529 | 1.75790 | 0.96982 | 0.39612 | 0.06305 | 1.42899 | 0.72667 | 0.27500 | 0.03525 | 1.03692 | 4.224 | 46.93 |
18 | MEC | 思维进化计算 | 0.69533 | 0.53376 | 0.32661 | 1.55569 | 0.72464 | 0.33036 | 0.07198 | 1.12698 | 0.52500 | 0.22000 | 0.04198 | 0.78698 | 3.470 | 38.55 |
19 | IWO | 入侵杂草优化 | 0.72679 | 0.52256 | 0.33123 | 1.58058 | 0.70756 | 0.33955 | 0.07484 | 1.12196 | 0.42333 | 0.23067 | 0.04617 | 0.70017 | 3.403 | 37.81 |
20 | Micro-AIS | 微型人工免疫系统 | 0.79547 | 0.51922 | 0.30861 | 1.62330 | 0.72956 | 0.36879 | 0.09398 | 1.19233 | 0.37667 | 0.15867 | 0.02802 | 0.56335 | 3.379 | 37.54 |
21 | COAm | 布谷鸟优化算法 M | 0.75820 | 0.48652 | 0.31369 | 1.55841 | 0.74054 | 0.28051 | 0.05599 | 1.07704 | 0.50500 | 0.17467 | 0.03380 | 0.71347 | 3.349 | 37.21 |
22 | SDOm | 螺旋动力学优化 M | 0.74601 | 0.44623 | 0.29687 | 1.48912 | 0.70204 | 0.34678 | 0.10944 | 1.15826 | 0.42833 | 0.16767 | 0.03663 | 0.63263 | 3.280 | 36.44 |
23 | NMm | Nelder-Mead方法 M | 0.73807 | 0.50598 | 0.31342 | 1.55747 | 0.63674 | 0.28302 | 0.08221 | 1.00197 | 0.44667 | 0.18667 | 0.04028 | 0.67362 | 3.233 | 35.92 |
24 | FAm | 萤火虫算法 M | 0.58634 | 0.47228 | 0.32276 | 1.38138 | 0.68467 | 0.37439 | 0.10908 | 1.16814 | 0.28667 | 0.16467 | 0.04722 | 0.49855 | 3.048 | 33.87 |
25 | GSA | 引力搜索算法 | 0.64757 | 0.49197 | 0.30062 | 1.44016 | 0.53962 | 0.36353 | 0.09945 | 1.00260 | 0.32667 | 0.12200 | 0.01917 | 0.46783 | 2.911 | 32.34 |
26 | BFO | 细菌觅食优化 | 0.61171 | 0.43270 | 0.31318 | 1.35759 | 0.54410 | 0.21511 | 0.05676 | 0.81597 | 0.42167 | 0.13800 | 0.03195 | 0.59162 | 2.765 | 30.72 |
27 | ABC | 人工蜂群 | 0.63377 | 0.42402 | 0.30892 | 1.36671 | 0.55103 | 0.21874 | 0.05623 | 0.82600 | 0.34000 | 0.14200 | 0.03102 | 0.51302 | 2.706 | 30.06 |
28 | BA | 蝙蝠算法 | 0.59761 | 0.45911 | 0.35242 | 1.40915 | 0.40321 | 0.19313 | 0.07175 | 0.66810 | 0.21000 | 0.10100 | 0.03517 | 0.34617 | 2.423 | 26.93 |
29 | SA | 模拟退火 | 0.55787 | 0.42177 | 0.31549 | 1.29513 | 0.34998 | 0.15259 | 0.05023 | 0.55280 | 0.31167 | 0.10033 | 0.02883 | 0.44083 | 2.289 | 25.43 |
30 | IWDm | 智能水滴 M | 0.54501 | 0.37897 | 0.30124 | 1.22522 | 0.46104 | 0.14704 | 0.04369 | 0.65177 | 0.25833 | 0.09700 | 0.02308 | 0.37842 | 2.255 | 25.06 |
31 | PSO | 粒子群优化 | 0.59726 | 0.36923 | 0.29928 | 1.26577 | 0.37237 | 0.16324 | 0.07010 | 0.60572 | 0.25667 | 0.08000 | 0.02157 | 0.35823 | 2.230 | 24.77 |
32 | Boids算法 | 虚拟生物算法 | 0.43340 | 0.30581 | 0.25425 | 0.99346 | 0.35718 | 0.20160 | 0.15708 | 0.71586 | 0.27846 | 0.14277 | 0.09834 | 0.51957 | 2.229 | 24.77 |
33 | MA | 猴群算法 | 0.59107 | 0.42681 | 0.31816 | 1.33604 | 0.31138 | 0.14069 | 0.06612 | 0.51819 | 0.22833 | 0.08567 | 0.02790 | 0.34190 | 2.196 | 24.40 |
34 | SFL | 混合蛙跳算法 | 0.53925 | 0.35816 | 0.29809 | 1.19551 | 0.37141 | 0.11427 | 0.04051 | 0.52618 | 0.27167 | 0.08667 | 0.02402 | 0.38235 | 2.104 | 23.38 |
35 | FSS | 鱼群搜索 | 0.55669 | 0.39992 | 0.31172 | 1.26833 | 0.31009 | 0.11889 | 0.04569 | 0.47467 | 0.21167 | 0.07633 | 0.02488 | 0.31288 | 2.056 | 22.84 |
36 | RND | 随机 | 0.52033 | 0.36068 | 0.30133 | 1.18234 | 0.31335 | 0.11787 | 0.04354 | 0.47476 | 0.25333 | 0.07933 | 0.02382 | 0.35648 | 2.014 | 22.37 |
37 | GWO | 灰狼优化算法 | 0.59169 | 0.36561 | 0.29595 | 1.25326 | 0.24499 | 0.09047 | 0.03612 | 0.37158 | 0.27667 | 0.08567 | 0.02170 | 0.38403 | 2.009 | 22.32 |
38 | CSS | 人工电场算法 | 0.44252 | 0.35454 | 0.35201 | 1.14907 | 0.24140 | 0.11345 | 0.06814 | 0.42299 | 0.18333 | 0.06300 | 0.02322 | 0.26955 | 1.842 | 20.46 |
39 | EM | 类电磁算法 | 0.46250 | 0.34594 | 0.32285 | 1.13129 | 0.21245 | 0.09783 | 0.10057 | 0.41085 | 0.15667 | 0.06033 | 0.02712 | 0.24412 | 1.786 | 19.85 |
总结
二进制遗传算法(BGA)在构建CLA的思路时起到了一定的作用。我的目标是开发一个速度更快的算法。因此,我提出了用十进制编码替换二进制编码的想法。代码锁机制成为了创建该算法的原型。事实证明,这是一个成功的解决方案。CLA的运行速度比BGA快,同时在效率方面也能成功与之竞争。此外,十进制编码在生成数字组合时允许使用不同类型的分布,这对于某些任务可能是有用的(在代码中,幂律分布和正态分布均已被注释掉,如有需要可以使用)。实验表明,在这种情况下,使用简单的均匀分布反而更为有效。
综上所述,CLA组合锁算法在所有测试函数上都表现出了卓越的性能、稳定性和效率。这表明该算法具有优秀的可扩展性,能够应对复杂问题,同时也凸显了CLA在各种优化场景中的灵活性和广阔的前景。”
图例2. 根据相关测试,将算法的颜色等级大于或等于0.99的结果以白色突出显示。
图例 3. 算法测试结果的直方图(标尺从 0 到 100,数字越大结果越好,
其中 100 是理论上的最大可能结果,将计算评级表格的脚本存档)
CLA的优缺点:
优势:
- 在各种类型的功能上表现出色。
- 实现简单。
缺点:
- 低维函数结果分散。
文章附有一个包含当前版本算法代码的归档文件。本文作者对标准算法描述的绝对准确性不承担责任。为提升搜索能力,已经对其中的许多算法进行了修改。文章中表述的结论和论断都是基于实验的结果。
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/14878



