この記事では、java に関する関連知識を提供します。主に Java のランダム関数の変換について紹介します。記事内のサンプルコードは詳細に説明されており、Java の学習に役立ちます。興味のある人はさらに詳しく学ぶことができます。
推奨学習: 「Java ビデオ チュートリアル 」
Java では、Math.random()
関数は、区間 [0,1)
内の任意の小数を等しい確率で返します。つまり、x の場合、<code>[0,x)
の数字が出現する確率は x
です。 ##x < 1 の場合、
[0,x) の数字の確率は
x^2 に調整されます。
[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.02886030.028900000000000006目標要件に近い。
質問 2
があるとします。この関数は、等しい確率で [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 を返すランダム関数
を取得するには、
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 < 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() << 2) + (m() << 1) + m();
} while (ans == 7);
return ans;
}</pre>
最終的に、目的の関数 f()
は次のように取得できます。完全なコードは次のとおりです。 <pre class="brush:java;"> // 等概率返回1~7
public static int g() {
return x() + 1;
}</pre>
質問 3
まずメソッドを実装する必要があります。等しい確率で 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 を返す方法はありますか? ランダム関数
アイデア、呼び出し
f()
関数を 2 回実行すると、次のような状況が得られます
1 1
0 11 0
は同じである必要がありますので、の確率になります。
0 1
1 0
0 1
Return 0、get1 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 サイトの他の関連記事を参照してください。