From ae5c9644073252c7de5200c66561765d1ae8c34e Mon Sep 17 00:00:00 2001 From: Fedor Baart Date: Wed, 13 Mar 2024 11:19:39 +0100 Subject: [PATCH 1/2] test sea routing --- dtv_backend/tests/test_route.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 dtv_backend/tests/test_route.py diff --git a/dtv_backend/tests/test_route.py b/dtv_backend/tests/test_route.py new file mode 100644 index 0000000..66ec67f --- /dev/null +++ b/dtv_backend/tests/test_route.py @@ -0,0 +1,30 @@ +import networkx as nx +import shapely + +import pytest + +import dtv_backend.fis + + +@pytest.fixture +def FG(): + FG = nx.read_gpickle('../notebooks/fis-network/result/network_digital_twin_v0.3.pickle') + for n, node in FG.nodes.items(): + node['geometry'] = shapely.geometry.shape(node['geometry']) + for e, edge in FG.edges.items(): + edge['geometry'] = shapely.geometry.shape(edge['geometry']) + return FG + +@pytest.fixture +def nodes(): + test_nodes = [ + {"n": "8862371", "route_to_sea": False}, + {"n": "8864002", "route_to_sea": True} + ] + return test_nodes + + +def test_route_to_sea(FG, nodes): + for row in nodes: + result = dtv_backend.fis.route_to_sea(row["n"], FG) + assert row['route_to_sea'] == result, "route to sea expected: {row['route_to_sea']}, observed: {result}" From fbb5e4a10eaacfd7a9188e6752b80a49923b9fc3 Mon Sep 17 00:00:00 2001 From: Fedor Baart Date: Wed, 13 Mar 2024 11:21:53 +0100 Subject: [PATCH 2/2] add hubs and spokes scenario --- notebooks/scenarios/hubs-spokes.ipynb | 233 ++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 notebooks/scenarios/hubs-spokes.ipynb diff --git a/notebooks/scenarios/hubs-spokes.ipynb b/notebooks/scenarios/hubs-spokes.ipynb new file mode 100644 index 0000000..f1dbced --- /dev/null +++ b/notebooks/scenarios/hubs-spokes.ipynb @@ -0,0 +1,233 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 74, + "id": "4192a844-3dac-48b3-bc31-a5d038013ef2", + "metadata": {}, + "outputs": [], + "source": [ + "import simpy\n", + "import networkx as nx\n", + "\n", + "import itertools\n", + "import requests\n", + "import pickle\n", + "import io\n" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "2b588e0f-b315-4854-91b3-8e2d6d6ed98f", + "metadata": {}, + "outputs": [], + "source": [ + "url = 'https://zenodo.org/records/6673604/files/network_digital_twin_v0.3.pickle?download=1'\n", + "resp = requests.get(url)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "1ef88994-8f64-43c6-b269-c0887ca2884d", + "metadata": {}, + "outputs": [], + "source": [ + "graph = pickle.load(io.BytesIO(resp.content))" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "d0ef66e9-7a5a-4d45-8371-30a32d875b91", + "metadata": {}, + "outputs": [], + "source": [ + "n_hubs_source = 5\n", + "n_hubs_dest = 5\n", + "\n", + "duration_spoke_hub = 1\n", + "duration_spoke = 2\n", + "capacity_hub = 1\n", + "\n", + "capacity_bus = 1\n", + "duration_bus = 10\n" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "06d00f37-199c-458e-8337-3a13df8b6126", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "52bd58a1-0c60-4941-85cc-cc0fa37a8a50", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "graph = nx.Graph()\n", + "hub_nodes = [\"hub_0\", \"hub_1\"]\n", + "for n in hub_nodes:\n", + " graph.add_node(n)\n", + "graph.add_edge(hub_nodes[0], hub_nodes[1])\n", + "\n", + "counter = itertools.count()\n", + "for i, n_id in zip(range(n_hubs_source), counter):\n", + " n = f\"spoke_{n_id}\"\n", + " graph.add_node(n)\n", + " graph.add_edge(n, hub_nodes[0])\n", + " \n", + "for i, n_id in zip(range(n_hubs_dest), counter):\n", + " n = f\"spoke_{n_id}\"\n", + " graph.add_node(n)\n", + " graph.add_edge(hub_nodes[1], n)\n", + "\n", + "pos = nx.spring_layout(graph)\n", + "nx.draw_networkx_labels(graph, pos=pos)\n", + "nx.draw(graph, pos=pos)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "14ba9b6f-6b4a-4a8b-9672-a949416fe90f", + "metadata": {}, + "outputs": [], + "source": [ + "def transport_direct(env, a, b, fairway):\n", + " print(f'claiming a at {env.now}')\n", + " with a[\"resource\"].request() as a_res_request:\n", + " yield a_res_request\n", + " yield a[\"container\"].get(1)\n", + " yield env.timeout(1)\n", + " print(f'start sailing at {env.now}')\n", + " with fairway.request() as fairway_request:\n", + " yield fairway_request\n", + " yield env.timeout(10)\n", + " print(f'claiming b at {env.now}')\n", + " with b[\"resource\"].request() as b_res_request:\n", + " yield b_res_request\n", + " yield b[\"container\"].get(1)\n", + " yield env.timeout(1)\n", + " print(f'done a at {env.now}')\n", + " \n", + "def transport_hubs(env, a, b, fairway):\n", + " print(f'claiming a at {env.now}')\n", + " with a[\"resource\"].request() as a_res_request:\n", + " yield a_res_request\n", + " yield a[\"container\"].get(1)\n", + " yield env.timeout(1)\n", + " \n", + " print(f'start sailing at {env.now}')\n", + " with fairway.request() as fairway_request:\n", + " yield fairway_request\n", + " yield env.timeout(10)\n", + " print(f'claiming b at {env.now}')\n", + " with b[\"resource\"].request() as b_res_request:\n", + " yield b_res_request\n", + " yield b[\"container\"].get(1)\n", + " yield env.timeout(1)\n", + " print(f'done a at {env.now}') \n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "dd698f7b-19d2-4b13-b0ff-16afa7e6c123", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "claiming a at 0\n", + "claiming a at 0\n", + "claiming a at 0\n", + "claiming a at 0\n", + "claiming a at 0\n", + "start sailing at 1\n", + "start sailing at 2\n", + "start sailing at 3\n", + "start sailing at 4\n", + "start sailing at 5\n", + "claiming b at 11\n", + "claiming b at 12\n", + "claiming b at 13\n", + "claiming b at 21\n", + "claiming b at 22\n" + ] + } + ], + "source": [ + "env = simpy.Environment()\n", + "fairway = simpy.Resource(env=env, capacity=3)\n", + "\n", + "a = {\"resource\": simpy.Resource(env), \"container\": simpy.Container(env, capacity=100, init=100)}\n", + "b = {\"resource\": simpy.Resource(env), \"container\": simpy.Container(env, capacity=100, init=0)}\n", + "spokes = [a, b]\n", + "env.process(transport(env, a=a, b=b, fairway=fairway))\n", + "env.process(transport(env, a=a, b=b, fairway=fairway))\n", + "env.process(transport(env, a=a, b=b, fairway=fairway))\n", + "env.process(transport(env, a=a, b=b, fairway=fairway))\n", + "env.process(transport(env, a=a, b=b, fairway=fairway))\n", + "env.run()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4f332ba7-6dd0-49a6-ac70-bfabfd0fa0a3", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "194ea0b3-1d16-45a3-9569-49f2fa2091a9", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}