package com.mindprod.example;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Random;
import static java.lang.System.*;
/**
* random choices with float weights.
*
* @author Roedy Green, Canadian Mind Products
* @version 1.0 2014-07-28 initial version
* @see com.mindprod.example.RandomWithIntWeights
* @since 2014-07-28
*/
public final class RandomWithFloatWeights
{
/**
* true if want extra output
*/
private static final boolean DEBUGGING = false;
/**
* build the translator table for generated weighted random numbers
*
* @param weights array of weights
*
* @return translator table
*/
@NotNull
private static float[] buildTranslator( @NotNull final float[] weights )
{
float totalWeights = 0;
for ( float weight : weights )
{
totalWeights += weight;
}
final float[] translator = new float[ weights.length ];
float cumulativeWeight = 0;
for ( int i = 0; i < weights.length; i++ )
{
translator[ i ] = cumulativeWeight;
final float normalisedWeight = weights[ i ] / totalWeights;
cumulativeWeight += normalisedWeight;
}
return translator;
}
/**
* Print out 30 ice cream flavours, but weighting toward choclate strawberry and orange.
*
* @param args not used
*/
public static void main( String[] args )
{
final String[] flavours = { "chocolate", "strawberry", "vanilla", "orange", "lime", "Cherry Garcia", "bubble gum" };
final float[] weights = { 30.2f, 40.0f, 2.0f, 36.0f, 20.1f, 4.0f, 0.5f };
final float[] translator = buildTranslator( weights );
if ( DEBUGGING )
{
for ( float lowbound : translator )
{
out.println( lowbound );
}
}
final Random wheel = new Random();
for ( int i = 0; i < 30; i++ )
{
final float rawChoice = wheel.nextFloat();
assert 0 <= rawChoice && rawChoice < 1 : "Random.float is broken";
int where = Arrays.binarySearch( translator, rawChoice );
final int weightedChoice;
if ( where < 0 )
{
weightedChoice = -where - 2;
}
else
{
weightedChoice = where;
}
if ( DEBUGGING )
{
out.println( rawChoice + " " + where + " " + weightedChoice );
}
out.println( flavours[ weightedChoice ] );
}
}
}