Get the same arrival rate across models - simulation

I have a model that I have duplicated and made some adjustments to it. When I run both models with the same fixed seed I don’t get the same results, which I understand because I have other sources of randomness in the model. Regardless, in both models, I am using a source block, such that the arrivals are defined by a rate schedule, the schedule is of type rate, and is provided from the database. Now, I know the following pieces of information:
Generally, I can use my own random number generator (RNG) in distributions, for example triangular(5, 10, 25, myRNG), such that Random myRNG = new Random (2)
By default, a schedule with “type” rate follows a passion distribution that utilizes the default RNG.
At anytime in the model, I can substitute the default RNG with my own by calling setDefaultRandomGenerator(Random r).
The question is: Is it possible to use a fixed seed for the arrival rate to make sure I am getting the same exact input in both models?

In anylogic, rates are always equivalent to a poisson distribution with lambda equal to the rate you set,
Intearrival times don't follow any distribution, but using exponential(lambda) in the field is equivalent to using a arrival by rate with a rate of lambda.
But poisson and exponential are closely related, which is why if you use poisson(1.0/lambda) in the intearrival time, you have the same average arrivals as if you use exponential(lambda).
It is not possible to set a seed for the arrival rate, and that's why you need to use intearrival times instead in your source
But you need to create a variable first, let's call it rand, of type Random with initial value new Random(seed)
where seed is any integer you want (long to be more exact)
then in the intearrival time you need to do:
exponential(lambda, 0,rand)
This will lead to unique simulation runs, no matter what configuration you have in the AnyLogic experiment

Sure, simply set both Source blocks to "Interarrival time" in the "arrivals defined by".
Then, use the same code poisson(1, myRNG) in the field, making sure that the myRNG RNG uses the same initial seed (i.e.new Random(1234)
(the "Rate" setting is the same as using poission(1) for interarrival-time)

Related

Anylogic - Substantial variances in identical arrival rate schedule outputs

I am currently completing some verification checks on an Anylogic DES simulation model, and I have two source blocks with identical hourly arrival rate schedules, broken down into 24 x 1h blocks.
The issue I am encountering is significant differences in the number of agents generated by one block compared with another. I understand that the arrival rate is based on the poisson distribution, so there is some level of randomness in the instants of agent generation, but I would expect that the overall number generated by these two blocks should be similar, if not identical. For example, in one operating scenario one block is generating 78 agents, whilst the other is only generating 67 over the 24h period. This seems to be a common issue across all operating scenarios.
Is there a potential explanation regarding idiosyncrasies within Anylogic that might explain this?
Any pointers would be welcomed.
I think it occurs because it follows a poisson distribution. To solve this, you could use the interarrival time function of the source block. In that case you would have the same number of arrivals for different source blocks. However, I'm not sure whether this fits a schedule. If not, you could use the getHourOfDay() function together with a parameter representing the interarrival time. You then have to write the code below for every hour of the day:
if(getHourOfDay()==14) parameter =5;
using sources with poisson distributions will definitely not produce same results... That's the magic of stocastic models.
An alternative to solve this problem is the following:
sources will generate using the inject function
use dynamic events that will be in charge to do source.inject();
let's imagine you have R trains coming per day, and this is a fixed value you want to use, you can then distribute the trains accross the day by doing this:
for(int i=0;i<R;i++){
create_DynamicEvent1(uniform(0,1),DAY); //for source1
create_DynamicEvent2(uniform(0,1),DAY); //for source2
}
This doesn't follow a poisson distribution, but generates a predefined number of arrivals of trains throughout the day, and you can use another distribution of your choice if the uniform is not good enough for you.
run this for every day

Arrival defined by a fixed value - AnyLogic

So Im trying to determine whether another vending machine is required in the gas station (it's an exercise not a real life problem). The only thing that Im given is the fact that each minute a customer is trying to use the vending machine and on average it takes 0.95 min for a customer to buy and pay for what he bought. Im having trouble with "arrivals defined by" field. The exercise says that I absolutely must use interarrival rate. It also says that the probability distribution is unknown and that it is most definitely not exponential. My question is the following, is there any way to define interarrival rate without using a distribution function. I tried inputing the number on it's own and the simulation doesn't work. I considered using rate even though Im not suppose to but it just didn't make sense since rate already considers the distribution to be exponential which isn't the case in my simulation.
Based on your requirement I absolutely must use interarrival rate I understand that you need to use an interarrival time, but not necessarily exponential. In this case you can choose any other distribution from a list of distributions (See below).
If you want those arrivals to be uniformly distributed, use the uniform distribution.
Or if you want them to arrive exactly every 5 minutes, create a bulk of the agents, delay them for 5 minutes and let them in to the system.

Arrival Distributions

Working on my model, set up a custom distribution for the agents to arrive in a bimodal distribution to simulate peaks during the day. To be clear, the agent has a parameter called 'arrivals', and we have a custom distribution connected to the agent, where the distribution for 'arrivals' is set to the custom distribution. And finally, the source has the arrival rate set to the aforementioned custom distribution.
However, upon running the model, the arrivals seem to be coming a lot faster than I intend on modelling.
The distributions are set 'per hour'.
Here are screenshots of the source settings and the custom distribution
Source_Settings
Distribution
I suspect that your source block is not re-drawing a different rate everytime it creates an agent, as you likely expect. Instead, it is defining a fixed rate once at the model start (by chance, it is on the faster end of the distr) and keeps that. Read how the Rate setting works and make sure this is what you want. You probably want the "Interarrival time" setting instead as here, a new value is drawn everytime.
Well, did you make sure the Source object also expects the arrivals to be "per hour"?
Sounds like you are still in the default "per second" mode...

Uniform Random Number blocks in my simulation model

I've used 2 Uniform Random Number blocks in my simulation model, but every time I run the program they generate last numbers (exactly the same). I need to test the model with new generated numbers. what should I do?
thanks for your helps in advance
The fact that random number generators generate the same random numbers "from the start" is a feature, not a bug. It allows for reproducible testing. You need to initialize your random number generator with a "random seed" in order to give a different result each time - you could use the current time, for example. When you do, it is recommended that you store the seed used - it means you can go back and run exactly the same code again.
For initializing a random seed, you can use the methods given in this earlier answer
In that answer, they are setting the seed to 0 - this is the opposite of what you are trying to do. You will want to generate a non-random number (like the date), and use that. A very useful article can be found here. To quote:
If you look at the output from rand, randi, or randn in a new MATLAB
session, you'll notice that they return the same sequences of numbers
each time you restart MATLAB. It's often useful to be able to reset
the random number generator to that startup state, without actually
restarting MATLAB. For example, you might want to repeat a calculation
that involves random numbers, and get the same result.
They recommend the command
rng shuffle
To generate a new random seed. You can access the seed that was used with
rng.seed
and store that for future use. So if you co
rng shuffle
seedStore = rng.seed;
Then next time you want to reproduce results, you set
rng(seedStore);

How can I use reproducible randomization in Perl?

I have a Perl script that uses rand to generate pseudorandom integers in some range. I want it to be random (i.e. not set the seed by myself to some constant), but also want to be able to reproduce the results of a specific run if needed.
What would you do?
McWafflestix says:
Possibly you want to have a default randomly determined seed, that will give you complete randomness when desired, but which can be set prior to a run manually to give reproducibility.
The obvious way to implement this is to follow your normal seeding process (either manually from a strong random source, or letting perl do it automatically on the first call to rand), then use the first generated random value as the seed, and record it. If you want to reproduce later, just use a recorded value for the seed.
# something like this?
if ( defined $input_rand_seed ) {
srand($input_rand_seed);
} else {
my $seed = rand(); # or something fancier
log_random_seed($seed);
srand($seed);
}
If the purpose is to be able to reproduce simulation paths which incorporate random shocks (say, when you are running an economic model to produce projections, I would give up on the idea of storing the seed, but rather store each sequence alongside the model data.
Note that the built in rand is subject to vagaries of the rand implementation provided by the C runtime. On all Windows machines and across all perl versions I have used, this usually means that rand will only ever produce 32768 unique values.
That is severely limited for any serious purpose. In simulations, a crucial criterion is that random sequences used be independent of each other so that each run can be considered an independent realization.
In fact, if you are going to run a simulation 1,000 times, I would pre-produce 1,000 corresponding random sequences using known-good generators that are consistent across platforms and store them with the model inputs.
You can update the simulations using the same sequences or a new set if parameter estimates change when you get new data.
Log the seed for each run and provide a method to call the script and set the seed?
Why don't you want to set the seed, but at the same time set the seed? As I've said to you before, you need to explain why you don't want to do something so we know what you are actually asking.
You might just set it yourself only in certain conditions:
srand( $ENV{SOME_SEED} ) if defined $ENV{SOME_SEED};
If you don't call srand, rand calls it for you automatically but it doesn't report the seed that it used (at least not until Perl 5.14).
It's really just a simple programming problem. Just turn what you outlined into the code that does what you said.
Your goals are at odds with each other. One one hand, you want a self-seeding, completely random sequence of integers; on the other hand, you want reproducibility. Completely random and reproducibility are at odds with each other.
You can set the seed to something you want. Possibly you want to have a default randomly determined seed, that will give you complete randomness when desired, but which can be set prior to a run manually to give reproducibility.