Randomization Policy

In both randomization policies, the frequencey of a candidate correlates to its weight as configured, in the long run. However, from moment to moment, the probability might vary, depending on the policy to use.

Independent

In this policy, for each randomization request, the probability of each candidate is fixed as long as the weight is not changed. With the randomization algorithm provided by Unreal, assuming it's very close to true random, each candidate's probability is exactly its weight divided by the sum of all children's weights.

If the weights are changed, the next randomization also adapts to the changes.

Shuffled Sequence

Shuffled Sequence policy is a generalized version of deck shuffling procedure. When every candidate has an integer weight, it is exactly like shuffling the weight count of cards into the deck, and reshuffling only until the deck runs out.

For decimal weights, this procedure also works great. It will bring a varied number of cards into each shuffle to match the frequency to the weight. Specifically, if you specify weights less than 1, you can keep it from being outputted until (1 / weight) shuffles.

If you need a better understanding on this procedure, consult the pseudo code below:

// pseudo code

// weights of candidates
float[] input_weights;

// internal state
float[] weights_base;

...

// upon a randomization request

start:
    float[] weights = for i: input_weights[i] + weights_base[i]

    for i: if weights[i] < 1 then weights[i] = 0

    if all(for i: weights[i] <= 0) then
        weights_base[i] += input_weight[i]
        goto start
    end

    x = random_pick(weights)
    weights_base[x] -= 1

This procedure supports dynamic input weights. However, it could become a little complicated to manage, resulting in an undesired outcome.