Recall that computers can't create real random numbers, just streams of numbers that appear random to the outside observer. As a rule of thumb, users are well advised to choose a well tested generator which has a long period, which is the number of draws that can be made before the sequence repeats. We also want a generator that runs fast and uses little memory. (These wishes are of course in conflict with each other, so choice involves compromise.) And the generator should perform `acceptably' in a statistical sense. Readers who wish to pursue what this might mean are referred to the bibliography.
Suppose you want to draw some random numbers with the default random generator. When a swarm program runs, it creates a globally available object called randomGenerator that can be used in any part of the program to draw random numbers.
If you want to draw unsigned integers, try this:
unsigned int myUnsigned; myUnsigned = [randomGenerator getUnsignedSample]; |
The values returned will be uniformly distributed in the range [0,4294967295] = [0,232-1].
Or, if you need floating-point values instead, you can say
double myDouble; myDouble = [randomGenerator getDoubleSample]; |
The returned values will be uniformly distributed in the range [0.0,1.0), i.e. they may be equal to 0.0 but never 1.0.
The default generator used in Swarm is MT19337, but there are a number of others that are provided to suit the needs of experimentation and replication of previous studies. These generators have been subjected to various statistical tests, and the results of these tests are described in Advanced Usage Guide.
The current generators in Swarm are:
ACGgen: Additive Congruential Generator
C2LCGXgen: A short component based generator. This is considered a high quality generator
C2MRG3gen: Combined Multiple Recursive Generator
C2TAUSUSxgen: A Family of Combined Trausworthe generators
C3MWCgen: Combined Multiply With Carry Generator
C4LCGXgen: Combined random generator using 4 (PMM)LGC generators
LCGxgen: Family of Linear Congruential Generators
MRGxgen: Family of Multiple Recrusive (LCG) Generators
MT19937gen: 'Mersenne Twister' Twisted GFSR generator. The Swarm default
MWCxgen: Family of Multiply-With Carry generators
PMMLCGxgen: Family of Prime Modulus Multiplicative Linear Congruential Generators
PSWBgen: Subract-With-Borrow Congruential Generator with prime modulus
RWC2gen: 2-lag Recursion With Carry generator
RWC8gen: Multiply With Carry generator
SCG: Subtractive Congruential Generator
SWBxgen: Family of Subtract-With-Borrow Congruential Generators
TGFSRgen: Twisted GFSR generator
TT403gen: A single long generator recommended for use
TT775gen: A single long generator recommended for use
TT800gen: A single long generator recommended for use
All the Swarm generators except two conform to the `SimpleRandomGenerator' protocol. The two `split' generators that do not, C2LCGX and C4LCGX, are described in the Generator Usage Guide.
Whenever a random generator is created, its state has to be initialized. It uses a "seed", a positive integer, as its starting place. To make life easy for the user, the Swarm generators can be initialized to a predictable and repeatable state. Every time you initialize a given generator with a particular seed, you should get the same sequence of numbers from it.
You create and initialize a generator with a specific seed this way:
#import <random.h> id <SimpleRandomGenerator> myGenerator; unsigned int mySeed; mySeed = 123776; myGenerator = [RWC8gen create: [self getZone] setStateFromSeed: mySeed]; |
If it is necessary to set or reset the seed after the generator has bene created, it can be done with the setStateFromSeed: method:
mySeed = 4532657; [randomGenerator setStateFromSeed: mySeed]; |
You may do this any time during a simulation, not just at the start.
If you start your simulation with the command line option -s, which is short for --varyseed, then the seed will be chosen at random on the basis of the system clock. If you do not add that command line option, your simultion will use the exact same stream of random numbers every time you run it. This makes replication easy.