1.问题说明
游戏开发中经常会碰到这样的需求:从一系列道具中随机抽出一个发给玩家,由于道具的价值不一样,所以抽取的概率并不是平均的。后台会处理成高价值的东西很难得到,要实现这种效果,需要给每个道具指定一个权重。比如道具A的权重是99,道具B的权重是1,那么99%的概率会抽到道具A,这就是基于权重的随机算法。
2.示例示范
示例1:
输入:A=[3,3,4],W=[1,2,7]
输出:调用1000次randomPick(),大约有300次取到3,700次取到4
解释:判段数组中含相同元素时的权重值是否会相加
示例2:
输入:A=[3,4],W=[1,9]
输出:调用1000次randomPick(),大约有100次取到3,大约900次取到4
解释:判段数组权重正常时的情况
示例3:
输入:A=[3,2,4],W=[3,0,7]
输出:调用1000次randomPick(),大约有300次取到3,0次取到2,大约700次取到4
解释:判段权重值为0是否会出现
3.核心代码
/**
* 按权重来随机生成数字
*
* @param A 值数组
* @param W 权重占比数组
* @param num 遍历次数
*/
public int[] randomPick(int[] A, int[] W, int num) {
int length = W.length;
//将权重数组分段
for (int i = 1; i < length; i++) {
W[i] = W[i] + W[i - 1];
}
int total = W[length - 1];
int random;
//初始化一个数组来统计出现的次数
int[] count = new int[A.length];
for (int i = 0; i < num; i++) {
//生成小于等于总权重的随机数
random = (int) (Math.random() * (total) + 1);
for (int j = 0; j < length; j++) {
if (random <= W[j]) {
//修改出现的次数
count[j]++;
break;
}
}
}
return count;
}
4.完整代码及结果展示
package leetcode;
/**
* @author WYB
* date 2022-05-20
*/
public class Weight {
public static void main(String[] args) {
int[] A4 = new int[]{3, 3, 4};
int[] W4 = new int[]{1, 2, 7};
int[] A5 = new int[]{3, 4};
int[] W5 = new int[]{1, 9};
int[] A6 = new int[]{3, 2, 4};
int[] W6 = new int[]{3, 0, 7};
Weight weight = new Weight();
int[] int4 = weight.randomPick(A4, W4, 1000000);
for (int i = 0; i < A4.length; i++) {
System.out.println(A4[i] + "出现的次数为:" + int4[i]);
}
System.out.println("------------------------");
int[] int5 = weight.randomPick(A5, W5, 1000000);
for (int i = 0; i < A5.length; i++) {
System.out.println(A5[i] + "出现的次数为:" + int5[i]);
}
System.out.println("------------------------");
int[] int6 = weight.randomPick(A6, W6, 1000000);
for (int i = 0; i < A6.length; i++) {
System.out.println(A6[i] + "出现的次数为:" + int6[i]);
}
}
/**
* 按权重来随机生成数字
*
* @param A 值数组
* @param W 权重占比数组
* @param num 遍历次数
*/
public int[] randomPick(int[] A, int[] W, int num) {
int length = W.length;
//将权重数组分段
for (int i = 1; i < length; i++) {
W[i] = W[i] + W[i - 1];
}
int total = W[length - 1];
int random;
//初始化一个数组来统计出现的次数
int[] count = new int[A.length];
for (int i = 0; i < num; i++) {
//生成小于等于总权重的随机数
random = (int) (Math.random() * (total) + 1);
for (int j = 0; j < length; j++) {
if (random <= W[j]) {
//修改出现的次数
count[j]++;
break;
}
}
}
return count;
}
}
结果图:
带权重的随机数的讲解到这里就结束啦!如果中途有任何问题可以在评论区留言,我会一一为你们解答哦!