I have a process to move a picking agent and a product through the same delay block - simulation

Currently, I have two delay blocks above each other, where one agent goes through one of the blocks and the other through the other one.
But when I want exponentially distributed values with a mean of 120 seconds, They both need to have the same value always. So they are done at the same time.

You simply need to have the two delay blocks use their own (but with the same seed) random object.
Start off by creating two identical random objects
And have each of the delay blocks use of them of them
Then the numbers they will sample will be the same for every sampling iteration.
See this post for a similar problem
Why do two flowcharts set up exactly the same end with different results every time the simulation is run even when I use a fixed seed?

Not questioning your probably bad design by not using resources, These are the steps to follow to ensure things happen at the exact same time:
1.Create a variable called seed of type long
2.create a cyclic event that runs every 1 minute and has the following code:
seed=(new Random()).nextLong();
3.In both blocks you will use the following code to calculate the exponential distribution:
exponential(120,0,new Random(seed))

Related

Why does every simulation I perform in Arena Simulation give the same results?

Every time I run a simulation with the same parameters in the Run window I get exactly the same results. The results are different if a different number of replications is set each time the run is started
These are my settings in the run window:
enter image description here
I have a lot of Process blocks. Most of them have a normal distribution in duration. Why are the results not different?
If it helps in any way, her is a photo of the constructed model:
enter image description here
Arena uses the same random nr stream for your run unless you tell it to use another - so your first rep will look the same every time. The answer depends on the distributions you sample from. If you change the logic and sample at other times, the answer will change. Each following rep will have a unique answer based on the random nr streams you are sampling from. It makes it easier/possible to find errors if you can execute exactly the same run.
Arena provides (by default) ten different "streams" of (pseudo) random numbers. If you don't ask the system to use a particular stream, it will use stream 10. For example NORM(10,2) will use stream 10 to calculate a random normally distributed number (mean 10, standard deviation 2); NORM(10,2,4) will use stream 4 to calculate a similarly distributed number.
By default, the 10 random number generators for the streams are initialised at the beginning of each run to 14561, 25971, 31131, 22553, 12121, 32323, 19991, 18765, 14327, and 32535 (from Arena help). At the end of one replication, the generators will not be re-initialised, so they will start the next replication with a new value.
You can control the random number generator initialisation with the SEEDS element.
As #Marlize says, this helps to ensure that you can reproduce a simulation result if you need to.

agent cannot be resolved to a variable when timing segments of AnyLogic model

In the model, I need to time segments in which some agents go through, but not all, rendering the use of timeMeasureStart and End blocks ineffective as any agents who go through a certain End block MUST go through it's corresponding Start block, but not all agents that will encounter the End block will have gone through it's corresponding Start block.
I have done the following and receive the error that 'agent cannot be resolved to a variable' in the Histogram
Defined the variables startTime endTime cycleTime in the agent class Patient which is being pushed through the model.
Put agent.cycleTime=agent.endTime-agent.startTime; in the On enter slot of the block in which I want the timing to end.
Defined a Histogram Data called myDataSet with the Value agent.cycleTime in Main
Made a histogram in Main which takes myDataSet in it's Histogram slot.
First, you can still use TimeMeasureStart/end blocks. Just let some agents bypass them with a SelectOutput block upstream of the TimeMeasureStart block. The condition would be determined by who should be measured.
Ok, then to your details:
Put agent.cycleTime=agent.endTime-agent.startTime; in the On enter slot of the block in which I want the timing to end.
This is not how you would measure time. The variables are a good start, though. Do this instead:
Wherever timing should start, you write agent.startTime = time() (logs curr model time)
Wherever timing should end, you write agent.cycleTime = time() - agent.startTime, essentially measuring how much time has passed since the start.
Now you do what you want with agent.cycletime
Defined a Histogram Data called myDataSet with the Value agent.cycleTime in Main
this is not how you use Histogram Data. You need to use the API calls on it properly, for example myHistogramData.add(someValue):
Also, always check example models and the help, many issues can be solved by checking those first :)

Is there a way to record when (and how often) Transporters get within a certain distance of each other?

I have an AnyLogic simulation model using trucks and forklifts as agents (Transporter type), and among other things would like to identify each time one of them becomes within a certain distance of another one (example within 5 meters). I will record this count as a variable within the main space of the model. I am using path-guided navigation.
I have seen a method "agentsInRange" which will probably be able to do the trick, but am not sure where to call this from. I assume I should be able to use the AL functionality of "Min distance to obstacle" (TransporterFleet) and "Collision detection timeout" (TransporterControl)?
Thanks in advance!
Since there don't seem to be pre-built functions for this, afaik, the easiest way is to:
add an int variable to your transporter agent type counter
add an event to your transporter type checkCollision that triggers every second or so
in the event, loop across the entire population of transporters and count the number that are closer than X meters (use distanceTo(otherTransporter) and write your own custom code)
add that number to counter
Note that this might be very inefficient computationally as it is quite brute-force. But might be good enough :)

How to obtain certain data from main on a graph using parameter variation in anylogic?

I am having trouble with the coding process or steps to extract data from the main and onto the parameter variation experiment in anylogic. I am currently working on total evacuation time due to random fire obstruction.
For now I have successfully obtained the total max evacuation time for 100 runs in my study but I also need another set of data for the number of exits obstructed during each run. My main has the collection (of 3 exits) availableExits and I can see what is obstructed during the simulation.
Furthermore, I would like to obtain data for the number of people evacuating at a particular time (for example number of pedestrians using exit at 120 seconds). I can see this in main from timeMeasureEnd and creating a histogram distribution graph, which shows number of pedestrians escaping at each time. I've managed to create one in parameter variation but when I run the experiment, I am unable to store or view the data as it keeps changing after every run.
Here is the code from analysis Histogram Data which is entered in after simulation run
data = root.timeMeasureEnd.distribution;
i would recommend to add a dataset to your main which would store all the values you want to keep in parameter variation. Dataset differs from histogram data in a way that it doesnt aggregate, it is just a raw array of values, and later you will not have a problem of "aggregating aggregated data".
So, after each simulation run you can access your dataset in main via "root" reference (as you are already doing it) and loop through it to store all the values one by one.

Is the Rate in the source block a fixed rate?

I have a simple source to sink model and I am merely altering the "Rate" to 6 per hour. I would expect a fixed 6 agents to be generated each hour, but it seems like in the first hour from 0 to 60min, only 3 agents are generated. Similarly in the time 60-120min, only 5 agents were generated.
Is there a warm up period in Anylogic or something like this that explains what is happening?
Another alternative is to just use the interarrival time with a fixed time. This will give you the same results as Felipe's answer, but with one less object, as you will not need the event.
A few important items to note on this approach:
Instead of 6.0, using a parameter would be better. You could call this parameter dArrivalsPerHour. This would make your source block easier to read in the future, and give you some better flexibility. Your interarrival time would be 1.0 / dArrivalsPerHour.
Make sure you divide by at least (1) double. If you did 1/6, java would actually return 0! This is because in Java two integers divided by each other returns an integer, so java just truncates the decimal. If you use a parameter, just set its type to double. Usually to be extra careful against anyone accidentally changing my parameter type to integer in the future, I would still go ahead and use a 1.0.
AnyLogic does not have an arrival at time zero in this approach. The first arrival would be at 0.166 hours. If you want an arrival at time zero, followed by this pattern (it would still be 6 per hour, just shifting when it starts), then you have a couple of options. First, you can use Felipe's approach and set the first occurrence time to zero. An alternative would be to could call an inject On Startup OR after you have finished any initialization code your model has.
Happy Modeling!
The source block doesn't produce exactly 6 agents per hour, it produces agents using a poisson distribution with mean 6 per hour (lambda=6). So the number of agents per hour you get will be random. But the reason why you always get 3 in the first hour and 5 in the second hour is that you have a fixed seed:
You can find that option clicking on your simulation experiment under the randomness tab. If you change to random seed it will produce different agents per hour instead of always 3 and 5.
To produce EXACTLY 6 per hours you need to use an event. But first create a source that generates agents through injection:
And the event running 6 times per hour, adding 1 agent to the source: