English Русский 中文 Español Deutsch Português
preview
ラクダアルゴリズム(CA)

ラクダアルゴリズム(CA)

MetaTrader 5トレーディング |
40 0
Andrey Dik
Andrey Dik

内容

  1. はじめに
  2. アルゴリズムの実装
  3. テスト結果


はじめに

近年、自然現象や動物の行動に着想を得た多数の最適化アルゴリズムが提案されています。これらのバイオインスパイアード手法は、多くのタスクにおいて優れた性能を示しています。本記事では、過酷な砂漠環境におけるラクダの生存戦略と移動戦略に基づく新しい最適化アルゴリズムであるラクダアルゴリズム(CA)について検討します。このアルゴリズムは、2016年にMohammed Khalid IbrahimおよびRamzy Salim Aliの2名の研究者によって提案されました。

ラクダは、極端な温度変化、限られた資源、変化する地形といった過酷な砂漠環境に適応するための独自の生理的および行動的特性を持っています。CAアルゴリズムは、こうした特性のうち、温度の影響、水や食料の補給管理、持久力、「オアシス」(有望な探索領域)の効果、そして隊列(キャラバン)における個体間の情報共有をモデル化しています。

本記事では、通常通りアルゴリズムの内部構造を分析し、改良を加え、テスト関数上で両バージョンを評価します。結果は最適化アルゴリズムのランキング表に含める予定です。


アルゴリズムの実装

広大な砂漠を横断するラクダのキャラバンを想像してみてください。彼らの目的は、無限に広がる砂の中から水と食料のあるオアシスを見つけることです。この旅のモデル化が、ラクダアルゴリズム(CA)の着想となっています。

このアルゴリズムは、過酷な砂漠環境においてラクダがどのように生存しながら資源を探索するかをシミュレーションします。各ラクダは候補解を表し、探索空間(砂漠)を移動しながら、最適解(最良のオアシス)を探します。 

ラクダがキャラバンとして行動するのは、生存率を高めるための戦略です。アルゴリズムでは、複数のラクダ(候補解)がそれぞれの探索結果を共有し、より良い経路を集団で学習します。これは実際のラクダが有用なルートや水場の情報を共有する行動に対応します。

以下は、主要要素です。

温度(T):ラクダの行動に影響を与えるランダム要因です。砂漠では温度が冷え込む夜から非常に暑い昼まで変動し、この変化がラクダの移動速度と進行方向に影響します。ラクダが極端な温度環境(寒い夜から非常に暑い砂漠の昼)に適応できるという特性が、このパラメータをアルゴリズムに導入する理由です。このパラメータは探索プロセスにランダム性と適応性を追加し、局所最適解への収束を回避する助けになります。これは、ラクダが変化する環境条件に応じてルートを調整する必要がある状況に類似しています。

補給(S):水と食料資源を表し、旅の進行とともに徐々に減少します。ラクダは地球上でも最も過酷な環境の一部で生存できるように進化しており、限られた資源を効率的に管理する能力がこのパラメータに反映されています。補給値は旅が続くにつれて減少し、これは探索戦略に直接影響します。ラクダがオアシスを見つけずに長く移動するほど、利用可能なエネルギーと資源は少なくなります。この仕組みにより、アルゴリズムは計算資源が限られた問題に特に適したものになります。

持久力(E):ラクダのエネルギーを表し、温度と旅の時間の両方に依存します。強い砂漠の太陽は徐々にキャラバンの体力を消耗させます。ラクダは優れた持久力と、最小限の資源で長距離を移動できる能力で知られています。本アルゴリズムでは、持久力パラメータが探索空間におけるエージェントの探索能力を制御します。持久力は時間とともに徐々に減少し、新しい領域の探索と、すでに見つかった有望解の活用とのバランスに影響を与えます。

オアシス効果:ラクダが有望な位置(高品質な解)に到達したときに発生します。このとき、資源と持久力が回復し、探索を継続できるようになります。アルゴリズムでは、良い解が見つかると補給と持久力の両方が補充されます。これにより周辺領域をより深く探索できるようになり、ラクダがオアシスで休息して体力を回復する状況と同様になります。これはこのアルゴリズムの最も重要な特徴の一つです。

ランダムウォーク:解空間における主探索経路からの逸脱を意味し、新しい領域を探索することを可能にします。

以下の図に示すように、5頭のラクダのグループが砂漠で豊かなオアシスを探索しています。初期状態ではそれぞれ異なる位置に存在し、異なる方向へ移動しています。

ラクダ1は北へ向かっていますが、高温の影響により移動速度が低下し、より頻繁に停止する必要があります。
ラクダ2は小さなオアシス(局所最適解)を発見し、水と食料の一部の補給を得ます。その情報を他のラクダに通知しますが、より大きなオアシスが存在する可能性があると考え、探索を継続します。
ラクダ3は比較的平坦な地形をさまよいながら探索を続けており、補給は徐々に減少していますが、新しい方向への探索を継続しています。
ラクダ4は非常に高温の領域に入り、持久力が大きく低下します。しかし、ランダムウォークの作用によりこの領域から脱出することができます。
ラクダ5は他のラクダからの情報と、ランダムウォークによる有利な方向を利用し、最も豊かなオアシス(大域最適解)を発見します。

    ラクダアルゴリズム

    図1:CAアルゴリズムの動作

    CAアルゴリズムの擬似コードを書いてみましょう。

    // パラメータを初期化する
    初期化:
        popSize = 集団規模(ラクダキャラバン)
        Tmin = 最低温度
        Tmax = 最高温度
        omega = 補給負荷率
        dyingRate = ラクダの「死亡」率
        alpha = オアシス効果の視認性パラメータ
        initialSupply = 水と食料の初期補給量(通常は1.0)
        initialEndurance = 初期持久力(通常は1.0)
        totalSteps = 経路の総ステップ数
        traveledSteps = 0(移動ステップの初期値)

    // 初期集団の生成
    ラクダの初期キャラバン(複数解)を作成する:
        各ラクダ i = 1からpopSizeまで:
            許容範囲内でランダムな解を生成する
            初期値を設定する:
                temperature [i] = TminとTmaxの間のランダム値
                supply [i] = initialSupply
                endurance [i] = initialEndurance
        
        キャラバン内の各ラクダの適応度を計算する
        現在の最良解を決定する

    // メイン最適化ループ
    While (traveledSteps < totalSteps):
        traveledSteps++
        
        // キャラバン内の各ラクダについて
        For i from 1 to popSize:
            // 1.パラメータ更新(温度、補給、持久力)
            // 式(1):Tnow = (Tmax - Tmin) * Rand(0,1) + Tmin
            temperature [i] = CalculateTemperature (i)
            
            // 式(2):Snow = Spast * (1 - ω * 移動ステップ / 総ステップ)
            supply [i] = CalculateSupply (i)
            
            // 式(4):Enow = Epast * (1 - Tnow/Tmax) * (1 - 移動ステップ / 総ステップ)
            endurance [i] = CalculateEndurance (i)
            
            // 2. ラクダの「死亡」判定
            If (random_number < dyingRate):
                ラクダ i の位置をランダム解で再初期化する
                次のループへ進む
            
            // 3. ラクダの位置更新
            delta = [-1, 1] の範囲の乱数 // ランダムウォーク係数
            古い位置を保存する
            
            // 各次元ごとに更新
            For each c coordinate:
                // 更新係数の計算
                enduranceFactor = (1.0 - endurance [i] / initialEndurance)
                supplyFactor = exp(1.0 - supply [i] / initialSupply)

                
                // 式(6)による位置更新
                new_position [c] = old_position [c] + delta * enduranceFactor * supplyFactor * (best_position [c] - old_position [c])
                
                // 範囲外チェックと補正
                new_position [c] = 有効範囲内にクリップする
            
            // 4. オアシス効果の適用
            If (random_number > (1.0 - alpha) AND fitness_new > fitness_old):
                // オアシス発見:補給と持久力を回復
                supply [i] = initialSupply
                endurance [i] = initialEndurance
            
        // ラクダを適応度順に評価し、最良解を更新する
        最良解を更新する

    // 最終的な最適解を返す

    ここからコードの実装を開始します。本実装には、著者によるオリジナル版(いくつかの文字列はコメントアウトされます)と、アルゴリズムのロジック改善を目的とした私の改良版の両方が含まれます。まず、CAmアルゴリズムの実装を表すC_AO_CAmクラスを作成します。このクラスはベースクラスであるC_AOを継承します。

    このクラスには、アルゴリズム固有のパラメータが含まれます。たとえば、集団サイズ、最小温度、最大温度、負荷係数、ラクダの「死亡」率、視認性パラメータです。これらのパラメータは初期化時に設定でき、parameters配列を通じて簡単に調整できるように設計されます。

    クラスのコンストラクタでは、アルゴリズムの基本情報(名前、説明、アイデアの出典リンクなど)を定義し、同時にパラメータ配列を初期化します。SetParamsメソッドでは、これらのパラメータを実行時に更新できるようにします。

    また、このクラスは、初期集団の生成、ラクダの移動処理、解の修正、各種係数の更新、そしてオアシス効果の適用のような主要な機能を実装します。これらはすべて、砂漠におけるラクダの行動をシミュレーションしながら最適解を探索するための処理です。クラスの主要な状態としては、各ラクダの温度、補給(水と食料)、持久力を保持する配列、および経過ステップ数と総ステップ数のカウンタがあります。また、初期の補給量および持久力レベルを表す変数も含まれており、通常はアルゴリズムの開始時に初期化されます。

    全体として、このクラスはラクダのキャラバンの行動に基づく改良型最適化アルゴリズムを実装したものです。「温度」と「補給」は中間的な探索状態をモデル化し、ラクダの移動と「死亡」イベントのダイナミクスによって、効率的に解空間を探索し最適解を見つけることを目的としています。

    //——————————————————————————————————————————————————————————————————————————————
    class C_AO_CAm : public C_AO
    {
      public: //--------------------------------------------------------------------
      ~C_AO_CAm () { }
      C_AO_CAm ()
      {
        ao_name = "CA";
        ao_desc = "Camel Algorithm M";
        ao_link = "https://www.mql5.com/ja/articles/18057";
    
        popSize   = 50;     // population size (camel caravan)
        Tmin      = 50;     // minimum temperature
        Tmax      = 100;    // maximum temperature
        omega     = 0.8;    // load factor for 'supply'
        dyingRate = 0.01;   // camels' "death" rate
        alpha     = 0.9;    // visibility parameter for the oasis effect
    
        ArrayResize (params, 6);
    
        params [0].name = "popSize";    params [0].val = popSize;
        params [1].name = "Tmin";       params [1].val = Tmin;
        params [2].name = "Tmax";       params [2].val = Tmax;
        params [3].name = "omega";      params [3].val = omega;
        params [4].name = "dyingRate";  params [4].val = dyingRate;
        params [5].name = "alpha";      params [5].val = alpha;
      }
    
      void SetParams ()
      {
        popSize   = (int)params [0].val;
        Tmin      = params      [1].val;
        Tmax      = params      [2].val;
        omega     = params      [3].val;
        dyingRate = params      [4].val;
        alpha     = params      [5].val;
      }
    
      bool Init (const double &rangeMinP  [],  // minimum values
                 const double &rangeMaxP  [],  // maximum values
                 const double &rangeStepP [],  // step change
                 const int     epochsP = 0);   // number of epochs
    
      void Moving   ();
      void Revision ();
    
      //----------------------------------------------------------------------------
      double Tmin;         // minimum temperature
      double Tmax;         // maximum temperature
      double omega;        // load factor for 'supply'
      double dyingRate;    // camels' "death" rate
      double alpha;        // visibility parameter for the oasis effect
    
      private: //-------------------------------------------------------------------
      double temperature [];   // current temperature for each camel
      double supply      [];   // current supply of water and food for each camel
      double endurance   [];   // current endurance for each camel
      double initialSupply;    // initial supply (usually 1.0)
      double initialEndurance; // initial endurance (usually 1.0)
      int    traveledSteps;    // number of steps taken
      int    totalSteps;       // total number of steps
    
      // Auxiliary methods
      void   InitializePopulation ();
      void   UpdateFactors        ();
      void   UpdatePositions      ();
      void   ApplyOasisEffect     ();
    };
    //——————————————————————————————————————————————————————————————————————————————
    

    Initメソッドは CAm アルゴリズムを初期化します。このメソッドの実行中に、後続の処理のために必要なデータ構造およびパラメータが準備されます。主な処理として、標準的な初期化処理の呼び出しがあり、これにより探索変数の変化範囲およびステップ幅が設定されます。初期化に失敗した場合、このメソッドも失敗として扱われます。

    次に、各ラクダのパラメータ(温度、水および食料の補給量、持久力)を格納する配列のメモリを確保します。これらの配列のサイズは、個体数(population size)と同じになります。さらに、初期補給量および初期持久力の値を設定し、エポック数に対応する総ステップ数も設定します。最後に、経過ステップ数(実行済みステップ数)は0に初期化されます。

    //——————————————————————————————————————————————————————————————————————————————
    bool C_AO_CAm::Init (const double &rangeMinP  [],  // minimum values
                         const double &rangeMaxP  [],  // maximum values
                         const double &rangeStepP [],  // step change
                         const int     epochsP = 0)    // number of epochs
    {
      if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;
    
      //----------------------------------------------------------------------------
      // Initialize arrays for each camel
      ArrayResize (temperature, popSize);
      ArrayResize (supply,      popSize);
      ArrayResize (endurance,   popSize);
    
      // Set initial values
      initialSupply    = 1.0;
      initialEndurance = 1.0;
      traveledSteps    = 0;
      totalSteps       = epochsP;
      
      return true;
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    Movingメソッドは、アルゴリズムの反復処理を実装する中核部分であり、ラクダの状態更新と移動処理を担当します。まず、最初の反復処理が完了しているかを確認します。まだ完了していない場合は、ラクダの初期集団を生成し、初期化完了フラグを設定します。

    その後の各ステップでは、経過ステップ数のカウンタが増加し、続いて以下の処理が順番に実行されます。

    1. 各ラクダの温度、補給量、持久力などのパラメータを更新します。これは、動的な行動と探索プロセスをモデル化する上で重要です。
    2. 探索空間内におけるラクダの位置を更新します。つまり、解を改善する可能性のある方向に移動します。
    3. オアシス効果を適用します。ラクダは補給量を回復し、持久力を再生できるため、局所極小解への収束を回避し、より広範囲かつ複雑な探索を促進できます。

    各ステップの最後では、各ラクダに対する適応度関数の値を保存します。これにより、現在の状態と前回の状態を比較でき、その結果に基づいて次の探索方針を決定できます。

    //+----------------------------------------------------------------------------+
    //| Basic optimization method                                                  |
    //+----------------------------------------------------------------------------+
    void C_AO_CAm::Moving ()
    {
      // First iteration - initialization of the initial population
      if (!revision)
      {
        InitializePopulation ();
        revision = true;
        return;
      }
    
      // Increase the steps counter
      traveledSteps++;
    
      // Main optimization
      // 1. Update factors (temperature, supply, endurance)
      UpdateFactors ();
    
      // 2. Update the camel positions
      UpdatePositions ();
    
      // 3. apply the oasis effect (replenishment of supply and endurance)
      ApplyOasisEffect ();
    
      // 4. Save the state of camels
      for (int i = 0; i < popSize; i++) a [i].fP = a [i].f;
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    Revisionメソッドは、現在のラクダ集団の中で発見された最良解を更新する役割を持ちます。このメソッドは集団内のすべてのラクダを順番に処理し、各ラクダの適応度を現在の最良値と比較します。現在のラクダの適応度値(a[i].f)が現在の最良値(fB)より優れている場合、以下が更新されます。

    1. fBに新しい最良値(a[i].f)を代入します。
    2. 最良値を達成したラクダの位置(座標、パラメータ)を、現在のラクダの座標(a[i].c)から最良解の座標配列(cB)へコピーします。 

    集団内のすべてのラクダに対するループが完了すると、fBとcBには、その反復において発見された最良解の評価値と座標が格納されます。

    //+----------------------------------------------------------------------------+
    //| Update the best solution                                                   |
    //+----------------------------------------------------------------------------+
    void C_AO_CAm::Revision ()
    {
      // Find the best solution in the current population
      for (int i = 0; i < popSize; i++)
      {
        // Update the best solution
        if (a [i].f > fB)
        {
          fB = a [i].f;
          ArrayCopy (cB, a [i].c, 0, 0, WHOLE_ARRAY);
        }
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    InitializePopulationメソッドは、最適化アルゴリズムにおけるラクダの初期集団を生成するために使用されます。このメソッドは、有効な探索空間全体に初期解を均等に配置します。

    このメソッドの基本的な処理は、集団全体、つまりすべてのラクダを順番に処理することです。各ラクダに対して、各変数(各座標)の許容範囲内でランダムな座標を生成します。これらの座標は、有効範囲全体を均等にカバーできるようランダムに選択されます。

    座標生成後、それぞれの値は最も近い許容ステップへ丸められます。これにより、探索が離散的な制約条件に適合するようになります。この処理は、初期解が許容範囲およびステップ幅に正確に一致することを保証するために行われます。さらに、各ラクダには、水や食料の補給量および持久力といった初期パラメータが割り当てられます。これらの値は、集団全体に対して事前に設定されたデフォルト値によって決定されます。

    このメソッドの実行結果として、探索空間全体に均一に分布した初期解集団が生成され、最適化プロセスを効率的に開始できるようになります。

    //+----------------------------------------------------------------------------+
    //| Initialize the initial population                                          |
    //+----------------------------------------------------------------------------+
    void C_AO_CAm::InitializePopulation ()
    {
      // Initialize the initial population uniformly throughout the space
      for (int i = 0; i < popSize; i++)
      {
        for (int c = 0; c < coords; c++)
        {
          // Generate random coordinates within acceptable limits
          a [i].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);
          // Round to the nearest acceptable step
          a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
        }
    
        // Initialize factors for each camel
        supply    [i] = initialSupply;
        endurance [i] = initialEndurance;
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    C_AO_CAmクラスのUpdateFactorsメソッドは、集団内の各「ラクダ」の行動に影響を与える主要な要素、すなわち温度、補給量、持久力を更新する役割を持ちます。これらの要素はアルゴリズムの各反復ごとに動的に変化し、最適解の探索に影響を与えます。

    まず、journeyRatioを計算します。これは、経過ステップ数traveledStepsを総ステップ数totalStepsで割った値です。この値はアルゴリズムの進行状況を表します。次に、各ラクダ(i = 0からpopSize - 1まで)について、温度(temperature[i])をTminからTmaxの範囲内でランダムに設定します。新しい温度は各ラクダごとに独立して生成されるため、探索プロセスにランダム性が導入されます。

    ラクダの補給量(supply [i])は、移動距離に応じて減少します。これは、前回の補給値に(1.0 - omega * journeyRatio)を乗算することで計算されます。omegaパラメータは補給の減少速度を制御します。omegaが大きいほど、またjourneyRatioが大きいほど(つまりアルゴリズムがより進行しているほど)、補給量はより速く減少します。

    ラクダの持久力(endurance [i])は、温度と移動距離の両方に依存して減少します。持久力は、前回の持久力値に(1.0 - temperatureRatio) * (1.0 - journeyRatio)を乗算することで計算されます。ここでtemperatureRatioは、現在のラクダの温度を最大温度Tmaxで割った値です。温度が高いほど、またアルゴリズムの進行が進むほど、持久力はより大きく減少します。

    このように、このメソッドはランダム変数(温度)とアルゴリズムの進行状況(移動距離)の両方を利用して、各ラクダの特性を動的に変化させます。これらの変化は、ラクダが探索空間をどのように探索するかに直接影響します。

    //+----------------------------------------------------------------------------+
    //| Update factors (temperature, supply, endurance)                            |
    //+----------------------------------------------------------------------------+
    void C_AO_CAm::UpdateFactors ()
    {
      double journeyRatio = (double)traveledSteps / (double)totalSteps;
    
      for (int i = 0; i < popSize; i++)
      {
        // Temperature update - random value in the [Tmin, Tmax] range,
        // equation (1): Tnow = (Tmax - Tmin) * Rand(0,1) + Tmin
        temperature [i] = u.RNDfromCI (Tmin, Tmax);
    
        // Supply update - decreases over time,
        // equation (2): Snow = Spast * (1 - ω * Traveled steps / Total journey steps)
        supply [i] = supply [i] * (1.0 - omega * journeyRatio);
    
        // Endurance update depends on temperature and time,
        // equation (4): Enow = Epast * (1 - Tnow/Tmax) * (1 - Traveled steps / Total journey steps)
        double temperatureRatio = temperature [i] / Tmax;
        endurance [i] = endurance [i] * (1.0 - temperatureRatio) * (1.0 - journeyRatio);
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    UpdatePositionsメソッドは、最適化アルゴリズムの各ステップにおいてラクダの位置を更新するために設計されています。このメソッドは、解の更新に影響を与える移動とランダムイベントをシミュレーションします。

    このメソッドは主に、ラクダ集団全体を順番に処理します。各ラクダに対して、以下の処理が実行されます。

    1. まず、一定の確率でラクダは「死亡」したものとして扱われます。これは、流砂、嵐、高温などの不利な条件を表しています。この場合、ラクダの位置は許容範囲内でランダムに再生成され、最小ステップ幅に合わせて補正されます。

    2. ラクダが「死亡」しなかった場合、新しい位置はランダムウォークモデルを用いて決定されます。各座標次元について、[-1, 1]の範囲でランダムなdelta係数を生成し、ランダムな変動をシミュレーションします。

    3. 新しい座標は、古い座標値に修正項を加えることで計算されます。この修正項には、ランダムウォーク、ラクダの現在の状態(持久力と補給量)、および現在座標とオアシス位置との差分が含まれます。このとき、「持久力」と補給量の影響が考慮されます。

    4. 新しい座標を計算した後、その値が許容範囲外に出ていないか確認します。

    この処理の結果として、ラクダの位置は動的に変化し、ランダム要因および内部状態(持久力と補給量)を考慮しながら探索空間内を移動します。このような更新により、アルゴリズムは局所最適解への停滞を回避しながら、より効率的に解空間を探索し、最適解の発見を促進できます。 

    なお、オリジナル実装に存在した「死亡」処理および位置再生成機能のコメントアウトされたコードは、現在の改良版アルゴリズムでは使用されていません。 

    改良版における主な変更点として、ラクダの「死亡」判定はラクダ全体ではなく各座標ごとに実行されるようになっています。また、完全にランダムな位置再生成を行う代わりに、最良解cBを中心とした正規分布(ガウス分布)が使用されます。GaussDistribution関数は、最良解を中心とする正規分布に基づいて新しい位置を生成し、これにより有望な領域をより集中的に探索できるようになります。

    //+----------------------------------------------------------------------------+
    //| Update camel positions                                                     |
    //+----------------------------------------------------------------------------+
    void C_AO_CAm::UpdatePositions ()
    {
      for (int i = 0; i < popSize; i++)
      {
        /*
        // Checking for camel "death" (quicksand, storm, etc.)
        if (u.RNDprobab () < dyingRate)
        {
          // Generate a new position randomly
          for (int c = 0; c < coords; c++)
          {
            a [i].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);
            a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
          }
          continue;
        }
        */
    
        // Updating position-------------------------------------------------------
        double delta = u.RNDfromCI (-1.0, 1.0); // Random walk factor
    
        // Update each coordinate
        for (int c = 0; c < coords; c++)
        {
          /*
          // Apply the update equation from the article
          double enduranceFactor = (1.0 - endurance [i] / initialEndurance);
          double supplyFactor    = MathExp (1.0 - supply [i] / initialSupply);
    
          // Update position
          a [i].c [c] = a [i].c [c] + delta * enduranceFactor * supplyFactor * (cB [c] - a [i].c [c]);
    
          // Check for out-of-bounds and adjust to acceptable value
          a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
          */
    
          // Checking for camel "death" (quicksand, storm, etc.)
          if (u.RNDprobab () < dyingRate)
          {
            // Generate a new position relative to the oasis coordinate using a normal distribution
            a [i].c [c] = u.GaussDistribution (cB [c], rangeMin [c], rangeMax [c], 8);
          }
          else
          {
            // Apply the update equation from the article
            double enduranceFactor = (1.0 - endurance [i] / initialEndurance);
            double supplyFactor    = MathExp (1.0 - supply [i] / initialSupply);
    
            // Update position
            a [i].c [c] = a [i].c [c] + delta * enduranceFactor * supplyFactor * (cB [c] - a [i].c [c]);
          }
    
          // Check for out-of-bounds and adjust to acceptable value
          a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
        }
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    ApplyOasisEffectメソッドは、探索中におけるオアシスの効果がラクダの状態に与える影響をシミュレーションします。このメソッドの主な目的は、ラクダがオアシスを発見したかどうかを判定し、その結果として資源状態を改善することです。

    このメソッドは集団全体を順番に処理し、各ラクダに対して2つの条件を確認します。1つ目は、オアシス発見の確率です。これは乱数によって決定され、alphaパラメータに依存します。alphaが大きいほど、オアシスを発見する確率は高くなります。2つ目は、現在の適応度関数の値(つまり解の品質)が前回の反復時よりも優れているかどうかを確認することです。これにより、実際に性能が改善されたラクダに対してのみオアシス効果が適用されます。

    両方の条件を満たした場合、そのラクダはオアシスを発見したものとみなされます。このとき、補給量および持久力は初期値へリセットされます。つまり、オアシスはラクダの資源回復を促進し、より高い効率で探索空間を継続的に探索できるようにします。

    このメソッド全体の基本的な考え方は、ラクダがオアシスを発見して回復し、その後も探索を継続できる能力をシミュレーションすることにあります。これにより、大域最適解へ到達する可能性を高めます。

    //+----------------------------------------------------------------------------+
    //| Apply the oasis effect (refresh supply and endurance)                      |
    //+----------------------------------------------------------------------------+
    void C_AO_CAm::ApplyOasisEffect ()
    {
      for (int i = 0; i < popSize; i++)
      {
        // Oasis detection condition:
        // 1) The camel should "see" the oasis (random probability depending on 'alpha')
        // 2) The current solution should be better than the previous iteration
    
        if (u.RNDprobab () > (1.0 - alpha) && a [i].f > a [i].fP)
        {
          // Oasis discovered, replenish supply and endurance
          supply    [i] = initialSupply;
          endurance [i] = initialEndurance;
        }
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    


    テスト結果

    ご覧のとおり、CAアルゴリズムのオリジナルバージョンを実行した場合の最高スコアは32.56%です。

    CA|Camel Algorithm|50.0|50.0|100.0|0.8|0.1|0.5|
    =============================
    5 Hilly's; Func runs:10000; result:0.5872886802671936
    25 Hilly's; Func runs:10000; result:0.3896531310299016
    500 Hilly's; Func runs:10000; result:0.3412707468979892
    =============================
    5 Forest's; Func runs:10000; result:0.5248302942062708
    25 Forest's; Func runs:10000; result:0.2760893244414008
    500 Forest's; Func runs:10000; result:0.18881523788478266
    =============================
    5 Megacity's; Func runs:10000; result:0.3507692307692308
    25 Megacity's; Func runs:10000; result:0.16676923076923078
    500 Megacity's; Func runs:10000; result:0.10464615384615475
    =============================
    All score:2.93013 (32.56%)

    改良版のアルゴリズムはより良い結果を示しました。

    CAm|Camel Algorithm|50.0|50.0|100.0|0.8|0.01|0.9|
    =============================
    5 Hilly's; Func runs:10000; result:0.786842172387197
    25 Hilly's; Func runs:10000; result:0.560421361070792
    500 Hilly's; Func runs:10000; result:0.3513297097198401
    =============================
    5 Forest's; Func runs:10000; result:0.8277193604225209
    25 Forest's; Func runs:10000; result:0.5604138230149972
    500 Forest's; Func runs:10000; result:0.24335977579892912
    =============================
    5 Megacity's; Func runs:10000; result:0.6484615384615386
    25 Megacity's; Func runs:10000; result:0.33092307692307693
    500 Megacity's; Func runs:10000; result:0.13417692307692433
    =============================
    All score:4.44365 (49.37%)

    アルゴリズム動作の可視化を、CA版およびCAm版の両方について示します。これは、2つのアルゴリズムの違いをより理解しやすくするためです。どちらのバージョンも、アルゴリズムのロジックに特徴的な、有望な解の近傍へ収束するような挙動を示します。

    Hilly

    Hillyテスト関数のCA

      Hilly

    Hillyテスト関数のCAm

    Forest

    Forestテスト関数のCA

        Forest

    Forestテスト関数のCAm

    Megacity

    Megacityテスト関数のCA

    Megacity

    Megacityテスト関数のCAm

    改良版アルゴリズムは、群知能型最適化アルゴリズムのランキングにおいて35位となりました。オリジナル版は参考情報としてのみ掲載しており、ランキング対象には含まれていません。

    # AO 詳細 Hilly Hilly
    ファイナル
    Forest Forest
    ファイナル
    Megacity(離散) Megacity
    ファイナル
    ファイナル
    結果

    MAX
    10p(5F) 50p(25F) 1000p(500F) 10p(5F) 50p(25F) 1000p(500F) 10p(5F) 50p(25F) 1000p(500F)
    1 ANS across neighbourhood search 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 コードロックアルゴリズム(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 動物移動最適化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)進化戦略 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 彗星の尾アルゴリズム(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 TETA 時間進化移動アルゴリズム(joo) 0.91362 0.82349 0.31990 2.05701 0.97096 0.89532 0.29324 2.15952 0.73462 0.68569 0.16021 1.58052 5.797 64.41
    7 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
    8 BOAm ビリヤード最適化アルゴリズムM 0.95757 0.82599 0.25235 2.03590 1.00000 0.90036 0.30502 2.20538 0.73538 0.52523 0.09563 1.35625 5.598 62.19
    9 AAm アーチェリーアルゴリズム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
    10 ESG 社会集団の進化(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
    11 SIA 等方的焼きなまし(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
    12 ACS 人工協調探索 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
    13 DA 弁証法的アルゴリズム 0.86183 0.70033 0.33724 1.89940 0.98163 0.72772 0.28718 1.99653 0.70308 0.45292 0.16367 1.31967 5.216 57.95
    14 BHAm ブラックホールアルゴリズムM 0.75236 0.76675 0.34583 1.86493 0.93593 0.80152 0.27177 2.00923 0.65077 0.51646 0.15472 1.32195 5.196 57.73
    15 ASO 無政府社会最適化 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
    16 RFO ロイヤルフラッシュ最適化(joo) 0.83361 0.73742 0.34629 1.91733 0.89424 0.73824 0.24098 1.87346 0.63154 0.50292 0.16421 1.29867 5.089 56.55
    17 AOSm 原子軌道探索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
    18 TSEA 亀甲進化アルゴリズム(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
    19 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
    20 SRA レストラン経営達人アルゴリズム(joo) 0.96883 0.63455 0.29217 1.89555 0.94637 0.55506 0.19124 1.69267 0.74923 0.44031 0.12526 1.31480 4.903 54.48
    21 CRO 化学反応の最適化 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
    22 BIO 血液型遺伝最適化(joo) 0.81568 0.65336 0.30877 1.77781 0.89937 0.65319 0.21760 1.77016 0.67846 0.47631 0.13902 1.29378 4.842 53.80
    23 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
    24 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
    25 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
    26 BCOm 細菌走化性最適化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
    27 ABO アフリカ水牛の最適化 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
    28 (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
    29 FBA フラクタルベースのアルゴリズム 0.79000 0.65134 0.28965 1.73099 0.87158 0.56823 0.18877 1.62858 0.61077 0.46062 0.12398 1.19537 4.555 50.61
    30 TSm タブーサーチ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
    31 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
    32 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
    33 AEFA 人工電界アルゴリズム 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
    34 AEO 人工生態系ベースの最適化アルゴリズム 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
    35 カム ラクダのアルゴリズムM 0.78684 0.56042 0.35133 1.69859 0.82772 0.56041 0.24336 1.63149 0.64846 0.33092 0.13418 1.11356 4.444 49.37
    36 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
    37 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
    38 SOA シンプル最適化アルゴリズム 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
    39 ABHA 人工蜂の巣アルゴリズム 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
    40 ACMO 大気雲モデルの最適化 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
    41 ADAMm 適応モーメント推定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
    42 CGO カオスゲーム最適化 0.57256 0.37158 0.32018 1.26432 0.61176 0.61931 0.62161 1.85267 0.37538 0.21923 0.19028 0.78490 3.902 43.35
    43 ATAm 人工部族アルゴリズム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
    44 CROm サンゴ礁最適化M 0.78512 0.46032 0.25958 1.50502 0.86688 0.35297 0.16267 1.38252 0.63231 0.26738 0.10734 1.00703 3.895 43.27
    45 CFO 中心力最適化 0.60961 0.54958 0.27831 1.43750 0.63418 0.46833 0.22541 1.32792 0.57231 0.23477 0.09586 0.90294 3.668 40.76
    カリフォルニア ラクダのアルゴリズム 0.58729 0.38965 0.34127 1.31821 0.52483 0.27609 0.18882 0.98974 0.35077 0.16677 0.10465 0.62219 2.930 32.56
    RW ニューロボイド最適化アルゴリズム2(joo) 0.48754 0.32159 0.25781 1.06694 0.37554 0.21944 0.15877 0.75375 0.27969 0.14917 0.09847 0.52734 2.348 26.09


    まとめ

    改良版のCAmラクダアルゴリズムは、いくつかの重要な改良によって、オリジナル版よりも大幅に高い性能を示しています。

    まず、ラクダの「死亡」メカニズムが根本的に変更されています。新しい解を完全にランダム生成する代わりに、発見済みの最良解を中心としたガウス分布を使用することで、最も有望な領域に対して集中的かつ指向性のある探索を実現しています。

    また、各ラクダについて前回の適応度関数値を保存することで、解の改善状況を正確に追跡できるようになり、オアシス効果をより適切に適用できるようになりました。さらに、調整可能なパラメータとしてTminを追加し、総ステップ数の決定に外部パラメータを使用することで、アルゴリズムの柔軟性が向上しています。これにより、CAmはさまざまな種類の最適化問題に対してより適応的になっています。

    これらの改良を総合すると、改良版は収束速度、解の精度、そして安定性の面で大きく性能が向上しています。

    チャート

    図2:対応するテストに応じたアルゴリズムのカラーグラデーション

    チャート

    図3:アルゴリズムテスト結果のヒストグラム(0から100のスケール、高いほど良い)100は理論上の最大値であり、アーカイブには評価表を計算するためのスクリプトがあります。

    CAmの長所と短所

    長所

    1. 迅速
    2. 実装がシンプル
    3. 大規模および中規模の関数(特に「滑らかな」問題)において良好な結果が得られる

    短所

    1. 多数の外部パラメータ
    2. 低次元関数に関する結果が散らばる

    この記事には、最新版のアルゴリズムコードを含むアーカイブが添付されています。記事の著者は、正規アルゴリズムの説明の絶対的な正確さについて責任を負いません。検索機能を向上させるために、それらの多くに変更が加えられています。記事に示された結論と判断は、実験結果に基づいています。


    記事で使用されているプログラム

    # 名前 種類 詳細
    1 #C_AO.mqh
    インクルード
    集団最適化アルゴリズムの親クラス
    2 #C_AO_enum.mqh
    インクルード
    集団最適化アルゴリズムの列挙
    3 TestFunctions.mqh
    インクルード
    テスト関数のライブラリ
    4
    TestStandFunctions.mqh
    インクルード
    テストスタンド関数ライブラリ
    5
    Utilities.mqh
    インクルード
    補助関数のライブラリ
    6
    CalculationTestResults.mqh
    インクルード
    比較表の結果を計算するスクリプト
    7
    Testing AOs.mq5
    スクリプト すべての集団最適化アルゴリズムの統一テストスタンド
    8
    Simple use of population optimization algorithms.mq5
    スクリプト
    可視化せずに集団最適化アルゴリズムを使用する簡単な例
    9
    Test_AO_CAm.mq5
    スクリプト CAmテストスタンド

    MetaQuotes Ltdによってロシア語から翻訳されました。
    元の記事: https://www.mql5.com/ru/articles/18057

    添付されたファイル |
    CA.zip (213.16 KB)
    MQL5における取引へのコンピュータビジョンの統合(第2回):アーキテクチャを2D RGB画像解析に拡張する MQL5における取引へのコンピュータビジョンの統合(第2回):アーキテクチャを2D RGB画像解析に拡張する
    取引におけるコンピュータビジョン:仕組みと開発手順本記事では、RGB画像として価格チャートを認識するアルゴリズムを構築し、アテンション機構と双方向LSTM層を用いる方法について説明します。結果として、EURUSDの価格を予測する動作モデルを構築し、検証セクションにおいて最大55%の正解率を得ます。
    機械学習ベースの取引システムにおける隠れマルコフモデル 機械学習ベースの取引システムにおける隠れマルコフモデル
    隠れマルコフモデル(HMM, Hidden Markov Models)は、観測された事象が、マルコフ過程を形成する未観測(隠れ)状態の系列に依存するような逐次データを解析するために設計された、確率的モデルの強力なクラスです。HMMの主要な仮定には、隠れ状態に対するマルコフ性(すなわち、次の状態への遷移確率は現在の状態のみに依存すること)と、現在の隠れ状態が既知である場合における観測の独立性が含まれます。
    初級から中級まで:継承 初級から中級まで:継承
    間違いなく、本記事の内容を理解し、それがどのように、そしてなぜ機能するのかを把握するためには、かなりの時間を要するでしょう。というのも、ここで示されている内容はすべて、一見するとオブジェクト指向的に見えますが、実際には構造化プログラミングの原理に基づいているためです。
    ヒルベルト=シュミット独立性基準(HSIC) ヒルベルト=シュミット独立性基準(HSIC)
    データ内の線形および非線形依存関係を検出するために設計されたノンパラメトリック統計検定HSIC (Hilbert-Schmidt Independence Criterion)について解説します。MQL5言語におけるHSIC計算アルゴリズムとして、厳密な置換検定とガンマ近似の2つの実装を提案します。また、特徴量と目的変数の間の非線形関係をモデル化した合成データを用いて、本手法の有効性を示します。