From a394600a8e2cffc6e1e18136ffda848101b11d84 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Sun, 31 Oct 2021 23:33:16 +0530 Subject: [PATCH] Added notebook for California road network (#426) --- docs/requirements.txt | 3 +- docs/source/conf.py | 5 +- docs/source/index.rst | 1 + docs/source/pydatastructs_sphinx_graphs.ipynb | 243 ++++++++++++++++++ docs/source/tutorials.rst | 2 +- 5 files changed, 251 insertions(+), 3 deletions(-) create mode 100644 docs/source/pydatastructs_sphinx_graphs.ipynb diff --git a/docs/requirements.txt b/docs/requirements.txt index b3ecdb274..6526a0ef8 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,2 +1,3 @@ sphinx==4.2.0 -sphinx-readable-theme==1.3.0 \ No newline at end of file +sphinx-readable-theme==1.3.0 +myst_nb==0.13.1 \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index f777adbb2..95974a93a 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -36,9 +36,12 @@ # ones. extensions = [ 'sphinx.ext.autodoc', - 'sphinx.ext.napoleon' + 'sphinx.ext.napoleon', + 'myst_nb' ] +jupyter_execute_notebooks = "off" + napoleon_numpy_docstring = True # Add any paths that contain templates here, relative to this directory. diff --git a/docs/source/index.rst b/docs/source/index.rst index 241096646..8ca90a45e 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -48,6 +48,7 @@ Contents :maxdepth: 1 tutorials.rst + pydatastructs_sphinx_graphs contributing.rst authors.rst pydatastructs/pydatastructs.rst diff --git a/docs/source/pydatastructs_sphinx_graphs.ipynb b/docs/source/pydatastructs_sphinx_graphs.ipynb new file mode 100644 index 000000000..724c0a07c --- /dev/null +++ b/docs/source/pydatastructs_sphinx_graphs.ipynb @@ -0,0 +1,243 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "pydatastructs-sphinx-graphs.ipynb", + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "2qB4MTFoYSdW" + }, + "source": [ + "Comparing Dijkstra and Bellman Ford Shortest Paths Algorithms using PyDataStructs\n", + "====================================" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Zu6G_1RLYitv" + }, + "source": [ + "Dataset\n", + "-------\n", + "\n", + "We have used [California road network](https://snap.stanford.edu/data/roadNet-CA.html) from [Stanford Network Analysis Project](https://snap.stanford.edu/index.html). The intent of this demo is to show how **pydatastructs** can be used for research and analysis purposes.\n", + "\n", + "The above dataset is a road network of California as the name suggests. The intersections and endpoints in this network are represented as vertices and the roads between them are represented as undirected edges. The data is read from a `txt` file where each line contains two numbers representing two points of an edge in the graph. We have used varying number of these edges to analyse how each algorithm responds to the varying scale of the shortest path problem at hand." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YoaukKUfaF66" + }, + "source": [ + "Results\n", + "-------\n", + "\n", + "We observed that for low inverse density (total number of possible edges divided by number of edges present) graphs, both algorithms take similar amounts of time. However Dijkstra algorithm performs significantly better with high inverse density graphs as compared to Bellman Ford algorithm." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_qWIIix_Twd5" + }, + "source": [ + "# Import modules and APIs for Graphs\n", + "from pydatastructs import Graph, AdjacencyListGraphNode\n", + "from pydatastructs import shortest_paths, topological_sort\n", + "\n", + "# Import utility modules\n", + "import timeit, random, functools, matplotlib.pyplot as plt" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8TDkoIgcXJr6" + }, + "source": [ + "def create_Graph(num_edges, file_path, ignore_lines=4):\n", + " \"\"\"\n", + " Creates pydatastructs.Graph object.\n", + "\n", + " Parameters\n", + " ==========\n", + "\n", + " num_edges: int\n", + " Number of edges that should be present in the\n", + " pydatastructs.Graph object.\n", + " file_path: str\n", + " The path to the file containing California\n", + " road network dataset.\n", + " ignore_lines: int\n", + " Number of inital lines that should be ignored.\n", + " Optional, by default 4 because the first 4 lines\n", + " contain documentation of the dataset which is not\n", + " required to generate the pydatastructs.Graph object.\n", + " \n", + " Returns\n", + " =======\n", + "\n", + " G: pydatastructs.Graph\n", + " \"\"\"\n", + " f = open(file_path, 'r')\n", + " for _ in range(ignore_lines):\n", + " f.readline()\n", + " G = Graph()\n", + " inp = f.readline().split()\n", + " for _ in range(num_edges):\n", + " u, v = inp\n", + " G.add_vertex(AdjacencyListGraphNode(u))\n", + " G.add_vertex(AdjacencyListGraphNode(v))\n", + " G.add_edge(u, v, random.randint(1, 1000)) \n", + " inp = f.readline().split()\n", + " return G" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qRS4Rz-ZRZ51" + }, + "source": [ + "def generate_data(file_name, min_num_edges, max_num_edges, increment):\n", + " \"\"\"\n", + " Generates computation time data for Dijkstra and Bellman ford\n", + " algorithms using pydatastructs.shortest_paths.\n", + "\n", + " Parameters\n", + " ==========\n", + "\n", + " file_path: str\n", + " The path to the file containing California\n", + " road network dataset.\n", + " min_num_edges: int\n", + " The minimum number of edges to be used for\n", + " comparison of algorithms.\n", + " max_num_edges: int\n", + " The maximum number of edges to be used for comparison\n", + " of algorithms.\n", + " increment: int\n", + " The value to be used to increment the scale of the\n", + " shortest path problem. For example if using 50 edges,\n", + " and increment value is 10, then in the next iteration,\n", + " 60 edges will be used and in the next to next iteration,\n", + " 70 edges will be used and so on until we hit the max_num_edges\n", + " value.\n", + "\n", + " Returns\n", + " =======\n", + "\n", + " graph_data, data_dijkstra, data_bellman_ford: (list, list, list)\n", + " graph_data contains tuples of number of vertices and number\n", + " of edges.\n", + " data_dijkstra contains the computation time values for each\n", + " graph when Dijkstra algorithm is used.\n", + " data_bellman_ford contains the computation time values for each\n", + " graph when Bellman ford algorithm is used. \n", + " \"\"\"\n", + " data_dijkstra, data_bellman_ford, graph_data = [], [], []\n", + " for edge in range(min_num_edges, max_num_edges + 1, increment):\n", + " G = create_Graph(edge, file_name)\n", + " t = timeit.Timer(functools.partial(shortest_paths, G, 'dijkstra', '1'))\n", + " t_djk = t.repeat(1, 1)\n", + " t = timeit.Timer(functools.partial(shortest_paths, G, 'bellman_ford', '1'))\n", + " t_bf = t.repeat(1, 1)\n", + " graph_data.append((len(G.vertices), len(G.edge_weights)))\n", + " data_dijkstra.append(t_djk[0])\n", + " data_bellman_ford.append(t_bf[0])\n", + " return graph_data, data_dijkstra, data_bellman_ford" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GTeSF1ChA2Bz" + }, + "source": [ + "def plot_data(graph_data, data_dijkstra, data_bellman_ford):\n", + " \"\"\"\n", + " Utility function to plot the computation time values\n", + " for Dijkstra and Bellman ford algorithms versus\n", + " the inverse density of the input graph.\n", + " \"\"\"\n", + " idensity, time_dijkstra, time_bellman_ford = [], [], []\n", + " for datum_graph, datum_djk, datum_bf in zip(graph_data, data_dijkstra, data_bellman_ford):\n", + " num_edges, num_vertices = datum_graph[1], datum_graph[0]\n", + " idensity.append((num_vertices*(num_vertices - 1))/(2*num_edges))\n", + " time_dijkstra.append(datum_djk)\n", + " time_bellman_ford.append(datum_bf)\n", + " plt.xlabel(\"Inverse Density of Input Graph\")\n", + " plt.ylabel(\"Computation Time (s)\")\n", + " plt.plot(idensity, time_dijkstra, label=\"Dijkstra\")\n", + " plt.plot(idensity, time_bellman_ford, label=\"Bellman Ford\")\n", + " plt.legend(loc=\"best\")\n", + " plt.show()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "UXqC736NXfs2" + }, + "source": [ + "graph_data, data_djk, data_bf = generate_data('roadNet-CA.txt', 50, 2000, 50)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 300 + }, + "id": "EEEPGwOpV_DC", + "outputId": "8e84de7b-c905-4cd1-e075-514982c2ef22" + }, + "source": [ + "plot_data(graph_data, data_djk, data_bf)" + ], + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/source/tutorials.rst b/docs/source/tutorials.rst index 704b4b19c..519b9ac6a 100644 --- a/docs/source/tutorials.rst +++ b/docs/source/tutorials.rst @@ -4,7 +4,7 @@ Tutorials We provide the following tutorials to show how ``pydatastructs`` APIs can help in solving complicated data structures and algorithms problems easily. For now the problems are abstract. However, we plan -to add some examples showing usage of ``pydatastructs`` on real world +to add some more examples showing usage of ``pydatastructs`` on real world data sets such as `Stanford Large Network Dataset Collection `_ and `Urban Dictionary Words And Definitions `_. If you are interested in playing around with the above datasets using our API,