# Remove agent from space, but not scheduler

**URL:** https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842
**Category:** General Usage
**Tags:** question, agents
**Created:** [April 8, 2025, 12:43pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842 "2025-04-08T12:43:32Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [April 8, 2025, 12:43pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/1 "2025-04-08T12:43:32Z")

</div>

Hello,

I have an agent based model in which some agents are removed from the space so they cannot interact with other agents for some number of iterations. I can remove agents with `remove_agent!` and put them in a separate vector, and add them back to the space after the target iterations have elapsed. However, because this has to be performed separately from the main `agent_step!` loop, it may introduce unintended order effects into the model. My question is this: can I remove an agent from the space, but keep them in the scheduler?

Thanks!

---

<div class="post-metadata">

### Author: ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)
#### Post date: [April 8, 2025, 1:14pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/2 "2025-04-08T13:14:08Z")

</div>

Hm this sounds like a complicated way to do it…

Perhaps you shouldn’t remove them from the space at all, but rather add an additional agent property that keeps track of this “absence”. Then when calling `nearby_agents` simply filter these agents out. What’s the problem with doing this?

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [April 8, 2025, 1:18pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/3 "2025-04-08T13:18:46Z")

</div>

Thanks for your reply. One potentially complicating factor is that a each cell in the grid can only be occupied at most by a single agent. If I relax that constraint, I need a way to move an agent to a cell that is either unoccupied, or occupied by an agent that is “suspended”. Currently, I use randomwalk! with GridSpaceSingle. What is the best way to do it with GridSpace?

---

<div class="post-metadata">

### Author: ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)
#### Post date: [April 8, 2025, 1:21pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/4 "2025-04-08T13:21:12Z")

</div>

just use `GridSpace` and allow multiple agents to occupy the same location? I am confused why that’s not an option.

I think you have to explain what you **want to achieve** instead of what you are **trying to do to achieve that**. See [XY Problem](https://en.wikipedia.org/wiki/XY_problem).

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [April 8, 2025, 1:41pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/5 "2025-04-08T13:41:35Z")

</div>

Ok. Let me see if I can clarify. In the model, agents move randomly within a radius to an unoccupied position in GridSpaceSingle. In other words, multiple agents cannot occupy the same position. Some agents are suspended from the simulation for a period of time. While suspended, the agent does not move and it does not occupy a position in the space. However, its suspension time counter is incremented on each iteration. I want to make sure that the suspended agents are added back to the space (in a different random, unoccupied position) after this period as elapsed. Right now I remove suspended agents, and track them in a separate vector, which is not ideal for ensuring the agents are processed in a random order.

Your advice is to use GridSpace and allow multiple agents to occupy a single position, in which case the suspended agent can be ignored (as though it has been removed). This approach can work, but it requires manually controlling which agents occupy a given position. For example, a suspended and non-suspended agent can occupy the same position, but it is not acceptable for two non-suspended agents to occupy the same position. In this case, my question is which function do I use to move agents to a random location within a radius which is either unoccupied or occupied only by a suspended-agent?

---

<div class="post-metadata">

### Author: ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)
#### Post date: [April 8, 2025, 1:57pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/6 "2025-04-08T13:57:47Z")

</div>

> [@Christopher\_Fisher](#):
>
> I want to make sure that the suspended agents are added back to the space (in a different random, unoccupied position) after this period as elapsed. Right now I remove suspended agents, and track them in a separate vector, which is not ideal for ensuring the agents are processed in a random order.

Okay. This seems to me the best way to go about what you want to achieve. Now, can you also explain what is your problem with the random order processing? Do you want **both** the suspended and non-suspended agents to act in a random sequence? And it is not enough for you to first activate all non-suspendent agents randomly (with the existing random scheduler), and then a `model_step!` function goes through all suspendent agents again randomly (by just getting a random sequence of indices of the suspendent vector)?

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [April 8, 2025, 2:05pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/7 "2025-04-08T14:05:49Z")

</div>

> [@Datseris](#):
>
> And it is not enough for you to first activate all non-suspendent agents randomly (with the existing random scheduler), and then a `model_step!` function goes through all suspendent agents again randomly (by just getting a random sequence of indices of the suspendent vector)?

That’s a good question. I am not sure whether it matters or not. Sometimes seemingly unimportant implementational details affect the results more than expected. Right now, my code essentially performs the following on each iteration in `model_step!`:

1. randomly activate suspended agents (some will get added back to the space, some will remain suspended)
2. randomly activate non-suspended agents in a separate loop

As a result, suspended and non-suspended agents are activated separately rather than interspersed within one random sequence. To answer your question, I would like to activate all agents within the same random sequence to test whether it matters.

---

<div class="post-metadata">

### Author: ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)
#### Post date: [April 8, 2025, 2:10pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/8 "2025-04-08T14:10:16Z")

</div>

the best way is to use `Agents.remove_agent_from_space!`, this function is unexported but it should do what it says. I think that having this function private is not good for flexibility, because to me it is clear that the space should have its own way to remove ids from it, each different component should have its way to be updated without affecting the other components, in Agents.jl we tie everything to the model, but this is wrong from a design perspective in my opinion.

---

<div class="post-metadata">

### Author: ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)
#### Post date: [April 8, 2025, 2:13pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/9 "2025-04-08T14:13:03Z")

</div>

> [@Christopher\_Fisher](#):
>
> As a result, suspended and non-suspended agents are activated separately rather than interspersed within one random sequence. To answer your question, I would like to activate all agents within the same random sequence to test whether it matters.

This is easy to achieve with a custom scheduler, see here:

> **[API · Agents.jl](https://juliadynamics.github.io/Agents.jl/stable/api/#advanced_scheduling)**
>
> Documentation for Agents.jl.

In sort, you shouldn’t pass an `agent_step!` function into the `StandardABM` consturctor. Only a `model_step!`. You should still define and use an `agent_step!` function, but only inside the `model_step!` . Inside this step you create two vectors: one containing all IDs (suspendent and not) and one a boolean saying whether an ID is suspended. They you randomly sort these vectors and you iterate through them. if boolean is true, call the `agent_step!`. if not, reduce the suspension countdown.

---

<div class="post-metadata">

### Author: ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)
#### Post date: [April 8, 2025, 2:13pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/10 "2025-04-08T14:13:45Z")

</div>

> [@Tortar](#):
>
> the best way is to use `Agents.remove_agent_from_space!`, this function is unexported but it should do what it says. I think that having this function private is not good for flexibility, because to me it is clear that the space should have its own way to remove ids from it, each different component should have its way to be updated without affecting the other components, in [Agents.jl](https://juliaregistries.github.io/General/packages/redirect_to_repo/Agents) we tie everything to the model, but this is wrong from a design perspective in my opinion.

Yes, good point. We can document it, say that it is called internally by `remove_agent!` and thus no need to call it then. Then added to the tests and export it. We should create a test with a model that uses this functionality to make sure it works.

Probably open an issue to keep track of it.

---

<div class="post-metadata">

### Author: ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)
#### Post date: [April 8, 2025, 2:16pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/11 "2025-04-08T14:16:03Z")

</div>

I opened also an issue for a general separation of concerns for spaces: [Refactoring the access to space related functions to move towards multispace models · Issue #910 · JuliaDynamics/Agents.jl · GitHub](https://github.com/JuliaDynamics/Agents.jl/issues/910), I don’t have much time for development, but if someone wants to try this refactoring I would be happy to review

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [April 8, 2025, 2:19pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/12 "2025-04-08T14:19:29Z")

</div>

Thank you both for your help working through this issue. I think `Agents.remove_agent_from_space!` is what I am looking for. It appears to work as expected:

```julia
agent = model[1]
Agents.remove_agent_from_space!(agent, model)
agent.id in allids(model) # evaluates to true
isempty(agent.pos, model) # evaluates to true

```

---

<div class="post-metadata">

### Author: ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)
#### Post date: [April 8, 2025, 2:20pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/13 "2025-04-08T14:20:30Z")

</div>

> [@Christopher\_Fisher](#):
>
> Thank you both for your help working through this issue. I think `Agents.remove_agent_from_space!` is what I am looking for.

I really wouldn’t recommend using this in any “production code” as it hasn’t been tested to be used outside `remove_agent!` and it may lead to undefined behavior. For now I would argue you should instead use the custom scheduler, which will continue to work even when we make `remove_agent_from_space!` available to end-users.

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [April 8, 2025, 2:26pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/14 "2025-04-08T14:26:14Z")

</div>

> [@Datseris](#):
>
> I really wouldn’t recommend using this in any “production code” as it hasn’t been tested to be used outside `remove_agent!` and it may lead to undefined behavior. For now I would argue you should instead use the custom scheduler, which will continue to work even when we make `remove_agent_from_space!` available to end-users.

Thanks for letting me know about the potential for unexpected behavior. Its not clear to me how the custom scheduler solves the problems outlined above. Would you mind elaborating a bit on a solution with a custom scheduler?

---

<div class="post-metadata">

### Author: ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)
#### Post date: [April 8, 2025, 2:28pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/15 "2025-04-08T14:28:29Z")

</div>

The scheduler allows you to do what you want to do: iterate randomly through both suspended and non suspended agents. when the suspension countdown is over, you add the agent back.

Can you elaborate on why this solution does not satisfy you, because I may have misunderstood what you want to achieve?

---

<div class="post-metadata">

### Author: ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)
#### Post date: [April 8, 2025, 2:34pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/16 "2025-04-08T14:34:29Z")

</div>

My bet is that it shouldn’t have undefined behaviours, though, it’s clear that, strictly speaking, this brand new [issue](https://github.com/JuliaDynamics/Agents.jl/issues/1154) opened by @Datseris should be solved before being 100%(99%?) sure that this is the case

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [April 8, 2025, 2:34pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/17 "2025-04-08T14:34:40Z")

</div>

> [@Datseris](#):
>
> Can you elaborate on why this solution does not satisfy you, because I may have misunderstood what you want to achieve?

I think the remaining issue is how to move the agent to a valid position. If I use GridSpaceSingle, I need to remove a suspended agent from its position so that other agents may occupy that position. If I use GridSpace, I can leave a suspended agent in its position, but I need a way to move non-suspended agents to a space that is either (1) unoccupied, or (2) only occupied by a suspend agent. Does that make sense?

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [April 8, 2025, 2:44pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/18 "2025-04-08T14:44:17Z")

</div>

> [@Tortar](#):
>
> My bet is that it shouldn’t have undefined behaviours, though, it’s clear that, strictly speaking, this brand new [issue](https://github.com/JuliaDynamics/Agents.jl/issues/1154) opened by @Datseris should be solved before being 100%(99%?) sure that this is the case

I tend to agree with your assessment. My informal tests seem to suggest that `Agents.add_agent_to_space!` and `Agents.remove_agent_to_space!` appropriately add and remove the agent from the space. I am will to tolerate some degree of uncertainty for now. If @Datseris has an alternative solution for moving agents with a custom scheduler, I will consider that. Thanks again for the help!

---

<div class="post-metadata">

### Author: ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)
#### Post date: [April 8, 2025, 2:56pm UTC](https://discourse.julialang.org/t/remove-agent-from-space-but-not-scheduler/127842/19 "2025-04-08T14:56:53Z")

</div>

Yes this seems the best for now.
