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程序设计有所帮助。