The example in this article describes the implementation method of random weight in Java. Share it with everyone for your reference. The specific analysis is as follows:
Random weighting is often used in projects, so I abstracted it into a tool class.
There are generally two ways to implement random weights:
1. Use an array to store the actual target corresponding to the weight. For example, the weight of A is 2 and the weight of B is 3. Then the length of the array is 5. The first two of the array store A and the last three store B.
Then randomize a number [0-data length) and directly take the value of the corresponding subscript of the array.
Advantages: simple data structure, efficient algorithm, simple implementation
Disadvantages: When the weight value is relatively large and there is a lot of data, memory will be wasted.
2. Use the interval algorithm, superimpose the weights from front to back, then randomly assign a number [1-weight sum], and then use the random weight to subtract the weight of each element in turn. When the first element less than or equal to 0 is our Find elements
This implementation can borrow the binarySearch method of Arrays.
Click here to download the complete example code.
Paste the code:
WeightMeta.java:
Copy the code code as follows:/**
* It is recommended to use the RandomUtil class to create RandomMeta objects
* @author wxf on 14-5-5.
*/
public class WeightMeta<T> {
private final Random ran = new Random();
private final T[] nodes;
private final int[] weights;
private final int maxW;
public WeightMeta(T[] nodes, int[] weights) {
this.nodes = nodes;
this.weights = weights;
this.maxW = weights[weights.length - 1];
}
/**
* This method returns a weighted random object
* @return
*/
public T random() {
int index = Arrays.binarySearch(weights, ran.nextInt(maxW) + 1);
if (index < 0) {
index = -1 - index;
}
return nodes[index];
}
public T random(int ranInt) {
if (ranInt > maxW) {
ranInt = maxW;
} else if(ranInt < 0){
ranInt = 1;
} else {
ranInt++;
}
int index = Arrays.binarySearch(weights, ranInt);
if (index < 0) {
index = -1 - index;
}
return nodes[index];
}
@Override
public String toString() {
StringBuilder l1 = new StringBuilder();
StringBuilder l2 = new StringBuilder("[random]/t");
StringBuilder l3 = new StringBuilder("[node]/t/t");
l1.append(this.getClass().getName()).append(":").append(this.hashCode()).append(":/n").append("[index]/t/t ");
for (int i = 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");
return l1.append(l2).append(l3).toString();
}
}
RandomUtil.java:
Copy the code code as follows:/**
* Random tools
*
* Use the weighted collection Map to construct a random metadata object
*
* for example:
* We have 3 url addresses, their weights are 1, 2, and 3. Now we use RandomUtil to randomly obtain the url based on the weight:
*
* <p><blockquote><pre>
*
* map.put(url1, 1);
* map.put(url2, 2);
* map.put(url3, 3);
* RandomMeta<String, Integer> md = RandomUtil.buildWeightMeta(map);
* String weightRandomUrl = md.random();
*
* </pre></blockquote><p>
*
* @author wxf on 14-5-5.
*/
public class RandomUtil {
public static <T> WeightMeta<T> buildWeightMeta(final Map<T, Integer> weightMap) {
final int size = weightMap.size();
Object[] nodes = new Object[size];
int[] weights = new int[size];
int index = 0;
int weightAdder = 0;
for (Map.Entry<T, Integer> each : weightMap.entrySet()) {
nodes[index] = each.getKey();
weights[index++] = (weightAdder = weightAdder + each.getValue());
}
return new WeightMeta<T>((T[]) nodes, weights);
}
}
I hope this article will be helpful to everyone’s Java programming.