根据这个代码,每个粒子都有一个当前的位置、速度和过去“最佳”点的记忆。这里,“最佳”点是指达到该粒子目标函数最高值的点(一组EA输入参数)。让我们在类里面描述一下。' `6 Y# L. ~# F$ b; e3 x
class Particle { public: double position[]; // current point double best[]; // best point known to the particle double velocity[]; // current speed double positionValue; // EA performance in current point double bestValue; // EA performance in the best point int group; Particle(const int params) { ArrayResize(position, params); ArrayResize(best, params); ArrayResize(velocity, params); bestValue = -DBL_MAX; group = -1; } };
4 `$ Z' c( R8 p4 {/ c5 W, I所有数组的大小都等于优化空间的维数,因此它等于正在优化的专家顾问参数的数目(传递给构造函数)。默认情况下,目标函数值越大,优化效果越好。因此,用最小可能的 -DBL_MAX 数值来初始化 bestValue 字段。其中一个交易指标通常被用来作为评估EA的标准,如利润、盈利能力、夏普比率等。如果通过较低值被认为更好的参数,例如回撤,来执行优化,则可以进行适当的转换以最大化相反的值。: N7 ~4 \9 d, I' q& }5 I$ m# @% x5 Q
数组和变量是公有的,以简化访问和它们的重新计算代码。严格遵守OOP原则需要使用“private”修饰符隐藏它们,并描述读取和修改方法。! ?4 b! v& {* T# m; W% T& ~; z# V, R e
除了单个粒子外,该算法还处理所谓的“拓扑”或粒子子集。它们可以根据不同的原则来创建。“社会群体拓扑”将用于我们的案例。这样的组存储有关其所有粒子中最佳位置的信息。, @* p- W9 r% M! F
class Group { private: double result; // best EA performance in the group public: double optimum[]; // best known position in the group Group(const int params) { ArrayResize(optimum, params); ArrayInitialize(optimum, 0); result = -DBL_MAX; } void assign(const double x) { result = x; } double getResult() const { return result; } bool isAssigned() { return result != -DBL_MAX; } };7 A+ y9 m- F. \. G6 i% T/ D+ |
通过在粒子类的“group”字段中指定组名,我们可以指示粒子所属的组(见上文)。
- D' k; i' W- {现在,让我们继续对粒子群算法本身进行编码。它将作为一个单独的类实现。让我们从粒子和群的数组开始。0 J, y% _" g u, _
class Swarm { private: Particle *particles[]; Group *groups[]; int _size; // number of particles int _globals; // number of groups int _params; // number of parameters to optimize9 h1 {) `+ Q2 B; L1 {# l
对于每个参数,我们需要指定执行优化的值的范围,以及增量(步长)。, U B- f9 b, K( Q9 A$ y
double highs[]; double lows[]; double steps[]; |