# Generate random weighted variables

In this post I describe the common problem how to generate random weighted variables. For example you have a die with 6 faces that is fixed, so the probability of an 1 is not the same with the probability of a 2 etc.

The table below shows an example:

 Face Probability 1 25 2 25 3 20 4 20 5 5 6 5

One easy solution is to reduce the problem to another one with a die with 100 faces that is not fixed.

You generate a random value from 0-99 that follows the uniform distribution. Do not use the modulo function to do that. See this post instead.

Once you have that value you perform the following steps:

You check the space within which that value relies.

1. between 0 and 24, you generate 1 as the weighted variable
2. between 25 and 49, you generate 2 as the weighted variable
3. between 50 and 69, you generate 3 as the weighted variable
4. between 70 and 89, you generate 4 as the weighted variable
5. between 90 and 94, you generate 5 as the weighted variable
6. between 95 and 99, you generate 6 as the weighted variable

# Generate uniformly distributed random variables

Formulas shown below generate values that follow uniform distribution.

Using simple modulo methods is not considered as a good solution (although used a lot by students) as the module function does not generate all the variables with the same frequency.

### Random integer between [ 0, 1 ]

int r = (int) (rand()/(RAND_MAX + 0.0));

### Random integer between [ 0, 1 )

int r = (int) (rand()/(RAND_MAX + 1.0));

### Random integer between [ 0, N ]

int r = (int) (N * (rand() / (RAND_MAX + 0.0)));

### Random integer between [ 0, N )

int r = (int) (N * (rand()/(RAND_MAX + 1.0)));

### Random integer between [ M, N ]

int r = (int) (Μ + (rand()/(RAND_MAX + 0.0))*(N-M+1));

### Random integer between [ M, N )

int r = (int) (Μ + (rand()/(RAND_MAX + 1.0))*(N-M+1));

### Summary

The general formula is:

int r = (int) (A + (rand()/(RAND_MAX + C))*B);

Values of M, N, K are shown in the following table:

 Range A B C [ 0, 1 ] 0 1 0.0 [ 0, N ] 0 N 0.0 [ M, N ] M N – M + 1 0.0 [ 0, 1 ) 0 1 1.0 [ 0, N ) 0 N 1.0 [ M, N ) M N – M + 1 1.0

# Generating values of normal distribution – Marsaglia method

Assuming you can already produce variables of uniform distribution, you can produce variables of normal distribution using various formulas. Two of the most important are:

Most methods are based on Box-Muller method.

The Marsaglia method is my favorite since it does not require using sin() or cos() functions and the steps are very easy to implement.

Here is a sequence of the steps:

1. Generate a value that follows uniform distribution in any space you want (eg: [ 0 , 1 ))
2. Map that value to space (-1, +1) and assign it to variable U
3. Repeat steps 1 and 2 and assign the result to variable V
4. Calculate S = U*U + V*V
5. if S = 0 or S >= 1 then free all variables if needed and restart from the beginning
6. The following two variables will be independent and standard normally distributed (mean = 0, variance = 1):

Optionally you can add m to the quantities above to change the mean value of the distribution.

# Java – Appending objects to binary files

Java is tricky, you cannot add objects to already existent files with default classes.

Here is the solution:

import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

public class Test{
private static String filename = "test";

public static void main(String[] args) {
writeToBinary (filename, "a", true);
writeToBinary (filename, "b", true);
writeToBinary (filename, "c", true);
}

public static void writeToBinary (String filename, Object obj, boolean append){
File file = new File (filename);
ObjectOutputStream out = null;

try{
if (!file.exists () || !append) out = new ObjectOutputStream (new FileOutputStream (filename));
else out = new AppendableObjectOutputStream (new FileOutputStream (filename, append));
out.writeObject(obj);
out.flush ();
}catch (Exception e){
e.printStackTrace ();
}finally{
try{
if (out != null) out.close ();
}catch (Exception e){
e.printStackTrace ();
}
}
}

public static void readFromBinaryFile (String filename){
File file = new File (filename);

if (file.exists ()){
ObjectInputStream ois = null;
try{
ois = new ObjectInputStream (new FileInputStream (filename));
while (true){
System.out.println (s);
}
}catch (EOFException e){

}catch (Exception e){
e.printStackTrace ();
}finally{
try{
if (ois != null) ois.close();
}catch (IOException e){
e.printStackTrace ();
}
}
}
}

private static class AppendableObjectOutputStream extends ObjectOutputStream {
public AppendableObjectOutputStream(OutputStream out) throws IOException {
super(out);
}

@Override
protected void writeStreamHeader() throws IOException {}
}
}


References:

https://stackoverflow.com/questions/4646272/appending-objects-to-a-binary-file