最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java生成抽樣隨機數(shù)的多種算法

 更新時間:2016年10月24日 09:30:51   作者:Q-WHai  
本文主要介紹了java生成抽樣隨機數(shù)的多種算法,主要是基于random庫函數(shù)的,有需要的可以了解一下。

本章先講解Java隨機數(shù)的幾種產(chǎn)生方式,然后通過示例對其進行演示。

概述:

這里你是不是會說,生成隨機數(shù)有什么難的?不就是直接使用Java封裝好了的random就行了么?當然對于一般情況下是OK的,而且本文要說明的這些算法也是基于這個random庫函數(shù)的。

本文主要是針對抽樣這一行為進行的,而抽樣本身有一個隱含的規(guī)則就是不要有重復(fù)數(shù)據(jù)。好了,有了這些說明。你可以先嘗試著用一些自己的想法來實現(xiàn)不重復(fù)地生成隨機數(shù)。

算法嘗試:

一些好的算法出現(xiàn),往往伴隨著一些不那么好的算法。但是對于效果不太好的算法,它們普遍有一個共性,方便理解和實現(xiàn)。下面是通過一個循序漸進的方式來作一個簡單地說明。

第一次嘗試:樸素隨機算法

這個算法很好理解,就是隨機!每一次產(chǎn)生一個隨機數(shù),并加入集合。 

 private void simpleRandom(int start, int end, int count) { 
    System.out.println("樸素隨機算法:"); 
    StringBuffer buffer = new StringBuffer(); 
    for (int i = 0; i < count; i++) { 
      int random = NumberUtils.randomInteger(start, end); 
      buffer.append(i == 0 ? ("[" + random) : (", " + random)); 
    } 
    buffer.append("]"); 
    System.out.println(buffer); 
  } 

第二次嘗試:檢查存在性隨機算法

我們知道上面的方法有一個問題,就是可能會有重復(fù)數(shù)據(jù)。于是,我們就想到,在生成一個隨機數(shù)的時候進行檢查一下這個數(shù)是不是已經(jīng)存在了,如果存在了就重新生成。

private void checkRandom(int start, int end, int count) { 
    System.out.println("檢查存在性隨機算法:"); 
    StringBuffer buffer = new StringBuffer(); 
    List<Integer> save = new ArrayList<>(); 
    for (int i = 0; i < count; i++) { 
      int random = NumberUtils.randomInteger(start, end); 
      if (exits(save, random)) { 
        i--; 
        continue; 
      } 
       
      save.add(random); 
      buffer.append(i == 0 ? ("[" + random) : (", " + random)); 
    } 
    buffer.append("]"); 
    System.out.println(buffer); 
  } 

第三次嘗試:元素移除隨機算法

上面的算法已經(jīng)解決了數(shù)據(jù)重復(fù)的問題。不過,有一個很糟糕的問題就是可能我們要花費很長的時間來生成抽樣隨機數(shù)(這個要看臉了。。。。)。

不過,這里我們有了新想法。那就是在一個集合中去隨機一個數(shù),當這個被選中的時候就remove掉,那么下次再隨機的時候是不是就不會再隨機到這個數(shù)了?這樣就很好地解決了隨機數(shù)的重復(fù)問題。代碼如下:

 private void removeRandom(int start, int end, int count) { 
    System.out.println("元素移除隨機算法:"); 
    StringBuffer buffer = new StringBuffer(); 
    List<Integer> numbers = initList(start, end); 
    for (int i = 0; i < count; i++) { 
      int random = NumberUtils.randomInteger(count - i); 
      buffer.append(i == 0 ? ("[" + numbers.get(random)) : (", " + numbers.get(random))); 
      numbers.remove(random); 
    } 
     
    buffer.append("]"); 
    System.out.println(buffer); 
  } 

第四次嘗試:狀態(tài)轉(zhuǎn)移隨機算法

在我之前的很多博客中,就有一些是算法中的狀態(tài)轉(zhuǎn)移過程。而狀態(tài)的轉(zhuǎn)移也是我最喜歡的算法之一。下面的圖-1中標注了隨機數(shù)的取值范圍,序列中的橙色數(shù)字是結(jié)果中的隨機序列。最下方的序列中有一些虛線的箭頭,代表了狀態(tài)的轉(zhuǎn)移。

圖-1 基于狀態(tài)轉(zhuǎn)移的抽樣隨機數(shù)生成算法

實現(xiàn)代碼:

 private void statusRandom(int start, int end, int count) { 
    System.out.println("狀態(tài)轉(zhuǎn)移隨機算法:"); 
    StringBuffer buffer = new StringBuffer(); 
    int[] status = new int[end + 1]; 
    for (int i = 0; i < count; i++) { 
      int random = NumberUtils.randomInteger(start, end); 
      System.err.println(random); 
      if (status[random] == 0) { 
        buffer.append(i == 0 ? ("[" + random) : (", " + random)); 
        status[random] = random == end ? start : (random + 1); // 不可能有在start之前的數(shù)字 
      } else { 
        // 狀態(tài)轉(zhuǎn)移 
        int index = random; 
        do { 
          index = status[index]; 
        } while (status[index] != 0); 
         
        buffer.append(i == 0 ? ("[" + index) : (", " + index)); 
        status[index] = index == end ? start : (index + 1); // 不可能有在start之前的數(shù)字 
      } 
    } 
     
    buffer.append("]"); 
    System.out.println(buffer); 
  } 

第五次嘗試:遞歸Floyd隨機算法

Floyd算法說到底也是一種狀態(tài)的轉(zhuǎn)移過程。該算法會要求輸入一個List或是array來保存已經(jīng)確定的隨機數(shù)。顧名思義,這里我會用到遞歸的解法。在遞歸的過程中,我們把第i個隨機數(shù)的狀態(tài)轉(zhuǎn)移到了第i-1個隨機身上了。代碼如下:

private List<Integer> simpleFloyd(List<Integer> list, int count, int start, int end) { 
    if (count == 0) { 
      return list; 
    } 
    list = simpleFloyd(list, count - 1, start, end - 1); 
    int random = NumberUtils.randomInteger(start, end); 
    if (list.contains(random)) { 
      list.add(end); 
    } else { 
      list.add(random); 
    } 
    return list; 
  } 

第六次嘗試:迭代Floyd隨機算法

思路與上面的遞歸Floyd隨機算法是相似的,不過,這里我們加入了一個變量來做優(yōu)化。就不需要再去遞歸了。代碼如下:

private List<Integer> iterationFloyd(int start, int end, int count) { 
    System.out.println("迭代Floyd隨機算法:"); 
    List<Integer> list = new ArrayList<>(); 
    for (int i = end - count + 1; i < end; i++) { 
      int random = NumberUtils.randomInteger(start, i); 
      if (list.contains(random)) { 
        list.add(i); 
      } else { 
        list.add(random); 
      } 
    } 
     
    return list; 
  } 

測試結(jié)果:

 

圖-2 隨機數(shù)生成算法測試結(jié)果

在上面的測試結(jié)果中,我們可以很明顯地看出樸素隨機算法不僅有重復(fù)數(shù)據(jù),而且還是最耗時的。所以,在抽樣的隨機數(shù)生成時,避免使用這一算法。而在后幾種算法中,狀態(tài)轉(zhuǎn)移隨機算法最佳,迭代Floyd隨機算法次之。這個可以根據(jù)個人偏愛來做選擇。

相關(guān)文章

  • Spring?Boot開發(fā)RESTful接口與http協(xié)議狀態(tài)表述

    Spring?Boot開發(fā)RESTful接口與http協(xié)議狀態(tài)表述

    這篇文章主要為大家介紹了Spring?Boot開發(fā)RESTful接口與http協(xié)議狀態(tài)表述,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-03-03
  • 簡單易懂講解happens-before原則

    簡單易懂講解happens-before原則

    Java內(nèi)存模型中的happens-before是什么?為什么會有這東西的存在?一個新東西肯定是上手先,但是等我們空下來回過頭來,我們還是需要去理解這些知識,只有這樣我才能深刻的記住,并且運用熟練。下來和小編來一起學(xué)習(xí)下
    2019-05-05
  • 使用Idea maven創(chuàng)建Spring項目過程圖解

    使用Idea maven創(chuàng)建Spring項目過程圖解

    這篇文章主要介紹了使用Idea maven創(chuàng)建Spring項目過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • springboot執(zhí)行延時任務(wù)之DelayQueue實例

    springboot執(zhí)行延時任務(wù)之DelayQueue實例

    這篇文章主要介紹了springboot執(zhí)行延時任務(wù)之DelayQueue實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • java接口Array介紹

    java接口Array介紹

    這篇文章主要介紹了java接口Array的相關(guān)資料,需要的朋友可以參考下
    2014-10-10
  • MyBatis?動態(tài)SQL使用及原理

    MyBatis?動態(tài)SQL使用及原理

    這篇文章主要為大家介紹了MyBatis動態(tài)SQL使用及原理的學(xué)習(xí)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • iReport使用指南及常見功能示例詳解

    iReport使用指南及常見功能示例詳解

    這篇文章主要介紹了iReport使用指南及常見功能,本文以iReport 3.5.1為例,通過示例演示給大家介紹的非常詳細,需要的朋友可以參考下
    2021-10-10
  • java實現(xiàn)拼圖游戲

    java實現(xiàn)拼圖游戲

    這篇文章主要為大家詳細介紹了java實現(xiàn)拼圖游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 使用Spring開啟@Async異步方式(javaconfig配置)

    使用Spring開啟@Async異步方式(javaconfig配置)

    這篇文章主要介紹了使用Spring開啟@Async異步方式(javaconfig配置),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 深入理解Java中的volatile關(guān)鍵字(總結(jié)篇)

    深入理解Java中的volatile關(guān)鍵字(總結(jié)篇)

    volatile這個關(guān)鍵字,不僅僅在Java語言中有,在很多語言中都有的,而且其用法和語義也都是不盡相同的。這篇文章主要介紹了Java中的volatile關(guān)鍵字,需要的朋友可以參考下
    2018-10-10

最新評論

门头沟区| 崇左市| 东港市| 嫩江县| 南城县| 合山市| 监利县| 阿克| 桐柏县| 靖州| 汝南县| 桐梓县| 澜沧| 保亭| 新密市| 梁山县| 进贤县| 贵溪市| 武鸣县| 建始县| 南丹县| 新营市| 靖西县| 万全县| 公主岭市| 扎兰屯市| 无极县| 五峰| 辽阳县| 诸城市| 都安| 班玛县| 马公市| 沈丘县| 绥棱县| 汨罗市| 集贤县| 福泉市| 岫岩| 吴忠市| 三穗县|