{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "qZYixNXYvPjf" }, "source": [ "# Small world assignment\n", "\n", "
\n", " \n", " \n", " Open this notebook in Google Colab\n", " \n", "
\n", "\n", "\n", "
\n", " \n", " \n", " Download this notebook (File -> Save As)\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": { "id": "FvWP-BfRvPjh" }, "source": [ "In this assignment, we will get ourselves more familiar with mathematical ways to understand networks, playing with walks, paths, and small-worldness. \n", "\n", "Let's start with importing the necessary libraries.\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import networkx as nx\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Adjacency matrix\n", "\n", "Adjacency matrix $\\mathbf{A}$ is an $N \\times N$ matrix, where each row $i$ corresponds to a node $i$ and each column $j$ corresponds to a node $j$. If the network is undirected and unweighted, the element $\\mathbf{A}_{ij}$ is 1 if there is an edge between node $i$ and node $j$, and 0 otherwise.\n", "\n", "In a directed graph, the element $\\mathbf{A}_{ij}$ can be used to represent either an edge from $i$ to $j$ or an edge from $j$ to $i$. We tend to use the latter ($j \\rightarrow i$) because this makes variuos matrix operations easier to understand (see WWND Ch. 25). \n", "\n", "### Edges and degrees\n", "\n", "Once you have an adjacency matrix, you can use it to compute various network properties. For example, the degree of a node $i$ is the sum of the elements in the $i$-th row (or column) of the adjacency matrix, i.e., $\\sum_j \\mathbf{A}_{ij}$.\n", "\n", "**Q: can you write how we can calculate the number of edges in a network using the adjacency matrix? Assume that the network is undirected and unweighted.**\n", "\n", "Explain as clearly as possible. If you're familiar with LaTeX, you can use LaTeX to write mathematical expressions." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n",
    "# YOUR SOLUTION HERE\n",
    "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### How to they look like?\n", "\n", "A useful exercise to build intuition into the adjacency matrix is to imagine how the adjacency matrix of a network would look like if we \"draw\" it. What I mean by that is to draw a square grid of size $N \\times N$, and then fill in the cells according to the adjacency matrix (e.g., black if 1 and white if 0).\n", "\n", "For instance, consider a random network where every edge is randomly placed with a probability $p$. What would the adjacency matrix look like? Think about it for a moment before you move on. Use the cell below to write down your thoughts (not graded). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n",
    "# YOUR SOLUTION HERE\n",
    "
" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# We can draw the adjacency matrix of a graph using the imshow function from matplotlib\n", "N = 100\n", "p = 0.2\n", "G = nx.erdos_renyi_graph(N, p)\n", "A = nx.adjacency_matrix(G).todense()\n", "plt.imshow(A, cmap='Greys', interpolation='none')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "How about other types of graphs? What about a network with strong modular structure (if we reshuffle the rows and columns so that the structure is shown clearly)? How about DAG (directed acyclic graph)? How about bipartite graphs? \n", "\n", "It will be very useful for you to think about these questions and try to sketch the adjacency matrix of various types of networks. You can see some examples in WWND Ch. 25. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Walks and paths\n", "\n", "Adjacency matrix also allows us to mathematically think about walks and paths. The simplest case is a walk of length 1. \n", "\n", "Think about this question: How many walks of length 1 are there from node $i$ to node $j$?\n", "\n", "
Solution

It's just $\\mathbf{A}_{ji}$

\n", "\n", "How about walks of length 2? Think about it first before revealing the solution. \n", "\n", "
Solution

You need to go to a node (say $k$) that is connected to $i$ first. And then you need to be able to go from $k$ to $j$. Therefore, it's $\\sum_k \\mathbf{A}_{ik} \\mathbf{A}_{kj}$

\n", "\n", "**Q: Can you generalize this to walks of length $l$ from $i$ to $j$?** " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n",
    "# YOUR SOLUTION HERE\n",
    "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Computing shortest paths\n", "\n", "It is interesting to see the link between the adjacency matrix and the number of walks with a certain length. For the shortest paths, it is much easier to think about the problem computationally and algorithmically, especially when the network involves weights and directions. Let's first think about the BFS (breadth-first search) algorithm. \n", "\n", "### BFS algorithm\n", "\n", "When the network is unweighted, we can compute the shortest path and distance between any pair of nodes using the BFS algorithm. The algorithm is simple:\n", "\n", "1. Start from the source node $s$ and set the distance to itself as 0.\n", "2. Set the distance to all other nodes as $\\infty$. Or you can simply keep a set/dictionary of distances and check whether you have visited the node before.\n", "3. Add the source node to the queue.\n", "4. While the queue is not empty, do the following:\n", " 1. Pop the first node from the queue.\n", " 2. For each neighbor of the popped node, if the distance is $\\infty$, set the distance to the distance of the popped node plus 1, and add the neighbor to the queue.\n", "\n", "If it is unclear why this works, I encourage you to try to run the algorithm on a piece of paper with a simple network and watch how the distance is updated. Also there are many good videos on YouTube that explain the BFS algorithm that you can watch as well!\n", "\n", "**Q: Can you write a Python function that computes, for every node, the shortest distance to a given node using the BFS algorithm?**" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{0: 0, 1: 1, 2: 1, 3: 2, 4: 2}\n" ] } ], "source": [ "def simple_bfs(G, source_node) -> dict:\n", " # this function returns a dictionary with the distance from the source node \n", " # to all other nodes. \n", " # e.g., {0: 0, 1: 1, 2: 1, 3: 1} means that the distance from the source node \n", " # to node 0 is 0, to node 1 is 1, and so on. \n", " \n", " distance_from_source = {}\n", " nodes_to_explore = [] # the queue\n", "\n", " # YOUR SOLUTION HERE\n", "\n", " return distance_from_source\n", "\n", "# let's test the function\n", "G = nx.Graph()\n", "G.add_edges_from([(0, 1), (0,2), (1, 3), (3, 4), (1,4)])\n", "print(simple_bfs(G, 0))\n", "\n", "assert simple_bfs(G, 0) == {0: 0, 1: 1, 2: 1, 3: 2, 4: 2} # this is the expected answer\n" ] }, { "cell_type": "markdown", "metadata": { "id": "MwvW4PEQhj33" }, "source": [ "This function lets you compute the shortest path from a given node to all other nodes. We can now use this function to compute all possible shortest paths between every node pair, and then compute the average shortest path length. \n", "\n", "If we have $N$ nodes in our network, we have roughly $N^2$ shortest paths to compute. It is slow and also consumes a lot of memory. There is not a lot of things we can do to drastically reduce the computing time, but we can drastically reduce the memory usage if we only care about the average shortest path length. How would you do that? Think about it before you move on.\n", "\n", "
Solution

We can compute the shortest path length from a given node to all other nodes, and then keep only the counts of the shortest path lengths. In other words, instead keeping the dictionary that we had above, we can simply summarize it as: there is one node (0) with distance 0, two nodes (1, 2) with distance 1, and so on.

\n", "\n", "To do this, we can use the `collections.Counter` class. If you are not familiar with it, read about it here: https://docs.python.org/3/library/collections.html#collections.Counter What it can do can be done with a dictionary, but it is often much more convenient to use `Counter`.\n", "\n", "**Q: Can you write a Python function that computes the shortest path length from a given node to all other nodes, and then returns the summary as a `Counter`?**" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "executionInfo": { "elapsed": 168, "status": "ok", "timestamp": 1642972731767, "user": { "displayName": "Ashutosh Hathidara", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GiF8R551zAQvapFAWqdihe4-meSQy-KHh-aXiSf=s64", "userId": "09642124213384184129" }, "user_tz": 300 }, "id": "c24vruOimmFN" }, "outputs": [], "source": [ "from collections import Counter\n", "def count_path_lengths(distances):\n", " # YOUR SOLUTION HERE" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "executionInfo": { "elapsed": 164, "status": "ok", "timestamp": 1642972733121, "user": { "displayName": "Ashutosh Hathidara", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GiF8R551zAQvapFAWqdihe4-meSQy-KHh-aXiSf=s64", "userId": "09642124213384184129" }, "user_tz": 300 }, "id": "6HqDT4s4n0mt" }, "outputs": [], "source": [ "# this should be satisfied. \n", "assert count_path_lengths({0: 0, 1: 1, 2: 1, 3: 2, 4: 2}) == Counter({0: 1, 1: 2, 2: 2})" ] }, { "cell_type": "markdown", "metadata": { "id": "eqAXaGblvPjj" }, "source": [ "**Q: Can you write a Python function that computes the average shortest path length of a network using the above function?**" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 2986, "status": "ok", "timestamp": 1642972749540, "user": { "displayName": "Ashutosh Hathidara", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GiF8R551zAQvapFAWqdihe4-meSQy-KHh-aXiSf=s64", "userId": "09642124213384184129" }, "user_tz": 300 }, "id": "6R_NW2f7vPjj", "outputId": "921d5f70-b8bd-445f-f922-a5e9c17a2dcb" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Counter({3: 52894, 4: 36370, 2: 9330, 1: 982, 5: 324, 0: 100})\n" ] } ], "source": [ "# path_length_counter should be a Counter object with keys being path lengths \n", "# and values being the number of pairs with that path length.\n", "path_length_counter = Counter()\n", "G = nx.erdos_renyi_graph(1000, 0.01)\n", "\n", "# YOUR SOLUTION HERE\n", " \n", "print(path_length_counter)" ] }, { "cell_type": "markdown", "metadata": { "id": "3rksfTe3vPjk" }, "source": [ "### Visualizing the results\n", "\n", "Now that you have a list of the shortest paths for the graph, we can examine it by drawing a bar chart of shortest path length distribution. We can use the following snippets to draw the bar chart. " ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 175, "status": "ok", "timestamp": 1642972757751, "user": { "displayName": "Ashutosh Hathidara", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GiF8R551zAQvapFAWqdihe4-meSQy-KHh-aXiSf=s64", "userId": "09642124213384184129" }, "user_tz": 300 }, "id": "o8uwvcx0peFD", "outputId": "a1b2127b-5228-4a32-e7c7-7ef293399fc6" }, "outputs": [ { "data": { "text/plain": [ "dict_items([(0, 10), (1, 20), (2, 10), (3, 1)])" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a_counter = Counter({0:10, 1:20, 2:10, 3:1})\n", "a_counter.items()" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 168, "status": "ok", "timestamp": 1642972759560, "user": { "displayName": "Ashutosh Hathidara", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GiF8R551zAQvapFAWqdihe4-meSQy-KHh-aXiSf=s64", "userId": "09642124213384184129" }, "user_tz": 300 }, "id": "9ErDs0wYpr3G", "outputId": "13833d36-0c24-48a1-ca4e-2492933be3e1" }, "outputs": [ { "data": { "text/plain": [ "[(0, 1, 2, 3), (10, 20, 10, 1)]" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(zip(*a_counter.items()))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Q: Can you draw the bar chart for the shortest path length distribution of the network that we calculated above?**\n" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 296 }, "executionInfo": { "elapsed": 524, "status": "ok", "timestamp": 1642972761482, "user": { "displayName": "Ashutosh Hathidara", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GiF8R551zAQvapFAWqdihe4-meSQy-KHh-aXiSf=s64", "userId": "09642124213384184129" }, "user_tz": 300 }, "id": "tg48ZnacvPjk", "outputId": "1ea43293-4779-41ea-c43b-395627a49a5b" }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAk0AAAHHCAYAAACiOWx7AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA75klEQVR4nO3de1hVZd7/8c8G5SC4IZGDJIpmHtCUERV3pWWhZNTkpJOak3joZMCkjKk8NWpOM3SYTMtTPc2IT09eHpq0SQpTTJ0mSsWY1Al/1WjaIIdU2EoKCuv3Rw9r3IG2QHSDvl/Xta/Lfa/vutd33Vl8Wnvthc0wDEMAAAC4IA93NwAAANAcEJoAAAAsIDQBAABYQGgCAACwgNAEAABgAaEJAADAAkITAACABYQmAAAACwhNAAAAFhCaALiYO3eubDabvvvuuwbtP2HCBEVGRjZuU5dARkaGbDabdu3a1ajz1nX+NptNc+fObdTj1GXr1q2y2WzaunWrOXbrrbeqV69el/zYknTw4EHZbDZlZGRcluMBlxuhCWgman7I17x8fHzUtWtXJScnq6ioqN7z/eEPf9D69esbv9EmZsmSJc3yh/jKlSu1YMECd7dRp6bcG3AptXB3AwDqZ968eerUqZNOnz6tjz76SEuXLtV7772nvXv3qlWrVpbn+cMf/qBRo0ZpxIgRl67ZJmDJkiVq27atJkyY4LYeTp06pRYt6vef25UrV2rv3r2aOnWq5X0GDx6sU6dOycvLq54d1s/5euvYsaNOnTqlli1bXtLjA+5CaAKameHDh6tfv36SpAcffFBBQUGaP3++3nnnHY0dO9bN3aEuPj4+l3T+06dPy8vLSx4eHpf8WBdScwUUuFLx8RzQzN12222SpAMHDkiS/vjHP+rGG29UUFCQfH19FRMTo7feestlH5vNpvLycq1YscL8uO/HV2JKS0s1YcIEBQYGKiAgQBMnTtT333/foB6rq6u1YMEC9ezZUz4+PgoNDdUjjzyi48ePu9RFRkbqrrvu0kcffaQBAwbIx8dHnTt31v/8z//UmvPzzz/XLbfcIl9fX7Vv317PPPOMli9fLpvNpoMHD5rz7du3T9u2bTPP89Zbb3WZp6KiQqmpqQoODpafn59+8YtfqKSkxNJ5rV+/Xr169ZKPj4969eqldevW1Vn343uaTpw4oalTpyoyMlLe3t4KCQnR0KFDtXv3bkk/3IeUmZmpb775xuy75j6pmvuWVq1apaeeekrXXnutWrVqJafTWec9TTVyc3N14403ytfXV506ddKyZctcttd8/FuzdjV+POeFejvfPU1btmzRoEGD5Ofnp8DAQN1zzz364osvXGpq7qX76quvGu3vHdDYuNIENHNff/21JCkoKEiStHDhQv385z/XuHHjVFlZqVWrVumXv/ylNmzYoISEBEnSG2+8oQcffFADBgzQww8/LEm67rrrXOa977771KlTJ6Wnp2v37t16/fXXFRISoueee67ePT7yyCPKyMjQxIkT9etf/1oHDhzQokWL9Nlnn+nvf/+7y8c5X331lUaNGqXJkycrMTFRf/7znzVhwgTFxMSoZ8+ekqR///vfGjJkiGw2m9LS0uTn56fXX39d3t7eLsddsGCBUlJS5O/vryeffFKSFBoa6lKTkpKia665RnPmzNHBgwe1YMECJScna/Xq1Rc8pw8++EAjR45UVFSU0tPTdfToUU2cOFHt27f/yfV49NFH9dZbbyk5OVlRUVE6evSoPvroI33xxRfq27evnnzySZWVlenbb7/VSy+9JEny9/d3meN3v/udvLy8NH36dFVUVFzwI7njx4/rzjvv1H333aexY8dqzZo1mjJliry8vDRp0qSf7PdcVno71+bNmzV8+HB17txZc+fO1alTp/TKK6/opptu0u7du2vdNN+Yf++ARmcAaBaWL19uSDI2b95slJSUGIcPHzZWrVplBAUFGb6+vsa3335rGIZhfP/99y77VVZWGr169TJuu+02l3E/Pz8jMTGx1nHmzJljSDImTZrkMv6LX/zCCAoK+sk+ExMTjY4dO5rv//a3vxmSjDfffNOlLisrq9Z4x44dDUnG9u3bzbHi4mLD29vb+M1vfmOOpaSkGDabzfjss8/MsaNHjxpt2rQxJBkHDhwwx3v27GnccssttfqsWc+4uDijurraHJ82bZrh6elplJaWXvA8o6OjjXbt2rnUffDBB4Ykl/M3DMOQZMyZM8d8HxAQYCQlJV1w/oSEhFrzGIZhfPjhh4Yko3PnzrX+Wdds+/DDD82xW265xZBkvPjii+ZYRUWFER0dbYSEhBiVlZWGYfxnPc5du/PNeb7eDhw4YEgyli9fbo7VHOfo0aPm2D/+8Q/Dw8PDGD9+vDl2sX/vgMuBj+eAZiYuLk7BwcGKiIjQmDFj5O/vr3Xr1unaa6+VJPn6+pq1x48fV1lZmQYNGmR+9GPVo48+6vJ+0KBBOnr0qJxOZ73mWbt2rQICAjR06FB999135ismJkb+/v768MMPXeqjoqI0aNAg831wcLC6deumf/3rX+ZYVlaWHA6HoqOjzbE2bdpo3Lhx9epNkh5++GHZbDbz/aBBg1RVVaVvvvnmvPscOXJEeXl5SkxMVEBAgDk+dOhQRUVF/eQxAwMD9emnn6qgoKDe/dZITEx0+Wd9IS1atNAjjzxivvfy8tIjjzyi4uJi5ebmNriHn1KzThMmTFCbNm3M8d69e2vo0KF67733au3TWH/vgEuBj+eAZmbx4sXq2rWrWrRoodDQUHXr1k0eHv/5/58NGzbomWeeUV5enioqKszxc4OBFR06dHB5f80110j6IYjZ7XbL83z55ZcqKytTSEhInduLi4sveNyaY597/9M333wjh8NRq65Lly6W+zrf8c49z/OpCVTXX399rW3dunX7yYD6/PPPKzExUREREYqJidGdd96p8ePHq3Pnzpb77tSpk+Xa8PBw+fn5uYx17dpV0g/3IQ0cONDyXPVRs07dunWrta1Hjx7auHGjysvLXXprrL93wKVAaAKamQEDBpjfnvuxv/3tb/r5z3+uwYMHa8mSJWrXrp1atmyp5cuXa+XKlfU6jqenZ53jhmHUa57q6mqFhITozTffrHN7cHDwJTmuVZf7eNIP9+0MGjRI69at0wcffKAXXnhBzz33nN5++20NHz7c0hxWrzJZdb5QXVVV1ajH+Snu+OcBWEVoAq4gf/nLX+Tj46ONGze63BS9fPnyWrX1vfLUUNddd502b96sm266qdF+0Hfs2FFfffVVrfG6xi7FeXbs2FHSD1fRfmz//v2W5mjXrp0ee+wxPfbYYyouLlbfvn31+9//3gxNjdl3QUFBrSs6/+///T9JMm/ErrmiU1pa6rJvXR9TWu2tZp3qWpP8/Hy1bdu21hUwoCnjnibgCuLp6SmbzeZydeDgwYN1Pvnbz8+v1g/IS+G+++5TVVWVfve739Xadvbs2Qb1EB8fr5ycHOXl5Zljx44dq/Nq1qU4z3bt2ik6OlorVqxQWVmZOb5p0yb985//vOC+VVVVLvtIUkhIiMLDw10+TvXz86tV11Bnz57Vq6++ar6vrKzUq6++quDgYMXExEj6z7cnt2/f7tLra6+9Vms+q72du07n/jPYu3evPvjgA915550NPSXALbjSBFxBEhISNH/+fN1xxx26//77VVxcrMWLF6tLly76/PPPXWpjYmK0efNmzZ8/X+Hh4erUqZNiY2MbvadbbrlFjzzyiNLT05WXl6dhw4apZcuW+vLLL7V27VotXLhQo0aNqtecM2bM0P/+7/9q6NChSklJMR850KFDBx07dszlSkhMTIyWLl2qZ555Rl26dFFISIj5bKuLkZ6eroSEBN18882aNGmSjh07pldeeUU9e/bUyZMnz7vfiRMn1L59e40aNUp9+vSRv7+/Nm/erJ07d+rFF1906Xv16tVKTU1V//795e/vr7vvvrtBvYaHh+u5557TwYMH1bVrV61evVp5eXl67bXXzMc99OzZUwMHDlRaWpqOHTumNm3aaNWqVTp79myt+erT2wsvvKDhw4fL4XBo8uTJ5iMHAgICLsvv4wMalXu/vAfAqpqvhO/cufOCdX/605+M66+/3vD29ja6d+9uLF++3Pw697ny8/ONwYMHG76+voYk8/EDNbUlJSV1Hv/HX0n/sR8/cqDGa6+9ZsTExBi+vr5G69atjRtuuMGYMWOGUVBQYNZ07NjRSEhIqLXvLbfcUuuxAZ999pkxaNAgw9vb22jfvr2Rnp5uvPzyy4Yko7Cw0KwrLCw0EhISjNatWxuSzHnOt551fcX+fP7yl78YPXr0MLy9vY2oqCjj7bffrvP8dc4jByoqKownnnjC6NOnj9G6dWvDz8/P6NOnj7FkyRKXfU6ePGncf//9RmBgoMtjDGr6W7t2ba1+zvfIgZ49exq7du0yHA6H4ePjY3Ts2NFYtGhRrf2//vprIy4uzvD29jZCQ0ON//qv/zI2bdpUa87z9VbXIwcMwzA2b95s3HTTTYavr69ht9uNu+++2/jnP//pUnOxf++Ay8FmGNxdB+DKMHXqVL366qs6efLkeW8oBoCG4p4mAM3SqVOnXN4fPXpUb7zxhm6++WYCE4BLgnuaADRLDodDt956q3r06KGioiL96U9/ktPp1G9/+1t3twbgCkVoAtAs3XnnnXrrrbf02muvyWazqW/fvvrTn/6kwYMHu7s1AFco7mkCAACwgHuaAAAALCA0AQAAWMA9TY2kurpaBQUFat269WX79RQAAODiGIah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8+aZNZ06dVJmZqamTZumhQsXqn379nr99dcVHx9v1owePVolJSWaPXu2CgsLFR0draysrFo3hwMAgKtXg57TFBQUpB07dui66667FD01SzynCbi68byhhmHd4G71+fndoCeCP/jgg1q5cmWDmgMAAGiOGvTx3OnTp/Xaa69p8+bN6t27t1q2bOmyff78+Y3SHAAAQFPRoND0+eefKzo6WpJcfj2JpAbfFA4AANCUNSg0ffjhh43dBwAAQJPWoHuaAAAArjYNutI0ZMiQC34Mt2XLlgY3BAAA0BQ1KDTV3M9U48yZM8rLy9PevXtr/SJfAACAK0GDQtNLL71U5/jcuXN18uTJi2oIAACgKWrUe5p+9atfXdTvnQMAAGiqGjU05eTkyMfHpzGnBAAAaBIa9PHcvffe6/LeMAwdOXJEu3bt0m9/+9tGaQwAAKApaVBoCggIcHnv4eGhbt26ad68eRo2bFijNAYAANCUNCg0LV++vLH7AAAAaNIaFJpq5Obm6osvvpAk9ezZUz/72c8apSkAAICmpkGhqbi4WGPGjNHWrVsVGBgoSSotLdWQIUO0atUqBQcHN2aPAAAAbtegb8+lpKToxIkT2rdvn44dO6Zjx45p7969cjqd+vWvf93YPQIAALhdg640ZWVlafPmzerRo4c5FhUVpcWLF3MjOAAAuCI16EpTdXW1WrZsWWu8ZcuWqq6uvuimAAAAmpoGhabbbrtNjz/+uAoKCsyxf//735o2bZpuv/32RmsOAACgqWhQaFq0aJGcTqciIyN13XXX6brrrlOnTp3kdDr1yiuvNHaPAAAAbtege5oiIiK0e/dubd68Wfn5+ZKkHj16KC4urlGbAwAAaCrqdaVpy5YtioqKktPplM1m09ChQ5WSkqKUlBT1799fPXv21N/+9rdL1SsAAIDb1Cs0LViwQA899JDsdnutbQEBAXrkkUc0f/78RmsOAACgqahXaPrHP/6hO+6447zbhw0bptzc3ItuCgAAoKmpV2gqKiqq81EDNVq0aKGSkpKLbgoAAKCpqVdouvbaa7V3797zbv/888/Vrl27i24KAACgqalXaLrzzjv129/+VqdPn6617dSpU5ozZ47uuuuuRmsOAACgqajXIweeeuopvf322+ratauSk5PVrVs3SVJ+fr4WL16sqqoqPfnkk5ekUQAAAHeqV2gKDQ3V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nDjR3a0BAAA3IzSdY/To0SopKdHs2bNVWFio6OhoZWVl1bo5HAAAXH0ITT+SnJxc58dxVytvb2/NmTOn1keRuDDWrf5Ys4Zh3RqGdWuYq33dbIaV79gBAABc5XgiOAAAgAWEJgAAAAsITQAAABYQmgAAACwgNOG8Fi9erMjISPn4+Cg2NlY7duxwd0tN3vbt23X33XcrPDxcNptN69evd3dLTV56err69++v1q1bKyQkRCNGjND+/fvd3VaTt3TpUvXu3dt8yKDD4dD777/v7raalWeffVY2m01Tp051dytN2ty5c2Wz2Vxe3bt3d3dbbkFoQp1Wr16t1NRUzZkzR7t371afPn0UHx+v4uJid7fWpJWXl6tPnz5avHixu1tpNrZt26akpCR98skn2rRpk86cOaNhw4apvLzc3a01ae3bt9ezzz6r3Nxc7dq1S7fddpvuuece7du3z92tNQs7d+7Uq6++qt69e7u7lWahZ8+eOnLkiPn66KOP3N2SW/DIAdQpNjZW/fv316JFiyT98CtlIiIilJKSolmzZrm5u+bBZrNp3bp15q/lgTUlJSUKCQnRtm3bNHjwYHe306y0adNGL7zwgiZPnuzuVpq0kydPqm/fvlqyZImeeeYZRUdHa8GCBe5uq8maO3eu1q9fr7y8PHe34nZcaUItlZWVys3NVVxcnDnm4eGhuLg45eTkuLEzXA3Kysok/RAAYE1VVZVWrVql8vJyORwOd7fT5CUlJSkhIcHlv3G4sC+//FLh4eHq3Lmzxo0bp0OHDrm7JbfgieCo5bvvvlNVVVWtXx8TGhqq/Px8N3WFq0F1dbWmTp2qm266Sb169XJ3O03enj175HA4dPr0afn7+2vdunWKiopyd1tN2qpVq7R7927t3LnT3a00G7GxscrIyFC3bt105MgRPf300xo0aJD27t2r1q1bu7u9y4rQBKDJSEpK0t69e6/a+yXqq1u3bsrLy1NZWZneeustJSYmatu2bQSn8zh8+LAef/xxbdq0ST4+Pu5up9kYPny4+efevXsrNjZWHTt21Jo1a666j4IJTailbdu28vT0VFFRkct4UVGRwsLC3NQVrnTJycnasGGDtm/frvbt27u7nWbBy8tLXbp0kSTFxMRo586dWrhwoV599VU3d9Y05ebmqri4WH379jXHqqqqtH37di1atEgVFRXy9PR0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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "# YOUR SOLUTION HERE" ] }, { "cell_type": "markdown", "metadata": { "id": "1Ct7Zr2WqGRC" }, "source": [ "**Q: We can now also calculate the average path length of the whole network by averaging the path lengths.**" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 176, "status": "ok", "timestamp": 1642972823987, "user": { "displayName": "Ashutosh Hathidara", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GiF8R551zAQvapFAWqdihe4-meSQy-KHh-aXiSf=s64", "userId": "09642124213384184129" }, "user_tz": 300 }, "id": "zWFWD7XnqLbX", "outputId": "093a2b2e-6a41-4807-bb36-de413856eab2" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.25424\n" ] } ], "source": [ "# calculate the average path length from the path_length_counter\n", "# YOUR SOLUTION HERE\n", "print(average_path_length)\n" ] }, { "cell_type": "markdown", "metadata": { "id": "XzgjpnW-ryMd" }, "source": [ "Can you make it as a function? " ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "executionInfo": { "elapsed": 178, "status": "ok", "timestamp": 1642972829355, "user": { "displayName": "Ashutosh Hathidara", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GiF8R551zAQvapFAWqdihe4-meSQy-KHh-aXiSf=s64", "userId": "09642124213384184129" }, "user_tz": 300 }, "id": "pJmoIEurvPjl" }, "outputs": [ { "data": { "text/plain": [ "3.253168" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def avg_path_length(G):\n", " # YOUR SOLUTION HERE\n", "\n", "avg_path_length(G)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ok! Now you can compute the average shortest path length of a network! 🎉\n", "\n", "In practice, you'd not implement the BFS algorithm yourself, but use a library like NetworkX, igraph, graph-tools, etc. But, it is really good to understand what is happening under the hood! " ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.2564244244244245" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Here's how you can do the same (average path length of a graph) with networkx\n", "nx.average_shortest_path_length(G)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You may notice a small difference. I will leave it to you to identify why there is a difference (extra credit). " ] }, { "cell_type": "markdown", "metadata": { "id": "793_3mbNdxwu" }, "source": [ "### How does it scale?\n", "\n", "Now go to https://icon.colorado.edu/#!/ and download multiple (at least three) networks that span a range of scale. For instance, pick a couple of networks with ~1000 nodes and then ~10000 nodes, and so on. Be careful with large networks! Calculating shortest paths is an expensive computation and it may take too much time (or not even finish)! Stick with not-so-large and not-too-small networks, but do experiment how far you can push. \n", "\n", "**Q: Using your code above, calculate the average path length of each network and also measure how long it takes.**\n", "\n", "You can use either `%%time` or `%%timeit` Jupyter magic commands or use a script. `%%timeit` runs the code multiple times to get a better estimate. So it may not be suitable for large networks. \n" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 4650, "status": "ok", "timestamp": 1642972870982, "user": { "displayName": "Ashutosh Hathidara", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GiF8R551zAQvapFAWqdihe4-meSQy-KHh-aXiSf=s64", "userId": "09642124213384184129" }, "user_tz": 300 }, "id": "-2AahtobeeCj", "outputId": "e2a3b187-d4c1-4907-b00d-9a7477921c91" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "24 ms ± 145 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%%timeit\n", "total = 0\n", "for i in range(1000000):\n", " total += i\n", " " ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 475, "status": "ok", "timestamp": 1642972875202, "user": { "displayName": "Ashutosh Hathidara", "photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GiF8R551zAQvapFAWqdihe4-meSQy-KHh-aXiSf=s64", "userId": "09642124213384184129" }, "user_tz": 300 }, "id": "2T98g9Vnsozd", "outputId": "05f0f564-090d-443e-8a78-8c0e74d948fc" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 60.8 ms, sys: 1.11 ms, total: 62 ms\n", "Wall time: 61 ms\n" ] } ], "source": [ "%%time\n", "total = 0\n", "for i in range(1000000):\n", " total += i" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Use however many cells you need.\n", "\n", "# YOUR SOLUTION HERE" ] }, { "cell_type": "markdown", "metadata": { "id": "w4dw218usswu" }, "source": [ "**Q: now make two plots that show two relationships.** \n", "\n", "The first one is about the relationship between the number of nodes in your networks and their average path length. Are they correlated? You can test whether they have a roughly logarithmic relationship $ d \\sim \\log N$ or not. \n", "\n", "The second one is about the execution time and the number of nodes ($|V|$) & the number of edges ($|E|$). Is it proportional to $|V|\\cdot|E|$? " ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "id": "xXXSnLKhtO8L" }, "outputs": [], "source": [ "# YOUR SOLUTION HERE" ] } ], "metadata": { "anaconda-cloud": {}, "colab": { "collapsed_sections": [], "name": "m03-pathlength.ipynb", "provenance": [ { "file_id": "1pnWYRFHs-g2lnHnkHrPtEJpm__Fa_9IK", "timestamp": 1642887851231 }, { "file_id": "https://github.com/yy/netsci-course/blob/master/m03-smallworld/shortest_path_length_distribution.ipynb", "timestamp": 1642887752640 } ] }, "kernelspec": { "display_name": "Python 3", "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.5" }, "vscode": { "interpreter": { "hash": "b0fa6594d8f4cbf19f97940f81e996739fb7646882a419484c72d19e05852a7e" } } }, "nbformat": 4, "nbformat_minor": 0 }