К каждой статье я прикрепляю архив, содержащий обновленные актуальные версии кодов алгоритмов, описанных в предыдущих статьях.
感谢作者的出色工作和无偿使用的机会!
enum EFunc { Skin, Forest, Megacity, Rastrigin, Universe }; C_Function *SelectFunction (EFunc f) { C_Function *func; switch (f) { case Skin: func = new C_Skin (); return (GetPointer (func)); case Forest: func = new C_Forest (); return (GetPointer (func)); case Megacity: func = new C_Megacity (); return (GetPointer (func)); case Rastrigin: func = new C_Rastrigin (); return (GetPointer (func)); case Universe: func = new C_Universe (); return (GetPointer (func)); default: func = new C_Skin (); return (GetPointer (func)); } }
我正在研究一下代码。并用这样一个恐怖的东西取代了这个美丽的东西。
#property script_show_inputs #include <Math\Functions.mqh> //https://www.mql5.com/zh/articles/13366 template <typename T> C_Function* New( const string &ClassName ) { return((typename(T) == ClassName) ? new T : NULL); } C_Function* New2( string ClassName ) { typedef C_Function* (*TNew)( const string& ); static const TNew FuncNew[] = {New<C_Skin>, New<C_Forest>, New<C_Megacity>, New<C_Rastrigin>, New<C_Universe>}; C_Function* Res = NULL; ClassName = "class " + ClassName; for (uint i = ArraySize(FuncNew); (Res == NULL) && (bool)i--;) Res = FuncNew[i](ClassName); return(Res); } C_Function* SelectFunction2( const EFunc f ) { return(New2("C_" + EnumToString(f))); } input EFunc inFunc = Skin; void OnStart() { C_Function* Func = SelectFunction2(inFunc); if (Func != NULL) { Print(Func.GetNamFun()); delete Func; } }
谢谢,很高兴我的工作有用)))
有趣
fxsaber#:
如果我没理解错的话,所有作为类的优化算法实现都有某种未格式化的通用接口。具体来说,就是搜索云规范。
是否有可能将其形式化为某种易于使用的变体?粗略地说,有一个基类,我们从中继承所有算法的实现,然后通过虚拟函数以相同的方式使用它们。
1. 是的,我采用了简单的方法,将算法的边界条件以开放成员(数组)的形式存在。
2. 一般来说,虽然优化算法的工作逻辑千差万别,但我试图将它们统一起来,它们都有三个步骤:初始化、将代理移动到新位置和修改,以及在最后两个步骤之间计算 FF,这样就可以在用户应用程序中灵活应用算法。
3. 我曾想过把所有算法都作为一个通用类的子对象,但这有碍于文章的教学目的,变量的命名和注释是针对每种算法的,有助于更好地理解其逻辑。
4. 不过,由于第 2 点所做的工作,所有算法确实都可以统一起来。
在 Init 方法中,rangeMax 和其他边界条件应该是参数。
根据请求创建函数应该在类本身中完成(不需要字符串舞蹈,也不需要 "绑定 "类名和枚举元素的匹配片段)。这里有作者的一个变体。下面是另一个版本--类似于这样
Functions.mqh 文件:
class C_Function; // 在 FunctionInstance 基类中使用的正向声明 class FunctionInstance // 以统一方式使用所有织物的共同母体,例如以数组形式列出 { protected: C_Function *instance; public: FunctionInstance(): instance(NULL) { } ~FunctionInstance() // 析构函数提供垃圾回收功能 { if(CheckPointer(instance) == POINTER_DYNAMIC) delete instance; } virtual C_Function *create() = 0; }; template<typename T> class FunctionFabric: public FunctionInstance // 特定织物 { public: virtual T *create() override { if(instance == NULL) instance = new T; // 为简单起见,这里采用动态 "单例 "模式(可以是对象集合,也可以没有引用) return instance; } }; //------------------------------------------------------------------------------ class C_Function { public: template<typename T> static FunctionFabric<T> *fabric() { static FunctionFabric<T> singleton; // here static "singleton" is implemeted as most appropriate for fabric (no need to have more than 1 fabric per class) return &singleton; } ... }; ...
在类似这样的脚本中使用:
C_Function* NewX(const EFunc elem) { // order of initialization corresponds to EFunc enumeration static FunctionInstance *pointers[] = {C_Function::fabric<C_Skin>(), C_Function::fabric<C_Forest>(), C_Function::fabric<C_Megacity>(), C_Function::fabric<C_Rastrigin>(), C_Function::fabric<C_Universe>()}; return pointers[elem].create(); } void OnStart() { C_Function* Func = NewX(inFunc); if (Func != NULL) { Print(Func.GetNamFun()); // delete Func; // not needed anymore, fabric will do itself } }
Stanislav Korotky #:
按理说,根据请求创建函数应该在类本身中进行(而不是在类名和枚举元素的匹配片段上进行字符串舞蹈和 "绑定")。这里有作者的一个变体。这里还有另一种说法--类似于这样:
Functions.mqh 文件:
在这样的脚本中使用:
对不起,我当然错了,就在那行代码中:
static FunctionInstance *pointers[] = {C_Function::fabric<C_Skin>(), C_Function::fabric<C_Forest>(), C_Function::fabric<C_Megacity>(), C_Function::fabric<C_Rastrigin>(), C_Function::fabric<C_Universe>()};
不会为每种类型创建一个对象?
......那么,如何在整个程序期间只使用一种类型?
新文章 群体优化算法:混合蛙跳算法(SFL)已发布:
本文详细描述了混合蛙跳(Shuffled Frog-Leaping,SFL)算法及其在求解优化问题中的能力。SFL算法的灵感来源于青蛙在自然环境中的行为,为函数优化提供了一种新的方法。SFL算法是一种高效灵活的工具,能够处理各种数据类型并实现最佳解决方案。
混合蛙跳(SFL)算法是由M.Eusuff 和其他一些作者在2003年提出的。该算法结合了模因算法和粒子群算法的原理,其设计灵感来自一群青蛙在觅食过程中的行为。
SFL算法最初是作为一种求解组合优化问题的元启发式方法而开发的。它是基于数学函数和启发式搜索的使用。
SFL算法由几个相互作用的虚拟青蛙种群组成,称为模因复合体。虚拟青蛙是模因的宿主或载体,模因代表了文化进化的一个单元。每个模因复合体都使用类似于粒子群优化的方法进行独立的局部搜索,但重点是局部搜索。
为了支持全局探索,虚拟青蛙被周期性地混洗,并使用类似于混洗复杂进化(Shuffled Complex Evolution,SCE)算法的方法重组为新的模因。此外,随机虚拟青蛙在种群中被生成和替换,以允许随机生成改进的信息。
混合蛙跳是解决复杂优化问题的一种有效方法,它可以在各种应用领域实现最佳解决方案。在本文中,我们将介绍该算法的基本原理和应用,以及它的优点和局限性。
作者:Andrey Dik