ホームページ  >  記事  >  Java  >  Javaのランダム関数変換例を詳しく解説

Javaのランダム関数変換例を詳しく解説

WBOY
WBOY転載
2022-08-24 11:59:021828ブラウズ

この記事では、java に関する関連知識を提供します。主に Java のランダム関数の変換について紹介します。記事内のサンプルコードは詳細に説明されており、Java の学習に役立ちます。興味のある人はさらに詳しく学ぶことができます。

Javaのランダム関数変換例を詳しく解説

推奨学習: 「Java ビデオ チュートリアル

解決済みの問題

質問 1

Java では、Math.random() 関数は、区間 [0,1) 内の任意の小数を等しい確率で返します。つまり、x の場合、<code>[0,x) の数字が出現する確率は x です。 ##x < 1 の場合、[0,x) の数字の確率は x^2 に調整されます。

質問 1 のアイデア

[0,x) の確率は x であるため、Math.random()# を 2 回呼び出します##、大きい方の値も [0,x) 間隔内にある場合、両方の呼び出しは [0,x) 間隔内にある必要があります (In は、 [x,1)、戻り値は [0,x)) にはなりません。つまり、確率は x^2 です。コードは次のとおりです。 <pre class="brush:java;">package snippet; public class Code_0004_RandToPow2 { // 将`[0,x)`中的数出现的的概率调整成`x^2` public static double randToPow2() { return Math.max(Math.random(), Math.random()); } }</pre> 次のテスト コードを通じて質問 1 の解決策を検証できます:

package snippet;

public class Code_0004_RandToPow2 {
    // 将`[0,x)`中的数出现的的概率调整成`x^2`
    public static double randToPow2() {
        return Math.max(Math.random(), Math.random());
    }

    // 测试用例
    public static void main(String[] args) {
        int count = 0;
        int testTimes = 10000000;
        double x = 0.17;
        for (int i = 0; i < testTimes; i++) {
            if (randToPow2() < x) {
                count++;
            }
        }
        System.out.println((double) count / (double) testTimes);
        System.out.println(Math.pow(x, 2));
    }
}

出力された結果は次のとおりです

0.0288603
0.028900000000000006


目標要件に近い。

質問 2

ランダム関数

f()

があるとします。この関数は、等しい確率で [1,5] の 1 つを返すことができます。数値、他のランダム関数を導入せずに f() 関数 のみを使用して、[1,7] の任意の数値を返す関数を取得する方法等しい確率 g()アイデア

目標は等しい確率で

[1,7]

を返すことなので、

x() 関数を処理できれば、この関数は、等しい確率で [0,6] の範囲内の任意の数値を返します。その場合、ターゲット関数 g() は、この x()## を呼び出すだけで済みます。 # 関数 1 を追加する、つまり g() 関数では、<pre class="brush:java;">public static int g() { return x() + 1; }</pre>[0,6] を取得し、等しい確率で数値を返す必要があります。 ## 最初に行う必要があります。等しい確率で 0 と 1 を返すランダム関数

m()

を取得するには、f() 関数を通じて取得できます。 , <pre class="brush:java;">// 通过[0,5]等概率返回的随机函数f() // 加工出等概率得到0和1 // 1,2,3,4,5 五个数 // 得到1,2的时候,返回0 // 得到4,5的时候,返回1 // 得到3的时候,弃而不用,再次尝试 public static int m() { int ans = 0; do { ans = f(); } while (ans == 3); return ans &lt; 3 ? 0 : 1; }</pre> はあります。等しい確率で 0 と 1 を返すランダム関数 m() を返す [0,6]

メソッドを簡単に生成できます。等しい確率の数値。

[ 0,6] は表すのに 3 つの 2 進数を必要とするため、m() 関数を 3 回呼び出すことができ、任意の数値を取得できます。 [0,7]の範囲を等しい確率で取得する場合、7を取得したときに上記のプロセスを再試行でき、[0,6]の場合は結果のみが返されます。 #xx() 関数を処理しています。 <pre class="brush:java;"> // 等概率返回0~6 public static int x() { int ans = 0; do { ans = (m() &lt;&lt; 2) + (m() &lt;&lt; 1) + m(); } while (ans == 7); return ans; }</pre>最終的に、目的の関数 f() は次のように取得できます。完全なコードは次のとおりです。 <pre class="brush:java;"> // 等概率返回1~7 public static int g() { return x() + 1; }</pre> 質問 3

は質問 2 と同じ考え方です。核心は

まずメソッドを実装する必要があります。等しい確率で 0 と 1 を返すランダム関数

m()

を指定し、ターゲット関数の間隔でバイナリ ビットの数が必要かどうかを確認して、

m() 関数を何回呼び出すかを決定します。詳細については説明しません。コード全体については、

package snippet;

public class Code_0005_Rand5ToRand7 {

    // 此函数只能用,不能修改
    // 等概率返回1~5
    public static int f() {
        return (int) (Math.random() * 5) + 1;
    }

    // 通过[0,5]等概率返回的随机函数f()
// 加工出等概率得到0和1
// 1,2,3,4,5 五个数
// 得到1,2的时候,返回0
// 得到4,5的时候,返回1
// 得到3的时候,弃而不用,再次尝试
    public static int m() {
        int ans = 0;
        do {
            ans = f();
        } while (ans == 3);
        return ans < 3 ? 0 : 1;
    }

    // 等概率返回0~6
    public static int x() {
        int ans = 0;
        do {
            ans = (m() << 2) + (m() << 1) + m();
        } while (ans == 7);
        return ans;
    }

    // 等概率返回1~7
    public static int g() {
        return x() + 1;
    }

    
}

質問 4を参照してください。関数 f() があり、不等確率 (ただし確率は固定) で 0 と 1 を返します。 f() 関数を介してのみ 0 と 1 を返す方法はありますか? ランダム関数

g()

アイデア、呼び出し f() 関数を 2 回実行すると、次のような状況が得られます

0 0

1 1

0 1

1 0

両方の時間が 0 の場合、または両方の時間が 1 の場合は、0 ですが破棄します。確率は 1 とは異なりますが、


0 1
1 0

の確率になります。
は同じである必要がありますので、

0 1

Return 0、get
1 0

Return 1、つまり
g()## を取得します。 #function

完全なコードは次のとおりです

/**
 * The rand7() API is already defined in the parent class SolBase.
 * public int rand7();
 * @return a random integer in the range 1 to 7
 */
class Solution extends SolBase {
    public int rand10() {
        return rand(10);
    }

    public int rand(int N) {
        int bit = 1;
        int base = 2;
        while (base <= N) {
            base = 2 << bit;
            bit++;
        }
        int v = build(bit);
        while (v < 1 || v > N) {
            v = build(bit);
        }
        return v;
    }

    private int build(int bit) {
        int v = 0;
        for (int i = 0; i < bit; i++) {
            v += (m() << i);
        }
        return v;
    }

    // 核心:生成 0 和 1 等概率返回的随机函数
    public int m() {
        int i = rand7();
        while (i == 7) {
            i = rand7();
        }
        return (i == 1 || i == 2 || i == 3) ? 0 : 1;
    }
}

推奨学習:「

Java ビデオ チュートリアル

以上がJavaのランダム関数変換例を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjb51.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。