English Русский 中文 Español 日本語 Português
preview
Artificial Tribe Algorithm (ATA)

Artificial Tribe Algorithm (ATA)

MetaTrader 5Beispiele |
93 0
Andrey Dik
Andrey Dik

Inhalt

  1. Einführung
  2. Implementierung des Algorithmus
  3. Testergebnisse


Einführung

Da sich die Technik rasant weiterentwickelt und die Optimierungsaufgaben immer komplexer werden, lassen sich Wissenschaftler und Forscher immer wieder von der Natur inspirieren. Eines der eindrucksvollsten Beispiele für diesen Ansatz ist der von den Wissenschaftlern T. Chen, Y. Wang und J. Li entwickelte und 2012 veröffentlichte Artificial Tribe Algorithm (ATA). In Anlehnung an das Verhalten von Stämmen (tribes) nutzt ATA zwei Hauptmechanismen – Ausbreitung und Migration – um sich an veränderte Bedingungen anzupassen und optimale Lösungen für eine Vielzahl von Problemen zu finden. Stellen Sie sich eine riesige Fläche vor, auf der sich Gruppen von Menschen wie ihre entfernten Vorfahren auf der Suche nach den besten Ressourcen zusammenschließen. Sie wandern, tauschen Wissen und Erfahrungen aus und entwickeln einzigartige Strategien zur Lösung komplexer Probleme. Dieses Verhalten bildete die Grundlage für die Entwicklung von ATA – dem Algorithmus, der zwei Schlüsselmechanismen harmonisch miteinander verbindet: Verteilung und Migration.

Der Artificial Tribe Algorithm ist eine völlig neue Optimierungsmethode, die auf den Prinzipien bionischer intelligenter Algorithmen beruht. Es simuliert das Verhalten natürlicher Stämme und nutzt deren Fortpflanzungs- und Wanderungsfähigkeiten, um optimale Lösungen zu erzielen. Bei diesem Algorithmus besteht der Stamm aus Individuen, die miteinander interagieren, um ein globales Optimum zu finden.


Implementierung des Algorithmus

Der Prozess des ATA-Algorithmus beginnt mit der Einstellung der Parameter und der zufälligen Initialisierung des Stammes, woraufhin der Fitnesswert berechnet wird. Anschließend wird der Iterationszähler erhöht und die aktuelle Situation des Stammes bewertet. Wenn die Situation günstig ist (der Unterschied im optimalen Fitnesswert zwischen den Generationen ist größer als ein bestimmtes Kriterium), wird ein Reproduktionsverhalten durchgeführt, bei dem die Individuen Informationen austauschen. Andernfalls wird ein Wanderverhalten angewandt, bei dem sich die Individuen auf der Grundlage der Erfahrungen des Einzelnen und des gesamten Stammes bewegen. Die Migration kann nicht kontinuierlich durchgeführt werden, um eine übermäßige Streuung zu vermeiden. Der Fitnesswert wird dann neu berechnet und mit den besten Werten verglichen, die für den Stamm und jedes Individuum aufgezeichnet wurden. Wird eine bessere Lösung gefunden, so wird diese im Speicher abgelegt. Die Abbruchbedingungen werden geprüft, und wenn sie erfüllt sind, wird die Iteration beendet. Andernfalls kehrt der Prozess zum Schritt der Situationsbewertung zurück.

Die Einbeziehung globaler Informationen in ATA verleiht der historischen Erfahrung des Stammes mehr Gewicht und hilft, bessere Lösungen zu finden und die Suchmöglichkeiten zu verbessern. Die Erhöhung des Gewichts der Erfahrung des Stammes trägt zur Verbesserung der Effizienz des Algorithmus bei und beschleunigt die Konvergenz. Um dies zu erreichen, führt ATA ein globales Trägheitsgewicht ein, das die Suchmöglichkeiten verbessert und den Prozess beschleunigt.

Die Hauptinnovation von ATA ist das Vorhandensein eines dualen Verhaltenssystems, das sich je nach Situation anpasst: Reproduktion wird für tiefe Exploration verwendet, wenn der Fortschritt gut ist, und Migration wird aktiviert, wenn man in lokalen Optima feststeckt, was eine tiefere Exploration fördert. Auch die Kombination von individuellem und sozialem Lernen ist wichtig. Der individuelle Speicher (Xs) wird während der Migration verwendet, und der globale Speicher (Xg) wird mit dem Trägheitsfaktor AT_w gewichtet. Bei der Vermehrung werden die Partner nach dem Zufallsprinzip ausgewählt, was zur Verbesserung der Vielfalt und zur Beschleunigung der Suche beiträgt.

Das Parametersystem in ATA ist einfach, aber effektiv. Es steuert die Größe der Population (tribe_size), das Kriterium für die Verhaltensumschaltung (AT_criterion) und den globalen Einfluss auf die Suche (AT_w), was den Algorithmus flexibel und leistungsfähig macht, sodass er nach Ansicht der Autoren leicht mit komplexeren Algorithmen konkurrieren kann, insbesondere bei kleinen Populationsgrößen.

Zu den Hauptkomponenten des Algorithmus gehört ein Zuchtverhalten, das angewendet wird, wenn der Fortschritt gut ist und der Unterschied in der Fitness größer als ein festgelegtes Kriterium ist. In diesem Fall tauschen die Personen Teilinformationen aus. Das Migrationsverhalten wird in einer schlechten Situation eingesetzt, in der der Unterschied in der Fitness gering ist, und beinhaltet Bewegungen, die auf individueller und globaler Erfahrung basieren, wobei das Gewicht der Trägheit berücksichtigt wird, um die globale Suche zu verbessern. Das Existenzkriterium bewertet die Veränderungen der besten Fitness zwischen den Iterationen: sind die Veränderungen signifikant, wird reproduziert, sind die Veränderungen unbedeutend, wird gewandert.

Der Algorithmus enthält auch ein System zur Aktualisierung des Gedächtnisses, das die besten Positionen sowohl für einzelne Personen als auch für den gesamten Stamm festhält. Diese Positionen werden aktualisiert, wenn neue, bessere Lösungen gefunden werden.

Zu den Konstruktionsmerkmalen von ATA gehören die Einfachheit der Parameter, die Integration von individuellem und sozialem Lernen und der selbstanpassende Wechsel zwischen Reproduktion und Migration. Die globale Trägheitsgewichtung verbessert die Suchleistung und beschleunigt die Suche nach optimalen Lösungen.

Die Regeln des individuellen Verhaltens lassen sich also wie folgt beschreiben:

1. Ausbreitung. Ein Individuum nutzt die Informationen in einer Population, um das genetische Material künftiger Generationen zu bilden. Wenn die bestehenden Umweltbedingungen günstig sind, wählt das Individuum zufällig ein anderes Individuum aus dem Stamm aus und kreuzt sich, um durch den Austausch genetischer Informationen die nächste Generation hervorzubringen.

2. Migration. Wenn die bestehende Situation schlecht ist (was bedeutet, dass der intergenerationelle Unterschied im optimalen Fitnesswert geringer ist als das bestehende Kriterium), bewegt sich das Individuum in Übereinstimmung mit seiner eigenen und der historischen Erfahrung des Stammes, um die Migration des Stammes durchzuführen.

Die wichtigsten Phasen der Algorithmuspopulation können schematisch wie folgt dargestellt werden.

ATA_2

Abbildung 1. Phasen der einzelnen Bewegungen in der Population des ATA-Algorithmus

Lassen Sie uns den Pseudocode des ATA-Algorithmus implementieren:

// Algorithmus für künstliche Stämme
// Wichtigste Parameter:
// tribe_size – Größe der Stammesbevölkerung
// ATA_criterion – Schwellenwert für das Existenzkriterium
// ATA_w – globales Trägheitsgewicht
// X – Vektor der Position der Person
// Xs – beste historische Position des Individuums
// Xg – weltweit beste historische Position des Stammes

ATA-Algorithmus:
    Initialisierung:
        Erstelle einen Stamm von Individuen der Größe tribe_size mit X zufälligen Positionen
        Berechne die anfänglichen Fitnesswerte für alle Individuen
        Initialisiere von Xs und Xg mit den besten gefundenen Positionen
        Iteration = 0
        
    Solange (iteration < max_iterations):
        iteration = iteration + 1
        
        // Prüfen, ob die Situation günstig ist
        difference = | current_best_fitness - previous_best_fitness |
        
        Wenn (difference > ATA_criterion):
            // Gute Situation – Reproduktionsverhalten ausführen
            Für jedes Individuum i:
                // Auswahl eines zufälligen Partners j aus dem Stamm
                j = random (1, tribe_size) mit j ≠ i
                
                // Reproduktionsgleichungen:
                r1 = random (0,1)
                Yi+1 = r1 * Yj + (1 - r1) * Xi  // Neue Partnerposition
                Xi+1 = r1 * Xi + (1- r1) * Yi // Neue Position der Person
                
        Andernfalls:
            // Schlechte Situation – Migrationsverhalten ausführen
            Für jedes Individuum i:
                // Migrationsgleichung:
                r1 = random (0,1)
                r2 = random (0,1)
                Xi+1 = Xi + r1 * (Xs - Xi) + ATA_w * r2 * (Xg - Xi)
                
        // Fitnesswerte und beste Positionen aktualisieren
        Für jedes Individuum i:
            Berechnung von new_fitness für Xi
            
            Wenn new_fitness besser ist als best_fitness_of_individual:
                Xs für das Individuum i aktualisieren
                
            Wenn new_fitness besser ist als global_best_fitness:
                Update Xg
                
        Aktuelle_beste_Fitness für die nächste Iteration speichern
        
    Xg als beste gefundene Lösung zurückgeben

ATA

Abbildung 2. Logisches Diagramm der Funktionsweise des ATA-Algorithmus

Definieren wir die Klasse C_AO_ATA, die den ATA-Algorithmus implementiert. Lassen Sie uns den Inhalt kurz beschreiben:

Vererbung und Hauptmitglieder:
  • Die Klasse erbt von der Basisklasse C_AO
  • Enthält einen Destruktor und einen Konstruktor
Der Konstruktor initialisiert die grundlegenden Parameter:
  • popSize = 50 (Stammesgröße)
  • AT_criterion = 0,3 (Kriterium der günstigen Lage)
  • AT_w = 1,46 (Trägheitsgewicht)
Methoden:
  • SetParams () – Parameter aus dem Array „params“ setzen
  • Init () – Initialisierung mit Suchbereichen
  • Moving () – Durchführung der Bewegung von Personen
  • Revision () – Lösungen bewerten und aktualisieren
Private Mitglieder:
  • prevBestFitness – speichert den vorherigen besten Wert zum Vergleich

Dies ist das Grundgerüst des Algorithmus, in dem alle notwendigen Parameter und Methoden für seine Funktionsweise definiert sind.

//——————————————————————————————————————————————————————————————————————————————
class C_AO_ATA : public C_AO
{
  public: //--------------------------------------------------------------------
  ~C_AO_ATA () { }
  C_AO_ATA ()
  {
    ao_name = "ATA";
    ao_desc = "Artificial Tribe Algorithm";
    ao_link = "https://www.mql5.com/en/articles/16588";

    popSize      = 50;   // Population size
    AT_criterion = 0.3;  // Criteria for assessing the current situation
    AT_w         = 1.46; // Global inertial weight

    ArrayResize (params, 3);

    // Initialize parameters
    params [0].name = "popSize";      params [0].val = popSize;
    params [1].name = "AT_criterion"; params [1].val = AT_criterion;
    params [2].name = "AT_w";         params [2].val = AT_w;
  }

  void SetParams () // Method for setting parameters
  {
    popSize      = (int)params [0].val;
    AT_criterion = params     [1].val;
    AT_w         = params     [2].val;
  }

  bool Init (const double &rangeMinP  [], // Minimum search range
             const double &rangeMaxP  [], // Maximum search range
             const double &rangeStepP [], // Search step
             const int     epochsP = 0);  // Number of epochs

  void Moving   ();       // Moving method
  void Revision ();       // Revision method

  //----------------------------------------------------------------------------
  double AT_criterion;    // Criteria for assessing the current situation
  double AT_w;            // Global inertial weight

  private: //-------------------------------------------------------------------
  double prevBestFitness; // Previous best solution
};
//——————————————————————————————————————————————————————————————————————————————

Die Methode Init der Klasse C_AO_ATA ist für die Initialisierung des Algorithmus zuständig. Zerlegen wir sie in Teile:

Parameter der Methode:
  • rangeMinP [] – Array der Mindestwerte für jede Suchdimension
  • rangeMaxP [] – Array der Höchstwerte
  • rangeStepP [] – Array der Diskretisierungsschritte
  • epochsP – Anzahl der Epochen (Standardwert 0)
Wichtigste Aktionen:
  • Aufruf von StandardInit aus der Basisklasse, um die Standardparameter zu initialisieren
  • Wenn StandardInit false zurückgibt, wird die Methode unterbrochen
  • prevBestFitness auf -DBL_MAX setzen (für die Maximierungsaufgabe)
Rückgabe:
  • true im Falle einer erfolgreichen Initialisierung
  • false , wenn die Standardinitialisierung fehlschlägt

Dies ist eine minimale Implementierung der Initialisierung, die den Algorithmus für die Arbeit vorbereitet.

//——————————————————————————————————————————————————————————————————————————————
bool C_AO_ATA::Init (const double &rangeMinP  [], // Minimum search range
                     const double &rangeMaxP  [], // Maximum search range
                     const double &rangeStepP [], // Search step
                     const int     epochsP = 0)   // Number of epochs
{
  if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false; // Initialization of standard parameters

  //----------------------------------------------------------------------------
  prevBestFitness = -DBL_MAX;
  return true;
}
//——————————————————————————————————————————————————————————————————————————————

Die Methode Moving() ist für die Bewegung von Stammesindividuen zuständig und besteht aus zwei Hauptteilen:

Wenn dies der erste Lauf ist (revision = false):
  • Platzierung aller Individuen im Suchraum nach dem Zufallsprinzip
  • bringe ihre Positionen auf akzeptable diskrete Werte
  • markiere, dass die Erstplatzierung abgeschlossen ist (revision = true)
Wenn es sich nicht um den ersten Durchlauf handelt, berechne das aktuelle Kriterium der Situation diff und ob die Situation gut ist (diff > AT_criterion):
  • jede Person wählt einen zufälligen Partner
  • sie tauschen Informationen über ihre Positionen aus
  • auf der Grundlage dieses Austauschs neue Positionen bilden
Wenn die Situation schlecht ist (diff ≤ AT_criterion), wird jedes Individuum unter Berücksichtigung folgender Faktoren bewegt:
  • seiner besten Position
  • global besten Position
  • das Trägheitsgewicht AT_w

Bei jeder Bewegung werden alle neuen Positionen überprüft und auf akzeptable Werte innerhalb der festgelegten Bereiche gebracht. Außerdem ist folgende Nuance zu beachten: Da das Kriterium für die Bewertung der Situation ein externer Parameter ist und einen dimensionslosen Wert hat, muss die Differenz zwischen der aktuell besten Fitness und der vorherigen um die Differenz zwischen der besten historischen Fitness und der schlechtesten normalisiert werden: diff = (fB – prevBestFitness) / (fB – fW). Zu diesem Zweck verfolgt dieser Algorithmus nicht nur die global beste, sondern auch die global schlechteste Lösung.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_ATA::Moving ()
{
  // Initial random positioning
  if (!revision) // If there has not been a revision yet 
  {
    for (int i = 0; i < popSize; i++) // For each particle
    {
      for (int c = 0; c < coords; c++) // For each coordinate
      {
        a [i].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);                             // Generate random position
        a [i].c [c] = u.SeInDiSp  (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); // Convert to discrete values
      }
    }

    revision = true; // Set revision flag
    return;          // Exit the method
  }

  //----------------------------------------------------------------------------
  // Check the existence criterion
  double diff = (fB - prevBestFitness) / (fB - fW);

  double Xi   = 0.0;
  double Xi_1 = 0.0;
  double Yi   = 0.0;
  double Yi_1 = 0.0;
  double Xs   = 0.0;
  double Xg   = 0.0;
  int    p    = 0;
  double r1   = 0.0;
  double r2   = 0.0;

  if (diff > AT_criterion)
  {
    // Spread behavior (good situation)
    for (int i = 0; i < popSize; i++)
    {
      for (int c = 0; c < coords; c++)
      {
        p  = u.RNDminusOne (popSize);
        r1 = u.RNDprobab ();

        Xi = a [i].cP [c];
        Yi = a [p].cP [c];

        Xi_1 = r1 * Xi + (1.0 - r1) * Yi;
        Yi_1 = r1 * Yi + (1.0 - r1) * Xi;

        a [i].c [c] = u.SeInDiSp  (Xi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
        a [p].c [c] = u.SeInDiSp  (Yi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
      }
    }
  }
  else
  {
    // Migration behavior (bad situation)
    for (int i = 0; i < popSize; i++)
    {
      for (int c = 0; c < coords; c++)
      {
        r1 = u.RNDprobab ();
        r2 = u.RNDprobab ();

        Xi = a [i].cP [c];
        Xs = a [i].cB [c];
        Xg = cB [c];

        Xi_1 = Xi + r1 * (Xs - Xi) + AT_w * r2 * (Xg - Xi);

        a [i].c [c] = u.SeInDiSp (Xi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
      }
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

Revision () ist für die Bewertung und Aktualisierung der besten Lösungen nach dem Umzug von Personen zuständig. Dies ist die Funktion:

Für alle Individuen des Stammes:
    • Prüfe, ob die global beste Lösung (fB) verbessert wurde
    • Aktualisiere der schlechtesten gefundenen Lösung (fW)
    • Überprüfe und Aktualisierung der persönlichen besten Lösung jedes Einzelnen (a [i].fB)
    • Speichere die aktuelle Positionen als vorherige (in cP)
    Wenn die neue beste Lösung gefunden ist (indB ist nicht -1):
      • Speichere den vorherigen besten Wert (prevBestFitness = tempB)
      • Kopiere die Koordinaten des besten Individuums in die globale beste Lösung (cB)

      Im Wesentlichen handelt es sich dabei um eine Methode zur „Überprüfung“ des aktuellen Zustands des Stammes, bei der alle wichtigen Indikatoren aktualisiert werden: die globalen besten/schlechtesten Werte, die persönlichen besten Werte jedes Einzelnen, und der Verlauf der Positionen wird gespeichert.

      //——————————————————————————————————————————————————————————————————————————————
      void C_AO_ATA::Revision ()
      {
        //----------------------------------------------------------------------------
        int    indB  = -1;                // Best particle index
        double tempB = fB;
      
        for (int i = 0; i < popSize; i++) // For each particle
        {
          if (a [i].f > fB)               // If the function value is better than the current best one
          {
            fB   = a [i].f;               // Update the best value of the function
            indB = i;                     // Save the index of the best particle
          }
      
          if (a [i].f < fW)               // If the function value is worse than the current worst one
          {
            fW   = a [i].f;               // Update the worst value of the function
          }
      
          if (a [i].f > a [i].fB)
          {
            a [i].fB = a [i].f;
            ArrayCopy (a [i].cB, a [i].c, 0, 0, WHOLE_ARRAY);
          }
      
          ArrayCopy (a [i].cP, a [i].c, 0, 0, WHOLE_ARRAY);
        }
      
        if (indB != -1)
        {
          prevBestFitness = tempB;
          ArrayCopy (cB, a [indB].c, 0, 0, WHOLE_ARRAY); // Copy the coordinates of the best particle
        }
      }
      //——————————————————————————————————————————————————————————————————————————————
      

      Kommen wir nun zu den Ergebnissen der Prüfung des ATA-Algorithmus auf dem Prüfstand.

      ATA|Artificial Tribe Algorithm|50.0|0.3|0.5|
      =============================
      5 Hilly's; Func runs: 10000; result: 0.540711768815426
      25 Hilly's; Func runs: 10000; result: 0.31409437631469717
      500 Hilly's; Func runs: 10000; result: 0.2512638813618161
      =============================
      5 Forest's; Func runs: 10000; result: 0.40309649266442193
      25 Forest's; Func runs: 10000; result: 0.2572536671383149
      500 Forest's; Func runs: 10000; result: 0.18349902023635473
      =============================
      5 Megacity's; Func runs: 10000; result: 0.24
      25 Megacity's; Func runs: 10000; result: 0.13600000000000004
      500 Megacity's; Func runs: 10000; result: 0.09518461538461616
      =============================
      All score: 2.42110 (26.90%)

      Wie aus dem Ausdruck der Ergebnisse des Algorithmus und der Visualisierung ersichtlich ist, kann der Algorithmus mit den vorliegenden Parametern nicht in unsere Bewertungstabelle gelangen. Die Visualisierung unten zeigt die schwache Fähigkeit des Algorithmus, lokalen Fallen zu entgehen. Dem Algorithmus fehlt es eindeutig an Vielfalt in der Lösungspopulation, was zu seiner Degeneration führt.

      Hilly Orig

      ATAm mit dem Test Hilly

      Wir wollen versuchen, den ATA-Algorithmus zu verbessern, indem wir uns auf die mangelnde Vielfalt der Lösungen in der Population konzentrieren. Dies ist ein wichtiger Aspekt, denn Vielfalt ist der Schlüssel für eine effektive Suche im Lösungsraum. In unserer Modifikation werden wir eine dynamische Wahrscheinlichkeit einführen, die vom Zustand der Fitness der Bevölkerung abhängt.

      Wenn die Population auf einen engen Bereich des Lösungsraums komprimiert wird, kann dies dazu führen, dass der Algorithmus in einem lokalen Optimum stecken bleibt. Genau wie in der ursprünglichen Version des Algorithmus verfolgen wir die Differenz zwischen der aktuellen und der vorherigen besten globalen Lösung, aber wenn sich diese Differenz als zu gering herausstellt, ist dies ein Signal dafür, dass die Population nicht vielfältig genug ist und sich dem Zusammenbruch der Lösung nähert.

      Um dies zu verhindern, werden wir mit einer gewissen Wahrscheinlichkeit Personen ausschließen, die weit von der aktuellen Gesamtlösung entfernt sind. Dies geschieht innerhalb der akzeptablen Grenzen der Aufgabe, wodurch sichergestellt wird, dass die Bedingungen der Aufgabe erfüllt werden und eine Überschreitung verhindert wird. Wir werden die Normalverteilung verwenden, um zu bestimmen, wie weit die verworfenen Individuen von der aktuellen globalen Lösung entfernt sind.

      Interessanterweise ist die Wahrscheinlichkeit solcher Ausreißer umso höher, je größer der Unterschied zwischen der aktuellen und der vorherigen besten Lösung (bezeichnet als „diff“) ist. Dies ermöglicht uns, adaptiv auf den Zustand der Population zu reagieren: Wenn sie anfängt, festzustecken, werden wir die Migrationsphase aktiver nutzen, was wiederum die Chancen erhöht, das lokale Optimum zu verlassen und optimalere Lösungen zu finden.

      Unsere Änderung des ATA-Algorithmus wird also nicht nur dazu beitragen, die Vielfalt der Lösungen zu erhalten, sondern auch die Gesamteffizienz der Suche im Lösungsraum verbessern. Dies kann zu nachhaltigeren Ergebnissen und einer höheren Qualität der gefundenen Lösungen führen.

      //——————————————————————————————————————————————————————————————————————————————
      void C_AO_ATAm::Moving ()
      {
        // Initial random positioning
        if (!revision) // If there has not been a revision yet 
        {
          for (int i = 0; i < popSize; i++) // For each particle
          {
            for (int c = 0; c < coords; c++) // For each coordinate
            {
              a [i].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);                             // Generate random position
              a [i].c [c] = u.SeInDiSp  (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); // Convert to discrete values
            }
          }
      
          revision = true; // Set revision flag
          return;          // Exit the method
        }
      
        //----------------------------------------------------------------------------
        // Check the existence criterion
        double diff = (fB - prevBestFitness) / (fB - fW);
      
        double Xi   = 0.0;
        double Xi_1 = 0.0;
        double Yi   = 0.0;
        double Yi_1 = 0.0;
        double Xs   = 0.0;
        double Xg   = 0.0;
        int    p    = 0;
        double r1   = 0.0;
        double r2   = 0.0;
      
        if (diff > AT_criterion)
        {
          // Spread behavior (good situation)
          for (int i = 0; i < popSize; i++)
          {
            for (int c = 0; c < coords; c++)
            {
              p  = u.RNDminusOne (popSize);
              r1 = u.RNDprobab ();
      
              Xi = a [i].cP [c];
              Yi = a [p].cP [c];
      
              Xi_1 = r1 * Xi + (1.0 - r1) * Yi;
              Yi_1 = r1 * Yi + (1.0 - r1) * Xi;
      
              a [i].c [c] = u.SeInDiSp  (Xi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
              a [p].c [c] = u.SeInDiSp  (Yi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
            }
          }
        }
        else
        {
          // Migration behavior (bad situation)
          for (int i = 0; i < popSize; i++)
          {
            for (int c = 0; c < coords; c++)
            {
              if (u.RNDprobab () < diff)
              {
                Xi_1 = u.GaussDistribution (cB [c], rangeMin [c], rangeMax [c], 1);
                a [i].c [c] = u.SeInDiSp (Xi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
              }
              else
              {
                r1 = u.RNDprobab ();
                r2 = u.RNDprobab ();
      
                Xi = a [i].cP [c];
                Xs = a [i].cB [c];
                Xg = cB [c];
      
                Xi_1 = Xi + r1 * (Xs - Xi) + AT_w * r2 * (Xg - Xi);
      
                a [i].c [c] = u.SeInDiSp (Xi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
              }
            }
          }
        }
      }
      //——————————————————————————————————————————————————————————————————————————————
      


      Testergebnisse

      Ergebnisse der modifizierten Version des ATAm-Algorithmus:

      ATAm|Artificial Tribe Algorithm M|50.0|0.9|0.8|
      =============================
      5 Hilly's; Func runs: 10000; result: 0.7177133636761123
      25 Hilly's; Func runs: 10000; result: 0.553035897955171
      500 Hilly's; Func runs: 10000; result: 0.25234636879284034
      =============================
      5 Forest's; Func runs: 10000; result: 0.8249072382287125
      25 Forest's; Func runs: 10000; result: 0.5590392181296365
      500 Forest's; Func runs: 10000; result: 0.2047284499286112
      =============================
      5 Megacity's; Func runs: 10000; result: 0.43999999999999995
      25 Megacity's; Func runs: 10000; result: 0.18615384615384617
      500 Megacity's; Func runs: 10000; result: 0.09410769230769304
      =============================
      All score: 3.83203 (42.58%)

      Diesmal waren die Ergebnisse vielversprechender und sind bereits jetzt der Aufnahme in die Bewertungstabelle würdig, die es uns ermöglichen wird, einen weiteren Außenseiter zu verdrängen. Die Visualisierung zeigt eine viel aktivere Bewegung von Individuen in der Population durch den Lösungsraum. Es ergab sich jedoch ein neues Problem: Die Ergebnisse waren sehr breit gestreut, und es war nicht möglich, das Feststecken in lokalen Optima vollständig zu vermeiden.

      Hilly

      ATAm mit dem Test Hilly

      Forest

      ATAm mit dem Test Forest

      Megacity

      ATAm mit dem Test Megacity

      Der künstliche Stammesalgorithmus liegt in der Rangliste auf Platz 33.

      # AO Description Hilly Hilly final Forest Forest final Megacity (discrete) Megacity final Final result % of MAX
      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 ANS Suche über die gesamte Nachbarschaft 0.94948 0.84776 0.43857 2.23581 1.00000 0.92334 0.39988 2.32323 0.70923 0.63477 0.23091 1.57491 6.134 68.15
      2 CLA Code-Sperr-Algorithmus (joo) 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 AMOm Optimierung der Tiermigration M 0,90358 0,84317 0,46284 2,20959 0,99001 0,92436 0,46598 2,38034 0,56769 0,59132 0,23773 1,39675 5.987 66,52
      4 (P+O)ES (P+O) Entwicklungsstrategien 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
      5 CTA Kometenschweif-Algorithmus (joo) 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
      6 SDSm stochastische Diffusionssuche 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
      7 AAm Algorithmus für das Bogenschießen M 0.91744 0.70876 0.42160 2.04780 0.92527 0.75802 0.35328 2.03657 0.67385 0.55200 0.23738 1.46323 5.548 61.64
      8 ESG Entwicklung sozialer Gruppen (joo) 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
      9 SIA Simuliertes isotropes Glühen (Joo) 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
      10 ACS künstliche, kooperative Suche 0.75547 0.74744 0.30407 1.80698 1.00000 0.88861 0.22413 2.11274 0.69077 0.48185 0.13322 1.30583 5.226 58.06
      11 ASO Anarchische Gesellschaftsoptimierung 0,84872 0,74646 0,31465 1,90983 0,96148 0,79150 0,23803 1,99101 0,57077 0,54062 0,16614 1,27752 5.178 57,54
      12 AOSm Suche nach atomaren Orbitalen M 0.80232 0.70449 0.31021 1.81702 0.85660 0.69451 0.21996 1.77107 0.74615 0.52862 0.14358 1.41835 5.006 55.63
      13 TSEA Schildkrötenpanzer-Evolutionsalgorithmus (joo) 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
      14 DE differentielle Evolution 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
      15 CRO Optimierung chemischer Reaktionen 0.94629 0.66112 0.29853 1.90593 0.87906 0.58422 0.21146 1.67473 0.75846 0.42646 0.12686 1.31178 4.892 54.36
      16 BSA Vogelschwarm-Algorithmus 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
      17 HS Harmoniesuche 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
      18 SSG Setzen, Säen und Wachsen 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
      19 BCOm Optimierung mit der bakteriellen Chemotaxis M 0.75953 0.62268 0.31483 1.69704 0.89378 0.61339 0.22542 1.73259 0.65385 0.42092 0.14435 1.21912 4.649 51.65
      20 ABO Optimierung des afrikanischen Büffels 0.83337 0.62247 0.29964 1.75548 0.92170 0.58618 0.19723 1.70511 0.61000 0.43154 0.13225 1.17378 4.634 51.49
      21 (PO)ES (PO) Entwicklungsstrategien 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
      22 TSm Tabu-Suche M 0.87795 0.61431 0.29104 1.78330 0.92885 0.51844 0.19054 1.63783 0.61077 0.38215 0.12157 1.11449 4.536 50.40
      23 BSO Brainstorming-Optimierung 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
      24 WOAm Wal-Optimierungsalgorithmus 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
      25 AEFA Algorithmus für künstliche elektrische Felder 0.87700 0.61753 0.25235 1.74688 0.92729 0.72698 0.18064 1.83490 0.66615 0.11631 0.09508 0.87754 4.459 49.55
      26 AEO Algorithmus zur Optimierung auf der Grundlage künstlicher Ökosysteme 0.91380 0.46713 0.26470 1.64563 0.90223 0.43705 0.21400 1.55327 0.66154 0.30800 0.28563 1.25517 4.454 49.49
      27 ACOm Ameisen-Kolonie-Optimierung 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
      28 BFO-GA Optimierung der bakteriellen Futtersuche — 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
      29 SOA einfacher Optimierungsalgorithmus 0.91520 0.46976 0.27089 1.65585 0.89675 0.37401 0.16984 1.44060 0.69538 0.28031 0.10852 1.08422 4.181 46.45
      30 ABHA Algorithmus für künstliche Bienenstöcke 0.84131 0.54227 0.26304 1.64663 0.87858 0.47779 0.17181 1.52818 0.50923 0.33877 0.10397 0.95197 4.127 45.85
      31 ACMO Optimierung atmosphärischer Wolkenmodelle 0.90321 0.48546 0.30403 1.69270 0.80268 0.37857 0.19178 1.37303 0.62308 0.24400 0.10795 0.97503 4.041 44.90
      32 ADAMm adaptive Momentabschätzung M 0.88635 0.44766 0.26613 1.60014 0.84497 0.38493 0.16889 1.39880 0.66154 0.27046 0.10594 1.03794 4.037 44.85
      33 ATAm Algorithmus für künstliche Stämme M 0.71771 0.55304 0.25235 1.52310 0.82491 0.55904 0.20473 1.58867 0.44000 0.18615 0.09411 0.72026 3.832 42.58
      34 ASHA Algorithmus für künstliches Duschen 0.89686 0.40433 0.25617 1.55737 0.80360 0.35526 0.19160 1.35046 0.47692 0.18123 0.09774 0.75589 3.664 40.71
      35 ASBO Optimierung des adaptiven Sozialverhaltens 0.76331 0.49253 0.32619 1.58202 0.79546 0.40035 0.26097 1.45677 0.26462 0.17169 0.18200 0.61831 3.657 40.63
      36 MEC Evolutionäre Berechnung des Geistes 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
      37 IWO Optimierung mit invasiven Unkräutern 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
      38 Micro-AIS Künstliches Mikro-Immunsystem 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
      39 COAm Kuckuck-Optimierungsalgorithmus 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
      40 SDOm Optimierung der Spiraldynamik 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
      41 NMm Nelder-Mead-Verfahren 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
      42 FAm Firefly-Algorithmus 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
      43 GSA Algorithmus für die Schwerkraftsuche 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
      44 BFO Optimierung der bakteriellen Futtersuche 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
      45 ABC Künstliches Bienenvolk (Artificial Bee Colony, 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



      Zusammenfassung

      In diesem Artikel haben wir einen der modernsten Optimierungsalgorithmen – den ATA-Algorithmus – eingehend untersucht. Obwohl dieser Algorithmus im Vergleich zu anderen Methoden nicht besonders gut abschneidet, leistet er einen wertvollen Beitrag zu unserem Verständnis der dynamischen Verwaltung von Populationszuständen und der Methoden zur Analyse von Problemen im Zusammenhang mit lokalen Optima.

      Das Interesse am ATA-Algorithmus beschränkt sich nicht nur auf seine beiden Hauptphasen, die für sich genommen als Lösungsmethoden von geringem Wert sind. Viel wichtiger ist der Ansatz der dynamischen Auswahl der Bewegungsphasen von Individuen und der Kontrolle über den Zustand der Population. Dieser Aspekt ermöglicht es uns, den Algorithmus effektiver an sich ändernde Problembedingungen anzupassen und die Qualität der erhaltenen Lösungen zu verbessern. Die Untersuchung von ATA eröffnet somit neue Horizonte für die weitere Forschung auf dem Gebiet der algorithmischen Optimierung und kann als Grundlage für die Entwicklung fortschrittlicherer Methoden dienen.

      Ich bin mir auch sicher, dass verschiedene Operatoren auf den diskutierten Algorithmus angewandt werden können, was seine Effizienz erheblich steigern wird. So kann beispielsweise die Verwendung von Auswahloperatoren auf der Grundlage von Sortierung oder Crossover die Ergebnisse erheblich verbessern.

      Es ist jedoch anzumerken, dass die aktuelle Version des Algorithmus nicht von der Qualität der Lösung abhängt und auch keine kombinatorischen Eigenschaften aufweist, was seine Möglichkeiten einschränkt. All diese Aspekte stellen interessante Richtungen für weitere Forschung und Verbesserungen dar, obwohl sie den Rahmen dieses Artikels sprengen würden. Ich würde mich freuen, wenn einer der Leser mit den vorgeschlagenen Änderungen experimentieren und seine Version des Algorithmus in den Kommentaren mitteilen würde.

      Tab

      Abbildung 3. Farbliche Abstufung der Algorithmen entsprechend den relevanten Tests Ergebnisse, die größer oder gleich 0,99 sind, werden weiß hervorgehoben

      Histogramm

      Abbildung 4. Histogramm der Algorithmus-Testergebnisse (Skala von 0 bis 100, je höher, desto besser, wobei 100 das maximal mögliche theoretische Ergebnis ist; im Archiv befindet sich ein Skript zur Berechnung der Bewertungstabelle)

      Vor- und Nachteile von ATAm:

      Vorteile:

      1. Geringe Anzahl von externen Parametern.
      2. Einfache Umsetzung.
      3. Interessante Idee, Suchstrategien dynamisch zu wechseln.

      Nachteile

      1. Hohe Streuung der Ergebnisse.
      2. Geringe Konvergenzgenauigkeit.
      3. Tendenz zum Steckenbleiben.

      Der Artikel wird von einem Archiv mit den aktuellen Versionen der Codes der Algorithmen begleitet. Der Autor des Artikels übernimmt keine Verantwortung für die absolute Richtigkeit der Beschreibung der kanonischen Algorithmen. An vielen von ihnen wurden Änderungen vorgenommen, um die Suchmöglichkeiten zu verbessern. Die in den Artikeln dargelegten Schlussfolgerungen und Urteile beruhen auf den Ergebnissen der Versuche.

      Programme, die im diesem Artikel verwendet werden

      # Name Typ Description
      1 #C_AO.mqh
      Include
      Übergeordnete Klasse von Populationsoptimierungsalgorithmen
      2 #C_AO_enum.mqh
      Include
      Aufzählung von Algorithmen zur Populationsoptimierung
      3 TestFunctions.mqh
      Include
      Bibliothek mit Testfunktionen
      4
      TestStandFunctions.mqh
      Include
      Bibliothek der Testfunktionen
      5
      Utilities.mqh
      Include
      Bibliothek der Hilfsfunktionen
      6
      CalculationTestResults.mqh
      Include
      Skript zur Berechnung der Ergebnisse in der Vergleichstabelle
      7
      Testing AOs.mq5
      Skript Der einheitliche Prüfstand für alle Algorithmen zur Populationsoptimierung
      8
      Simple use of population optimization algorithms.mq5
      Skript
      Ein einfaches Beispiel für die Verwendung von Algorithmen zur Populationsoptimierung ohne Visualisierung
      9
      Test_AO_ATAm.mq5
      Skript ATAm-Prüfstand

      Übersetzt aus dem Russischen von MetaQuotes Ltd.
      Originalartikel: https://www.mql5.com/ru/articles/16588

      Beigefügte Dateien |
      ATAm.zip (145.57 KB)
      Neuronale Netze im Handel: Ein hybrider Handelsrahmen mit prädiktiver Kodierung (letzter Teil) Neuronale Netze im Handel: Ein hybrider Handelsrahmen mit prädiktiver Kodierung (letzter Teil)
      Wir setzen unsere Untersuchung des hybriden Handelssystems StockFormer fort, das prädiktive Kodierungs- und Verstärkungslernalgorithmen für die Analyse von Finanzzeitreihen kombiniert. Das System basiert auf drei Transformer-Zweigen mit einem diversifizierten Mehrkopf-Aufmerksamkeitsmechanismus (DMH-Attn), der die Erfassung komplexer Muster und Abhängigkeiten zwischen Assets ermöglicht. Zuvor haben wir uns mit den theoretischen Aspekten des Frameworks vertraut gemacht und die DMH-Attn-Mechanismus implementiert. Heute werden wir über die Modellarchitektur und das Training sprechen.
      Visuelle Bewertung und Anpassung des Handels im MetaTrader 5 Visuelle Bewertung und Anpassung des Handels im MetaTrader 5
      Mit dem Strategietester können Sie mehr tun, als nur die Parameter Ihres Handelsroboters zu optimieren. Ich zeige Ihnen, wie Sie den Handelsverlauf Ihres Kontos im Nachhinein auswerten und Anpassungen an Ihrem Handel im Tester vornehmen, indem Sie die Stop-Losses Ihrer offenen Positionen ändern.
      Quantencomputing und Handel: Ein neuer Ansatz für Preisprognosen Quantencomputing und Handel: Ein neuer Ansatz für Preisprognosen
      Der Artikel beschreibt einen innovativen Ansatz zur Vorhersage von Kursbewegungen auf den Finanzmärkten mit Hilfe von Quantencomputern. Das Hauptaugenmerk liegt auf der Anwendung des Algorithmus Quantum Phase Estimation (QPE), um Prototypen von Preismustern zu finden, die es Händlern ermöglichen, die Analyse von Marktdaten erheblich zu beschleunigen.
      Analyse des Binärcodes der Börsenkurse (Teil I): Ein neuer Blick auf die technische Analyse Analyse des Binärcodes der Börsenkurse (Teil I): Ein neuer Blick auf die technische Analyse
      In diesem Artikel wird ein innovativer Ansatz für die technische Analyse vorgestellt, der auf der Umwandlung von Kursbewegungen in Binärcodes beruht. Der Autor zeigt, wie verschiedene Aspekte des Marktverhaltens – von einfachen Preisbewegungen bis hin zu komplexen Mustern – in einer Folge von Nullen und Einsen kodiert werden können.