Created
January 16, 2024 16:31
-
-
Save quaquel/b2e8c7be21aee4e1ffdf6e2fd4286dff to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "id": "506a9a81-79f0-480e-adcf-b98d15c2f193", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from typing import List, Any\n", | |
| "import random\n", | |
| "from functools import cache\n", | |
| "\n", | |
| "from mesa import Model, Agent\n", | |
| "\n", | |
| "class GridCell:\n", | |
| " @property\n", | |
| " def neighbors(self):\n", | |
| " return [entry.content for entry in self.neighborhood if entry.content != None]\n", | |
| " \n", | |
| " def __init__(self, i:int, j:int) -> None:\n", | |
| " self.i = i\n", | |
| " self.j = j\n", | |
| " self.coords = (i, j)\n", | |
| " self._neighborhood = None\n", | |
| " self.content = None\n", | |
| "\n", | |
| " self.left: GridCell = None\n", | |
| " self.right: GridCell = None\n", | |
| " self.top: GridCell = None\n", | |
| " self.bottom: GridCell = None\n", | |
| " self.topleft: GridCell = None\n", | |
| " self.topright: GridCell = None\n", | |
| " self.bottomright: GridCell = None\n", | |
| " self.bottomleft: GridCell = None\n", | |
| "\n", | |
| " def _calculate_neighborhood(self):\n", | |
| " neighborhood = [self.topleft, self.top, self.topright, \n", | |
| " self.right, self.bottomright, self.bottom,\n", | |
| " self.bottomleft, self.left]\n", | |
| " neighborhood = [entry for entry in neighborhood if entry != None]\n", | |
| " self.neighborhood = neighborhood\n", | |
| "\n", | |
| "\n", | |
| "class Grid:\n", | |
| " def __init__(self, width:int, height:int, torus:bool = False) -> None:\n", | |
| " self.width = width\n", | |
| " self.height = height\n", | |
| " self.torus = torus\n", | |
| "\n", | |
| " self.cells: List[List[GridCell]] = [[GridCell(j, i) for i in range(width)] for j in range(height)]\n", | |
| " \n", | |
| " # connect within a row\n", | |
| " for row in self.cells:\n", | |
| " for cell1, cell2 in zip(row, row[1::]):\n", | |
| " cell1.right = cell2\n", | |
| " cell2.left = cell1\n", | |
| "\n", | |
| " if torus:\n", | |
| " for row in self.cells:\n", | |
| " row[0].left = row[-1]\n", | |
| " row[-1].right = row[0]\n", | |
| "\n", | |
| " # connect across rows\n", | |
| " for entry in zip(self.cells, self.cells[1::]):\n", | |
| " for cell1, cell2 in zip(*entry):\n", | |
| " cell1.bottom = cell2\n", | |
| " cell1.bottomleft = cell2.left\n", | |
| " cell1.bottomright = cell2.right\n", | |
| "\n", | |
| " cell2.top = cell1\n", | |
| " cell2.topright = cell1.left\n", | |
| " cell2.topleft = cell1.right\n", | |
| "\n", | |
| " if torus:\n", | |
| " for cell1, cell2 in zip(self.cells[0], self.cells[-1]):\n", | |
| " cell1.top = cell2\n", | |
| " cell1.topleft = cell2.left\n", | |
| " cell1.topright = cell2.right\n", | |
| "\n", | |
| " cell2.bottom = cell1\n", | |
| " cell2.bottomleft = cell1.left\n", | |
| " cell2.bottomright = cell1.right\n", | |
| "\n", | |
| " for row in self.cells:\n", | |
| " for cell in row:\n", | |
| " cell._calculate_neighborhood()\n", | |
| "\n", | |
| " @cache\n", | |
| " def get_neighborhood(self, coords, radius):\n", | |
| " i, j = coords\n", | |
| " \n", | |
| " neighborhood = {}\n", | |
| " if radius==0:\n", | |
| " return {self.cells[i][j]:None}\n", | |
| " else:\n", | |
| " radius = radius - 1\n", | |
| " for cell in self.cells[i][j].neighborhood:\n", | |
| " neighborhood = neighborhood | self.get_neighborhood(cell.coords, radius)\n", | |
| " \n", | |
| " return neighborhood\n", | |
| "\n", | |
| " def get_neighbors(self, coords, radius):\n", | |
| " neighborhood = self.get_neighborhood(coords, radius)\n", | |
| " \n", | |
| " return [content for entry in neighborhood if (content := entry.conten != None)]\n", | |
| "\n", | |
| " \n", | |
| " def place_agent(self, agent, pos):\n", | |
| " pass\n", | |
| "\n", | |
| "\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 2, | |
| "id": "d8255039-4b64-490f-b45c-02c192ccfaa0", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "random.seed(42)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 3, | |
| "id": "068985d2-3752-440f-a7f4-3e2b9ce33b26", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "646 ms ± 1.52 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "%%timeit\n", | |
| "grid = Grid(1000, 1000, torus=True)\n", | |
| "\n", | |
| "# a = grid.cells[0][1]\n", | |
| "# print([entry.coords for entry in a.neighbors])\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 4, | |
| "id": "6e28896c-ea44-4ac3-900e-76212add9384", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "random.seed(42)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 5, | |
| "id": "7c856c69-5010-4aa6-aff4-c3ee1f7fbfd3", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "model = Model()\n", | |
| "\n", | |
| "grid = Grid(100, 100)\n", | |
| "\n", | |
| "counter = 0\n", | |
| "for i in range(100):\n", | |
| " for j in range(100):\n", | |
| " grid.cells[i][j].neighborhood\n", | |
| " if random.random() > 0.2:\n", | |
| " agent = Agent(model.next_id(), model)\n", | |
| " grid.cells[i][j].content = agent" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 7, | |
| "id": "1b149cf6-0da4-4c66-82ad-7e835dad975e", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "469 ns ± 17.1 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "%%timeit\n", | |
| "grid.cells[random.randint(0, 99)][random.randint(0, 99)].neighbors" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 6, | |
| "id": "a3ba0513-1477-4e1a-bc23-a226f35dabec", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "616 ns ± 10.2 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "%%timeit\n", | |
| "grid.get_neighborhood((random.randint(0, 99), random.randint(0, 99)), radius=3)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "ec8d067c-8f0e-4d07-9c55-880225799daf", | |
| "metadata": {}, | |
| "source": [ | |
| "# MESA" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 8, | |
| "id": "7a5bff9a-940a-4ebd-9711-331c9d870365", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from mesa.space import SingleGrid\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 9, | |
| "id": "da4e7b8e-961a-48aa-836b-3790aa1d0c89", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "random.seed(42)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 10, | |
| "id": "4487d5d9-1e3c-4442-8f75-d8a0a684419e", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "40.5 ms ± 206 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "%%timeit\n", | |
| "grid = SingleGrid(1000, 1000, torus=True)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 11, | |
| "id": "9024706d-3b92-4778-9115-86fb5cfa8f9a", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "random.seed(42)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 12, | |
| "id": "f384c770-ca3c-4d6a-b9ec-aff7c6eac00b", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "model = Model()\n", | |
| "\n", | |
| "grid = SingleGrid(1000, 1000, torus=True)\n", | |
| "\n", | |
| "counter = 0\n", | |
| "for i in range(100):\n", | |
| " for j in range(100):\n", | |
| " if random.random() > 0.2:\n", | |
| " agent = Agent(model.next_id(), model)\n", | |
| " grid.place_agent(agent, (i,j))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 16, | |
| "id": "571a4cfc-20df-46eb-81d6-457d7389692b", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "1.35 µs ± 27.4 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "%%timeit\n", | |
| "grid.get_neighbors((random.randint(0, 99), random.randint(0, 99)), moore=False, radius=1)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 14, | |
| "id": "a92425ec-8b8c-4ae9-90b3-244368e92273", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "2.95 µs ± 117 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "%%timeit\n", | |
| "grid.get_neighbors((random.randint(0, 99), random.randint(0, 99)), moore=False, radius=3)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 15, | |
| "id": "d73d031c", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "4.83 µs ± 125 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "%%timeit\n", | |
| "grid.get_neighbors((random.randint(0, 99), random.randint(0, 99)), moore=True, radius=3)" | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": "Python 3 (ipykernel)", | |
| "language": "python", | |
| "name": "python3" | |
| }, | |
| "language_info": { | |
| "codemirror_mode": { | |
| "name": "ipython", | |
| "version": 3 | |
| }, | |
| "file_extension": ".py", | |
| "mimetype": "text/x-python", | |
| "name": "python", | |
| "nbconvert_exporter": "python", | |
| "pygments_lexer": "ipython3", | |
| "version": "3.11.6" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 5 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment