Java权重随机的实现方法
本文实例讲述了Java权重随机的实现方法。分享给大家供大家参考。具体分析如下:
权重随机在项目中经常用到,所以我把它抽象到一个工具类中。
一般实现随机权重有两种方式:
1.使用一个数组存放权重对应的实际目标,比如A的权重是2,B的权重是3,那么数组长度为5,数组前两个存放A,后三个存放B。
然后随机一个[0-数据长度)的数字,直接取数组对应下标的值就可以了。
优点:数据结构简单,算法高效,实现简单
缺点:当权重值比较大同时数据又比较多的时候,会浪费内存
2.使用区间算法,从前到后依次叠加权重,然后随机一个[1-权重和]的数字,再用随机的权重依次减去每个元素的权重,当第一个小于等于0的元素就是我们找元素
这里实现可以借用Arrays的binarySearch方法。
完整实例代码点击此处本站下载。
贴一下代码:
WeightMeta.java:
/**
*建议使用RandomUtil类创建RandomMeta对象
*@authorwxfon14-5-5.
*/
publicclassWeightMeta<T>{
privatefinalRandomran=newRandom();
privatefinalT[]nodes;
privatefinalint[]weights;
privatefinalintmaxW;
publicWeightMeta(T[]nodes,int[]weights){
this.nodes=nodes;
this.weights=weights;
this.maxW=weights[weights.length-1];
}
/**
*该方法返回权重随机对象
*@return
*/
publicTrandom(){
intindex=Arrays.binarySearch(weights,ran.nextInt(maxW)+1);
if(index<0){
index=-1-index;
}
returnnodes[index];
}
publicTrandom(intranInt){
if(ranInt>maxW){
ranInt=maxW;
}elseif(ranInt<0){
ranInt=1;
}else{
ranInt++;
}
intindex=Arrays.binarySearch(weights,ranInt);
if(index<0){
index=-1-index;
}
returnnodes[index];
}
@Override
publicStringtoString(){
StringBuilderl1=newStringBuilder();
StringBuilderl2=newStringBuilder("[random]\t");
StringBuilderl3=newStringBuilder("[node]\t\t");
l1.append(this.getClass().getName()).append(":").append(this.hashCode()).append(":\n").append("[index]\t\t");
for(inti=0;i<weights.length;i++){
l1.append(i).append("\t");
l2.append(weights[i]).append("\t");
l3.append(nodes[i]).append("\t");
}
l1.append("\n");
l2.append("\n");
l3.append("\n");
returnl1.append(l2).append(l3).toString();
}
}
RandomUtil.java:
/**
*随机工具类
*
*使用权重的集合Map构建随机元数据对象
*
*比如:
*我们有3个url地址,他们的权重分别为1,2,3现在我们利用RandomUtil来根据权重随机获取url:
*
*<p><blockquote><pre>
*
*map.put(url1,1);
*map.put(url2,2);
*map.put(url3,3);
*RandomMeta<String,Integer>md=RandomUtil.buildWeightMeta(map);
*StringweightRandomUrl=md.random();
*
*</pre></blockquote><p>
*
*@authorwxfon14-5-5.
*/
publicclassRandomUtil{
publicstatic<T>WeightMeta<T>buildWeightMeta(finalMap<T,Integer>weightMap){
finalintsize=weightMap.size();
Object[]nodes=newObject[size];
int[]weights=newint[size];
intindex=0;
intweightAdder=0;
for(Map.Entry<T,Integer>each:weightMap.entrySet()){
nodes[index]=each.getKey();
weights[index++]=(weightAdder=weightAdder+each.getValue());
}
returnnewWeightMeta<T>((T[])nodes,weights);
}
}
希望本文所述对大家的Java程序设计有所帮助。