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

Java實(shí)現(xiàn)游戲抽獎(jiǎng)算法

 更新時(shí)間:2020年11月26日 12:44:17   作者:易成  
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)游戲抽獎(jiǎng)算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

常用抽獎(jiǎng)算法對(duì)比

基礎(chǔ)的游戲抽獎(jiǎng)算法通常要求實(shí)現(xiàn)在指定獎(jiǎng)品的集合中,每個(gè)獎(jiǎng)品根據(jù)對(duì)對(duì)應(yīng)概率進(jìn)行抽取。個(gè)人了解的主要有以下幾中抽獎(jiǎng)算法:

隨機(jī)數(shù)一一對(duì)應(yīng)

算法思想

這種算法思想最為簡(jiǎn)單。將n個(gè)獎(jiǎng)品編號(hào)0 - N-1,其中各類獎(jiǎng)品的概率通過其數(shù)量體現(xiàn),最后程序產(chǎn)生0~n-1之間的隨機(jī)數(shù)便是抽中的獎(jiǎng)品編號(hào)。例如:

蘋果手機(jī)概率1%,網(wǎng)站會(huì)員20%,折扣券20%,很遺憾59%。這樣,編號(hào)0是蘋果手機(jī),1-20是會(huì)員,21-40是折扣券,41~100是 很遺憾。產(chǎn)生的隨機(jī)數(shù)落在那個(gè)區(qū)間,就代表那個(gè)獎(jiǎng)品被抽中。

存在問題

1、總數(shù)N快速膨脹

概率通過數(shù)量來體現(xiàn)在各個(gè)獎(jiǎng)品概率較大的情況下,總數(shù)n可以較小。但如果在精度很高的情況下,總數(shù)必須按比例成倍擴(kuò)大。
例如,所有獎(jiǎng)品概率都是10%,那么n只需要取10就可以。但是如果某個(gè)獎(jiǎng)品概率是0.01%,按照這種算法,總數(shù)要擴(kuò)大到100*100。

2、平衡性影響

在Java中,Math.random()方法本身基本可以保證大量測(cè)試的情況下避免高重復(fù),且概率分布比較平均。但是需要注意的是,該方法默認(rèn)返回0-1之間的數(shù)據(jù)。

在當(dāng)前算法中,必須擴(kuò)大指定倍數(shù)并且強(qiáng)制使用int進(jìn)行類型轉(zhuǎn)換。在這樣的擴(kuò)大和轉(zhuǎn)換過程中,必然會(huì)對(duì)數(shù)據(jù)精度進(jìn)行修改,轉(zhuǎn)換后的數(shù)據(jù)也不能保證概率分布平均。

因此,該算法實(shí)際可能達(dá)不到預(yù)期的概率要求。

3、算法復(fù)雜度

數(shù)據(jù)準(zhǔn)備階段,為每個(gè)獎(jiǎng)品確定編號(hào)與獎(jiǎng)品信息的關(guān)系集合需要O(n);
產(chǎn)生隨機(jī)數(shù)階段并轉(zhuǎn)換,O(1);
從集合中查找,不同的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)不同,最差需要O(n);

離散法

算法思想

(高中數(shù)學(xué)里幾何概形的思想)
將獎(jiǎng)品集合的概率劃分區(qū)段放入數(shù)組中。概率區(qū)段通過該概率累計(jì)相加確定。利用隨機(jī)數(shù)產(chǎn)生隨機(jī)概率,加入數(shù)組并排序,該數(shù)據(jù)的下標(biāo),就是對(duì)應(yīng)獎(jiǎng)品集合中獎(jiǎng)品的索引。例如,獎(jiǎng)品的集合有X1,X2,X3,X4,對(duì)應(yīng)概率為P1=0.2,P2=0.2,P3=0.3,P4=0.3。
那么,產(chǎn)生的概率區(qū)段數(shù)組為[0.2,0.4,0.7,1.0]。
0.2以下代表X1,0.2-0.4代表X2,0.4-0.7代表X3,0.7~1代表X4。
這樣,如果產(chǎn)生一個(gè)隨機(jī)概率為0.5,加入數(shù)組排序后,0.4~0.7之間,是X3相加所在的概率區(qū)間,返回index=2。
由于區(qū)間分布的確定是按照X集合順序的,所以該索引也正是X3在原集合中的索引。

特點(diǎn)

1、利用幾何概形,概率數(shù)組分布在0到1之間,不再需要擴(kuò)大倍數(shù)和取整操作,基本可以保證概率平均分布,避免大量重復(fù)的情況
2、概率分配的排序過程,可以使用java默認(rèn)的排序工具類,也可以自己實(shí)現(xiàn)。保證時(shí)間復(fù)雜度最小。
3、復(fù)雜度
準(zhǔn)備階段,即對(duì)準(zhǔn)備概率集合,進(jìn)行歸一化等操作,假設(shè)樣本的概率個(gè)數(shù)為M個(gè),則復(fù)雜度為O(m)。m遠(yuǎn)小于方法一中的n,因?yàn)楦怕手挥袔讉€(gè),不會(huì)大量膨脹。
產(chǎn)生隨機(jī)數(shù),O(1)
排序取下標(biāo),根據(jù)排序算法,O(logM)即可實(shí)現(xiàn)
取值,根據(jù)下標(biāo),O(1);

Alias 算法

這種算法對(duì)數(shù)學(xué)要求比較高,沒有仔細(xì)研究。
感興趣的小伙伴可以自己研究一下和我分享

算法實(shí)現(xiàn)

獎(jiǎng)品實(shí)體類

/**
 * 抽獎(jiǎng)獎(jiǎng)品實(shí)體類
 * @author irving
 * @since 2017年7月23日 下午9:41:33
 * @version MARK 0.0.1
 */
public class Gift {
 
 private int id; //獎(jiǎng)品Id
 private String name; //獎(jiǎng)品名稱
 private double prob; //獲獎(jiǎng)概率
 
 public int getId() {
 return id;
 }
 public void setId(int id) {
 this.id = id;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public double getProb() {
 return prob;
 }
 public void setProb(double prob) {
 this.prob = prob;
 }
 
 @Override
 public String toString() {
 return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
 }
}

抽獎(jiǎng)實(shí)現(xiàn)工具類

/**
 * 抽獎(jiǎng)工具類<br/>
 * 整體思想:
 * 獎(jiǎng)品集合 + 概率比例集合
 * 將獎(jiǎng)品按集合中順序概率計(jì)算成所占比例區(qū)間,放入比例集合。并產(chǎn)生一個(gè)隨機(jī)數(shù)加入其中,排序。</br>
 * 排序后,隨機(jī)數(shù)落在哪個(gè)區(qū)間,就表示那個(gè)區(qū)間的獎(jiǎng)品被抽中。</br>
 * 返回的隨機(jī)數(shù)在集合中的索引,該索引就是獎(jiǎng)品集合中的索引。</br>
 * 比例區(qū)間的計(jì)算通過概率相加獲得。
 * @author irving
 * @since 2017年7月23日 下午9:48:23
 * @version MARK 0.0.1
 */
package com.xxx.xxx.xxx.service;

import java.util.*;

/**
 * 抽獎(jiǎng)工具類
 * @Author yuanyicheng
 * @Date 7:14 上午 2020/9/9
 */
public class DrawUtil {

 public static Gift draw(List<Gift> gifts) {
  if (null == gifts || gifts.size() == 0) {
   return null;
  }

  gifts.sort((o1, o2) -> (o1.prob - o2.prob) > 0 ? 1 : -1);

  List<Double> probLists = new ArrayList<>(gifts.size());
  Double sumProb = 0D;
  for (Gift gift : gifts) {
   sumProb += gift.getProb();
  }
  if (sumProb <= 0) {
   return null;
  }

  // 歸一化概率端點(diǎn)
  Double rate = 0D;
  for (Gift gift : gifts) {
   rate += gift.getProb();
   probLists.add(rate / sumProb);
  }

  double random = Math.random();
  probLists.add(random);
  Collections.sort(probLists);
  int index = probLists.indexOf(random);
  if (index >= 0) {
   return gifts.get(index);
  }
  return null;
 }

 public static void main(String[] args) {
  List<Gift> gifts = new ArrayList<>();
  Gift nothing = new Gift("謝謝惠顧", 0.5D);
  Gift vip = new Gift("XX會(huì)員1個(gè)月", 0.4D);
  Gift phone = new Gift("手機(jī)", 0.1D);

  gifts.add(nothing);
  gifts.add(phone);
  gifts.add(vip);

  // 抽獎(jiǎng)
//  Gift g = draw(gifts);

  // 以下是測(cè)試統(tǒng)計(jì)
  Map<String, Integer> countMap = new HashMap<>();
  for (Gift gift: gifts) {
   countMap.put(gift.getName(), 0);
  }
  countMap.put("null", 0);
  for (int i=0; i<1000; i++) {
   // 抽一個(gè)
   Gift gift = draw(gifts);
   String name = "null";
   if (null != gift) {
    name = gift.getName();
   }

   int count = countMap.get(name);
   countMap.put(name, ++count);
  }

  for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
   System.out.println("抽到"+entry.getKey()+", "+entry.getValue()+"次");

  }
 }
}

/**
 * 獎(jiǎng)品類
 */
class Gift {
 String name;
 Double prob;

 public Gift(String name, Double prob) {
  this.name = name;
  this.prob = prob;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Double getProb() {
  return prob;
 }

 public void setProb(Double prob) {
  this.prob = prob;
 }
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 淺談Spring解決jar包依賴的bom

    淺談Spring解決jar包依賴的bom

    這篇文章主要介紹了淺談Spring解決jar包依賴的bom,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2017-12-12
  • java利用udp實(shí)現(xiàn)發(fā)送數(shù)據(jù)

    java利用udp實(shí)現(xiàn)發(fā)送數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了java利用udp實(shí)現(xiàn)發(fā)送數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • 如何將復(fù)雜SQL轉(zhuǎn)換成Java對(duì)象的實(shí)例講解

    如何將復(fù)雜SQL轉(zhuǎn)換成Java對(duì)象的實(shí)例講解

    轉(zhuǎn)換復(fù)雜SQL到Java代碼,我們需要確定數(shù)據(jù)庫(kù)連接方式和工具,使用JDBC的API來連接數(shù)據(jù)庫(kù)、執(zhí)行SQL語(yǔ)句,復(fù)雜SQL語(yǔ)句可以被拆分為多個(gè)步驟,每個(gè)步驟執(zhí)行一個(gè)特定的操作,通過將SQL語(yǔ)句拆分為多個(gè)步驟,我們可以更好地理解復(fù)雜SQL的邏輯,并且更容易將其轉(zhuǎn)換為Java代碼
    2024-05-05
  • 詳解如何在SpringBoot里使用SwaggerUI

    詳解如何在SpringBoot里使用SwaggerUI

    本篇文章主要介紹了詳解如何在SpringBoot里使用SwaggerUI,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-02-02
  • Java中的HashSet、LinkedHashSet集合解析

    Java中的HashSet、LinkedHashSet集合解析

    這篇文章主要介紹了Java中的HashSet、LinkedHashSet集合解析,與HashSet不同的是,LinkedHashSet在內(nèi)部使用了一個(gè)雙向鏈表來維護(hù)元素的順序,因此它可以保持元素的插入順序,這使得LinkedHashSet在需要保持元素順序的場(chǎng)景下非常有用,需要的朋友可以參考下
    2023-11-11
  • Java this super代碼實(shí)例及使用方法總結(jié)

    Java this super代碼實(shí)例及使用方法總結(jié)

    這篇文章主要介紹了Java this super代碼實(shí)例及使用方法總結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • spring boot 自定義參數(shù)過濾器,把傳入的空字符轉(zhuǎn)換成null方式

    spring boot 自定義參數(shù)過濾器,把傳入的空字符轉(zhuǎn)換成null方式

    這篇文章主要介紹了spring boot 自定義參數(shù)過濾器,把傳入的空字符轉(zhuǎn)換成null方式。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java中的ThreadPoolExecutor線程池原理細(xì)節(jié)解析

    Java中的ThreadPoolExecutor線程池原理細(xì)節(jié)解析

    這篇文章主要介紹了Java中的ThreadPoolExecutor線程池原理細(xì)節(jié)解析,ThreadPoolExecutor是一個(gè)線程池,最多可使用7個(gè)參數(shù)來控制線程池的生成,使用線程池可以避免創(chuàng)建和銷毀線程的資源損耗,提高響應(yīng)速度,并且可以管理線程池中線程的數(shù)量和狀態(tài)等等,需要的朋友可以參考下
    2023-12-12
  • Java并發(fā)讀寫鎖ReentrantReadWriteLock 使用場(chǎng)景

    Java并發(fā)讀寫鎖ReentrantReadWriteLock 使用場(chǎng)景

    ReentrantReadWriteLock是Java中一種高效的讀寫鎖,適用于讀多寫少的并發(fā)場(chǎng)景,它通過允許多個(gè)線程同時(shí)讀取,但在寫入時(shí)限制為單線程訪問,從而提高了程序的并發(fā)性和性能,本文給大家介紹Java并發(fā)讀寫鎖ReentrantReadWriteLock 使用場(chǎng)景,感興趣的朋友跟隨小編一起看看吧
    2024-10-10
  • SpringBoot+mail 輕松實(shí)現(xiàn)各類郵件自動(dòng)推送

    SpringBoot+mail 輕松實(shí)現(xiàn)各類郵件自動(dòng)推送

    在實(shí)際的項(xiàng)目開發(fā)過程中,經(jīng)常需要用到郵件通知功能,例如,通過郵箱注冊(cè),郵箱找回密碼,郵箱推送報(bào)表等等,實(shí)際的應(yīng)用場(chǎng)景非常的多,今天通過這篇文章,我們一起來學(xué)習(xí)如何在 Spring Boot 中快速實(shí)現(xiàn)一個(gè)自動(dòng)發(fā)送郵件的功能
    2024-07-07

最新評(píng)論

株洲市| 呼玛县| 台山市| 阳春市| 泸定县| 民县| 天长市| 玉山县| 锡林浩特市| 海口市| 新宾| 盘山县| 新沂市| 梨树县| 教育| 沙湾县| 玉山县| 星座| 平泉县| 麻栗坡县| 苏州市| 桦川县| 日土县| 克东县| 沈丘县| 辽源市| 白沙| 鄂托克前旗| 馆陶县| 湘西| 常宁市| 革吉县| 长沙市| 松江区| 西吉县| 台东县| 四子王旗| 平南县| 原阳县| 宁化县| 宁强县|