user3qpu
user3qpu

Reputation: 67

AnyLogic agent-based modelling: ClassCastException

I am working with an agent-based simulation of an infectious disease epidemic in AnyLogic. I have two agents types in my model- Person and Building. I'm trying to write a function that counts the number of infectious contacts that the agent type 'Person' has at any given point in time. Below is my code for the function:

int infectedConnections = 0;

if (getConnections() != null)
    for (Agent a : this.getConnections())
        {
        Person p = (Person) a;

        if (p.IsCurrentlyInfected()) 
            infectedConnections++;
            }

return infectedConnections ;

The code compiles without any errors but during runtime, it throws up a java.lang.ClassCastException with the message: model.Building cannot be cast to model.Person.

When I try the same code with just one agent type (i.e. 'Person'), the model runs fine and the function returns the correct value. Could someone tell me how I could rectify my code so that I am able to run the function for 'Person' please?

Upvotes: 1

Views: 1981

Answers (2)

Stuart Rossiter
Stuart Rossiter

Reputation: 2517

Although Rob's answer solves your problem, note that having mixed Person and Building connections is really the 'root cause' of your problems: in general, mixing types in a collection of things is a design flaw for the type of reasons you're seeing (and probably your agents' connections to other Person agents or Building agents are two conceptually different relationships).

In AnyLogic you can have multiple networks per agent, not just the default connections one, by adding extra Link to agents elements. So, for example, your Person agent could have one for family relationships (say called family connecting to Person agents) and one for places they live/work in (say called workHomePlaces connecting to Building agents); obviously I'm inventing possible purposes of these networks.

Then you can do things like family.getConnections() and workHomePlaces.getConnections(), avoiding the issues you're encountering and having a more conceptually-correct design.

In the help, see Agent Based Modeling --> Agent interaction --> Defining custom contact links.

Upvotes: 0

Rob Obdeijn
Rob Obdeijn

Reputation: 243

If you just want to ignore agents of type Building, then you can do the following:

int infectedConnections = 0;

if (getConnections() != null) {
    for (Agent a : this.getConnections())
    {
        if(a instanceof Person) {
            Person p = (Person) a;

            if (p.IsCurrentlyInfected()) {
               infectedConnections++;
            }
        }
    }
}
return infectedConnections;

The problem is that (Person) a; will fail if a is a Building instead of a Person.

Upvotes: 2

Related Questions