抽奖算法

406 阅读3分钟

1. 均匀抽奖算法

解释: 均匀抽奖算法是最简单的抽奖算法,每个奖项被抽中的概率都是相同的。假设有n个奖项,那么每个奖项被抽中的概率都是1/n。

使用场景: 适用于所有奖项价值相同,或者不需要考虑奖项概率的情况。

代码示例:

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

public class UniformLottery {
    public static <T> T draw(List<T> items) {
        Random random = new Random();
        int index = random.nextInt(items.size());
        return items.get(index);
    }
}

2. 权重抽奖算法

解释: 权重抽奖算法根据每个奖项的权重值来决定中奖概率。权重越高,奖项被抽中的概率越大。权重值相当于每个奖项的相对概率。

使用场景: 适用于奖项价值不同,需要根据权重(概率)来决定中奖情况的抽奖。

代码示例:

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

public class WeightedLottery {
    static class Prize {
        String name;
        int weight;

        Prize(String name, int weight) {
            this.name = name;
            this.weight = weight;
        }
    }

    public static String draw(List<Prize> prizes) {
        int totalWeight = prizes.stream().mapToInt(prize -> prize.weight).sum();
        Random random = new Random();
        int randomNumber = random.nextInt(totalWeight);
        int currentWeight = 0;

        for (Prize prize : prizes) {
            currentWeight += prize.weight;
            if (randomNumber < currentWeight) {
                return prize.name;
            }
        }
        return null;
    }
}

3. 随机概率抽奖算法

解释: 随机概率抽奖算法是指在每次抽奖时都有一定的概率(例如25%)中奖。中奖与否是通过生成一个随机数并与设定的概率比较来决定的。

使用场景: 适用于简单的概率控制,例如决定某个用户是否中奖的情况。

代码示例:

java
import java.util.Random;

public class ProbabilityLottery {
    public static boolean draw(double probability) {
        Random random = new Random();
        double randomNumber = random.nextDouble();
        return randomNumber < probability;
    }
}

4. 轮盘赌算法

解释: 轮盘赌算法是基于概率区间来抽奖的。每个奖项占据一个区间,根据生成的随机数落在的区间来确定中奖奖项。这个算法本质上是权重抽奖算法的一种实现。

使用场景: 适用于多个奖项有不同的中奖概率的场景,适合抽奖、资源分配等。

代码示例:

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

public class RouletteWheelSelection {
    static class Prize {
        String name;
        double probability;

        Prize(String name, double probability) {
            this.name = name;
            this.probability = probability;
        }
    }

    public static String draw(List<Prize> prizes) {
        double totalProbability = prizes.stream().mapToDouble(prize -> prize.probability).sum();
        Random random = new Random();
        double randomNumber = random.nextDouble() * totalProbability;
        double currentProbability = 0.0;

        for (Prize prize : prizes) {
            currentProbability += prize.probability;
            if (randomNumber < currentProbability) {
                return prize.name;
            }
        }
        return null;
    }
}

5. 洗牌算法 (Fisher-Yates Shuffle)

解释: 洗牌算法用于将一个列表的元素随机打乱顺序。它确保每个元素在每个位置上的概率都是相同的。

使用场景: 适用于需要随机排列列表元素的场景,例如打乱一个扑克牌的顺序。

代码示例:

java
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class FisherYatesShuffle {
    public static <T> List<T> shuffle(List<T> items) {
        List<T> shuffledItems = new ArrayList<>(items);
        Random random = new Random();
        for (int i = shuffledItems.size() - 1; i > 0; i--) {
            int j = random.nextInt(i + 1);
            Collections.swap(shuffledItems, i, j);
        }
        return shuffledItems;
    }
}

6. 抽奖池算法

解释: 抽奖池算法将所有奖项放入一个池子中,每次抽取一个奖项时从池中随机选取并移除,直到池子为空。

使用场景: 适用于需要多次抽奖且奖项不会重复的情况。

代码示例:

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

public class LotteryPool {
    static class Prize {
        String name;

        Prize(String name) {
            this.name = name;
        }
    }

    public static Prize draw(List<Prize> prizePool) {
        Random random = new Random();
        int index = random.nextInt(prizePool.size());
        return prizePool.remove(index);
    }
}