乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      JAVA基礎(chǔ):隨機(jī)整數(shù)的生成

       鳳舞天煌 2007-01-11
      JAVA基礎(chǔ):隨機(jī)整數(shù)的生成

      使用Java 2 SDK基礎(chǔ)類(lèi)庫(kù)產(chǎn)生隨機(jī)數(shù)的方法很多。但是如果你跟不上這些類(lèi)庫(kù)的更新腳步,你有可能正在使用的是一種低效的隨機(jī)數(shù)生成機(jī)制,更糟糕的是:你有可能得到的不是均勻分布的隨機(jī)數(shù)。本文將向你展示一種較為可靠的隨機(jī)數(shù)生成方法,同時(shí)與其他方法進(jìn)行比較。

      自從JDK最初版本發(fā)布起,我們就可以使用java.util.Random類(lèi)產(chǎn)生隨機(jī)數(shù)了。在JDK1.2中,Random類(lèi)有了一個(gè)名為nextInt()的方法:
      public int nextInt(int n)
      給定一個(gè)參數(shù)n,nextInt(n)將返回一個(gè)大于等于0小于n的隨機(jī)數(shù),即:0 <= nextInt(n) < n。

      你所要做的就是先聲明一個(gè)Random的對(duì)象,在調(diào)用其nextInt(n)函數(shù)以返回隨機(jī)值。

      這里有個(gè)示例,下面的代碼段將生成很多隨機(jī)數(shù)并輸出它們的平均值:

      int count = 1000000;
      int range = Integer.MAX_VALUE / 3 * 2;
      double sum = 0;
      Random rand = new Random();
      for (int i=0; i<count; i++) {
      sum += rand.nextInt(range);
      }
      System.out.println(sum/count);

      執(zhí)行了1000000次循環(huán)之后,得到的平均值基本上就處于隨機(jī)數(shù)范圍的中點(diǎn)(midpoint)。

      到目前為止,事情還并不復(fù)雜,但是我們會(huì)問(wèn)為什么要使用nextInt(n)?考慮一下的隨機(jī)數(shù)生成方法:
      (1)使用老的方法nextInt(),沒(méi)有制定數(shù)值范圍
      (2)用Math.abs()靜態(tài)函數(shù)得到(1)中產(chǎn)生值的絕對(duì)值
      (3)對(duì)(2)的結(jié)果進(jìn)行取模運(yùn)算(%),得到期望范圍類(lèi)的值

      我們說(shuō)nextInt(n)要比上述方法更好,為什么呢?參考以下的代碼段:

      sum = 0;
      for (int i=0; i<count; i++) {
      sum += Math.abs(rand.nextInt()) % range;
      }
      System.out.println(sum/count);

      不難發(fā)現(xiàn),每次循環(huán)都多出了幾步運(yùn)算。事實(shí)上,這種隨機(jī)數(shù)生成的方法存在著以下三個(gè)問(wèn)題:

      首先,nextInt()返回的值是趨于均勻分布在Integer.MIN_VALUE 和 Integer.MAX_VALUE之間的。如果你取Integer.MIN_VALUE的絕對(duì)值,得到的仍然不是一個(gè)正數(shù)。事實(shí)上,Math.abs(Integer.MIN_VALUE)等于Integer.MIN_VALUE。因此,存在著這樣一種情況(雖然很少見(jiàn)):rand.nextInt()=Integer.MIN_VALUE,經(jīng)過(guò)取絕對(duì)值Math.abs(rand.nextInt())之后,得到是一個(gè)負(fù)數(shù)。這種幾率為 1/(2^31),在我們的測(cè)試中不太可能發(fā)生——循環(huán)次數(shù)只有1000000次。

      其次,當(dāng)你對(duì)nextInt()取模時(shí),你使結(jié)果的隨機(jī)性大打折扣。隨機(jī)數(shù)中較小的值出現(xiàn)的幾率更大一些。這就是眾所周知的偽隨機(jī)數(shù)生成,因此我們不是用取模的方法。

      最后,也可能是最糟糕的:隨機(jī)數(shù)不是均勻分布。如果你執(zhí)行了上述的兩段代碼,第一段代碼的結(jié)果將會(huì)大于715,000,000,考慮到數(shù)值范圍的中點(diǎn)(midpoint)是715,827,882,所以這是一個(gè)可以接受的結(jié)果。然而,你會(huì)吃驚的發(fā)現(xiàn)第二段代碼得到的平均值肯定不會(huì)超過(guò)600,000,000。

      為何第二段代碼的結(jié)果會(huì)如此的偏差?糾其本質(zhì),問(wèn)題出在數(shù)值分布的不均勻。當(dāng)你進(jìn)行取模運(yùn)算時(shí),你將過(guò)大的數(shù)轉(zhuǎn)換成了較小的。這使得較小的數(shù)更容易產(chǎn)生。

      使用nextInt(range)將會(huì)解決上述的三個(gè)問(wèn)題。

      還有一種隨機(jī)數(shù)生成方法——使用Math.random()。這個(gè)方法的效果如何?

      sum = 0;
      for (int i=0; i<count; i++) {
      sum += (int)(Math.random() * range);
      }
      System.out.println(sum/count);

      很好,使用random()不會(huì)碰到nextInt()的麻煩。你不會(huì)得到負(fù)數(shù)返回值,沒(méi)有使用取模運(yùn)算,值分布也是均勻的。還有什么問(wèn)題嗎?你有沒(méi)有考慮到Math.random()使用了浮點(diǎn)運(yùn)算,而nextInt()和nextInt(range)只有整數(shù)操作?Math.random()可能會(huì)慢上四倍。再加上從浮點(diǎn)到整數(shù)的類(lèi)型轉(zhuǎn)換,整個(gè)運(yùn)算將會(huì)更慢。

      好了,經(jīng)過(guò)一番比較,我們發(fā)現(xiàn)使用nextInt(range)生成隨機(jī)數(shù)更為有效,因?yàn)樗苊饬似渌椒ǖ姆N種弊端。

      最后再給出一段代碼,通過(guò)測(cè)試可以比較本文提到的幾種隨機(jī)數(shù)生成方法。

      import java.util.*;
      import java.text.*;

      public class RandomTest {
      public static void main(String args[]) {
      NumberFormat nf = NumberFormat.getInstance();
      int count = 1000000;
      int range = Integer.MAX_VALUE / 3 * 2;
      System.out.println("Midpoint: " + nf.format(range/2));
      double sum = 0;
      Random rand = new Random();

      for (int i=0; i<count; i++) {
      sum += rand.nextInt(range);
      }
      System.out.println("Good : " + nf.format(sum/count));

      sum = 0;
      for (int i=0; i<count; i++) {
      sum += Math.abs(rand.nextInt()) % range;
      }
      System.out.println("Bad : " + nf.format(sum/count));

      sum = 0;
      for (int i=0; i<count; i++) {
      sum += (int)(Math.random() * range);
      }
      System.out.println("Longer : " + nf.format(sum/count));
      }
      }

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多