内容 PLC
にはソート命令が備わっている機種もありますが、ここではSTG〜JMP命令のサンプルを兼ねて実装します。 |
●PDFを表示 |
◆ シェーカーソート (Shaker
Sort) バブルソートで1回スキャンを行う と、最後の要素1個がスキャン範囲中最大であることが分かり 次回のスキャン範囲を1狭めることができる。 さらに、このスキャンの最後で連続してm個の要素の交換が行われていなければ そのm個についてはソート済みであることが分かるので、次回のスキャン範囲をm狭めることができる。 この工夫で、後半が殆ど整列済みのデータに対してバブルソートが高速に行えるようになる。 シェーカーソートはこれに加え、スキャン方向を毎回反転することにより、スキャン範囲を後方からだけではなく 前方からも狭めるようにしたものである。 挿入ソートのように、殆ど整列済みのデータに対しては高速に行うことができる。 (ウィキペディアより) 変数: 【INDEX_Top】:配列添え字の小さい方の位置 【INDEX_Bot】:配列添え字の大きい方の位置 【INDEX_Swap】:最後にデータ入替を行った位置 【COUNT_IDX】:ループカウンタ(比較位置) ![]() ・インデックスの初期値を設定します。 ・トリガ[@MR000]をセットすると、他に起動しているソートルーチンが無いかをチェック(サブルーチン9)し、なければ次を実行します。 ・【INDEX_Top】に”0”、【INDEX_Bot】に”要素数[Element] - 1 ”を代入します。 ![]() ・順方向スキャンループルーチンです。初期値を設定します。 ・【INDEX_Top】を【INDEX_Swap】と【COUNT_IDX】に代入します。 ・[SPAN]は入替するデータの距離です。(1なら後隣どうし、2なら後ろ1飛ばした位置です) ![]() ・大小比較です。 ・サブルーチン側では、【COUNT_IDX】が[Z1]に【COUNT_IDX】 + 1 が[Z2]に代入され、大小を比較します。 ・【Sort_Data:Z1】 > 【Sort_Data:Z2】ならデータを入替し、入替実行フラグ[F_SWAP]をセットします。 ・入替が行われたら、【INDEX_Swap】に【COUNT_IDX】の値を代入します。 ![]() ・ループカウンタを進めます。比較終了条件、【COUNT_IDX】≧【INDEX_Bot】でループを抜けます。 ・最後の入替が行われた位置【INDEX_Swap】を【INDEX_Bot】に代入します。 ![]() ・【INDEX_Top】= 【INDEX_Bot】ならソートを完了します。 ・【INDEX_Top】≠ 【INDEX_Bot】なら逆方向スキャンへ飛びます。 ![]() ・逆方向スキャンループルーチンです。初期値を設定します。 ・【INDEX_Bot】を【INDEX_Swap】と【COUNT_IDX】に代入します。 ・[SPAN]は入替するデータの距離です。(-1なら前隣どうし、-2なら前に1飛ばした位置です) ![]() ・大小比較です。 ・サブルーチン側では、【COUNT_IDX】が[Z1]に【COUNT_IDX】 - 1 が[Z2]に代入され、大小を比較します。 ・【Sort_Data:Z1】 < 【Sort_Data:Z2】ならデータを入替し、入替実行フラグ[F_SWAP]をセットします。 ・入替が行われたら、【INDEX_Swap】に【COUNT_IDX】の値を代入します。 ![]() ・ループカウンタを進めます。比較終了条件、【COUNT_IDX】 ≦ 【INDEX_Top】でループを抜けます。 ・最後の入替が行われた位置【INDEX_Swap】を【INDEX_Top】に代入します。 ![]() ・【INDEX_Top】= 【INDEX_Bot】ならソートを完了します。 ・【INDEX_Top】≠ 【INDEX_Bot】なら順方向スキャンへ飛びます。 ![]() ・ソートを完了したら、トリガをリセットして最初に戻ります。 ![]() ・入 替実行フラグ[F_SWAP]は他のアルゴリズムでも使用していますので、モジュールの最後でリセットします。 ◆ テスト操作 ・9行目でチェックしてください。 ・[乱数生成] / [乱数転写] にカーソルを合わせ、ダブルクリックすると、ON-OFFできます。 ・[乱数生成]は、乱数を[@FM0]〜 [Element]個分生成します。 ・[乱数転写]は、[乱数生成]で生成した乱数を、ソート対象の[FM0]〜 に転送します。 ・再度同じ要素でソートする場合は、[乱数転写]で同じ要素を転送します。 ・[@MR000]をセットすると実行します。 |
◆ 奇偶転置ソート (Odd-even Sort) 奇偶置換ソートは、奇数番目とその次の偶数番目をペア (Pair1) にして比較/交換した後、 偶数番目とその次の奇数番目をペア(Pair2) にして比較/交換することを繰り返すアルゴリズムである。 Pair1:(1番目と2番目を比較、3番目と4番目を比較、5番目と6番目を比較、…)の後に Pair2:(2番目と3番目を比較、4番目と5番目を比較、6番目と7番目を比較、…)を行う。これを繰り返す。 (ウィキペディアより) 変数: [FLAG]: 【BRAKE】: COUNT_IDX】: ループカウンタ(比較位置) ![]() ・ループの終了条件と入 替するデータの距離[SPAN] を設定します。 ・ トリガ[@MR001]をセットすると、他に起動しているソートルーチンが無いかをチェック(サブルーチン9)し、なければ次を実行します。 ・ソート未完了フラグ[FLAG]をセットします。 ・偶数/奇数ループを抜ける条件【BRAKE】に”要素数[Element] - 2 ”を代入します。 ![]() ・未完了フラグ[FLAG]が偽(ソート完了)ならトリガ[@MR001]をリセットし、最初に戻ります。 ・未完了フラグが真ならフラグをリセットして、【COUNT_IDX】を”0”に初期化します。(偶数) ・フラグで分岐する場合、同”STG”で真のフラグをリセットする (フラグの状態を変える)のは後に記述 してください。 (この例では、36行と37行を入替た記述はしないでください。 フラグが真の時、両方の条件が成立 します。) ![]() ・偶数ペア大小比較です。 ・サブルーチン側では、【COUNT_IDX】が[Z1]に【COUNT_IDX】 + 1 が[Z2]に代入され、大小を比較します。 ・【Sort_Data:Z1】 > 【Sort_Data:Z2】ならデータを入替し、入替実行フラグ[F_SWAP]をセットします。 ・入替が行われたら、未完了フラグをセットします。 ![]() ・ループカウンタを進めますが、偶数にするため+2しています。 ・比較終了条件、【COUNT_IDX】 > 【BRAKE】でループを抜けます。 ・比較が最後まで達していない時は比較ルーチンへ戻ります。 ![]() ・【COUNT_IDX】を”1”に初期化します。(奇数) ![]() ・ 奇数ペア大小比較です。 ・サブルーチン側では、【COUNT_IDX】が[Z1]に【COUNT_IDX】 + 1 が[Z2]に代入され、大小を比較します。 ・【Sort_Data:Z1】 > 【Sort_Data:Z2】ならデータを入替し、入替実行フラグ[F_SWAP]をセットします。 ・入替が行われたら、未完了フラグをセットします。 ![]() ・ループカウンタを進めますが、奇数にするため+2しています。 ・比較終了条件、【COUNT_IDX】 > 【BRAKE】でループを抜けてソート未完了フラグをチェックします。 ・比較が最後まで達していない時は比較ルーチンへ戻ります。 ![]() ・入替実行フラグ[F_SWAP]は他のアルゴリズムでも使用していますので、モジュールの最後でリセットします。 |
◆ 比較、入替サブルーチン □1 . 昇順 ![]() ・[Sort_Data:Z1] > [Sort_Data:Z2]ならサブルーチン40を呼び出し、データを入替します。 □2 . 降順 ![]() ・[Sort_Data:Z1] < [Sort_Data:Z2]ならサブルーチン40を呼び出し、データを入替します。 □3 . データ入替 ![]() ・入替実行フラグ[F_SWAP]をセットします。 ・[Sort_Data:Z1] と [Sort_Data:Z2]の値を入替ます。 ◆ テスト操作 ・33行目でチェックしてください。 ・[乱数生成] / [乱数転写] にカーソルを合わせ、ダブルクリックすると、ON-OFFできます。 ・[乱数生成]は、乱数を[@FM0]〜 [Element]個分生成します。 ・[乱数転写]は、[乱数生成]で生成した乱数を、ソート対象の[FM0]〜 に転送します。 ・再度同じ要素でソートする場合は、[乱数転写]で同じ要素を転送します。 ・[@MR001]をセットすると実行します。 |
◆ 乱数生成、転送ルーチン □1 . 乱数生成 ![]() ![]() ・乱数関数で乱数を発生させます。(SEEDの初期値は1) ![]() ・乱数を1〜[AREA]の範囲で生成します。 ・生成される乱数範囲の 1〜65535 を 1〜[AREA] の範囲に変換します。 ・変換後の値が”0”ではなかったら[@FM0:Z1]に代入し、Z1をカウントアップします。 ・生成個数が要素数に達するまで、82行目にジャンプし、繰り返します。 ・全ての乱数が生成されると、サブルーチンを抜けます。 □1 . 乱数転送 ![]() ・乱数生成で[@FM0]〜に書込まれた数値を、ソート対象の[FM0]〜に転送します。 ・[FM0]〜最大個数分をクリアします。 ・[@FM0]〜のデータを[FM0]〜に転送します。 |
●PDFを表示 |