Repository: projectmesa/mesa
Pull request #1564 (2022-12-17 12:40:45)

Implement radius for NetworkGrid.get_neighbors
Implement a way to retrieve the neighbors of a certain node even when the radius is greater than 1. It should be the intended way with the networkx library. Still need to add some tests. There are no problem for reproducibility because everything inside `single_source_shortest_path_length` is done with dicts and not with sets.

codecov[bot]: # [Codecov](https://codecov.io/gh/projectmesa/mesa/pull/1564?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa) Report
Base: **82.05**% // Head: **81.75**% // Decreases project coverage by **`-0.29%`** :warning:
> Coverage data is based on head [(`dfc76eb`)](https://codecov.io/gh/projectmesa/mesa/pull/1564?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa) compared to base [(`fc013ab`)](https://codecov.io/gh/projectmesa/mesa/commit/fc013ab9838b79771c112d237596bdcb1909c4e7?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa).
> Patch coverage: 44.44% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #1564      +/-   ##
==========================================
- Coverage   82.05%   81.75%   -0.30%     
==========================================
  Files          18       18              
  Lines        1382     1387       +5     
  Branches      270      272       +2     
==========================================
  Hits         1134     1134              
- Misses        204      208       +4     
- Partials       44       45       +1     
```


| [Impacted Files](https://codecov.io/gh/projectmesa/mesa/pull/1564?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa) | Coverage Δ | |
|---|---|---|
| [mesa/space.py](https://codecov.io/gh/projectmesa/mesa/pull/1564/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa#diff-bWVzYS9zcGFjZS5weQ==) | `90.10% <44.44%> (-1.16%)` | :arrow_down: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/projectmesa/mesa/pull/1564?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa).

Tortar: all should be ok now!
Tortar: @rht do you have any concerns about this implementation?
rht: LGTM

Patch:
diff --git a/mesa/space.py b/mesa/space.py
index f3e28b97..279e876a 100644
--- a/mesa/space.py
+++ b/mesa/space.py
@@ -26,6 +26,7 @@ import math
 from warnings import warn
 
 import numpy as np
+import networkx as nx
 
 from typing import (
     Any,
@@ -1033,11 +1034,21 @@ class NetworkGrid:
         self.G.nodes[node_id]["agent"].append(agent)
         agent.pos = node_id
 
-    def get_neighbors(self, node_id: int, include_center: bool = False) -> list[int]:
-        """Get all adjacent nodes"""
-        neighbors = list(self.G.neighbors(node_id))
-        if include_center:
-            neighbors.append(node_id)
+    def get_neighbors(
+        self, node_id: int, include_center: bool = False, radius: int = 1
+    ) -> list[int]:
+        """Get all adjacent nodes within a certain radius"""
+        if radius == 1:
+            neighbors = list(self.G.neighbors(node_id))
+            if include_center:
+                neighbors.append(node_id)
+        else:
+            neighbors_with_distance = nx.single_source_shortest_path_length(
+                self.G, node_id, radius
+            )
+            if not include_center:
+                del neighbors_with_distance[node_id]
+            neighbors = list(neighbors_with_distance.keys())
         return neighbors
 
     def move_agent(self, agent: Agent, node_id: int) -> None:


Test patch:
diff --git a/tests/test_space.py b/tests/test_space.py
index 769214cf..37a6f691 100644
--- a/tests/test_space.py
+++ b/tests/test_space.py
@@ -340,7 +340,7 @@ class TestSingleNetworkGrid(unittest.TestCase):
         """
         Create a test network grid and populate with Mock Agents.
         """
-        G = nx.complete_graph(TestSingleNetworkGrid.GRAPH_SIZE)
+        G = nx.cycle_graph(TestSingleNetworkGrid.GRAPH_SIZE)
         self.space = NetworkGrid(G)
         self.agents = []
         for i, pos in enumerate(TEST_AGENTS_NETWORK_SINGLE):
@@ -357,14 +357,10 @@ class TestSingleNetworkGrid(unittest.TestCase):
             assert a.pos == pos
 
     def test_get_neighbors(self):
-        assert (
-            len(self.space.get_neighbors(0, include_center=True))
-            == TestSingleNetworkGrid.GRAPH_SIZE
-        )
-        assert (
-            len(self.space.get_neighbors(0, include_center=False))
-            == TestSingleNetworkGrid.GRAPH_SIZE - 1
-        )
+        assert len(self.space.get_neighbors(0, include_center=True)) == 3
+        assert len(self.space.get_neighbors(0, include_center=False)) == 2
+        assert len(self.space.get_neighbors(2, include_center=True, radius=3)) == 7
+        assert len(self.space.get_neighbors(2, include_center=False, radius=3)) == 6
 
     def test_move_agent(self):
         initial_pos = 1