【MQL5】ArgSort関数について

MQL5リファレンス
スポンサーリンク
スポンサーリンク

ArgSort関数の働き・役割

ArgSort関数は、ベクトル行列要素を並べ替える際に、その順番を示すインデックス(通し番号)を返すために使用します。例えば、値がランダムに並んでいるデータを昇順や降順に整理したい場合、ArgSort関数はその並べ替えに必要な要素の位置を教えてくれます。

この関数では、並べ替えそのものを直接実行するのではなく、「どの要素をどの順序で並べればよいのか」を示すインデックスのリストを提供します。

また、カスタム並べ替え関数を使用することで、ユーザー自身が独自のルールを指定して並べ替えを行うこともできます。

ArgSort関数の引数について

ArgSort関数には、ベクトル用と行列用、さらに行列で軸を指定する場合の3つの書式があります。それぞれの書式について詳しく解説します。


1. ベクトル用の書式

vector vector::Sort(func_name compare_func=NULL, T context);

引数の詳細

  1. compare_func
    並べ替えを行うための比較関数を指定します。初期値NULLで、この場合、昇順での並べ替えが行われます。比較関数を指定することで、独自の並べ替えルールを適用できます。
    • 例:compare_funcにENUM_SORT_MODE(例えばSORT_DESCENDING)を指定すると降順に並べ替えます。
    • カスタム比較関数を使用する場合、次の形式を持つ必要があります。
      • int comparator(T x1, T x2)
        x1x2を比較し、並べ替えのルールを定義します。
      • int comparator(T x1, T x2, TContext context)
        上記に加え、contextを使用して追加の条件を加えた比較が可能です。

        引数データ型の一つである「T」は、テンプレート型を意味します。これは、関数クラスが異なるデータ型で動作できるようにするための仕組みです。
        例えば、整数や浮動小数点数、文字列など、さまざまなデータ型を扱う場合に、特定の型に固定せずに汎用的に使えるようにするための記号として「T」が使われます。具体的な型は、関数クラスを呼び出すときに自動的に決定されます。
  2. context
    比較関数に渡す追加のオプションパラメータです。この引数を使用して、並べ替えに必要なカスタム情報を指定できます。

動作例

ベクトル{50, 10, 40, 30, 20}を昇順で並べ替えた場合、ArgSort関数の結果はインデックス{1, 4, 3, 2, 0}を返します。このインデックスを使用して、並べ替えたデータを取得できます。


2. 行列用の書式(軸指定なし)

matrix matrix::Sort(func_name compare_func=NULL, T context);

引数の詳細

  1. compare_func
    ベクトルの場合と同じく、並べ替えに使用する比較関数を指定します。初期値NULLで、この場合、行列全体を1つのデータセットとして昇順に並べ替えます。
  2. context
    比較関数に渡す追加のパラメータです。カスタムルールに基づいた並べ替えを行う場合に使用します。

動作例

行列

5  1  7  
2  6  3  
8  4  9

を並べ替えると、すべての要素を1次元データとして扱い、昇順に並べ替えます。この場合の結果は次のようになります(インデックス):

1  0  2  
3  4  5  
6  7  8

3. 行列用の書式(軸指定あり)

matrix matrix::Sort(const int axis, func_name compare_func=NULL, T context);

引数の詳細

  1. axis
    並べ替えを行う軸を指定します。次の値が指定可能です。
    • 0: 列方向で並べ替え(垂直方向)
    • 1: 行方向で並べ替え(横方向)
  2. compare_func
    並べ替えに使用する比較関数です。ベクトルや軸指定なしの行列の場合と同様、初期値NULLで、昇順で並べ替えます。
  3. context
    比較関数に渡す追加のパラメータです。

動作例

行列

5  1  7  
2  6  3  
8  4  9

軸を1(行方向)に指定した場合
各行を独立して昇順に並べ替えた結果のインデックスは次のようになります。

1  0  2  
0  2  1  
1  0  2

このインデックスを使用して並べ替えると、次の行列が得られます。

1  5  7  
2  3  6  
4  8  9

これらの3つの書式は、データ構造や並べ替えの目的に応じて使い分けることで、柔軟なデータ処理を実現します。特に行列の場合は軸指定が重要で、操作の結果が大きく異なる点に注意してください。

ENUM_SORT_MODEについて

ENUM_SORT_MODEは、データを並べ替える際の順序を指定するための列挙型です。これにより、データを昇順または降順に整列させることができます。

SORT_ASCENDING

SORT_ASCENDINGは、データを小さい順から大きい順に並べ替えることを指定します。例えば、数値のリストが [5, 2, 8, 3] であれば、昇順に並べ替えると [2, 3, 5, 8] となります。

SORT_DESCENDING

SORT_DESCENDINGは、データを大きい順から小さい順に並べ替えることを指定します。先ほどの例で、数値のリストが [5, 2, 8, 3] であれば、降順に並べ替えると [8, 5, 3, 2] となります。

これらの識別子を使用することで、データの並べ替えを簡単に制御することができます。

ArgSort関数の戻り値について

ArgSort関数は、並べ替えの結果を直接返すのではなく、並べ替えた結果のインデックス(通し番号)を持つベクトルまたは行列を返します。このインデックスを使用することで、元のデータを並べ替えた結果を簡単に再現できます。

たとえば、以下のベクトルがあるとします。

[50, 10, 40, 30, 20]

このベクトルを昇順で並べ替えた場合、ArgSort関数戻り値は以下のようになります。

[1, 4, 3, 2, 0]

この戻り値が示す意味は、次のとおりです。

したがって、このインデックスを元にデータを並べ替えると、次のベクトルが得られます。

[10, 20, 30, 40, 50]

行列の場合も同様に、戻り値は並べ替えられたインデックスを示す行列となります。たとえば、次の行列があるとします。

5  1  7  
2  6  3  
8  4  9

軸を1(行方向)に指定して昇順に並べ替えると、ArgSort関数戻り値は次のような行列となります。

1  0  2  
0  2  1  
1  0  2

この戻り値を使用して並べ替えを再現すると、次のような行列が得られます。

1  5  7  
2  3  6  
4  8  9

サンプルコードについて

サンプルコードを組もうとしたのですが、現状vectormatrixインスタンスからメソッドが呼び出されず、挙動が確認できませんでした(「vectormatrixにはそのようなメソッドが実装されていない」というコンパイルエラーが出てしまう)。公式リファレンス内に以下のようなコードがあったのですが、

void OnStart()
  {
   int arr[4][5]=
     {
        {22, 34, 11, 20,  1},
        {10, 36,  2, 12,  5},
        {33, 37, 25, 13,  4},
        {14,  9, 26, 21, 59}
     };
   ulong indexes[4][5];
//--- Sort the array
   arr.ArgSort(indexes,-1,0);
   Print("indexes");  
   ArrayPrint(indexes);
   
  }

// Result log:
// indexes
//     [,0][,1][,2][,3][,4]
// [0,]   4   2   3   0   1
// [1,]   2   4   0   3   1
// [2,]   4   3   2   0   1
// [3,]   1   0   3   2   4

上記のコードのように多次元配列インスタンスから呼び出して使う事はできました。

4行5列の2次元配列arrを作成しています。この配列には、整数がランダムに格納されています。

第1引数には並べ替え結果のインデックスを格納するための配列を指定し、第2引数には並べ替えを行う次元(軸)を指定します。-1は「最も内側の次元」を意味します。つまり、この場合、行方向に並べ替えが実行されます。第3引数は並べ替え方法を指定します。0は昇順を意味します。

ArrayPrint関数を使用して、並べ替え結果のインデックスが格納されたindexes配列を出力します。

並べ替え後のインデックス配列(indexes)は、各行について、インデックス配列は「元の要素を昇順で並べ替えた場合に、どの位置の要素がどの順番になるか」を示します。

1行目

元の行:22, 34, 11, 20, 1
昇順で並べ替えると:1, 11, 20, 22, 34
並べ替えた順序のインデックス4, 2, 3, 0, 1

2行目

元の行:10, 36, 2, 12, 5
昇順で並べ替えると:2, 5, 10, 12, 36
並べ替えた順序のインデックス2, 4, 0, 3, 1

3行目

元の行:33, 37, 25, 13, 4
昇順で並べ替えると:4, 13, 25, 33, 37
並べ替えた順序のインデックス4, 3, 2, 0, 1

4行目

元の行:14, 9, 26, 21, 59
昇順で並べ替えると:9, 14, 21, 26, 59
並べ替えた順序のインデックス1, 0, 3, 2, 4

という、挙動でした。

・・・ただし、これは公式リファレンスの解説ページにあるようなベクトル行列に対して行うアプローチではなく、解説ページに従った使い方をしようとするとコンパイルエラーが起こってしまいます。

どなたか、正しい使い方をご存じの方いましたら教えてください。

タイトルとURLをコピーしました