Skip to content

概率抽奖算法

需求

微信抽奖,初始概率值为 1,每分享一位好友且好友助力抽奖,概率值加 1,概率值越大,中奖的几率越大。

思路

  1. 将概率值放入数组中,计算概率值之和;
  2. 随机产生一个中奖值,最大不超过总概率值;
  3. 遍历这个数组,累加概率值,如果中奖值在当前用户累加概率值范围之内,返回中奖用户。

实现

java
/**
 * 从用户列表中产生一个中奖用户
 * @param users 待抽奖的用户列表
 * @return 中奖用户
 */
private static User getWinner(List<User> users) {
    // 统计总的幸运值
    int sum = users.stream().mapToInt(User::getLuckyPoint).sum();
    // 随机获得一个中奖值,最大不超过总幸运值
    int randomPoint = new Random().nextInt(sum) + 1;

    // 用户累加幸运值
    int i = 0;
    for (User user : users) {
        i += user.getLuckyPoint();
        // 如果中奖值在当前用户累加幸运值范围之内,返回中奖用户
        if (randomPoint <= i) {
            return user;
        }
    }
    return null;
}

测试

java
public static void main(String[] args) {
    ArrayList<User> users = new ArrayList<>();
    users.add(new User("小明", 2));
    users.add(new User("小花", 4));
    users.add(new User("张三", 6));
    users.add(new User("李四", 8));
    users.add(new User("王二", 11));
    users.add(new User("麻子", 11));

    User winner = getWinner(users);
    assert winner != null;
    System.out.println("中奖的用户是:" + winner.getName());

}

中奖的用户是:李四

完整代码

java
package study.helloworld.something4j._2020._04._16;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 根据幸运值抽奖,幸运值越大,中奖概率越大
 */
public class LuckDrawByProbability {

    public static void main(String[] args) {
        ArrayList<User> users = new ArrayList<>();
        users.add(new User("小明", 2));
        users.add(new User("小花", 4));
        users.add(new User("张三", 6));
        users.add(new User("李四", 8));
        users.add(new User("王二", 11));
        users.add(new User("麻子", 11));

        User winner = getWinner(users);
        assert winner != null;
        System.out.println("中奖的用户是:" + winner.getName());

    }

    /**
     * 从用户列表中产生一个中奖用户
     * @param users 待抽奖的用户列表
     * @return 中奖用户
     */
    private static User getWinner(List<User> users) {
        // 统计总的幸运值
        int sum = users.stream().mapToInt(User::getLuckyPoint).sum();
        // 随机获得一个中奖值,最大不超过总幸运值
        int randomPoint = new Random().nextInt(sum) + 1;

        // 用户累加幸运值
        int i = 0;
        for (User user : users) {
            i += user.getLuckyPoint();
            // 如果中奖值在当前用户累加幸运值范围之内,返回中奖用户
            if (randomPoint <= i) {
                return user;
            }
        }
        return null;
    }

}

/**
 * 用户
 */
class User {

    /**
     * 用户名
     */
    private String name;

    /**
     * 用户幸运值
     */
    private int luckyPoint;

    public User(String name, int luckyPoint) {
        this.name = name;
        this.luckyPoint = luckyPoint;
    }

    public String getName() {
        return name;
    }

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

    public int getLuckyPoint() {
        return luckyPoint;
    }

    public void setLuckyPoint(int luckyPoint) {
        this.luckyPoint = luckyPoint;
    }
}

Released under the MIT License.