I have an agent that is nested in another agent. This nested agent has a function that calls the annylogic probability distribution functions(pdfs) such as gamma(), lognormal(), etc. However I keep getting a nullPointerException if I call these pdfs inside the nested agent. I am realising this is because the nested agent cannot access the default randomNumberGenerator. Is there a way I can access the defaultRandomNumberGenerator within the nested agent as well or is the only solution to create a new generator for each nested agent?
-
`main.getDefaultRandomGenerator()` does not work? – Yashar Ahmadov Feb 04 '22 at 10:49
-
Unfortunately no. – user1234 Feb 04 '22 at 12:17
2 Answers
Only agents that are connected to the engine in some way have access to the random number generator. And if your experiment is set to run main - like the example below - then all agents that want to use the random number generator must be connected to main in some way
So if you do this for example it wont work, and you get an NPE (Null Pointer Exception)
If you do this it will
Best option is to just create your own random number generator
lognormal(0.1, 0.1, 5, new Random(0));
(Just put the random number generator somewhere so that you can use it again and again, else you will get the same number every time since it is the same (new) random object used to get the number)
This design is way better - see example here 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?

- 3,770
- 2
- 16
- 33
-
Yes this is exactly the type of situation I am facing. Your solution makes sense. I just wonder if this is considered a "good practice" or if I should consider moving the function itself out from the nested agent and placing it in main. Placing it in main would make it a bit more clunky from a design and modularity point of view but I wonder what the trade-off is vs following your approach mentioned above. – user1234 Feb 04 '22 at 23:46
-
It's a better solution IMO to either have agents in the model hierarchy or delegate all such calls to an agent which is in the model hierarchy; see my answer. Arbitrarily creating a new RNG is not a good idea and requires work to make the model reproducible (and allow the randomness of this RNG to be variable). – Stuart Rossiter Feb 05 '22 at 10:04
-
IMO I would not go for a design where an agent is dependent on some external provided for something so basic as generating a random number. Furthermore, you cannot guarantee multiple run reproducibility for such an agent for different scenarios if the random stream is accessed by other agents... Take the case where you have 5 machines that share a random number generator and you use seed 1 and you get 50% downtime on machine 1 - now you remove 2 of the machines, also run seed 1 and now you get different % downtime... because all the 5 machines shared the same random stream. This is not ideal! – Jaco-Ben Vosloo Feb 10 '22 at 08:39
The error is because your agent is outside the model hierarchy of agents.
This is not good practice; there should very rarely be a need to have 'floating' agents outside the model hierarchy; they can always be inside an agent population somewhere.
In the rare cases that there are strong design reasons to do so (or if you use plain Java classes and thus have Java objects which by definition are not Agents and are therefore outside the agent hierarchy), just give them a parameter (field in the case of a Java class) that points to some agent that is in the model hierarchy (typically their 'generator'), and then you can call all 'required-to-be-in-model-hierarchy' functions via that parameter. (That is, you are delegating all such calls to an agent instance which can call them.)
e.g., the nested agent type (let's say Thing
) has parameter agentRef
of type Agent
set by whoever creates it; for example
Thing t = new Thing(this);
Then, within Thing, you use code such as agentRef.normal(1,10)
.

- 2,432
- 1
- 17
- 20