Some users have contacted us with the suggestion that the network and matrix calculator should be enhanced in order to provide for a random number generator. Indeed, random numbers can be very useful in many cases, such as when introducing random variations on the normally assumed average time or demand values, in order to assess the robustness of the obtained solutions.
While most users might not be aware of this, random number generators
can be implemented easily with the existing versions of the network
and matrix calculator modules. The trick is to properly use the
two intrinsics
get()
and
put()
,
which are provided mainly to optimize common subexpressions within
the same expression (see section III-3.3 of the User's Manual for
a description).
While normally a get()
can only be performed when a corresponding
put()
has already been executed within the same expression, a special
provision is made to allow a call get(1)
even if no corresponding
put has been made in the same expression yet. In this case,
get(1)
returns the value stored in the first put()
of the last
expression used within the same module, or zero on the first call.
This feature can thus be used to automatically generate consecutive
numbers, e.g. with the simple expression
``put(get(1)
1)+''.
This feature can be used in a similar manner to implement a random number generator according to the linear congruential method. The following expressions are different implementations of the same basic method, all yielding real numbers between 0 and 1, with cycle length of 11979, 6655 and 6057 respectively:
put(int(get(1)*430+2531).mod.11979)/11979 put(int(get(1)*936+1399).mod.6655)/6655 put(int(get(1)*1366+1283).mod.6075)/6075
These expressions can be used alone to initialize vectors or matrices
with random values, or as a subexpression in longer calculations. In
the latter case, if the get()/put()
mechanism is used not just for the
random numbers, you have to make sure that the put()
in the random number
generator precedes the other calls to put()
in the expression.
Note that the random sequence is restarted whenever the module is entered.
If the random numbers are to be generated in a sequence which involves
more than a single call to a module (e.g. when using it in a complex macro
procedure), the internal state of random number generator can be
saved in a scalar (say ms
X) before leaving the module by using a dummy
calculation with the expression
get(1)
.
Later on, when the same random sequence is to be continued, the generator
can be "seeded" by an initial dummy calculation of the expression
put(ms(
X))
.
If you are interested in more details on the theory and practice of random number generators, such as why the specific choice of the numbers used in the above expressions, refer to the following references: