質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.37%

【JAVA】乱数0を4分の1の確率で出す

解決済

回答 4

投稿

  • 評価
  • クリップ 1
  • VIEW 8,300

amono

score 12

 JAVAの課題で乱数(0 ~ 10)を配列に入れ、その配列の中には4分の1の確率で0を入れなければならないという課題があります。

この4分の1の確率で0をどう入れることが出来るか分からず困っています。
アドバイスを頂けたら幸いです。

int[] Array = new int[5];
int inputNum = 0; 
for(int i = 0; i < Array.Length; i++)
{
   // 乱数を配列に入れる。
   inputNum = (int)(Math.random * 10);
  /*   
   4分の1の確率で0を出す。

  */
}

*Eclipseを使用しています

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+1

「0か0以外か」を別途乱数で判断するのが一番わかりやすいのではないでしょうか?

int inputNum;
if((int)(Math.random() * 4) == 0) {  // 1/4の確率でここに入る
    inputNum = 0;
} else {  // 残りの3/4はここに
    inputNum = (int)(Math.random() * 10) + 1;  // 0-9の乱数に1を加え、1-10の乱数を発生
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

一回の乱数でする方法を考えてみました。

まず、それぞれの数字が現れる確率を考えます。初めに0とそれ以外を考えます。

  • 0 … 1/4
  • 0以外 … 3/4

0以外は1から10です。それらが平等に現れるなら1/10になります。

  • 0 … 1/4 = 10/40
  • 1 … 3/4 × 1/10 = 3/40
  • 2 … 3/4 × 1/10 = 3/40
  • 3 … 3/4 × 1/10 = 3/40
  • (中略)
  • 9 … 3/4 × 1/10 = 3/40
  • 10 … 3/4 × 1/10 = 3/40

つまり、40通りの乱数を生成し、それぞれ0または0以外の数字にすれば良いとなります。40通りなので0から39とすると、10/40になるのは4の倍数の時ですから4で割った余りが0になればわかります。それ以外の時は4で割れば0から9の数字に均等に現れるので、1をたせば1から10の均等な数字になります。

// Java8での実装例
class ZeroDake {
  public static void main(String[] args) {
    int[] arr = new int[20];
    final java.util.Random random = new java.util.Random();
    java.util.Arrays.setAll(arr, i -> {
      final int r = random.nextInt(40);
      if (r % 4 == 0) {
        return 0;
      } else {
        return r / 4 + 1;
      }
    });
    for (final int x: arr) {
      System.out.println(x);
    }
  }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/15 14:16

    丁寧な解説ありがとうございます。理解することが出来ました。

    キャンセル

  • 2016/05/15 15:26 編集

    間違えたコメントをしました。

    キャンセル

0

次のような数字列の例 A. B, C. D. を考えます。

![イメージ説明

質問の場合なら、
D. の数字列からランダムに1つの数字を選べば、
  1/4 の確率で 0 が選ばられる
  1 .. 10 は それぞれ 3/40 の確率で選ばれる
ことになります。
D. の数字列から、1つをランダムに選ぶ操作は、 たとえば 次のようなコードで実装できます。

int r = random.nextInt(40);   # 0, 1, ... 39 の乱数を得る。
return (r % 4 == 0)? 0: (r / 4) + 1;

実行可能なプログラムとして作成し、 1億回の数字選択をして、 0.. 10 の数字が何回現れるかを表示させてみました。
![イメージ説明](16d1a1448f8d8762b46269c20fb6cfe7.png)

ほぼ 0 が 1億の 1/4 , その他の数字は、どれもほぼ同じ回数 選択されたことがわかります。

コード全体:

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.stream.IntStream;

public class RandomX {

    public static void main(String[] args) {
        Random random = new Random();
        IntStream intStream = random.ints(0, 40);
        int[] array;
        int limit = 10;

        // limit = 10;
        // array = intStream.limit(limit)
        // .map((x) -> (x % 4 == 0) ? 0 : (x / 4) + 1).toArray();
        // System.out.println(Arrays.toString(array));

        limit = 100_000_000; // 1億
        Map<Integer, Integer> counts = new HashMap<Integer, Integer>();
        array = intStream.limit(limit).map((x) -> (x % 4 == 0) ? 0 : (x / 4) + 1).toArray();
        Arrays.stream(array).forEach(x -> counts.put(x, counts.getOrDefault(x, 0) + 1));
        System.out.println(counts);
    }
}


Stream を使っていますが、エッセンスは、

int r = random.nextInt(40);
return (r % 4 == 0)? 0: (r / 4) + 1;


です。
乱数については、次のことも参照するとよいです。

参考情報

補足:
この考え方を延長させると、 0 の出現確率が 1/2, 1/3, ... 1/n になるようにするとか、 n/m (ただし n < m) になるようにすることもできるはずです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

既に解決済みではありますが、、

以下のように、全要素のうち1/4を 0 が、残りをその他の値が一様に占める配列を用意し、
その配列に乱数で生成したインデックスでアクセスしてやるのが、最も簡単な方法かと思います。

import java.util.Random;

public class Main {

    private static int[] elements = { 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
    };

    private static Random random = new Random();

    public static void main(String[] args) {

        int[] Array = new int[5];

        for (int i = 0; i < Array.length; i++) {

            /*
             * 4分の1の確率で0を出す。
             */
            int inputNum = elements[random.nextInt(elements.length)];

            // 乱数を配列に入れる。
            Array[i] = inputNum;
        }

        for (int i = 0; i < Array.length; i++) {
            System.out.println(Array[i]);
        }
    }

}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/16 06:24

    [0.. 1) の範囲の乱数を発生させ、
      [0..0.25) の範囲だったら 0,
      [0.25 .. 0.25 + 0.075) なら 1,
      [0.25 + 0.075 .. 0.25 + 0.075* 2) なら 2
    ...
    のようにすれば、 0.. 10 のすべての出現率を自由に設定できます。

    キャンセル

  • 2016/05/16 11:17

    katoy様

    おっしゃる通り、その方法なら 0 だけでなく、 1 〜 10 の出現率も制御できますね。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る