Macromedia Flash非公式テクニカルノート 配列を偏りなくランダムに並替える
Platform: All [*注] ActionScript 3.0にもとづくスクリプトと解説は「配列を偏りなくランダムに並べ替える」をご参照ください。 1. 配列をランダムに並替える // function定義: xShuffleArray [1]配列をランダムに並替えるユーザー定義関数('function')xShuffleArrayを定義します。ランダムに並替える対象となる配列を、引数として渡します。引数の配列自体を並替えますので、戻り値はありません。 [2]まず配列の長さを取得します。エレメントの数をもとに、取出すランダムな位置のインデックス番号を計算するためです。同じ値を、ローカル変数nとiに代入します。変数iの値は、後の処理で変化します。変数nの値は、終始変わりません。 [3]配列のエレメントすべてをループ処理します。ループ条件は、論理式でなく変数iになっています。変数が数値の場合、0以外の値は'true'と評価されます。変数iの値は、ポストデクリメントで、評価後に1減算されます。したがって、エレメント数と同じ回数の処理が行われることになります。 [4]並替える対象となるインデックス番号を、ランダムに決定します。返される値は、0からnまでの整数です。変数nの値は配列の長さで、配列の最後のエレメントのインデックスより1大きいです。したがって、0から最後のインデックス番号までの値が、ランダムで返されます。 [5]配列の最後のエレメントから順に抜出して、ランダムに決められたインデックス番号のエレメントと差替えていきます。変数iの初期値は配列の長さで、'while'アクションの評価後にポストデクリメントi--で1減算しています。ですから、最後のエレメントから最初のエレメントまで、さかのぼってすべて処理することになります。 2. 並替えの偏り このスクリプトでは、毎回最大値が最終インデックス番号までのランダムな整数を計算しています。配列の長さ(エレメント数)が3だとすると、0から2までの整数を毎回ランダムに出す訳です。このとき得られる整数は、0、1、2の3通りです。 3通りのランダムな整数値を使ってエレメント数と同じ3回順序の入替えを行った場合、その並替えの結果は3×3×3=27通りになります。ところが、3つの値のすべての並び順のパターンつまり順列は、3×2×1=6通りです。27は6で割切れず、3余りが出ます。つまり、27通りの中には、他の並び順より多く発生しているパターンが3通りあるということです(後述「参考」を参照)。 3. 偏りのない並替え // function定義: xShuffleArray 変更したのは、ランダムなインデックスの計算を行うステートメントです。変数iを元にしますので、発生するランダムな整数の最大値が、処理とともに減少します。 この考え方は、カードのシャッフルと同じです。カードをまとめて手にしたら、好きな位置から1枚抜いてテーブルの上に重ねます。つぎのカードも同じように、1枚抜いてはテーブルのカードに積重ねます。それを繰返して、手に残った最後の1枚をテーブルの山の一番上に重ね終わったとき、ランダムに並替えたカードの山ができあがる訳です。 この場合手元のカードは、テーブルに積み重ねるたびに、1枚ずつ減っていきます。ですから、ランダムなインデックスの最大値も、同様に減らすことになります。ランダムに取出したカードはテーブルに積んで、手元のカードに戻さないことにより、すべてのカードを漏れなく処理したことになるのです。 参考
_____ 作成者: 野中文雄 Copyright © 2001-2006 Fumio Nonaka. All rights reserved. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||