Selecting agents of a specific class in agents.jl

Hi, I have an agents.jl model that uses two classes of GridAgent: Nurse and Patient.

I’d like the step function to locate an available nurse and link them to an available patient:

function nursepatient_step!(nurse::Nurse, model) 
   if nurse.patient_id == -1 
         patient = random_agent(model, patient -> typeof(patient) == "Patient" & patient.nurse_id == -1 & patient.nurse_complete == false) 
         nurse.patient_id = patient.id
         patient.nurse_id = nurse.id 
         patient.nurse_start_time = abmtime(model)
    end
end

After reading the documentation, it’s unclear to me how to scope random_agent to return only Patients.

Additionally, wondering how handle initializing a new agent with some of the parameters missing. In other words, I would like nurse_id to be missing on initialization. I’ve set this up using -1 as the initial value, but that does not seem ideal.

Thanks for the help!

In your condition function you use typeof(patient) == "Patient", but what you need is typeof(patient) == Patient because you need to compare types rather than a type to a string.

I’m not quite sure about your other question. My suspicion is that setting the id field manually is not a safe approach. Is there a different way you can identify a specific nurse? Maybe if you create a new nurse who is available, you can have a Boolean field for available.

Hi, thanks for this. I probably should have shared a bit more code. I am cribbing the agent structure from the predation model:


using Agents, Random, PoissonRandom

@agent struct Patient(GridAgent{2})
    nurse_req::Int  
    nurse_complete::Bool = false 
    nurse_id::Int = -1 
    nurse_start_time::Int = -1
    nurse_end_time::Int = -1 
    
end


@agent struct Nurse(GridAgent{2})
    patient_id::Int = -1 
end

When I update the code as suggested, I get: LoadError: ArgumentError: Agent of type Patient has not been created via @multiagent.

So l gather I need to either use a different structure for the agents, or find another way to disambiguate nurses and patients? Not sure which of these paths will be most effective.

With regard to the other question, I’m thinking of nurse_id and patient_id as being blank/missing until a nurse and patient are linked. I could not figure out how to initialize agents with missing parameter values, though, so I set them to -1 in place of missing. So when I look for a patient with nurse_id = -1, I’m really looking for a patient who does not have a linked nurse. I would like to stop using -1 as my proxy for missingness. Hope that’s a better explanation.

Why not? Using a dummy value is perfectly fine. there is no practical difference in using a dummy value, if a possibility for it exists, and using the formal undef of Julia. What you do now is what I’d do as well actually!

Just give the condition function to check whether the type of the agent is what you want in the two-argument version of random_agent: API · Agents.jl

It’s difficult to understand what you mean here. As suggested by whom and where? The error message you provide seems unrelated with the code you paste. Could you perhaps create a full MWE that creates this error you paste?

Using a dummy value is fine, as long as there is zero chance the value you’ve chosen will actually be a valid value for that variable in the future. One way to avoid this possibility is to use whatever notation your software/environment assigns to missing values. In this instance, I don’t know enough about how agents.jl assigns agent id’s to be certain -1 will never be an assigned value, so I was hoping to go with missing instead.

It’s difficult to understand what you mean here. As suggested by whom and where? The error message you provide seems unrelated with the code you paste. Could you perhaps create a full MWE that creates this error you paste?

Earlier in this thread, @Christopher_Fisher had suggested I do something like the following:
patient = random_agent(model, patient -> kindof(patient) == Patient )

When I implemented that change, I received a new error for that line: ArgumentError: Agent of type Patient has not been created via @multiagent.

Thus, it appears to me that now that I am using working syntax to refer to agent types, that code is creating an error saying I have not correctly created agents of the type I desire, and that perhaps I need to do this with multiagent.

use typeof, not kindof, if your agents are two different types.

Yep, typeof gets it done. Thanks

unforutnately this will make type instability. Agent IDs are positive definite in agents.jl so you can use -1 freely.

Slight variation on the typeof issue discussed above. I am trying to return all agents of a given type for further processing.

I’ve tried (without success) several variants of:

patients = findall(patient -> typeof(patient) == Patient, allagents(model))

How can I scope allagents(model) to a given type, or otherwise return a collection of agents of a specific type?

use <: instead of == as that’s how you enquire for subtyping relationships in Julia.