English Русский 中文 Español Português
preview
カオス最適化アルゴリズム(COA):続編

カオス最適化アルゴリズム(COA):続編

MetaTrader 5テスター |
22 2
Andrey Dik
Andrey Dik

内容

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


はじめに

前回の記事では、カオス最適化手法を紹介し、アルゴリズムに含まれるいくつかのメソッドについて解析しました。本記事では、残りのメソッドの解析を完了し、その後テスト関数を用いたアルゴリズムの評価へ進みます。 

この実装におけるカオス最適化手法では、決定論的カオスを利用して解空間を探索します。主な原理は、ロジスティック写像、サイン写像、テント写像という3種類の異なるカオス写像を使用し、疑似乱数性およびエルゴード性を持つ系列を生成することにあります。アルゴリズムは、初期カオス探索、重み付き勾配法を用いた解の洗練、適応的に探索範囲を縮小する最終局所探索の3段階で動作します。

また、慣性を持つ速度ベクトルや停滞検出メカニズムを利用することで、アルゴリズムが局所最適に陥ることを防いでいます。さらに、パラメータの動的適応や複数種類の突然変異によって、大域探索と局所探索のバランスが維持されています。それでは、残りのメソッドについて見ていきましょう。



アルゴリズムの実装

ApplyMutationメソッドは、エージェントに突然変異を導入するために使用されます。このメソッドの主な目的は、特定のエージェントのパラメータをランダムに変更することです。

メソッドはまず、指定されたエージェントのインデックスが有効かどうかを確認します。インデックスが範囲外である場合、メソッドは終了します。次に、エージェントに関連付けられた各配列のサイズを取得します。これには、パラメータ配列や速度配列のサイズが含まれます。この処理により、配列の範囲外アクセスを防止しています。

次に、利用可能な配列サイズに基づいて変更可能な座標数の最大値が計算され、安全な操作が保証されます。突然変異を適用する座標数はランダムに決定され、その数は利用可能な最大座標数の1%から30%の範囲となります。続いて、変更可能な座標を表すインデックス配列が生成されます。この配列はシャッフルされ、突然変異の適用対象がランダムに選択されるようになっています。

ループ処理では、シャッフル済み配列から突然変異対象の座標が選択されます。各座標について、ランダム値に基づき突然変異の種類が決定されます。主な突然変異の種類には、完全ランダム突然変異(指定範囲内で新しい値を完全にランダムに選択)、大域最良解に基づく突然変異、カオス写像を利用した突然変異が含まれます。

各座標の値が変更された後、以前の速度の影響を受けないように、エージェントの速度はリセットされます。最後に、対応するエージェント座標の新しい値が、探索範囲およびステップ幅を考慮して設定されます。これにより、すべての値が許容範囲内に維持されます。

//——————————————————————————————————————————————————————————————————————————————
void C_AO_COA_chaos::ApplyMutation (int agentIdx)
{
  // Determine the number of coordinates for mutation (from 1 to 30% of coordinates)
  int mutationCount = 1 + (int)(u.RNDprobab () * coords * 0.3);
  mutationCount = MathMin (mutationCount, coords);

  // Create an array of indices for mutation without repetitions
  int mutationIndices [];
  ArrayResize (mutationIndices, coords);

  // Fill the array with indices
  for (int i = 0; i < coords; i++)
  {
    mutationIndices [i] = i;
  }

  // Shuffle the indices
  for (int i = coords - 1; i > 0; i--)
  {
    int j = (int)(u.RNDprobab () * (i + 1));
    if (j <= i) // Additional security check
    {
      int temp = mutationIndices [i];
      mutationIndices [i] = mutationIndices [j];
      mutationIndices [j] = temp;
    }
  }

  // Apply mutations to the selected coordinates
  for (int m = 0; m < mutationCount; m++)
  {
    int c = mutationIndices [m];

    // Different types of mutations for variety
    double r = u.RNDprobab ();
    double x;

    if (r < 0.3)
    {
      // Complete random mutation
      x = rangeMin [c] + u.RNDprobab () * (rangeMax [c] - rangeMin [c]);
    }
    else
      if (r < 0.6)
      {
        // Mutation relative to global best
        double offset = (u.RNDprobab () - 0.5) * (rangeMax [c] - rangeMin [c]) * 0.2;
        x = cB [c] + offset;
      }
      else
      {
        // Mutation using chaotic map
        agent [agentIdx].gamma [c] = SelectChaosMap (agent [agentIdx].gamma [c], (epochNow + c) % 3);
        x = rangeMin [c] + agent [agentIdx].gamma [c] * (rangeMax [c] - rangeMin [c]);
      }

    // Reset velocity
    agent [agentIdx].velocity [c] = 0.0;

    // Apply the new value with range check
    a [agentIdx].c [c] = u.SeInDiSp (x, rangeMin [c], rangeMax [c], rangeStep [c]);
  }
}
//——————————————————————————————————————————————————————————————————————————————

UpdateSigmaメソッドは、最適化処理で使用されるペナルティパラメータを動的に調整する役割を担います。これは、エージェント集団内に存在する実行可能解の数に応じて、ペナルティ値を制御するものです。

メソッドが初めて呼び出される場合(epoch == 1)、現在のペナルティ値(currentSigma)は基準値(sigma)の半分に設定されます。その後、メソッドはエージェント集団全体を走査し、実行可能な解の数を計算します。この判定には、エージェントが有効かどうかを確認する補助関数が使用されます。すべてのエージェントに対して反復処理をおこなうことで、条件を満たすエージェント数を取得できます。

次に、実行可能解の割合を、実行可能なエージェント数を総エージェント数で割ることで算出します。この比率により、現在の探索戦略がどの程度有効に機能しているかを評価できます。算出された実行可能解の割合に基づき、メソッドはペナルティ値を調整します。実行可能解の割合が30%未満の場合、アルゴリズムの制約が厳しすぎると判断されます。そのため、探索挙動を変化させ、エージェント行動の多様性を高める目的で、ペナルティ値を増加させます。実行可能解の割合が70%を超える場合、多くのエージェントが容易に実行可能解へ到達していることを意味し、早期収束のリスクがあります。この場合、探索性能を維持するためにペナルティ値を減少させます。

最後に、現在のペナルティ値が許容範囲内に収まるよう制限をおこないます。currentSigmaが基準値の10%未満になった場合は、その下限値まで引き上げられます。同様に、基準値の500%を超えた場合は、その上限値に制限されます。

//——————————————————————————————————————————————————————————————————————————————
void C_AO_COA_chaos::UpdateSigma ()
{
  // Dynamic adaptation of the penalty parameter
  // Start with a small value and increase it if necessary

  if (epochNow == 1)
  {
    currentSigma = sigma * 0.5;
    return;
  }

  // Calculate the number of feasible solutions
  int feasibleCount = 0;
  for (int i = 0; i < popSize; i++)
  {
    if (IsFeasible (i))
    {
      feasibleCount++;
    }
  }

  double feasibleRatio = (double)feasibleCount / MathMax (1, popSize);

  // Adapt the penalty parameter depending on the proportion of feasible solutions
  if (feasibleRatio < 0.3)
  {
    // Too few feasible solutions - increase the penalty
    currentSigma *= 1.2;
  }
  else
    if (feasibleRatio > 0.7)
    {
      // Too many feasible solutions - reduce the penalty
      currentSigma *= 0.9;
    }

  // Limit the sigma value
  if (currentSigma < sigma * 0.1) currentSigma = sigma * 0.1;
  else
    if (currentSigma > sigma * 5.0) currentSigma = sigma * 5.0;
}
//——————————————————————————————————————————————————————————————————————————————

IsFeasibleメソッドは、指定されたインデックスagentIdxを持つエージェントが表す解が、与えられた制約条件に対して実行可能であるかどうかを判定します。

まず、このメソッドは、指定されたエージェントインデックス(agentIdx)が許容範囲内にあるかを確認します。具体的には、0以上かつ集団サイズ(popSize)未満である必要があります。インデックスが無効な場合、メソッドはfalseを返し、その解が無効であることを示します。エージェントインデックスが有効な場合、メソッドは対象となる解の制約条件チェックを開始します。解のすべての座標に対して反復処理をおこない、各座標についてCalculateConstraintValue関数を使用して制約違反値を計算します。

CalculateConstraintValue関数は、特定の解の座標に対する制約違反の度合いを表す値を返します。すべての座標を確認した結果、いずれの制約も違反していない、つまりすべての違反値がeps以下である場合、その解は実行可能とみなされ、メソッドはtrueを返します。

//——————————————————————————————————————————————————————————————————————————————
bool C_AO_COA_chaos::IsFeasible (int agentIdx)
{
  // Check if the solution is within the feasible region
  for (int c = 0; c < coords; c++)
  {
    double violation = CalculateConstraintValue (agentIdx, c);
    if (violation > eps)
    {
      return false;
    }
  }
  return true;
}
//——————————————————————————————————————————————————————————————————————————————

UpdateBestHistoryメソッドは、現在の最良値を探索履歴に保存する役割を持ちます。このメソッドは新しい最良値を受け取り、まず、その値が有効であるかを確認します。値が有効である場合、その値は最良結果の履歴を保持する配列に対して、現在のインデックス位置へ保存されます。その後、次回の保存位置を更新するためにインデックスが更新されます。この更新には、履歴配列サイズに対する剰余演算を用いた循環更新方式が使用されます。これにより、配列の境界を超えることなく、常に直近10件の値のみが履歴として保持されます。

このメソッドにより、探索の進行状況を追跡できるほか、最良解の履歴を分析に利用することが可能になります。

//——————————————————————————————————————————————————————————————————————————————
void C_AO_COA_chaos::UpdateBestHistory (double newBest)
{
  // Protection against invalid values
  if (!MathIsValidNumber (newBest)) return;

  // Update the history of the best values
  globalBestHistory [historyIndex] = newBest;
  historyIndex = (historyIndex + 1) % 10;
}
//——————————————————————————————————————————————————————————————————————————————

IsConvergedメソッドは、アルゴリズムが収束状態に到達したかどうかを判定するために使用されます。このメソッドは、大域最良解の履歴を解析し、時間の経過に伴う解の改善度合いを評価します。改善が十分に小さくなった場合、アルゴリズムは収束したと判断されます。

まず、メソッドは、有効な値の数、値の合計、および大域最良解の履歴(globalBestHistory)における最小値と最大値を管理するための変数を初期化します。minValとmaxValは、それぞれ後続の最小値と最大値を正しく判定するため、double型で表現可能な最大値および最小値で初期化されます。

その後、メソッドはglobalBestHistory配列を反復処理し、履歴内の各値に対して、有効性の確認、データ数の十分性確認、および値の多様性確認を行います。また、平均値および相対差分を計算し、それらに基づいて収束判定を実施します。全体として、IsConvergedメソッドは、最良解の履歴を分析し、時間経過に伴う改善の大きさを評価することで、最適化アルゴリズムの収束状態を判定する仕組みを提供します。 

//——————————————————————————————————————————————————————————————————————————————
bool C_AO_COA_chaos::IsConverged ()
{
  // Check if there is enough data in the history
  int validValues = 0;
  double sum      = 0.0;
  double minVal   = DBL_MAX;
  double maxVal   = -DBL_MAX;

  // Find min, max, and sum of values in history
  for (int i = 0; i < 10; i++)
  {
    if (globalBestHistory [i] == -DBL_MAX || !MathIsValidNumber (globalBestHistory [i])) continue;

    minVal = MathMin (minVal, globalBestHistory [i]);
    maxVal = MathMax (maxVal, globalBestHistory [i]);
    sum += globalBestHistory [i];
    validValues++;
  }

  // If there is not enough data or all values are the same
  if (validValues < 5 || minVal == maxVal) return false;

  // Calculate the average value
  double average = sum / validValues;

  // Check the case when the mean is close to zero
  if (MathAbs (average) < eps) return MathAbs (maxVal - minVal) < eps * 10.0;

  // Relative difference for convergence testing
  double relDiff = MathAbs (maxVal - minVal) / MathAbs (average);

  return relDiff < 0.001; // Convergence threshold - 0.1%
}
//——————————————————————————————————————————————————————————————————————————————

ResetStagnatingAgentsメソッドは、最適化処理中のエージェント管理を目的としており、特にエージェントの結果改善が停止した場合に対応します。このメソッドは、各エージェントの停滞状態を監視し、局所最適解に陥っているエージェントに対して必要に応じて突然変異を適用します。

各エージェントについて、現在の適応度関数値(a[i].f)が、以前の値(a[i].fB)と比較して改善しているかを確認します。現在の値が改善していない、または悪化している場合、エージェントのstagnationCounterがインクリメントされ、そのエージェントが停滞状態にあることを示します。一方、値が改善している場合は、停滞カウンタがリセットされます。

エージェントが5イテレーション以上停滞している場合、メソッドはリセット確率(resetProb)を計算します。この確率は現在の停滞カウンタ値に比例しており、停滞期間が長いほどリセットされる可能性が高くなります。確率計算では、固定値(0.2)と停滞カウンタの相対値が考慮されます。その後、生成された乱数が計算済みのresetProbより小さい場合、ApplyMutation関数を使用してエージェントへ突然変異を適用します。突然変異適用後は、エージェントの停滞カウンタがリセットされ、resetCountカウンタが増加します。

このメソッドは、停滞閾値を超え、かつ突然変異条件を満たしたすべてのエージェントの処理が完了した時点で終了します。

//——————————————————————————————————————————————————————————————————————————————
void C_AO_COA_chaos::ResetStagnatingAgents ()
{
  int resetCount = 0;

  for (int i = 0; i < popSize; i++)
  {
    // Increase the stagnation counter if there is no improvement
    if (a [i].f <= a [i].fB)
    {
      agent [i].stagnationCounter++;
    }
    else
    {
      agent [i].stagnationCounter = 0;
    }

    // Reset the agent if it has been stagnating for too long
    if (agent [i].stagnationCounter > 5)
    {
      // Reset only some of the agents with a probability depending on stagnation
      double resetProb = 0.2 * (1.0 + (double)agent [i].stagnationCounter / 10.0);

      if (u.RNDprobab () < resetProb)
      {
        ApplyMutation (i);
        agent [i].stagnationCounter = 0;
        resetCount++;
      }
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

CalculateWeightedGradientメソッドは、特定のエージェントおよび座標に対する制約勾配を、制約違反の度合いを考慮しながら推定するために使用されます。このメソッドにより、違反を解消するために解をどの方向へ、どの程度調整すべきかを判断できます。また、勾配は違反レベルに応じて重み付けされます。

まず、エージェントインデックスおよび座標インデックスが許容範囲内にあるかを確認します。インデックスが無効な場合は、0.0を返します。次に、現在のエージェントに関連付けられたすべての座標を反復処理して、それぞれの制約違反値を計算します。この過程で、すべての制約の中から最大違反値を探索します。ある座標に対する違反値がeps閾値を超えている場合、その方向への修正をおこなう価値があると判断されます。一方、違反値が閾値以下である場合は、その方向への移動が不要であるため、0が返されます。

違反が十分に大きい場合、対象座標に対する制約勾配が計算されます。これは、その座標の変化に対して制約がどの方向へ、どの程度変化するかを示す指標です。その後、勾配値に重みが適用されます。この重みは、現在の座標における違反値を、すべての制約の中での最大違反値で割った比率として定義されます。これにより、違反が大きい制約ほど、調整方向へ強い影響を与えるようになります。最終的に得られる値は、重み付き制約勾配であり、指定された座標における違反を解消するために、解をどの程度、どの方向へ調整すべきかを、違反の大きさに比例して示します。

//——————————————————————————————————————————————————————————————————————————————
double C_AO_COA_chaos::CalculateWeightedGradient (int agentIdx, int coordIdx)
{
  // Calculate the maximum value of the constraint violation
  double maxViolation = eps;

  for (int c = 0; c < coords; c++)
  {
    double violation = CalculateConstraintValue (agentIdx, c);
    maxViolation = MathMax (maxViolation, violation);
  }

  // Violation for the current coordinate
  double violation = CalculateConstraintValue (agentIdx, coordIdx);

  // If there is no significant violation, return 0
  if (violation <= eps) return 0.0;

  // Calculate the gradient
  double gradient = CalculateConstraintGradient (agentIdx, coordIdx);

  // Normalize the impact depending on the degree of violation
  double weight = violation / maxViolation;

  return gradient * weight;
}
//——————————————————————————————————————————————————————————————————————————————

CalculateConstraintValueメソッドは、特定のエージェントの特定座標における制約違反の程度を推定するために使用されます。このメソッドは、現在の座標値が許容範囲(境界)からどの程度逸脱しているかを判定し、その違反の大きさを数値として返します。

まず、エージェントインデックス(agentIdx)および座標インデックス(coordIdx)が有効であるかを確認します。次に、エージェントの状態から現在の「x」座標値を取得し、この座標に対する許容下限(min)および上限(max)をそれぞれ決定します。その後、取得した値xが許容範囲(min~max)の内側にあるかどうかを判定します。最終的に、この座標における制約違反の総量を表すviolation値を返します。

このメソッドの主な特徴は以下の通りです。

  • 制約が満たされている場合は0を返し、違反している場合は正の値を返します。
  • 違反の大きさは、座標値が許容範囲からどれだけ逸脱しているかに比例します。

各エージェントが問題の制約条件をどの程度満たしているかを定量的に評価するための重要な情報を提供します。これにより、アルゴリズムはエージェントの位置をどの程度修正すべきかを判断できます。

//——————————————————————————————————————————————————————————————————————————————
double C_AO_COA_chaos::CalculateConstraintValue (int agentIdx, int coordIdx)
{
  double x = a [agentIdx].c [coordIdx];
  double min = rangeMin [coordIdx];
  double max = rangeMax [coordIdx];

  // Smoothed constraint violation function with a smooth transition at the boundary
  double violation = 0.0;

  // Check the lower bound
  if (x < min)
  {
    violation += min - x;
  }
  // Check the upper bound
  else
    if (x > max)
    {
      violation += x - max;
    }

  return violation;
}
//——————————————————————————————————————————————————————————————————————————————

CalculateConstraintGradientメソッドは、特定のエージェントの特定座標に対する制約勾配を計算するために使用されます。このメソッドは、制約違反が発生している場合に、その座標値をどの方向へ、どの程度変更すべきかを決定します。

まず、入力されたエージェントインデックス(agentIdx)および座標インデックス(coordIdx)が正しい範囲内にあるかを確認します。いずれかのインデックスが有効範囲外である場合、勾配を計算できないことを示すために0.0を返します。次に、エージェントの現在の座標値を取得し、この座標に対して設定されている最小境界および最大境界を取得します。これらの値は、以降の評価において必要となります。その後、現在の座標値xが定義された境界範囲の外にあるかどうかを判定します。

最終的に、このメソッドが返す値は、制約条件を考慮した上で、現在のエージェントの座標値をどの方向へ、どの程度変更すべきかを反映した勾配値となります。

//——————————————————————————————————————————————————————————————————————————————
double C_AO_COA_chaos::CalculateConstraintGradient (int agentIdx, int coordIdx)
{
  double x = a [agentIdx].c [coordIdx];
  double min = rangeMin [coordIdx];
  double max = rangeMax [coordIdx];

  // Smoothed gradient for better stability
  if (x < min) return -1.0; // Need to increase the value
  else
    if (x > max) return 1.0;  // Need to decrease the value

  return 0.0;
}
//——————————————————————————————————————————————————————————————————————————————

CalculatePenaltyFunctionメソッドは、特定のエージェントに対して、制約違反に対するペナルティを考慮した目的関数の値を計算します。このメソッドでは、目的関数の基本値と、制約違反の大きさに基づくペナルティを組み合わせます。

まず、このメソッドはエージェントのインデックス(agentIdx)の有効性を確認します。インデックスが有効な場合、対象エージェントの目的関数の基本値(ペナルティを含まない値)であるa[agentIdx].fを取得し、それをbaseValue変数に格納します。次に、メソッドは各エージェントのすべての座標(coords)を順番に処理します。各座標について、制約違反の大きさを計算します。違反の大きさが、指定された小さな値epsを超える場合、その違反量の二乗をペナルティ合計penaltySumに加算します。

軽微な違反にはより「緩やかな」評価を、大きな違反にはより「厳しい」評価を与えるために、二次ペナルティが使用されます。すべての制約違反に対するペナルティを加算した後、最終的なpenaltyが計算されます。

最後に、このメソッドは、目的関数の基本値baseValueからpenaltyを減算することで、ペナルティを考慮した目的関数の値を計算します。そして、そのペナルティ適用後の目的関数値を返します。

//——————————————————————————————————————————————————————————————————————————————
double C_AO_COA_chaos::CalculatePenaltyFunction (int agentIdx)
{
  // Base value of the objective function
  double baseValue = a [agentIdx].f;

  // Penalty term
  double penaltySum = 0.0;

  for (int c = 0; c < coords; c++)
  {
    double violation = CalculateConstraintValue (agentIdx, c);

    // Quadratic penalty for better resolution of solutions close to the boundary
    if (violation > eps)
    {
      penaltySum += violation * violation;
    }
  }

  // Apply a dynamic penalty ratio
  double penalty = currentSigma * penaltySum;

  // For the maximization problem: f_penalty = f - penalty
  return baseValue - penalty;
}
//——————————————————————————————————————————————————————————————————————————————

Movingメソッドは、最適化において解を移動させるための主要な制御手続きです。このメソッドは、システムの現在状態を更新し、パラメータを適応的に調整し、探索フェーズを管理することを目的とした一連の処理を実行します。

まず、現在のエポックカウンタがインクリメントされます。初回の呼び出し時には、メソッドは集団を初期化して処理を終了します。次に、ペナルティパラメータ(sigma)が動的に更新されます。これにより、探索過程におけるペナルティ関数の影響度を調整できます。また、重要な処理として、停滞しているエージェントや進展を示していないエージェントを定期的に検出し、リセットします。これにより、局所解への収束を防止できます。

その後、エポックカウンタの値に基づいて、現在の探索フェーズが決定されます。初期段階では大域探索が実行され、その後、より限定的な局所探索へ移行します。フェーズに応じて、それぞれ対応する探索戦略が呼び出され、エージェントの移動を制御します。

//——————————————————————————————————————————————————————————————————————————————
void C_AO_COA_chaos::Moving ()
{
  epochNow++;

  if (!revision)
  {
    InitialPopulation ();

    revision = true;
    return;
  }

  // Dynamically update the penalty parameter
  UpdateSigma ();

  // Reset stagnating agents
  if (epochNow % 5 == 0)
  {
    ResetStagnatingAgents ();
  }

  // Determine the search phase
  if (epochNow <= S1)
  {
    FirstCarrierWaveSearch ();
  }
  else
    if (epochNow <= S1 + S2)
    {
      SecondCarrierWaveSearch ();
    }
}
//——————————————————————————————————————————————————————————————————————————————

Revisionメソッドは、反復最適化の過程において、解の改善および探索パラメータの適応を担当します。このメソッドは、集団の現在状態を再評価し、最良解を更新するとともに、直近の探索結果に基づいて探索パラメータを調整します。

まず、このメソッドは集団内のすべての解を順番に処理し、ペナルティ関数を用いて新しい「ペナルティ付き」評価値を計算します。これにより、制約違反を考慮した評価が可能になります。計算された値は検証され、有効である場合には現在の関数値として保存されます。新しい関数値が以前の値よりも優れているエージェントについては、その個人データが更新されます。具体的には、新しい評価値が保存され、現在の座標もコピーされます。これにより、各エージェントの個体最良解が保持されます。さらに、あるエージェントの解が現在の大域最良解よりも優れている場合には、大域最良解が更新され、対応する座標も保存されます。また、最良解の履歴も更新されます。

最初の反復段階(epochNow > 1)以降では、探索の成功度が評価されます。具体的には、全エージェントに対する改善数の割合が計算されます。この評価結果に基づいて、特にalpha(各座標に対する探索範囲)などのパラメータが適応的に調整されます。現在の探索フェーズ(大域探索または局所探索)に応じて、alphaの調整ルールは異なります。大域探索フェーズでは、改善率が低い場合、探索範囲を拡大して新しい解を探索しやすくします。一方、局所探索フェーズでも、改善が不十分な場合には探索範囲を広げます。逆に、大きな改善が得られた場合には、探索範囲を縮小します。これにより、最適解付近への局所化が促進されます。また、alphaパラメータには、各座標の許容範囲に基づいた最小値および最大値の制限が適用されます。

このアプローチにより、過去の反復結果に関する情報を活用しながら、新しい解の探索と最適解周辺への集中との間で、動的なバランスを実現できます。

//——————————————————————————————————————————————————————————————————————————————
void C_AO_COA_chaos::Revision ()
{
  int    improvementCount = 0;
  double bestImprovement  = 0.0;

  // Evaluate all solutions
  for (int i = 0; i < popSize; i++)
  {
    double newValue = CalculatePenaltyFunction (i);

    // Check the validity of the new value
    if (!MathIsValidNumber (newValue)) continue;

    // Save the current value for the next iteration
    a [i].f = newValue;

    // Update the personal best solution (before a global one for efficiency)
    if (newValue > a [i].fB)
    {
      a [i].fB = newValue;
      ArrayCopy (a [i].cB, a [i].c, 0, 0, WHOLE_ARRAY);
      improvementCount++;
    }

    // Update the global best solution
    if (newValue > fB)
    {
      double improvement = newValue - fB;
      fB = newValue;
      ArrayCopy (cB, a [i].c, 0, 0, WHOLE_ARRAY);

      // Update the history of the best values
      UpdateBestHistory (fB);

      bestImprovement = MathMax (bestImprovement, improvement);
      improvementCount++;
    }
  }

  // Adapt search parameters depending on the phase and success
  if (epochNow > 1)
  {
    // Search success rate (prevention of zero divide)
    double successRate = (double)improvementCount / MathMax (1, 2 * popSize);

    // Adaptation of the alpha parameter
    for (int c = 0; c < coords; c++)
    {
      double oldAlpha = alpha [c];

      if (epochNow <= S1)
      {
        // In the global search phase
        if (successRate < 0.1)
        {
          // Very few improvements - increasing the search scope
          alpha [c] *= t3;
        }
        else
          if (successRate < 0.3)
          {
            // Few improvements - slightly expanding the scope
            alpha [c] *= 1.2;
          }
          else
            if (successRate > 0.7)
            {
              // Many improvements - narrowing the scope
              alpha [c] *= 0.9;
            }
      }
      else
      {
        // In the local search phase
        if (successRate < 0.05)
        {
          // Very few improvements - increasing the search scope
          alpha [c] *= t3;
        }
        else
          if (successRate > 0.2)
          {
            // Enough improvements - narrowing the scope
            alpha [c] *= 0.8;
          }
      }

      // Limits on alpha range with safe bounds verification
      if (c < ArraySize (rangeMax) && c < ArraySize (rangeMin))
      {
        double maxAlpha = 0.2 * (rangeMax [c] - rangeMin [c]);
        double minAlpha = 0.0001 * (rangeMax [c] - rangeMin [c]);

        if (alpha [c] > maxAlpha)
        {
          alpha [c] = maxAlpha;
        }
        else
          if (alpha [c] < minAlpha)
          {
            alpha [c] = minAlpha;
          }
      }
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

これで、すべてのメソッドの検討が完了したため、アルゴリズムのテストへ直接進むことができます。


テスト結果

結果は非常に明確でした。外部パラメータについてはわずかな最適化がおこなわれましたが、内部パラメータについては変更されず、前述の各メソッドで説明した内容のまま使用されました。

COA(CHAOS)|Chaos Optimization Algorithm|50.0|10.0|40.0|2.0|1.2|0.0001|
=============================
5 Hilly's; Func runs:10000; result:0.6083668756744218
25 Hilly's; Func runs:10000; result:0.4079413401686229
500 Hilly's; Func runs:10000; result:0.2678056430575926
=============================
5 Forest's; Func runs:10000; result:0.668343763134901
25 Forest's; Func runs:10000; result:0.38894787694645416
500 Forest's; Func runs:10000; result:0.2198998763835145
=============================
5 Megacity's; Func runs:10000; result:0.32307692307692304
25 Megacity's; Func runs:10000; result:0.1987692307692308
500 Megacity's; Func runs:10000; result:0.10598461538461638
=============================
All score:3.18914 (35.43%)

アルゴリズムの動作の可視化にも注目したいと思います。使用されている多様な探索手法の組み合わせによって、極めて独特な視覚効果が生み出されています。

Hilly

Hillyテスト関数のCOA(CHAOS)

Forest

Forestテスト関数のCOA(CHAOS)

Megacity

Megacityテスト関数のCOA(CHAOS)

テスト結果に基づき、COA(CHAOS)アルゴリズムを評価表に示します。

# 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)
1ANSacross neighbourhood search0.949480.847760.438572.235811.000000.923340.399882.323230.709230.634770.230911.574916.13468.15
2CLAコードロックアルゴリズム(joo)0.953450.871070.375902.200420.989420.917090.316422.222940.796920.693850.193031.683806.10767.86
3AMOm動物移動最適化m0.903580.843170.462842.209590.990010.924360.465982.380340.567690.591320.237731.396755.98766.52
4(P+O)ES(P+O)進化戦略0.922560.881010.400212.203790.977500.874900.319452.171850.673850.629850.186341.490035.86665.17
5CTA彗星の尾アルゴリズム(joo)0.953460.863190.277702.094350.997940.857400.339492.194840.887690.564310.105121.557125.84664.96
6TETA時間進化移動アルゴリズム(joo)0.913620.823490.319902.057010.970960.895320.293242.159520.734620.685690.160211.580525.79764.41
7SDSm確率的拡散探索M0.930660.854450.394762.179880.999830.892440.196192.088460.723330.611000.106701.441035.70963.44
8BOAmビリヤード最適化アルゴリズムM0.957570.825990.252352.035901.000000.900360.305022.205380.735380.525230.095631.356255.59862.19
9AAmアーチェリーアルゴリズムM0.917440.708760.421602.047800.925270.758020.353282.036570.673850.552000.237381.463235.54861.64
10ESG社会集団の進化(joo)0.999060.796540.350562.146161.000000.828630.131021.959650.823330.553000.047251.423585.52961.44
11SIA等方的焼きなまし(joo)0.957840.842640.414652.215130.982390.795860.205071.983320.686670.493000.090531.270205.46960.76
12ACS人工協調探索0.755470.747440.304071.806981.000000.888610.224132.112740.690770.481850.133221.305835.22658.06
13DA弁証法的アルゴリズム0.861830.700330.337241.899400.981630.727720.287181.996530.703080.452920.163671.319675.21657.95
14BHAmブラックホールアルゴリズムM0.752360.766750.345831.864930.935930.801520.271772.009230.650770.516460.154721.321955.19657.73
15ASO無政府社会最適化0.848720.746460.314651.909830.961480.791500.238031.991010.570770.540620.166141.277525.17857.54
16RFOロイヤルフラッシュ最適化(joo)0.833610.737420.346291.917330.894240.738240.240981.873460.631540.502920.164211.298675.08956.55
17AOSm原子軌道探索M0.802320.704490.310211.817020.856600.694510.219961.771070.746150.528620.143581.418355.00655.63
18TSEA亀甲進化アルゴリズム(joo)0.967980.644800.296721.909490.994490.619810.227081.841390.690770.426460.135981.253225.00455.60
19DE差分進化0.950440.616740.303081.870260.953170.788960.166521.908650.786670.360330.029531.176534.95555.06
20SRAレストラン経営達人アルゴリズム(joo)0.968830.634550.292171.895550.946370.555060.191241.692670.749230.440310.125261.314804.90354.48
21CRO化学反応の最適化0.946290.661120.298531.905930.879060.584220.211461.674730.758460.426460.126861.311784.89254.36
22BIO血液型遺伝最適化(joo)0.815680.653360.308771.777810.899370.653190.217601.770160.678460.476310.139021.293784.84253.80
23BSA鳥群アルゴリズム0.893060.649000.262501.804550.924200.711210.249391.884790.693850.326150.100121.120124.80953.44
24HSハーモニー検索0.865090.687820.325271.878180.999990.680020.095901.775920.620000.422670.054581.097254.75152.79
25SSG苗木の播種と育成0.778390.649250.395431.823080.859730.624670.174291.658690.646670.441330.105981.193984.67651.95
26BCOm細菌走化性最適化M0.759530.622680.314831.697040.893780.613390.225421.732590.653850.420920.144351.219124.64951.65
27ABOアフリカ水牛の最適化0.833370.622470.299641.755480.921700.586180.197231.705110.610000.431540.132251.173784.63451.49
28(PO)ES(PO)進化戦略0.790250.626470.429351.846060.876160.609430.195911.681510.590000.379330.113221.082554.61051.22
29TSmタブーサーチM0.877950.614310.291041.783300.928850.518440.190541.637830.610770.382150.121571.114494.53650.40
30BSOブレインストーム最適化0.937360.576160.296881.810410.931310.558660.235371.725340.552310.290770.119140.962224.49849.98
31WOAm鯨最適化アルゴリズムM0.845210.562980.262631.670810.931000.522780.163651.617430.663080.411380.113571.188034.47649.74
32AEFA人工電界アルゴリズム0.877000.617530.252351.746880.927290.726980.180641.834900.666150.116310.095080.877544.45949.55
33AEO人工生態系ベースの最適化アルゴリズム0.913800.467130.264701.645630.902230.437050.214001.553270.661540.308000.285631.255174.45449.49
34ACOm蟻コロニー最適化M0.881900.661270.303771.846930.858730.586800.150511.596040.596670.373330.024720.994724.43849.31
35BFO-GA細菌採食の最適化:Ga0.891500.551110.315291.757900.969820.396120.063051.428990.726670.275000.035251.036924.22446.93
36SOAシンプル最適化アルゴリズム0.915200.469760.270891.655850.896750.374010.169841.440600.695380.280310.108521.084224.18146.45
37ABHA人工蜂の巣アルゴリズム0.841310.542270.263041.646630.878580.477790.171811.528180.509230.338770.103970.951974.12745.85
38ACMO大気雲モデルの最適化0.903210.485460.304031.692700.802680.378570.191781.373030.623080.244000.107950.975034.04144.90
39ADAMm適応モーメント推定M0.886350.447660.266131.600140.844970.384930.168891.398800.661540.270460.105941.037944.03744.85
40CGOカオスゲーム最適化0.572560.371580.320181.264320.611760.619310.621611.852670.375380.219230.190280.784903.90243.35
41ATAm人工部族アルゴリズムM0.717710.553040.252351.523100.824910.559040.204731.588670.440000.186150.094110.720263.83242.58
42CROmサンゴ礁最適化M0.785120.460320.259581.505020.866880.352970.162671.382520.632310.267380.107341.007033.89543.27
43CFO中心力最適化0.609610.549580.278311.437500.634180.468330.225411.327920.572310.234770.095860.902943.66840.76
44ASHA人工シャワーアルゴリズム0.896860.404330.256171.557370.803600.355260.191601.350460.476920.181230.097740.755893.66440.71
45ASBO適応型社会行動最適化(ASBO)0.763310.492530.326191.582020.795460.400350.260971.456770.264620.171690.182000.618313.65740.63
CHAOSカオス最適化アルゴリズム0.608370.407940.267811.284120.668340.388950.219901.277190.323080.198770.105980.627833.18935.43
RWニューロボイド最適化アルゴリズム2(joo)0.487540.321590.257811.066940.375540.219440.158770.753750.279690.149170.098470.527342.34826.09


まとめ

テスト後に得られた35%という結果は、COA (CHAOS)アルゴリズムが高い潜在能力を持っていることを示しています。特に、その複雑さや、最適化されていない内部パラメータを含む多数の調整可能な外部パラメータを考慮すると、この結果は非常に有望です。つまり、このアルゴリズムはまだ最大限の性能を発揮していないと言えます。

このアルゴリズムにおける最も興味深く、有望な特徴としては、ロジスティック写像、正弦写像、テント写像という3種類のカオスマップを活用している点が挙げられます。また、慣性を導入することで、局所解の罠を乗り越えながら探索の勢いを維持できるようになっています。さらに、最適化の成功度や探索フェーズに応じてパラメータを動的に変更することで、高い柔軟性を実現しています。加えて、解の履歴を追跡し、「停滞した」エージェントをリセットすることで、有望でない領域への計算資源の浪費を防いでいます。さらに、ラテン超方格法や、異なる初期配置戦略を用いることで、探索開始時点から探索空間を広範囲にカバーできる点も重要です。アルゴリズムをさらに改善するためには、内部パラメータについて、より詳細かつ包括的な最適化を実施する価値があるでしょう。

このアルゴリズムは、他の最適化手法を改良するための多くのアイデアを提供しています。特に、適応的メカニズムや停滞状態への対処方法は、金融市場向けの機械学習アルゴリズムや他の最適化アルゴリズムにも効果的に応用できる可能性があります。

Tab

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

チャート

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

COA(CHAOS)の長所と短所

長所

  1. 多様な検索方法
  2. 将来的な発展性が期待できる
  3. 安定した結果

短所

  1. 多数の外部パラメータ
  2. 最適化不可能な内部パラメータが多数存在する

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


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

#名前種類詳細
1#C_AO.mqh
インクルード
集団最適化アルゴリズムの親クラス
2#C_AO_enum.mqh
インクルード
集団最適化アルゴリズムの列挙
3TestFunctions.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_COA_chaos.mq5
スクリプトCOA(CHAOS)テストスタンド

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

添付されたファイル |
COAcCHAOSd.zip (203.55 KB)
最後のコメント | ディスカッションに移動 (2)
Jesus Manzur
Jesus Manzur | 12 2月 2026 において 21:04
それは、異なる方法が組み合わされたとき、それは古いテレビのもののように静的な一種を生成することを見て驚くべきことであり、ある意味で彼女のように、この "ノイズ "またはカオスのようなものを示すことは、はい、記録されたまま、我々は取るに足らないという真実で、最終的な結果を完全に変更してしまう感度によって決定された小さな初期変動と同じ事実でなければなりません、非常に良い記事です。
Andrey Dik
Andrey Dik | 13 2月 2026 において 05:22
Jesus Manzur #:
...
ありがとう!
FX裁定取引:リスク管理を伴う公正価値への回帰を目指す行列取引システム FX裁定取引:リスク管理を伴う公正価値への回帰を目指す行列取引システム
本記事では、クロスレート計算アルゴリズムの詳細な説明、不均衡マトリクスの可視化、さらに効率的な取引のためのMinDiscrepancyおよびMaxRiskパラメータの最適な設定方法について解説します。本システムは、クロスレートを用いて各通貨ペアの「公正価値」を自動的に算出し、価格が公正価値より低い方向へ乖離した場合には買いシグナルを、高い方向へ乖離した場合には売りシグナルを生成します。
カオス最適化アルゴリズム(COA) カオス最適化アルゴリズム(COA)
本記事では、カオス理論と適応型探索メカニズムを組み合わせた改良型カオス最適化(COA)を紹介します。このアルゴリズムでは、複数のカオス写像と慣性成分を利用して探索空間を効率的に走査します。また、金融最適化におけるカオス的手法の理論的基盤についても解説します。
エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法 エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法
この記事では、MT4において複数のEAの衝突をさける方法を扱います。ターミナルの操作、MQL4の基本的な使い方がわかる人にとって、役に立つでしょう。
価格変動の角度分析:金融市場予測のためのハイブリッドモデル 価格変動の角度分析:金融市場予測のためのハイブリッドモデル
金融市場の角度分析とは何でしょうか。プライスアクションにおける「角度」をどのように活用すれば、機械学習によって67%の予測精度を達成できるのでしょうか。さらに、角度特徴量を用いた回帰モデルと分類モデルをどのように統合し、実用可能なアルゴリズムへと落とし込むことができるのでしょうか。ギャンはこれとどのような関係があるのでしょうか。価格変動の角度が機械学習において有効な指標である理由は何でしょうか。