• ベストアンサー

乱数について

今、あるデータの順番をばらばらにするプログラムを作ろうとしています。  たとえば、a,b,c,dとあったら、d,b,c,aとするように、この時考えられるプログラムは、データの数だけ配列を用意して、乱数で、どのデータを出力させるかを決定し、出力し終わったら、その配列のところに印を立てて、次にくるデータに対して、2重にならないように順次、出力していく方法が考えられるのですが。。。    膨大なデータをこのように、すると、二重になる確立が出力するたびに、高くなっていって、なかなか終わらなくなってしまいます。  そこで、残ったデータから、ランダムに選び出すアルゴリズムまたは、関数はないでしょうか?よろしくお願いします。

  • Nickee
  • お礼率79% (107/134)

質問者が選んだベストアンサー

  • ベストアンサー
  • nakashi
  • ベストアンサー率51% (21/41)
回答No.1

データの数だけ配列を用意して、乱数で適当な回数、場所を入れ替えて (シャフルして)から 先頭から順番に取れば?

Nickee
質問者

お礼

 なるほど!以外に単純でしたね。 ありがとうがございました。

その他の回答 (3)

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.4

No.1の方の方式(仮にAとします)とNo.3の方の方式(仮にBとします)がよく使われます。 バッチ的な処理ではAが適しています。(前処理に時間がかかってもいいが、処理をはじめたら高速) 一方、リアルタイム処理ではBが適しています。(前処理がいらず、毎回一定時間で処理可能) 全部終わったら又、対象を広げて続けると言う場合、Aでは、又、シャッフルが必要ですが、Bでは対象範囲を広げるだけでいいので一瞬ですみます。 特別にまずいという理由がなければ、B方式をお勧めします。私はいつもB方式を使っています。

Nickee
質問者

お礼

 なるほど。勉強になります。 2種類の方法がでているので、ポイントはあげられませんが、ありがとうございました。m (_ _) m

noname#30727
noname#30727
回答No.3

乱数の範囲を狭めていき、選択されたものを次に選択されない位置に移動させるようにします。 #define N 10 int a[N]; int i, r, t; for (i = 0; i < (N - 1); i++) { // i の位置から最後までの中で1つ選択 r = i + rand() % (N - i); // 選択したものを i の位置と交換する t = a[i]; a[i] = a[r]; a[r] = t; } for (i = 0; i < N; i++) { 出力(a[i]); }

Nickee
質問者

お礼

ほ~ 非常に勉強になりました。そういう方法もあるんですね。 ありがとうございました。

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.2

実データとは別に、それに対するインデックスまたはポインタの配列を作ります。 例えば  1 - a  2 - b  3 - c  4 - d という感じです。 乱数で、インデックスを選択し、対応するデータを出力します。 例えば上の例で3が選択されたらcです。 選択されたインデックスを取り除きます。すると  1 - a  2 - b  4 - d    cはインデックスなし となります。 残ったインデックスから乱数で一つを選択し、インデックスが 無くなるまでこれを続けます。

Nickee
質問者

お礼

>残ったインデックスから乱数で一つを選択し いや、その残ったインデックスから、どのように選択するのか知りたかったものですから。。乱数で選択すると、重なる部分が出てくるわけじゃないですか。そうすると、選択するたびに、重なる部分が多くなるので、処理速度が遅くなるので、残ったインデックスからどのように、乱数で選択するのかを聞きたかったのですが。。。 ご意見 ありがとうございました。

関連するQ&A

  • 乱数ってなんですか?

    なんどもすいません。配列のはなしなんですが、まずAという配列の中の0~10番目の中身をランダムに動かして、Bという配列に再編成させたいのですが、 乱数を使えば簡単になるよと知り合いにはいわれたのですが、乱数がどうゆうもの だかあまりよくわかりません。 自分は今VC++のMFCで作ってるのですが、乱数自体がわからないので教えてください。 それとこの方法でいくと日本語の時は配列を2個づつランダムに変えることになると思うのですが、それはぜんぜん予想もできません。教えていただけると助かります。お願いします。

  • 乱数での確率

    乱数に確率をつけることはできるでしょうか? たとえば配列にA、B、Cの3つの要素を収めておいて、  Aが出る確率=50%  Bが出る確率=30%  Cが出る確率=10% といったように確率を設定してランダム表示させたいのですが。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • 配列と乱数を使ったプログラム

    配列と乱数を使ったプログラムについて 今年からプログラミングについて勉強する事になったのですが、 配列と乱数を上手く使うことができません。やりたいと思っていることが おみくじのプログラムで 大吉 中吉 小吉 という3つの配列からウィンドウ上にランダムで 一つ表示するというプログラムです。 【おみくじの結果は *** です。】 ←***の部分がランダムに配列から表示される結果です。(分かりづらなかったら、ごめんなさい) 病欠で2週ほど授業に出席する事が出来なかったので、配列と乱数についてよく分かりません。 PENというソフトで学習しているので、出来るならPENにそって教えてもらえると、嬉しいです。 宜しくお願いしますm(_ _)m

  • 重複せず担当を割り振りたい

    人数をX人とします。 担当が同数のX個あります。 これらを「ランダム」に「1人1担当」で「過去に担当したものは重複しない」結果を出すプログラムを検討しています。 何かいいアルゴリズムや方法はないでしょうか? 例:4人(A、B、C、D) 出力結果 担当1:A→B→C→D 担当2:B→D→A→C 担当3:C→A→D→B 担当4:D→C→B→A このような結果を、ランダムで出力したいです。

  • プログラミングの乱数

    c言語、c++の乱数rand()の使い方がよくわかりません。わかりやすい説明をお願いします。 あと、プログラミングが得意な方にお願いです。 [0,1]乱数で平均と分散を求めるプログラムを配列なしで作ってください。

  • javaの乱数で質問です

    100個の配列を準備して各要素に0~9までの乱数を発生させ5の要素がいくつあるか数えて個数を出力するプログラムがわかりません。 教えてください。

  • c言語乱数について

    トランプのシャッフルと同様な操作をコンピュータで行いたい。52枚のトランプを配列に置き換え、1~52の乱数を割り当てる。ただし発生した乱数はすでに割り当て済みの数である場合は、まだ割り当てていない乱数が出るまで繰り返すものとする。 というプログラムをC言語でつくりたいのですがまったくわからないので誰か教えてください。お願いします。

  • 重複しない乱数を作り配列に入れる(AS3.0)

    Flash Pro CS5 AS3.0 で記述しています。 1~10の整数をランダムかつ重複せずに配列に格納したいと考えています。 そこで,ネット上で参考になるソースを見つけ, 以下のように書き直しました。 var int_a = new Array(); var int_b = new Array(); function RandomInt():void{ //ここだけ変更すればよい var maxN:Number = 10;//乱数の最大値 //0~maxNの数字を全部配列に入れる for (var i:int=0; i< maxN; i++) { int_a[i] = i+1; } var j:Number = 0; var a_length:Number = int_a.length; //要は配列をシャッフルする while (a_length) { var int_r:Number = Math.floor(Math.random()*(maxN+1-j)); //乱発生した整数を配列int_bに順番に入れ、int_aから削除する int_b[j] = int_a.splice(int_r, 1); j++; //配列int_a内の数字が一つずつ減っていく a_length = int_a.length; } //ここで配列int_bがシャッフルされた trace(int_b); } RandomInt(); としました。 しかし出力結果がなぜか 8,2,4,9,,7,6,5,10,3,1のように抜けている部分があり, 次のフレームで for(var j:int=1; j <= 10; j++){   trace(int_b[j]); } として確認してもやはり 2 4 9 7 6 5 10 3 1 となってしまします。 どの部分がおかしいのか教えていただきたいです。 また,乱数発生の部分で Math.floor(Math.random()*(maxN+1-j)); という風に記述してあったのですが,ここは間違いではないのでしょうか? jを引いていくと発生する乱数の範囲が徐々に狭くなっていってしまうと思ったのですが; それとも元のソースコードを使って ttp://www.renowan.com/blog/?p=143 0~9までの乱数を発生させてそれぞれに1を足す方が簡単でしょうか? よろしくお願いします。

    • ベストアンサー
    • Flash
  • C言語 乱数

    C言語 乱数 プログラミングの宿題なのですが、よく分かりません。教えていただける方、よろしくお願いします。 ・表示する文字数の長さは12とする。 ・表示する文字は毎回ランダムで表示すること。 ・文字は英字のうち、小文字のみとする。 ・プログラムにrandom()を使うこと。 ・プログラムにsrandom()を使うこと。 よろしくお願いします。

  • 乱数生成について

    c言語のプログラムで、1と-1をランダムにn個出力するプログラムを書きたいと思っています。どのようにすればいいでしょうか。

専門家に質問してみよう