Java weight random implementation method

  • 2020-04-01 03:37:10
  • OfStack

This article illustrates the implementation of random weight in Java. Share with you for your reference. Specific analysis is as follows:

Random weights are used a lot in projects, so I've abstracted them into a utility class.

Generally, there are two ways to realize random weight:

1. Use an array to store the actual target corresponding to the weight. For example, if the weight of A is 2 and the weight of B is 3, then the length of the array is 5.

Then a random [0- data length) number, directly take the array corresponding to the index of the value.

Advantages: simple data structure, efficient algorithm, simple implementation

Disadvantages: when the weight value is relatively large and more data, will waste memory

2. The interval algorithm is used to stack the weight from front to back, and then a random number of [1- weight and] is added, and then the random weight is used to subtract the weight of each element. When the first element is less than or equal to 0, we find the element

The implementation here can borrow the binarySearch method of Arrays.

Complete sample code click here (link: http://xiazai.jb51.net/201501/yuanma/WeightMeta (jb51.net). Rar).

Post the code:

WeightMeta. Java:

/** 
 * It is recommended to use RandomUtil Class to create RandomMeta object
 * @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]tt"); 
        l1.append(this.getClass().getName()).append(":").append(this.hashCode()).append(":n").append("[index]tt"); 
        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:

/** 
 * Random tool class
 *
 * A set of weights Map Build random metadata objects
 *
 * Such as:
 * We have a 3 a url Addresses, and their weights are 1,2,3 Now we use RandomUtil I'm going to get it randomly based on the weights url :
 *
 * <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 has been helpful to your Java programming.


Related articles: