按照权重随机抽取元素


指定一个样本数组,并为样本数组中的元素设置权重,按照权重随机抽取元素。
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.collections.Bag;
import org.apache.commons.collections.bag.TreeBag;
/**
* 按照权重随机抽取元素
* @author heyang
*
*/
public class RandomUtil {
/**
* 根据指定的样本数组和样本-权重映射随机抽取一个元素
* @param elementArray 样本数组
* @param weightMap 样本-权重映射
* @return
* @throws Exception
*/
public static Object randomByWeight(Object[] elementArray,Map weightMap) throws Exception{
if(elementArray==null||elementArray.length==0){
throw new Exception("ElementArray must not be empty!");
}
if(weightMap==null|| weightMap.isEmpty()){
throw new Exception("WeightMap must not be empty!");
}
int[] weightArray = new int[elementArray.length+1];
Object[] tempElementArray = new Object[elementArray.length];
for(int i=0;i<elementarray.length;i++){
tempElementArray[i] = elementArray[i];
Integer weight = weightMap.get(elementArray[i]);
weightArray[i+1] = weight+weightArray[i];
}
double randomNum = weightArray[weightArray.length-1]*Math.random();
int index = bidSearch(weightArray,randomNum);
return index==-1?null:tempElementArray[index];
}
private static int bidSearch(int[] desArray,double des){
int low = 0;
int high = desArray.length-1;
while(low <= high) {
int middle = (low + high)/2;
if(des > desArray[middle] && des<=desArray[middle+1]) {
return middle;
}else if(des <desarray[middle]) {
high = middle - 1;
}else {
low = middle + 1;
}
}
return -1;
}
public static void main(String[] args) throws Exception{
String[] a = {"a","b","c","d","e"};
Map b = new HashMap();
b.put("a", 12);
b.put("b", 11);
b.put("c", 0);
b.put("d", 19);
b.put("e", 0);
b.put("f", 20);
int total = 0;
for(Object x:a){
int c = b.get(x);
total+=c;
}
for(Object x:a){
BigDecimal percent = new BigDecimal(b.get(x)).divide(new BigDecimal(total),8,BigDecimal.ROUND_HALF_EVEN);
System.out.println("Element:"+x+"\tpercent:"+ percent.toString());
}
Bag bag = new TreeBag();
for(int i=0;i<1000000;i++){
Object res = randomByWeight(a,b);
bag.add(res);
}
for(Object x:a){
System.out.println("Element:"+x+"\tcount:"+bag.getCount(x));
}
}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值