Diskussion zum Artikel "Algorithmen zur Optimierung mit Populationen: Shuffled Frog-Leaping Algorithmus (SFL)"

 

Neuer Artikel Algorithmen zur Optimierung mit Populationen: Shuffled Frog-Leaping Algorithmus (SFL) :

Der Artikel enthält eine detaillierte Beschreibung des Shuffled-Frog-Leaping-Algorithmus (SFL) und seiner Fähigkeiten bei der Lösung von Optimierungsproblemen. Der SFL-Algorithmus ist vom Verhalten der Frösche in ihrer natürlichen Umgebung inspiriert und bietet einen neuen Ansatz zur Funktionsoptimierung. Der SFL-Algorithmus ist ein effizientes und flexibles Werkzeug, das eine Vielzahl von Datentypen verarbeiten und optimale Lösungen erzielen kann.

Der Shuffled-Frog-Leaping-Algorithmus (SFL) wurde von М. Eusuff und anderen Autoren im Jahr 2003 vorgeschlagen. Dieser Algorithmus kombiniert die Prinzipien des memetischen Algorithmus und des Partikelschwarm-Algorithmus, und sein Design wurde durch das Verhalten einer Gruppe von Fröschen bei der Nahrungssuche inspiriert.

Der SFL-Algorithmus wurde ursprünglich als metaheuristische Methode zur Lösung von kombinatorischen Optimierungsproblemen entwickelt. Sie basiert auf der Verwendung mathematischer Funktionen und einer fundierten heuristischen Suche.

Der SFL-Algorithmus besteht aus mehreren interagierenden virtuellen Froschpopulationen, den sogenannten Memeplexen. Virtuelle Frösche fungieren als Wirte oder Träger von Memen, wobei ein Mem eine Einheit der kulturellen Evolution darstellt. Jeder Memeplex wird einer unabhängigen lokalen Suche unterzogen, wobei eine Methode ähnlich der Partikelschwarm-Optimierung angewandt wird, bei der jedoch der Schwerpunkt auf der lokalen Suche liegt.

Um die globale Exploration zu unterstützen, werden die virtuellen Frösche in regelmäßigen Abständen neu gemischt und in neue Memeplexe umorganisiert, wobei eine dem Algorithmus „Shuffled Complex Evolution“ ähnliche Methode verwendet wird. Außerdem werden zufällige, virtuelle Frösche generiert und in der Population ersetzt, um eine zufällige Generierung von besseren Informationen zu ermöglichen.

Das Shuffled-Frog-Leaping ist eine effektive Methode zur Lösung komplexer Optimierungsprobleme. Es kann in verschiedenen Anwendungsbereichen optimale Lösungen erzielen. In diesem Artikel werden wir die Grundprinzipien und Anwendungen dieses Algorithmus sowie seine Vorteile und Grenzen erläutern.

Autor: Andrey Dik

 
К каждой статье я прикрепляю архив, содержащий обновленные актуальные версии кодов алгоритмов, описанных в предыдущих статьях.

Vielen Dank an den Autor für seine großartige Arbeit und die unentgeltliche Möglichkeit, sie zu nutzen!


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));
  }
}

Ich schaue mir den Code ein wenig. Und ersetzt diese Schönheit mit einem solchen Horror.

#property script_show_inputs

#include <Math\Functions.mqh> // https://www.mql5.com/de/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 #:

Ich schaue mir den Code ein wenig an.

Wenn ich es richtig verstehe, haben alle Implementierungen von Optimierungsalgorithmen in Form von Klassen eine unformatierte gemeinsame Schnittstelle. Insbesondere die Einstellung der Suchwolke.

  public: double rangeMax  []; //Maximaler Suchbereich
  public: double rangeMin  []; //minimaler Suchbereich
  public: double rangeStep []; //Schritt Suche

Ist es möglich, dies in einer einfach zu verwendenden Variante zu formalisieren? Grob gesagt, gibt es eine Basisklasse, von der wir die Implementierungen aller Algorithmen erben und sie dann auf die gleiche Weise durch virtuelle Funktionen verwenden.

 
fxsaber #:

Vielen Dank an den Autor für seine großartige Arbeit und für die unentgeltliche Möglichkeit, sie zu nutzen!

Danke, freut mich, dass meine Arbeit nützlich ist)))

fxsaber #:

Habe mir den Code ein wenig angeschaut. Und ersetzte diese Schönheit mit einem solchen Horror.

interessant

fxsaber #:

Wenn ich es richtig verstehe, haben alle Implementierungen von Optimierungsalgorithmen als Klassen eine Art unformatierte gemeinsame Schnittstelle. Genauer gesagt, die Spezifikation der Suchwolke.

Ist es möglich, sie in einer einfach zu verwendenden Variante zu formalisieren? Grob gesagt gibt es eine Basisklasse, von der wir die Implementierungen aller Algorithmen erben und sie dann auf die gleiche Weise durch virtuelle Funktionen verwenden.

1. Ja, ich habe den einfachen Weg gewählt und die Randbedingungen der Algorithmen in Form von offenen Mitgliedern - Arrays - gemacht.

2. Im Allgemeinen gibt es zwar eine große Vielfalt an Optimierungsalgorithmen in Bezug auf die Logik ihrer Arbeit, aber ich habe versucht, sie alle einheitlich zu gestalten. Sie haben alle drei Schritte: Initialisierung, Verschieben von Agenten zu neuen Positionen und Revision, und zwischen den letzten beiden die Berechnung der FF, was eine flexible Anwendung der Algorithmen in Benutzeranwendungen ermöglicht.

3. ich hatte die Idee, alle Algorithmen als Kindobjekte einer generischen Klasse zu machen, aber das verhindert für die Lehrzwecke der Artikel, Variablen werden spezifisch für jeden Algorithmus benannt und kommentiert und helfen, die Logik besser zu verstehen.

4. Es stimmt jedoch, dass alle Algorithmen dank der in Punkt 2 geleisteten Arbeit vereinheitlicht und auf einen einheitlichen Stand gebracht werden können.


Der BereichMax und andere Randbedingungen sollten Argumente in der Init-Methode sein.

 
fxsaber #:


Ich schaue mir den Code ein wenig an. Ich ersetzte diese Schönheit mit einem solchen Horror.

Die Erstellung einer Funktion auf Anfrage sollte in der Klasse selbst erfolgen (ohne Stringtänze und "Anbinden" an passende Fragmente von Klassennamen und Aufzählungselementen). Da gibt es eine Variante des Autors. Hier ist eine andere - etwa so:

Functions.mqh-Datei:

class C_Function; // Forward-Deklaration zur Verwendung in der Basisklasse FunctionInstance

class FunctionInstance // gemeinsames übergeordnetes Element für alle Stoffe, die auf einheitliche Weise verwendet werden sollen, z. B. in einem Array aufgelistet
{
  protected:
    C_Function *instance;
  public:
    FunctionInstance(): instance(NULL) { }
    ~FunctionInstance()                    // Destruktor sorgt für Garbage Collection
    {
      if(CheckPointer(instance) == POINTER_DYNAMIC) delete instance;
    }
    virtual C_Function *create() = 0;
};

template<typename T>
class FunctionFabric: public FunctionInstance // spezifischer Stoff
{
  public:
    virtual T *create() override
    {
      if(instance == NULL) instance = new T; // hier wird der Einfachheit halber ein dynamisches "Singleton"-Muster implementiert (könnte eine Sammlung von Objekten oder überhaupt keine Referenzen sein)
      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;
  }
  ...
};
...

Verwendung in einem Skript wie diesem:

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 #:

Auf jeden Fall sollte die Erstellung einer Funktion auf Anfrage in der Klasse selbst erfolgen (ohne Stringtänze und "Anbinden" an passende Fragmente von Klassennamen und Aufzählungselementen). Da gibt es eine Variante des Autors. Hier ist eine andere - etwa so:

Functions.mqh-Datei:

Verwendung in einem Skript wie diesem:

Zwei Argumente gegen diese Option.

  1. Verweigerung der Angabe einer Funktion durch eine Zeichenkette - Verweigerung der Angabe von Robotereinstellungen über eine Ini-Datei.
  2. Singleton - Verweigerung der parallelen Arbeit von mehreren identischen Robotern mit unterschiedlichen Einstellungen.
 
fxsaber #:

Zwei Argumente sprechen gegen diese Option.

  1. Verweigerung der Angabe einer Funktion durch einen String - Verweigerung der Angabe von Robotereinstellungen über eine Ini-Datei.
  2. Singleton - Verweigerung der parallelen Arbeit von mehreren identischen Robotern mit unterschiedlichen Einstellungen.

Ich habe es nur skizziert, weil, wenn ich schon ein paar Tricks erfinden will, dann ohne potentielle Probleme - ich wurde durch die Verwendung von Schleifen mit Stringsuche (!) "angefixt" - kann es in größeren Programmen super ineffizient sein.

Nicht nur String-Parameter in der Ini-Datei, sondern auch andere Typen (wenn auch durch Text dargestellt).

Ein Singleton bei einer Fabrik ist in Ordnung. Singleton bei Funktionsobjekt - in diesem Fall nur für die Funktionsfähigkeit des Beispiels - Sie können Multiplizität implementieren.

 
Stanislav Korotky #:

Ich habe es nur skizziert, denn wenn ich schon etwas konstruiere, dann sollte es ohne potentielle Probleme sein - ich wurde durch die Verwendung einer Schleife mit Stringsuche (!) "angefixt" - das kann in größeren Programmen sehr ineffizient sein.

Die ini-Datei enthält nicht nur String-Parameter, sondern auch andere Arten von Parametern (obwohl sie durch Text dargestellt werden).

Ein Singleton bei einer Fabrik ist in Ordnung. Singleton bei Funktionsobjekt - in diesem Fall nur für die Funktionsfähigkeit des Beispiels - Sie können Multiplizität implementieren.

Ich verwende die String-Auflösung in der Initialisierungsphase. Ich glaube, das dauert weniger als eine Millisekunde. Ehrlich gesagt, habe ich keine potenziellen Probleme bemerkt.

 
fxsaber #:

Vielen Dank an den Autor für seine großartige Arbeit und für die unentgeltliche Möglichkeit, sie zu nutzen!



Ich schaue mir den Code ein wenig. Und ersetzt diese Schönheit mit einem solchen Horror.

Was ist der Gewinn? Es ist wirklich furchtbar. Sorry, wenn überhaupt)))

 
Stanislav Korotky #:

Auf jeden Fall sollte das Erstellen einer Funktion auf Anfrage in der Klasse selbst erfolgen (ohne Stringtänze und "Anbinden" an passende Fragmente von Klassennamen und Aufzählungselementen). Da gibt es eine Variante des Autors. Hier ist eine andere - etwa so:

Functions.mqh-Datei:

Verwendung in einem Skript wie diesem:

Tut mir leid, aber ich liege natürlich falsch, genau in dieser Code-Zeile:

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>()};
 

nicht für jeden Typ ein Objekt erstellt wird?

...dann wie, nur ein Typ wird während der gesamten Zeit des Programms verwendet werden.

 
Dmitry Fedoseev #:

Was ist der Gewinn? Ich meine, es ist wirklich furchtbar. Ich entschuldige mich, wenn etwas)))

Das ist eine schwierige Frage. Ich weiß es nicht.