{ "cells": [ { "metadata": { "collapsed": true }, "cell_type": "markdown", "source": [ "# Graph Example\n", "\n", "In this example we try to find a graph that represents a network of pipelines with a flow of water. The goal is to find a graph that has a total flow of 5 units and no isolated nodes. The fitness function is designed to penalize graphs that have a dissipation of flow, isolated nodes, or a total flow that is not 5 units." ], "id": "3350c13988fa2e6d" }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-04T19:56:40.988896501Z", "start_time": "2026-02-04T19:56:40.851403571Z" } }, "cell_type": "code", "source": [ "from networkx import (\n", " Graph, DiGraph, draw_networkx_edges, draw_networkx_nodes,\n", " get_edge_attributes, draw_networkx_edge_labels, circular_layout\n", ")\n", "\n", "from altbacken.core.annealing import RandomChoice\n", "from altbacken.external.annealing import SimpleSimulatedAnnealing\n", "from altbacken.external.neighbourhood.graph import GraphNeighbourhood, AddNode, AddEdge, RemoveNode, RemoveEdge\n", "from altbacken.external.temperature import LogarithmicCooling\n" ], "id": "410ce054f9a15244", "outputs": [], "execution_count": 1 }, { "metadata": {}, "cell_type": "markdown", "source": [ "## Alter flow modification\n", "\n", "We introduce a modification that allows us to alter the flow of a pipeline. This modification is used to explore the space of possible solutions by changing the flow of a pipeline." ], "id": "bd4fdb80676bc576" }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-04T19:56:41.052858040Z", "start_time": "2026-02-04T19:56:41.004965207Z" } }, "cell_type": "code", "source": [ "def alter_flow(graph: Graph, *, choice: RandomChoice) -> bool:\n", " if not graph.edges:\n", " return False\n", " edge = choice(list(graph.edges))\n", " flow: int = max(1, graph.edges[edge]['flow'] + choice([-1, 1]))\n", " if flow == graph.edges[edge]['flow']:\n", " return False\n", " else:\n", " graph.edges[edge]['flow'] = flow\n", " return True\n" ], "id": "226274f997dd5542", "outputs": [], "execution_count": 2 }, { "metadata": {}, "cell_type": "markdown", "source": [ "## Neighbourhood\n", "\n", "We set the neighbourhood for the graph. The neighbourhood defines the set of modifications that can be applied to the graph. In this case, we have modifications for adding nodes, adding edges, removing nodes, removing edges, and altering the flow of a pipeline." ], "id": "85dd023c4746294b" }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-04T19:56:41.101694692Z", "start_time": "2026-02-04T19:56:41.054316141Z" } }, "cell_type": "code", "source": [ "neighbourhood: GraphNeighbourhood = GraphNeighbourhood(\n", " modifications={\n", " AddNode(): 3,\n", " AddEdge({\"flow\": 1}): 3,\n", " RemoveNode(): 1,\n", " RemoveEdge(): 1,\n", " alter_flow: 5\n", " }\n", ")" ], "id": "43fcd618ca39dd8f", "outputs": [], "execution_count": 3 }, { "metadata": {}, "cell_type": "markdown", "source": [ "## Fitness Function\n", "\n", "The fitness function consists of three components: dissipation, overall flow, and isolated nodes. Dissipation is the sum of the absolute values of the overflow at each node. Overall flow is the sum of the flow of all edges. Isolated nodes are nodes with no edges connected to them.\n", "Overall flow and dissipation pull in different directions. We want to minimize dissipation and maximize overall flow. Isolated nodes are penalized.\n", "Overall flow and dissipation pull in different directions. We want to minimize dissipation and maximize overall flow. Isolated nodes are penalized." ], "id": "a67897b9592299c7" }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-04T19:56:41.154402989Z", "start_time": "2026-02-04T19:56:41.103205614Z" } }, "cell_type": "code", "source": [ "def calc_dissipation(graph: DiGraph) -> float:\n", " value: int = 0\n", " for node in graph.nodes:\n", " overflow: int = 0\n", " for edge in graph.in_edges(node):\n", " overflow += graph.edges[edge]['flow']\n", " for edge in graph.out_edges(node):\n", " overflow -= graph.edges[edge]['flow']\n", " value += abs(overflow)\n", " return value\n", "\n", "def calc_overall_flow(graph: DiGraph) -> int:\n", " value: int = 0\n", " for edge in graph.edges:\n", " value += graph.edges[edge]['flow']\n", " return value\n", "\n", "DESIRED_FLOW: int = 10\n", "DESIRED_NODES: int = 5\n", "\n", "def fitness(graph: DiGraph) -> float:\n", " dissipation: float = calc_dissipation(graph)\n", " overall_flow: int = calc_overall_flow(graph)\n", " isolated_nodes: int = sum(1 for node in graph.nodes if graph.degree(node) == 0)\n", " return dissipation + max(0, DESIRED_FLOW - overall_flow) + isolated_nodes + max(0, DESIRED_NODES - len(graph.nodes))\n" ], "id": "c99a48d3d87f9bff", "outputs": [], "execution_count": 4 }, { "metadata": {}, "cell_type": "markdown", "source": [ "## Simulation\n", "\n", "We simulate with a logarithmic cooling scheme. Feel free to try other cooling schemes or play with the temperature" ], "id": "38601a7aafec665f" }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-04T19:56:42.409647393Z", "start_time": "2026-02-04T19:56:41.162329306Z" } }, "cell_type": "code", "source": [ "annealing: SimpleSimulatedAnnealing = SimpleSimulatedAnnealing(fitness, neighbourhood, LogarithmicCooling(100000))\n", "best, score = annealing.simulate(DiGraph())\n", "print(\"Fitness : \", score)\n", "print(\"Dissipation : \", calc_dissipation(best))\n", "print(\"Overall Flow : \", calc_overall_flow(best), f\"(expected min {DESIRED_FLOW})\")\n", "print(\"Nodes : \", len(best.nodes), f\"(expected min {DESIRED_NODES})\")\n", "print(\"Isolated nodes: \", sum(1 for node in best.nodes if best.degree(node) == 0))" ], "id": "b50a7da508b9738", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fitness : 7\n", "Dissipation : 4\n", "Overall Flow : 8 (expected min 10)\n", "Nodes : 5 (expected min 5)\n", "Isolated nodes: 1\n" ] } ], "execution_count": 5 }, { "metadata": {}, "cell_type": "markdown", "source": [ "## Visualization\n", "\n", "Next we draw the graph. The fitness is non-smooth, multi-objective, and mixes hard constraints (conservation) with soft ones (minimum flow, minimum nodes). Despite that, SA still trends toward reasonable graphs because local changes usually affect fitness in a consistent direction, and temperature helps jump out of traps" ], "id": "f3c94fbbd3f83683" }, { "metadata": { "ExecuteTime": { "end_time": "2026-02-04T19:56:42.582468301Z", "start_time": "2026-02-04T19:56:42.422047843Z" } }, "cell_type": "code", "source": [ "pos = circular_layout(best)\n", "draw_networkx_nodes(best, pos)\n", "draw_networkx_edges(best, pos, edge_color=\"red\", arrows=True)\n", "draw_networkx_edge_labels(best, pos, edge_labels=get_edge_attributes(best, \"flow\"))\n", "\n" ], "id": "ee565866a87a5a4e", "outputs": [ { "data": { "text/plain": [ "{(1, 2): Text(0.6545134471069989, 0.47552144216518943, '2'),\n", " (2, 5): Text(-0.2500001438200925, 0.18163545643614243, '2'),\n", " (3, 1): Text(0.0954942171513593, 0.2938917387184805, '1'),\n", " (5, 3): Text(-0.8090170266926682, -9.259401781980259e-06, '3')}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "
" ], "image/png": "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" }, "metadata": {}, "output_type": "display_data", "jetTransient": { "display_id": null } } ], "execution_count": 6 } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 5 }