{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Analysis of Algorithms\n", "\n", "Code examples from [Think Complexity, 2nd edition](https://thinkcomplex.com).\n", "\n", "Copyright 2017 Allen Downey, [MIT License](https://opensource.org/licenses/MIT)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import seaborn as sns\n", "\n", "import os\n", "import string\n", "\n", "from utils import decorate, savefig" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Empirical order of growth\n", "\n", "Sometimes we can figure out what order of growth a function belongs to by running it with a range of problem sizes and measuring the run time.\n", "\n", "To measure runtimes, we'll use `etime`, which uses `os.times` to compute the total time used by a process, including \"user time\" and \"system time\". User time is time spent running your code; system time is time spent running operating system code on your behalf." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def etime():\n", " \"\"\"Measures user and system time this process has used.\n", "\n", " Returns the sum of user and system time.\"\"\"\n", " user, sys, chuser, chsys, real = os.times()\n", " return user+sys" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`time_func` takes a function object and a problem size, `n`, runs the function, and returns the elapsed time." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def time_func(func, n):\n", " \"\"\"Run a function and return the elapsed time.\n", " \n", " func: function\n", " n: problem size\n", " \n", " returns: user+sys time in seconds\n", " \"\"\"\n", " start = etime()\n", " func(n)\n", " end = etime()\n", " elapsed = end - start\n", " return elapsed" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's an example: a function that makes a list with the given length using `append`." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.07999999999999985" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def append_list(n):\n", " t = []\n", " for i in range(n):\n", " t.append(i)\n", " return t\n", "\n", "time_func(append_list, 1000000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`run_timing_test` takes a function, runs it with a range of problem sizes, and returns two lists: problem sizes and times." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def run_timing_test(func, max_time=1):\n", " \"\"\"Tests the given function with a range of values for n.\n", " \n", " func: function object\n", "\n", " returns: list of ns and a list of run times.\n", " \"\"\"\n", " ns = []\n", " ts = []\n", " for i in range(10, 28):\n", " n = 2**i\n", " t = time_func(func, n)\n", " print(n, t)\n", " if t > 0:\n", " ns.append(n)\n", " ts.append(t)\n", " if t > max_time:\n", " break\n", "\n", " return ns, ts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's an example with `append_list`" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024 0.0\n", "2048 0.0\n", "4096 0.0\n", "8192 0.0\n", "16384 0.010000000000000009\n", "32768 0.0\n", "65536 0.010000000000000009\n", "131072 0.0\n", "262144 0.020000000000000018\n", "524288 0.040000000000000036\n", "1048576 0.07000000000000006\n", "2097152 0.1599999999999997\n", "4194304 0.29000000000000004\n", "8388608 0.5900000000000003\n", "16777216 1.1099999999999999\n" ] } ], "source": [ "ns, ts = run_timing_test(append_list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`fit` takes the lists of ns and ts and fits it with a curve of the form `a * n**exp`, where `exp` is a given exponent and `a` is chosen so that the line goes through a particular point in the sequence, usually the last. " ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "def fit(ns, ts, exp=1.0, index=-1):\n", " \"\"\"Fits a curve with the given exponent.\n", " \n", " ns: sequence of problem sizes\n", " ts: sequence of times\n", " exp: exponent of the fitted curve\n", " index: index of the element the fitted line should go through\n", " \n", " returns: sequence of fitted times\n", "\n", " \n", " \"\"\"\n", " # Use the element with the given index as a reference point, \n", " # and scale all other points accordingly.\n", " nref = ns[index]\n", " tref = ts[index]\n", "\n", " tfit = []\n", " for n in ns:\n", " ratio = n / nref\n", " t = ratio**exp * tref\n", " tfit.append(t)\n", "\n", " return tfit" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`plot_timing_test` plots the results." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def plot_timing_test(ns, ts, label='', color='blue', exp=1.0, scale='log'):\n", " \"\"\"Plots data and a fitted curve.\n", "\n", " ns: sequence of n (problem size)\n", " ts: sequence of t (run time)\n", " label: string label for the data curve\n", " color: string color for the data curve\n", " exp: exponent (slope) for the fitted curve\n", " \"\"\"\n", " tfit = fit(ns, ts, exp)\n", " fit_label = 'exp = %d' % exp\n", " plt.plot(ns, tfit, label=fit_label, color='0.7', linestyle='dashed')\n", " plt.plot(ns, ts, 'o-', label=label, color=color, alpha=0.7)\n", " plt.xlabel('Problem size (n)')\n", " plt.ylabel('Runtime (seconds)')\n", " plt.xscale(scale)\n", " plt.yscale(scale)\n", " plt.legend()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here are the results from `append_list`. When we plot `ts` versus `ns` on a log-log scale, we should get a straight line. If the order of growth is linear, the slope of the line should be 1. " ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYoAAAEKCAYAAAAMzhLIAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nO3deXiU5dX48e/JZCWBQDYSwpJAQkgIiWJQEQRs61Kr0lqXUvuzVqvVil3e1re2vm+1ttYu2lrFpVhwr/oq1UJrW6utoGIVUPYdwhJACNn3bc7vj2cCIWSZhExmMjmf6/IKc8/M85zhkTm5n3s5oqoYY4wxnQnxdwDGGGMCmyUKY4wxXbJEYYwxpkuWKIwxxnTJEoUxxpguWaIwxhjTpVB/B+ALCQkJmpaW5u8wjDFmQFmzZs1RVU1s3x6UiSItLY3Vq1f7OwxjjBlQRGRvR+1268kYY0yXLFEYY4zpkiUKY4wxXQrKMYqONDU1UVRURH19vb9DGRQiIyMZPXo0YWFh/g7FGHOKBk2iKCoqYujQoaSlpSEi/g4nqKkqJSUlFBUVkZ6e7u9wjAl6y5fDggVQWAjp6TB/Psye3XfHHzS3nurr64mPj7ck0Q9EhPj4eOu9GdMPli+H730PjhyBkSOdn9/7ntPeVwZNogAsSfQj+7s2pn8sWADR0QDN7NihDBniPF6woO/OEfCJQkSiReRpEXlCRK7xdzwD3UUXXcTw4cO55JJL/B2KMaYP7NihHDxYz/r1LZSWtnDoEMTEOLeh+opfEoWILBaRIyKysV37RSKyTUR2isgdnubLgVdU9Ubgsn4PNsjcfvvtPPvss/4OwxhzitxueP11KCmBw4dDACUhoZlRo6C62hmr6Cv+6lE8BVzUtkFEXMAjwGeBHGCeiOQAo4H9npe19GOMfe65557jzDPP5LTTTuMb3/gGLS0t7N27l8zMTI4ePYrb7ebcc8/ljTfeYM+ePUyaNImvfvWr5OXlccUVV1BbW3vKMXz6059m6NChffBpjDH+sn59M9/+tpvHHoPRo4WoKBfjx7uYMCGSmhqoqXEGtPuKX2Y9qeoKEUlr13wmsFNVdwOIyIvAXKAIJ1mspYvEJiI3ATcBjB07ttsY/vKXv3T63JQpUxg3bhwAe/fuZcOGDZ2+1ttbOFu2bOGll17ivffeIywsjG9+85s8//zzXHvttfzgBz/g5ptv5qyzziInJ4cLLriAPXv2sG3bNhYtWsSMGTO4/vrrefTRR/n+979/wnF//etf8/zzz590vlmzZvHQQw95FZsxZmAoLYUFC6r529/qiIiIZMKEofzoR9DQ4OKRR1w+m/UUSNNjUznecwAnQZwFPAQsEJHPAcs6e7OqLgQWAhQUFARcIfC33nqLNWvWMG3aNADq6upISkoC4Otf/zovv/wyjz/+OGvXrj32njFjxjBjxgwAvvKVr/DQQw+dlChuv/12br/99n76FMYYf2huhldfbWLhwhoqKhoIDXVz7rkH+NGPJhIV5fz+PGeO784fSImio2kyqqo1wNf6+mTe9gTGjRt3rHdxKlSVr371q9x3330nPVdbW0tRUREA1dXVx24NtZ851NFMIutRGBPc1q6F3/62hm3banG73UyaVM4tt4Rz1lkTCQnpn9GDQEoURcCYNo9HAwd7cgARuRS4NCMjoy/j6hOf/vSnmTt3Lt/97ndJSkqitLSUqqoqxo0bxw9+8AOuueYaxo0bx4033njstti+fft4//33mT59Oi+88AIzZ8486bjWozAmOB05Ak884ebvf6+koaGBuLh6rrqqnKuumkBMTEy/xhJIiWIVkCki6cAB4EvAl3tyAFVdBiwrKCi40QfxnZKcnBx+9rOfccEFF+B2uwkLC+ORRx5hz549rFq1ivfeew+Xy8WSJUt48sknOe+888jOzubpp5/mG9/4BpmZmdxyyy2nHMe5557L1q1bqa6uZvTo0SxatIgLL7ywDz6hMaYvNDbCn/4EL78MjY0hREQos2Yd5LrrRpCRkeeXNUqi2v+380XkBWAOkAAcBu5S1UUicjHwIOACFqvqvb05fkFBgbavR7Flyxays7NPKe7+tGfPHi655BI2btzY/YsD1ED7OzfGn1Thww/hsceaOXwYQkNDmTULrrmmgREj3ERFRfk8BhFZo6oF7dv9NetpXiftrwOv93M4xhjjVwcOwMKFyrvv1lFdXU1qahN3351CXl4IEOHv8ALq1tMpC+Qxip5KS0sb0L0JY0z36uvhpZfglVeaKC2twuWq48ILD3DJJS6ys5MIlM0zgipRBPIYhTHGtFKFd96BRYuU/ftrqKmpIT+/mIsvLubss7NJTk72d4gnCKpEYYwxgW7PHvj972HjRqWs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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plot_timing_test(ns, ts, 'append_list', exp=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For small values of `n`, the runtime is so short that we're probably not getting an accurate measurement of just the operation we're interested in. But as `n` increases, runtime seems to converge to a line with slope 1. \n", "\n", "That suggests that performing append `n` times is linear, which suggests that a single append is constant time. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### list.pop\n", "\n", "Now let's try that with `pop`, and specifically with `pop(0)`, which pops from the left side of the list." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024 0.0\n", "2048 0.0\n", "4096 0.009999999999999787\n", "8192 0.009999999999999787\n", "16384 0.040000000000000036\n", "32768 0.1299999999999999\n", "65536 0.6299999999999999\n", "131072 2.7600000000000007\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def pop_left_list(n):\n", " t= []\n", " for i in range(n):\n", " t.append(i)\n", " for _ in range(n):\n", " t.pop(0)\n", " return t\n", "\n", "ns, ts = run_timing_test(pop_left_list)\n", "plot_timing_test(ns, ts, 'pop_left_list', exp=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That doesn't look very good. The runtimes increase more steeply than the line with slope 1. Let's try slope 2." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plot_timing_test(ns, ts, 'pop_left_list', exp=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The last few points converge on the line with slope 2, which suggests that `pop(0)` is quadratic." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** What happens if you pop from the end of the list? Write a function called `pop_right_list` that pops the last element instead of the first. Use `run_timing_test` to characterize its performance. Then use `plot_timing_test` with a few different values of `exp` to find the slope that best matches the data. What conclusion can you draw about the order of growth for popping an element from the end of a list?" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024 0.0\n", "2048 0.0\n", "4096 0.0\n", "8192 0.0\n", "16384 0.0\n", "32768 0.009999999999999787\n", "65536 0.009999999999999787\n", "131072 0.030000000000001137\n", "262144 0.03999999999999915\n", "524288 0.08000000000000185\n", "1048576 0.16000000000000014\n", "2097152 0.3099999999999987\n", "4194304 0.6699999999999999\n", "8388608 1.2800000000000011\n" ] }, { "data": { "image/png": "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8KyqrgvkuKq6AFiQm5s7salrNsaYE7VnjxMYn31WBQj9+8fws59B794dEUknIqJ1DRsYql5VVx9j+bvAu81cjjHGBEVNDfztb/Dqqx6KikpRreD88/fyi18MIjY2Cudv5NandcVcM1q4EK66CnJzna/BnE0rGN5++20efvjh427zySefHHPolccee6zR0XizsrI4cOAAAGeeeeZxt33wwQePu96YcLNsGUyZosydW8nu3UX07r2LW25Zx09+kkJMTEt6ShC4sAoOEblEROYcPnz4pI4TiqkYm5Lb7ebSSy/lrrvuanzjY/AnOOr7/PPPj7vegsO0FQcOwEMPwd13e9iw4RBRUXuZMGEDEyeWcPHFZ5Gdnd1iu9n6q3XHXgP+PuO45JLjH2fZMqiuhsh6/3bcbrj6ajjttGPvt+CYb5k48vPzufDCCxkxYgQrVqygT58+vPDCCyxevJjbb78dt9vN8OHDefrpp4mJiSErK4tx48bx8ccfA/Dyyy9zrAf/1113HR06dGDFihUMGzaMwYMHs3TpUmbPns22bdsYP348Ho+HsWPH8uijj1JWVgY4gypeeeWVrF27ltNOO40XX3yRJ554gl27dvGd73yHtLS0I+c/nsTERMrKyti9ezfjxo2jpKQEt9vN008/zT/+8Q8qKysZOnQoAwcOPOqgjMa0dm63M7HSK69AVZVSXl7MqFEFjBpVzODB/cnMzGz1gVEnrFocTaWiAhr2iHO5nOUna9OmTUyaNInVq1eTnJzMo48+ynXXXcerr77KmjVrjvyyrZOcnMyXX37J1KlT+Z//+Z/jHnvz5s18+OGHzJw58xvLb731Vm699VaWLFlC586dv7FuxYoVPPbYY6xfv57t27fzn//8h2nTptG5c2c+/vhjv0KjvpdffpkLLriAlStXsmrVKoYOHcrDDz9MXFwcK1eutNAwYWnNGpg2Df7yF6e77ZlnCs88A1dcAd/97mi6du0aNqEBYdbi8FdjLYOrrnJuTyUnf72spATS0+H110/u3A3n2JgxYwbZ2dn06dMHgGuvvZYnn3zySEhcffXVR77edtttjdR91VH7gC9evJi///3vAPz4xz/+xpwep59+OpmZmQAMHTqU/Pz8o47C66/hw4dz/fXXU1tby+WXX87QoUNP+FjGtHQHD8Kzz8LHHysVFRWkpdVw553tfXcmOvr+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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Solution\n", "\n", "def pop_right_list(n):\n", " t= []\n", " for i in range(n):\n", " t.append(i)\n", " for _ in range(n):\n", " t.pop(-1)\n", " return t\n", "\n", "ns, ts = run_timing_test(pop_right_list)\n", "plot_timing_test(ns, ts, 'pop_right_list', exp=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sorting\n", "\n", "We expect sorting to be `n log n`. On a log-log scale, that doesn't look like a straight line, so there's no simple test whether it's really `n log n`. Nevertheless, we can plot results for sorting lists with different lengths, and see what it looks like." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024 0.0\n", "2048 0.0\n", "4096 0.009999999999999787\n", "8192 0.0\n", "16384 0.0\n", "32768 0.0\n", "65536 0.009999999999999787\n", "131072 0.009999999999999787\n", "262144 0.019999999999999574\n", "524288 0.040000000000000924\n", "1048576 0.08000000000000007\n", "2097152 0.16999999999999993\n", "4194304 0.34999999999999964\n", "8388608 0.75\n", "16777216 1.549999999999999\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def sort_list(n):\n", " t = np.random.random(n)\n", " t.sort()\n", " return t\n", "\n", "ns, ts = run_timing_test(sort_list)\n", "plot_timing_test(ns, ts, 'sort_list', exp=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It sure looks like sorting is linear, so that's surprising. But remember that `log n` changes much more slowly than `n`. Over a wide range of values, `n log n` can be hard to distinguish from an algorithm with linear growth. As `n` gets bigger, we would expect this curve to be steeper than slope 1. But often, for practical problem sizes, `n log n` is as good as linear." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Bisection search\n", "\n", "We expect bisection search to be `log n`, which is so fast it is hard to measure the way we've been doing it.\n", "\n", "To make it work, I create the sorted list ahead of time and use the parameter `hi` to specify which part of the list to search. Also, I have to run each search 100,000 times so it takes long enough to measure. " ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024 0.16999999999999815\n", "2048 0.19000000000000128\n", "4096 0.1999999999999993\n", "8192 0.21000000000000085\n" ] }, { "data": { "image/png": "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srOzbeJMM2xcfnnPxzdtguZmCPwcb2uDa6+Fs8/u/n2vvNJzufX19VxzzTVUVlbS3t7Ot7/9bXJzc/nGN75BXV0daWlprFixgoyMDJ5++mmeeuopWlpayM3N5Xe/+x2JiYksXbqUlJQU3nvvPc466yy++93vcscdd7Bx40ZEhAceeID//M//BOD+++/nL3/5CwkJCbz00ktMmDChy7hWrVrFd7/7XdxuN0lJSaxdu5ampiZuvfVWNm7cSExMDI888ggXXHABK1as4NVXX6WpqYn6+noaGhooLS1lzpw53HDDDdx5553ce++9rF69mubmZm677TZuvvlmVJU77riDN954g+zsbPoyK0xWVhYbN24kISHhlJ/fwYMH2bdvHxdccAFpaWm8+eabIZfbFUs2A6CpqYmKigpmzJiBiJCQkMBFF12E2+2OdmjGDKiGBgheldztdvb3x1//+lfOPPNMXn31VQCqq6v5xCc+wUsvvcT48eP5wx/+wP33388zzzzDZz7zGW666SYAli1bxvLly7njjjsA2L59O//4xz9wu93cc889JCUlda650/FwdX19Peeeey4PPvgg3/rWt3j66adZtmxZl3F973vf429/+xsTJ07sbK56/HHnefLi4mK2bdvGkiVL2L59OwDr16/H6/WSkpLC6tWr+clPftI5eehTTz1FUlISGzZsoLm5mQULFrBkyRLee+89PvjgA4qLizl48CCzZ8/mxhtv7PfPLykpiUceeYQ333yTtLS0PpXXFUs2EaSq7Nmzh61bt9LW1kZ8fDxZWVkAlmjMsNRbDeTqq52ms8BW45oaSE+HVatO/7oFBQXcdddd3HPPPVx22WUkJydTUlLCxRdfDDiPFmRkZABQUlLCsmXLOH78OHV1dSdNlnn11Vd3/t/8xz/+wcqVKzuPJScnAxAbG9u5jMLZZ5/N3//+927jWrBgAUuXLuWaa67hM5/5DADr1q3rTG4zZ85kypQpncnm4osvJiUlpcuyXn/9dbxeb2d/THV1NTt27GDt2rVce+21uN1uzjzzTC688MI+/vRO/fktXLiwz2X0xpJNhNTX1+P1eqmqqgIgPT2926q2MSPF7bc7fTQAo0dDXR3U1zv7+2P69Ols2rSJ1157jfvuu4+LL76YvLw81q9ff8q5S5cu5cUXX6SoqIgVK1awevXqzmOBI0JVtcvZ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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "t = np.random.random(16777216)\n", "t.sort()\n", "\n", "from bisect import bisect\n", "\n", "def search_sorted_list(n):\n", " for i in range(100000):\n", " index = bisect(t, 0.1, hi=n) \n", " return index\n", "\n", "ns, ts = run_timing_test(search_sorted_list, max_time=0.2)\n", "plot_timing_test(ns, ts, 'search_sorted_list', exp=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It looks like the runtime increases slowly as `n` increases, but it's definitely not linear. To see if it's constant time, we can compare it to the line with slope 0." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/png": "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xDvuCLv9OlcRFbZE2OzZ4Xlt7N+BHTvgssvgpJMK/ty4cfuvd+PGjVxyySXk5uayc+dO7r77blq2bMn//d//sWHDBurVq8eoUaNo2LAhw4cPZ9iwYWzbto2WLVvyr3/9i5o1a9KnTx/q1KnDhx9+SLt27Rg8eDA333wzs2bNQhKDBg3iZz/7GQADBgxg/PjxHHjggbzyyiscdthhCeMaM2YMgwcPJisri+zsbKZPn86WLVu44YYbmDVrFlWrVuWhhx6ic+fOjBo1itdee40tW7awceNGNm3axMKFCznxxBO56qqruOWWW7jzzjuZOnUqW7du5aabbuK6667DzLj55pt56623aN68ecIV4AvSrFkzZs2axYEHHrjPz+/bb79l5cqVdO7cmXr16jFlypSk603E/9nLYCtWwIABkJcXtqG/805PVK5y27QJqlffuywrK5SXxMSJEzn88MN57bXXAMjLy+O8887jlVdeoX79+vz73/9mwIABjBw5kosuuoh+/foBMHDgQEaMGMHNN98MwOeff84bb7xBVlYWv/3tb8nOzt6951b+zr8bN27ktNNOY8iQIdxxxx0MHz6cgQMHJozr3nvvZdKkSTRq1Gj37bZHH30UgLlz5/Lpp5/StWtXPv/8cwDee+89PvnkE+rUqcPUqVP5y1/+snt/sGHDhpGdnc3MmTPZunUr7du3p2vXrnz44Yd89tlnzJ07l2+//ZZjjz2Wvn37lvjnl52dzUMPPcSUKVOoV69ekepLxP/py1Bffx0S1fffw/HHh9fxf0mdq2gK6wH17h1u/R188J6ydeugQYOwK3ZxtWnThttuu43f/va39OjRg0MPPZR58+bRpUsXAHbu3EnDhg0BmDdvHgMHDuSHH35gw4YNnHvuuTHx9SYrukf/xhtvMHr06N3HDj30UACqV6++exuUk046icmTJxcYV/v27enTpw+XXHIJF110EQAzZszYnRyPPvpomjZtujtZ5e82nMjrr7/OJ598svt5VF5eHosWLWL69OlcdtllZGVlcfjhh3P22WcX8ae378+vQ4cORa6jMJ6sikBSC2AAkG1mF5d2/dOmwdCh8Pnn4S/gj34EHTuGgRWeqJyD/v3DMyqAgw6CDRvCs9z+/UtW75FHHsns2bOZMGECd911F126dOG4447jvffe2+fcPn368PLLL3PCCScwatSo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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plot_timing_test(ns, ts, 'search_sorted_list', exp=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Nope, looks like it's not constant time, either. We can't really conclude that it's `log n` based on this curve alone, but the results are certainly consistent with that theory." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Dictionary methods\n", "\n", "**Exercise:** Write methods called `add_dict` and `lookup_dict`, based on `append_list` and `pop_left_list`. What is the order of growth for adding and looking up elements in a dictionary?" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024 0.0\n", "2048 0.0\n", "4096 0.0\n", "8192 0.0\n", "16384 0.010000000000001563\n", "32768 0.0\n", "65536 0.00999999999999801\n", "131072 0.010000000000001563\n", "262144 0.019999999999999574\n", "524288 0.05000000000000071\n", "1048576 0.13000000000000256\n", "2097152 0.2099999999999973\n", "4194304 0.4299999999999997\n", "8388608 0.7699999999999996\n", "16777216 1.6000000000000014\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Solution\n", "\n", "def add_dict(n):\n", " d = {}\n", " for i in range(n):\n", " d[i] = 1\n", " return d\n", "\n", "ns, ts = run_timing_test(add_dict)\n", "plot_timing_test(ns, ts, 'add_dict', exp=1)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024 0.0\n", "2048 0.0\n", "4096 0.0\n", "8192 0.010000000000001563\n", "16384 0.0\n", "32768 0.0\n", "65536 0.019999999999999574\n", "131072 0.019999999999999574\n", "262144 0.05999999999999872\n", "524288 0.07000000000000028\n", "1048576 0.16999999999999815\n", "2097152 0.33999999999999986\n", "4194304 0.6799999999999997\n", "8388608 1.3500000000000014\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYwAAAEKCAYAAAAB0GKPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nO3deXxcdbn48c8zk6TZumdr0y1t0jVNS0nhlgJFEMQrm0rRioKircimiGUT5V4FQRGvlFqwP1BEULkIXK1Wlis2CO3F7knbdF/Tluxt9m3m+f1xJmmaJs2kzWQmM8/79eprMmfOnPMkp5kn3/P9fp+vqCrGGGNMd1zBDsAYY0z/YAnDGGOMXyxhGGOM8YslDGOMMX6xhGGMMcYvljCMMcb4JSrYAQRCUlKSjhs3LthhGGNMv7J+/foyVU3u6vWwTBjjxo1j3bp1wQ7DGGP6FRE5cLrX7ZaUMcYYv1jCMMYY4xdLGMYYY/wSln0YnWlubqaoqIiGhoZghxIRYmNjGTVqFNHR0cEOxRjTSyImYRQVFTFw4EDGjRuHiAQ7nLCmqpSXl1NUVERGRkawwzEm7OXlwdKlsG8fZGTAHXfAvHm9f56IuSXV0NDA8OHDLVn0ARFh+PDh1pozpg/k5cE990BJCaSmOo/33ONs720RkzAASxZ9yH7WxvSNpUshIQGghV27lPh45/nSpb1/rohKGAauvPJKhgwZwlVXXRXsUIwxvWDPHqW4uIH8/BYqKjwcOQKJic7tqd5mCSPCLF68mN/+9rfBDsMY0wsKCqCyEo4ccT7Khw9vIT0damqcvozeZgmjD7300kucd955zJw5k69//et4PB4OHDhAVlYWZWVleL1eLrroIt5++23279/P5MmTufnmm8nJyeH666+nrq7urGO47LLLGDhwYC98N8aYYDl+vIWnnvLw4IOQlibExEQxbpybzMxYamuhttbp+O5tETNKqqO//OUvXb42ffp0xo4dC8CBAwcoKCjocl9/b+0UFhbyyiuv8MEHHxAdHc1tt93Gyy+/zE033cR9993Hrbfeyvnnn8/UqVO54oor2L9/Pzt27OD5559n7ty53HLLLSxbtozvfOc7Jx33iSee4OWXXz7lfBdffDFLlizxKzZjTP+xcmUlP/95A01NiQwdOpC77oLUVBfPPOMK+CipiE0Yfe3vf/8769evZ/bs2QDU19eTkpICwNe+9jVeffVVnn32WTZt2tT2ntGjRzN37lwAvvjFL7JkyZJTEsbixYtZvHhxH30Xxphg+eijJh59tIwPP3QDLiZMOM7jjycwdqxzo+jSSwMfQ8QmDH9bBmPHjm1rbZwNVeXmm2/mscceO+W1uro6ioqKAKipqWm7ZdRxpFFnI4+shWFMeFOFV14p59lnm6mrcxMT4+Wmm5SvfnUkbnff9iqEfMIQkQRgGdAErFLVUz8d+4HLLruMa6+9lrvvvpuUlBQqKiqorq5m7Nix3Hfffdx4442MHTuWhQsXtt0uO3jwIGvWrGHOnDn8/ve/58ILLzzluNbCMCZ8FRV5+P73S9iyxQUIOTmNfPe7w8jISAxKPEHp9BaRX4lIiYhs6bD9ShHZISK7ReR+3+bPAH9U1YXANX0ebC+ZOnUqjzzyCFdccQU5OTlcfvnlHD16lLy8PNauXduWNGJiYvj1r38NwJQpU/jNb35DTk4OFRUVfOMb3zjrOC666CLmz5/P3//+d0aNGsVbb7111sc0xvQujwdeew2++U03u3fHkZDg4Z57vCxfPjpoyQJAVLXvTypyMVADvKiq2b5tbmAncDlQBKwFFgDXAn9T1U0i8jtV/UJ3x8/NzdWO62EUFhYyZcqU3v1GAmj//v1cddVVbNmypfudQ1R/+5kbEwq2bq1n6VI3RUUxAFx0UQs339xMampcwM8tIutVNber14NyS0pV3xORcR02nwfsVtW9ACLyB5xkUQSMAjZxmhaRiCwCFgGMGTOm94M2xpgAamxUliwp4/XXvYhEMXnyMG6/XTj33ChCpfcglOZhpAOH2j0v8m17HfisiDwDrOjqzaq6XFVzVTU3ObnLFQb7jXHjxvXr1oUxxn9r1tQyf34xr77qxetVLr20hqeeauHcc4Md2clCI205Ois+pKpaC3ylr4MxxphAq6ry8sQTZbz9tqIqjBjRyOLFcVx44dmPzAyEUEoYRcDods9HAUd6cgARuRq4OjMzszfjMsaYXvfBB8ojj5RRXq643cp11zVy110jiYsL3TVkQilhrAWyRCQDOAx8Hui2g7s9VV0BrMjNzV0YgPiMMeasVVTAs8/CmjVCc3MiGRmlPPjgQGbMSAt2aN0KSsIQkd8DlwBJIlIEPKyqz4vIHcBbgBv4lapuDUZ8xhjT21Thj3+s4qWXovB644mNha9/PY5PfCKd6OhQ+tu9a8EaJbWgi+0rgZVnely7JWWMCUUHD7bwgx9UkJ+viAhXXBHFN78ZQ1KSEFo3ek4vlEZJnTVVXaGqiwYPHnzWx8rLg/nzITfXeeyN1asSE89sws2qVav6bP2K9uf685//zOOPP97lvseOHWPZsmV9Epcx/VFLCzz//HFuvNFJFgkJLdx5ZwMPP+wmKSnY0fVc/0ltfah1ycOEhJOXPHzyycBUgAxV11xzDddc0/Xk+taEcdttt/VhVMaErvZraw8f7qGlpYrq6iYAzj+/hvvvTyY9fVCQozxzEZkwrr769K+vXw+NjRDV7qfT0gILFnDacdErupwlcjJV5d577+Vvf/sbIsJDDz3E5z73uS63t7d27VoWLVrEa6+9xosvvkhiYmJbBdvs7Oy2OlRXXnkl559/Phs3bmTixIm8+OKLxMfHdxrPm2++ybe+9S2SkpKYNWtW2/YXXniBdevWsXTpUoqLi7n11lvZu3cvAM888wxLlixhz549zJw5k8svv5wnnnjCvx+AMWGo9Q/NuDhobob/+z8vLS2JTJlSyfe/38hVV2XgcvXvmzphlTB6qw+jrg5iYk7e5nY723vD66+/zqZNm9i8eTNlZWXMnj2biy++mNWrV3e6vdXq1au58847+dOf/tTtbHZ/1tIAaGhoYOHChbz77rtkZmaekqBa3XXXXcybN4833ngDj8dDTU0Njz/+OFu2bDmpJLsxkWrpUqdj++BBaGiAAQPcDB7cwMiRQ7nmmtAdKtsTYZUw/B1W211LYP585zbUoHYtx6oqSEmBV189+zjff/99FixYgNvtJjU1lXnz5rF27doutw8aNIjCwkIWLVrE22+/zciRI7s9hz9raQBs376djIwMsrKy2vZdvnz5Kfu9++67vPjiiwC43W4GDx5MZWXl2fwYjAkbNTXKBx94aGhQoqOjiI8XMjJcxMXFc6RHs8lCW/9uHwXIHXc4SxxWVYHX6zz25pKHXRV8PF0hyBEjRhAbG8vGjRvbtkVFReH1etueNzQ0tH3tz1oa/rxmjDm9vLx6brihjIaGFlpavKSltTBtmtMHGqi1tYPFEkYn5s1zOrhTUqC42HnszQ7viy++mFdeeQWPx0NpaSnvvfce5513XpfbAYYMGcJf//pXHnzwQVatWgU49aY2bNgAwIYNG9i3b1/bOVrX0gC6XEsDYPLkyezbt489e/a07duZyy67jGeeeQYAj8dDVVUVAwcOpLq6+ux/IMb0Q8eOKfffX86991ZTVuZl+vRK0tOFIUOiUO39PzRDgSWMLsyb59x+WrfOeezN0VGf/vSnycnJYcaMGVx66aX85Cc/IS0trcvtrVJTU1mxYgW33347H374IZ/97GepqKhg5syZPPPMM0ycOLFtX3/X0oiNjWX58uV86lOf4sILL+xydcGnnnqKf/zjH0yfPp1zzz2XrVu3Mnz4cObOnUt2drYt4mQihir87W91zJ9fyrvvthAV5eHzn6/hzTeH8eyzMaSkSED+0AwFQVkPI1DadXov3LVr10mvRdLaDKGylkYk/cxNZCgrg2XL4N13q6mrqyMrq477709k+vT+XyEbQnQ9jECxWlLGmEBQhZUrPfzmN27q6yE1NYErrqjkS18aRUxMeIyA8kdYJQzj6GotjU9/+tMn9XMA/PjHP+YTn/hEX4VmTL9TVOThBz+opKBAGTZsOHPmuLjtNhfDhkXeQm0RlTBUNaJHBL3xxht9dq5wutVpIpPHAy+/XM1zz9XT0KAkJDSzcGEF116bRKR+jERMwoiNjaW8vJzhw4dHdNLoC6pKeXk5sbGxwQ7FmDOya1czP/zhcbZv9wAwe3YN9903jDFjhgY5suAKq4Rxupneo0aNoqioiNLS0r4PLALFxsYyatSoYIdhTI80N8Nzz1Xx0ksNNDcrgwc38Y1veLnuuv5f1qM3hNUoqVa5ubm6bt26YIdhjOlHduyAp56C3bsbOXbsGBddVM3ixSmkpfXfYoE9FVGjpIwxpqfq65XnnqvnnXfiUYWMjAEsWOBm3rwJdvu6A0sYxpiI9eGHDfzoR9UcPeolKSmKz30uhgULICamHy5W0QcsYRhjIk5NjfLkk5WsXNmCqjJiRAP33XeMCy5ICXZoIc0ShjEmoqxaVc9PflJNWZniditXX13DnXemM3BgXLBDC3lhlTBsTW9jTFeOHYOf/rSad96pQxXGjq3n3ntjyc21vgp/hdU4sd5c09sYEx5U4R//gNtug40b44mJUb7whRp++9uRzJ6dZsmiB8KqhWGMMXBibe2dO5W6umaSkqJJShJmzXKzcOEQxoxJ6/4g5hSWMIwxYSUvD779baira6G42ENzs1BS4uXhh93cfTeIWAWCMxVWt6SMMeYnP/Fy+HAzR4968Hph6NBmJk3ysmYNEVsDqrdYC8MYExY8HnjxxSreey8Ol8tLdLSX0aOV9PR4VIUOhZrNGbCEYYzp9/btg8cfr2fjxnqio2OIi/MyZUo0cXHOWhXV1eG1tnawWMIwxvRbTU3wyivw2mvg8cSSklLNNdcc5403UmhuFgYMgJqa8FtbO1jCKmHYPAxjIsfmzU088kgVtbVDiYpyc/XVwhe/mEx8vHDRRc4oqX37nJbFHXeE19rawWLVao0x/Up9vbJkyTHeeKMZr1cZPVp45JEUbPn4s2fVao0xYWPNmgYee6yajz7y4nIpn/xkDXffPZIhQ4IdWWSwhGGMCXnV1coTT1Ty1ltOscCRIxv4zneimTvXynr0JUsYxpiQtno1LF3awu7dzURFebn22jpuvz2dxESbgNfXLGEYY0JSRYXyy18Kq1cDRHPOOTEsWtTIrFnjrVURJJYwjDEhRRVWrKhlyZJaRAYxZEgsX/kKfPKTQ22mdpBZwjDGhIyjRz088kgla9d6AMjOLuGxx0aTmmqZIhRYwjDGBJ0q/OEPNfzyl3XU1SlxcS3cfHMTX/rSaKKjLVmECksYxpigOnDAw3/+ZyVbtjitipkza3jggWFkZKQHOTLTkSUMY0xQtLTA66/D734nFBdDYmIzCxe2cMMN43C73cEOz3SiRwlDRBKABlX1BCgeY0wEKCxsYtmyKPbvdwEurrkmjptuiiY93VbLDGWnTRgi4gI+D9wIzAYagQEiUgqsBJar6q6AR+knqyVlTGhraoJnnjnGK680ER0dS2bmIO68E2bOTAh2aMYP3S2g9A9gAvAAkKaqo1U1BbgI+D/gcRH5YoBj9Jut6W1M6Nq0qYkFC0p5+eVGPB4vc+aU8PTTXmbODHZkxl/d3ZL6uKo2d9yoqhXAa8BrIhIdkMiMMf1a67rau3crLS3NtLTUMnCgl5SUBr71LTeXXWZlPfqb0yaM1mQhIhOAIlVtFJFLgBzgRVU91llCMcZEtrw8uOceUFUOH26ivl7wehO44YZafv7zZAYPjg92iOYM+Lum92uAR0QygeeBDOB3AYvKGNOvLV0K9fVw+LDg8bhITGxh4kSlpibdkkU/5u8oKa+qtojIp4Gfq+rTIrIxkIEZY/qnysoa1qyJp6nJhQiMGeNmxAgXIm5bV7uf87eF0SwiC4Cbgb/4tlnfhTGmjdfrZePGvSxcWEx9vbO4UWYmjBrlwu12U1Nj62r3d/62ML4C3Ao8qqr7RCQDeClwYRlj+pPjx4/z5pvbef75ERw7NoBJkxqpqoomKkrwem1d7XDhV8JQ1W3AXe2e7wMeD1RQxpj+wePxsGvXLlauLOP118fj8URz7rkJPPpoPAUFtq52uOlu4l4B0OWi36qa0+sRGWP6BVVl9eo1rFwZy7vvZhIXF8/VVydw991uYmKc5GAJIrx018K4yvd4u+/xt77HG4G6gERkjOkXWlqEd96ZRl6eh6FDB3HLLTHMn4+tWRHGupuHcQBAROaq6tx2L90vIh8APwhkcMaY0FJSUkJjYyMDB47m0Udh+/YhjBgB99wjXHBBsKMzgeZvp3eCiFyoqu8DiMgFgBV/MSZCNDU1sW3bNoqKiigpSWDVqhFUVkaRlCR873swfnywIzR9wd+E8VXgVyLSWqTpGHBLYEIyxoSSo0ePsmXLFhobG9m5cxjvvJOD2+1m8mT47ndh6NBgR2j6ir+jpNYDM0RkECCqejywYRljgq2hoYEtW7bw0UcfoQqbN2fxwQcTiIqK4mMfc0Y9xcQEO0rTl/xKGCIyAPgsMA6Iai0YpqrWh2FMmNq8eTOlpaV4vVF8+OF55OcPJTpauOkm+OxnrXM7Evl7S+pPwHFgPc6aGH1GRMYD3wUGq+r1fXluYyLZ1KlT+de/drFixXT27IkmNha+8x04//xgR2aCxd+EMUpVr+zpwUXkVzhDc0tUNbvd9iuBpwA38JyqdjkJUFX3Al8VkT/29PzGGP+oKvv376eyspJzzjkHEaG0dCAvvTSLsjJITobvfc9Ke0Q6fxPGahGZrqoFPTz+C8BS4MXWDSLiBn4BXA4UAWtF5M84yeOxDu+/RVVLenhOY0wPVFdXk5+fT2VlJQBjx45lx47h/Oxn0NgIU6bAgw/CkCFBDtQEnb8J40LgyyKyD+eWlADa3UxvVX1PRMZ12HwesNvXckBE/gBcq6qPcWKioDEmwLxeL3v27GHXrl14vV4GDBhAdvZ0/vd/h/OSr1LcpZc6ndvRVmrU4H/C+GQvnjMdONTueRHQ5V1RERkOPAqcIyIP+BJLZ/stAhYBjBkzpveiNSYMHTt2jPz8fKqqqgAYPXo0mZlTWbYsmvfeczq0v/xl+PSnrXPbnODvsNoDIjIDZy1vgH+q6uYzPGdn//1OV6+qHKdS7mmp6nJgOUBubm6XxzPGOHMrqqqqiI+PJycnB5crie99D3btgthYWLwYzjsv2FGaUOPvsNpvAguB132bXhKR5ar69BmcswgY3e75KODIGRzHGNMDzc3NRPvuLU2cOJGoqCgyMjLYvz+KRx6B8nJISXE6t8eNC26sJjT1ZKb3+apaCyAiPwbWAGeSMNYCWb41NQ4Dnwe+cAbHOYWIXA1cnZmZ2RuHMyYstLS0UFhYSHFxMfPmzSM6Ohq3201WVhbvvw//9V/Q1ATTpsEDD8Dgwd0f00Qmf1fcE8DT7rmHzm8tnfwmkd/jJJZJIlIkIl9V1RbgDuAtoBD4b1Xd2rOwO6eqK1R10WD7H28M4BQLXLVqFQcOHKCxsZHy8nIAVOH3v4cf/9hJFh//ODzyiCULc3r+tjB+DXwoIm/4nl8HPN/dm1R1QRfbVwIr/Ty3MaaHmpqa2Lp1K4cPHwZg8ODBzJgxg0GDBtHYCD//Obz/vtOh/ZWvwHXXWee26Z6/nd4/E5FVOMNrBfiKqm4MZGBnwm5JGQPFxcVs3ryZpqYmXC4XkyZNIiMjA5fLRXk5PPqo07kdFwf33gu5ucGO2PQX/nZ6/xuwVVU3+J4PFJHzVfXDgEbXQ6q6AliRm5u7MNixGBMsLpeLpqYmhg0bxowZM1i3LoH774fCQqiuhpEjnf6K738fbAS66Ql/+zCeAWraPa/1bTPGBJmqts3SBkhOTubf/u3fmDNnDuvWJfDtb8POnVBWBjU1zhrbn/mMJQvTc/72YYiqts1tUFWviPj7XmNMgNTW1pKfn09JSTlZWXOprx/KkSNw5EgSR47Aiy9CVRVE+X5bR4yAYcPg17+Gf//34MZu+h9/P/T3ishdnGhV3AbsDUxIZ876MEw483qhtBSOHIHDh5X8/DK2bTtGWdlIqqomkJgYz4ABJ7+nshIGDHD+paVBaqpznH37gvM9mP7N34RxK7AEeAhnVvbf8ZXhCCXWh2FCVV4eLF3qfFBnZDj1mebNO3U/1RNJ4cgROHr0xNcffQQtLc68iqqqKpqbvcAgYmNjGTo0kZQUNyNHctK/H/zAaWG0LxxYU2NVZ82Z8XeUVAnOBDtjTA/l5cE990BCgvMXfkkJ3HUXfPObzod6a0JoTQrNzV0fKy6uDtUjjBnTQFqal/POG0V29mBGjOh89bt773XO7XJBYqKTLGprnYRlTE9Ju66JrncSmYhzOypVVbNFJAe4RlUfCXSAZyI3N1fXrVsX7DCMAWD+fCdJNDSceGxqcm4TnXvuqfsPHcopLYURI5x/Io3k5eWRlpbGlClT2kp9nI6/rRtjRGS9qnY50NrfhJEHLAZ+qarn+LZtab8oUiho14excNeuXcEOxxjgxDyHQ+1qNEdFgccD999/amKIizuxn8fjYf/+/W3zKMCZlBdji2mbAOguYfjbhxGvqv+Sk6eCtpxVZAFgfRgmFMXFwbZtTpIYOxaSkpzbQikp8K1vdf2+srIy8vPzqaurw+v1kpWVBWDJwgSNvwmjTEQm4CtDLiLXA0cDFpUxYeKdd5yOao/HaUEkJ3ffj9Dc3ExhYSEHDx4EYODAgSQnJ/dh1MZ0zt+EcTvOWhOTReQwsA/4YsCiMiYM/OMf8PTTToti8WLYtKn7foTi4mIKCgpoaGhARMjKyiIzM7PtdpQxweTvKKm9wMdFJAFwqWp1YMMypn/75z+dsuGqcPPNcP313b+ntLSUtWvXAjBkyBBmzJjBwIEDAxypMf7z688WEfmmiAwC6oD/EpENInJFYEPrORG5WkSWHz9+PNihmAi2Zg389KdOsrjxRv+SBUBSUhIpKSlMnTqVuXPnWrIwIcffdu4tqloFXAGkAF8BHg9YVGfI1sMwwbZ2LfzkJ85s6vnz4XOf63rf+vp61q9fT11dHQAiwuzZsxk/fjxitcZNCPK7lpTv8d+BX6vqZrH/0cacZONGeOwxp5P7uuvgS1/qfI0JVeXgwYMUFhbS0tKCqpLrG3trv1YmlPmbMNaLyNtABvCAiAwEvIELy5j+paDAWbGuuRk+9Sm45ZbOk0VrscDWle9SU1PJzg6p6UzGdKkna3rPBPaqap2IDMe5LWVMxCssdGo2NTXBFVfA179+arLwer3s27ePHTt24PV6iYmJITs7mxEjRlirwvQbp00YIjJOVferqhfY0LpdVcuBct9tqXRVLQpwnMaEpJ074eGHnXIfl17qDJft7PO/rq6O7du3o6qkp6czbdo0m4Bn+p3uWhhPiIgL+BOwHigFYoFM4GPAZcDDgCUME3H27nVWrauvh4svdooJtk8WXq8XEUFESExMZOrUqcTHx5Oamhq8oI05C6dNGKo6X0SmAjcCtwAjcIbWFgIrgUdVtSHgUfrJ1sMwfWX/fnjoIWfG9pw5cPfdTkXYVpWVleTn55OVlcXIkSMByLCa4qaf86v4YH9j1WpNIBUVOUUDjx+H2bPhwQdPrGjX0tLCjh072OdboWjo0KFccMEF1k9h+oXeKj5ojMFZ0Oi733WSxTnnOImjNVm0LxYoIowfP56JEydasjBhwxKGMX4qKXFaExUVkJPjJI6YGKdVsXXrVg756pcPGjSInJwchrRf5s6YMGAJwxg/lJXBAw84j1OmwPe+R9v62SJCeXk5LpeLrKwsJkyYYMUCTVjyK2H4hs/eCIxX1R+IyBggTVX/FdDojAkBFRVOy6KkBCZNgv/4D2flu+ZmF9HR0bjdbmbNmoXb7bb6Tyas+ftn0DJgDrDA97wa+EVAIjImhBw/7oyGOnoUJkyA//gPpaKiiFWrVlFYWNi235AhQyxZmLDn7y2p81V1lohsBFDVShGxWUcmrFVXO8ni0CEYNw4efLCebdsKKCkpAWhbCc9uP5lI4W/CaBYRNydW3EsmBGtJ2TwM01tqa51ksX8/jBqlLFx4kA0bnGKB0dHRTJ06lVGjRtkIKBNR/P3TaAnwBpAiIo8C7wM/ClhUZ8jKm5veUFfnzODeuxfS0rxce+1aDh4soKWlhbS0NObNm8fo0aMtWZiI4++Key+LyHqcUiACXKeqhd28zZh+p6HB6dTeuRNSU+Gxx1wcOhRNWdmAtmKBxkSqngyrLQb+6XtPnIjMUtUN3bzHmH6jsdGpOltQ0MywYcqPfhRDUhIMGjQNwIoFmojn77DaHwJfBvbg68fwPV4amLCM6VtNTfDDH3pZs6YOl+sYn/nMQYYPPx9wW6IwxsffFsYNwARVbQpkMMYEQ0sLPPxwPXl5tQwY0MCXvrSdSZPSgh2WMSHH34SxBRgClAQwFmP6XENDC/fdV86aNRAX18KiRQf5xCdmMWzYsGCHZkzI8TdhPAZsFJEtQGPrRlW9JiBRGdMHPB7l7rsPsX59PLGxHh56qIFLLz0ft9sd7NCMCUn+JozfAD8GCgjB+RfG9JQqLFki7NqVRkJCDU8+Gc+sWSODHZYxIc3fhFGmqksCGomJGHl5sHQp7NsHGRnOsqbz5vXNuV9/vZznnotly5YEWlogKyuWZcsGMG2azdY2pjv+Joz1IvIY8GdOviVlw2pNj+Tlwbe+5axO53JBYSF89atwyy2QnR248zY1NfHuuyW88cZQVJ3bUapCWZnzzxjTPX8Txjm+x39rt82G1ZputbTAgQOwY4fzb+lSOHbsxKJDrfssXQrnnhuICJSGhgaqq6vZuTOJlhYXMTFuoqNh4kRnj6VL+66FY0x/5u9M748FOpDeYLWkgksVystPJIcdO2D3bmeOQ6vycoiNhcREiIsDEed9VVVw9dW9G09TUyOHDx+muroGgAMHBjNypBu3282wYU4MXq9za8wY073TJgwR+aKqviQi3+7sdVX9WWDCOjOqugJYkZubuzDYsUSChvf1dzsAABUESURBVAYnIbRPEBUVp+43cqSzjsTEiU5rorYW2pf7qqqCyZNh0aLeje/DDzcxblwp0dHRTJs2jeLiGEpKhEGDTuxTU+P0oxhjutddCyPB99hZoX/tZJsJU6pQVHRycti/39neXkLCieQwebLz2H6ZiIED4Z57nJZFYqLzgV1b63R8906c2lYUcNq0aezcuZNp06YxYMAA7rjDOTcE5tzGhDvRjr/xne0kMldVP+huW6jIzc3VdevWBTuMfu34cacA3/btzuPOnU4V1/ZcLuev80mTTvwbOdJJBqcTiFFSXq+XvXv3UllZSW5ubpeVZIM5QsuYUCci61U1t8vX/UwYG1R1VnfbQoUljJ5pbnZKebe2HHbuhI8+OnW/pKSTk8OECSfWtQ6m48ePs3nzZqqqqgC44IILbKa2MWegu4TRXR/GHOACILlDP8YgwKbD9kOqUFx8cnLYs8fpW2hvwADIyjo5QYTaZ7DH42HXrl3s2bMHVSUuLo6cnBxLFsYESHd9GDFAom+/9v0YVcD1gQrK9J7aWti16+QEcfz4yfuIwOjRJyeHMWMglCtkVFRUsHnzZmprawHIyMhg0qRJREX1pGK/MaYnTvvbpap5QJ6IvKCqB/ooJnOGPB44ePDkjumiolM7pgcPPrlTOivL6azuT0pLS6mtrSUxMZEZM2YwdOjQYIdkTNjz98+xASKyHBjX/j2qahP3gqii4kSn9I4dTkuisfHkfaKinL6G9gkiNbX7julQ1NTU1LY2RWZmJtHR0YwdO9aKBRrTR/xNGK8CzwLPAZ7AhWO60tjozHloP3KprOzU/dLSTk4O48dDdHTfx9ubmpqa2LZtG6WlpcybN4+YmBjcbjfjx48PdmjGRBR/E0aLqj4T0EhMG1U4fPhEn8P27c6cB2+HOsHx8U5SaO13mDjx5Alx4eDIkSNs2bKFpqYmXC4Xx44dIyUlJdhhGROR/E0YK0TkNuANTi4+2Mm8XtNT1dUn9zvs3Ol0Vrcncuqch1Gj+uetJX80NDSwZcsWPvKN7x02bBg5OTkkJiYGOTJjIpe/CeNm3+PidtsUsHsCPdTS4kwaa58gjh49db9hw05ODpmZTg2mSHD06FHy8/Npbm4mKiqKKVOmMGbMmC4n4xlj+oa/xQet2s4ZUIXS0pOTw549zkS59mJinITQPkEMHx6+rYfuREdH09zcTHJyMjk5OcTFxQU7JGMMfiYMEbmps+2q+mLvhtO/1dc7I5Xaj1w6duzU/dLTT3RKT5oEY8eeXO470qgq5eXlJCUlAZCUlMTcuXMZMmSItSqMCSH+fkzNbvd1LHAZsAGI2ITh9TpzHtqPWjp48NQ5DwMHnjxqaeJEp/CdcVRXV5Ofn09lZSVz5sxh+PDhADavwpgQ5O8tqTvbPxeRwcBvAxJRByJyHfApIAX4haq+HYjzdFeUrrLy1GJ8DQ0nH8Ptdoaxtq/WmpYWubeWTsfr9bJnzx527dqF1+tlwIABeDsOAzPGhJQzvRFSB2R1t5OI/Aq4CihR1ex2268EnsKpR/Wcqj7e1TFU9X+A/xGRocBPgV5PGHl5TtnrhARnUttHH8Ftt8GCBc4chh07nL6IjlJSTh7SOmGC0x9hTu/YsWNs3ryZ6upqAMaMGcOUKVOI7u8TRowJc/72YazgxPoXLmAqzmS+7rwALKXdrSsRcQO/AC4HioC1IvJnnOTxWIf336KqJb6vH/K9r9ctXeqMQKqshEOHnDLezc2wbNmJZUNjY0+d82B3TXruyJEjbNy4EVUlPj6enJyctr4LY0xo87eF8dN2X7cAB1S1qLs3qep7IjKuw+bzgN2quhdARP4AXKuqj+G0Rk4iTq/n48DfVHVDV+cSkUXAInD+Yu2Jffuc1sLevU49JhGn78HrhTvvdBLE6NHO+g/m7CQlJRETE0N6ejoTJ060YoHG9CP+9mHktX8uIm4RuVFVXz6Dc6YDh9o9LwLOP83+dwIfBwaLSKaqPttFjMuB5eCsh9GTgDIyoKQExo1zbkElJDgT51JS4IorenIk01FzczP79u0jMzMTl8tFTEwMl1xyid1+MqYfOu3fzCIySEQeEJGlInKFOO4A9gI3nOE5O+sC7vIDXlWXqOq5qnprV8nibN1xh5MgoqOdEUy1tbZ0Z28oLi4mLy+PnTt3snv37rbtliyM6Z+6u8nyW2ASUAB8DafDeT7OLaRrz/CcRcDods9HAUfO8FgnEZGrRWT58Y4LPnRj3jx48kmnRVFc7Dw++aQt3Xmmmpqa2LhxI2vXrqWhoYHBgweTlpYW7LCMMWfptEu0ikiBqk73fe0GyoAxqlrt9wmcPoy/tI6SEpEoYCfOXI7DwFrgC6q69Qy/h1PYEq3BoaocPXr0pGKBkyZNYvz48TYBz5h+4KyWaAXailioqkdE9vUwWfweuARIEpEi4GFVfd53W+stnJFRv+rNZGGCp7S0lA0bnHEJw4cPJycnh4T+tjKTMaZL3SWMGSJS5ftagDjfcwFUVQed7s2quqCL7SuBlT0N1oS25ORk0tLSSE5OtmKBxoSh7pZo7VdLmYnI1cDVmZmZwQ4lItTW1rJ161amTZtGQkICIkJubpetWWNMPxdWMwtUdYWqLhocbqsIhRhVZe/eveTl5VFSUkJhYWGwQzLG9AGbNWV6pLq6ms2bN3PMV4Z35MiRZGdnd/MuY0w4sIRh/OL1etm9eze7du1CVYmNjWX69OmkpqYGOzRjTB8Jq4RhfRiBU1dXx+7du1FVxo4dy+TJk20CnjER5rTzMPorm4fROzweDy6Xq22004EDB0hISLBigcaEqe7mYYRVp7fpPWVlZeTl5XH48OG2bWPHjrVkYUwEC6tbUubsNTc3U1hYyMGDBwE4dOgQ6enpNqfCGBNeCcP6MM5OcXExBQUFNDQ0ICJkZWWRmZlpycIYA4RZwlDVFcCK3NzchcGOpT9pbm6moKCAI0ecGpBDhgxhxowZDBw4MMiRGWNCSVglDHNmXC4XVVVVuN1uJk2aREZGhrUqjDGnsIQRoerr63G73cTExOB2uznnnHOIioqyYoHGmC5ZwogwqsrBgwcpLCxkxIgRzJgxAwArp2KM6U5YJQzr9D692tpa8vPzKS8vB5yFjrxeLy5brNwY44ewShjW6d05r9fLvn372LFjB16vl5iYGLKzsxkxYoT1VRhj/BZWCcOcyuPxsHr1alqXrU1PT2fatGnExMQEOTJjTH9jCSPMud1uBg0aRGNjIzk5OaSkpAQ7JGNMP2UJIwxVVlYCMHToUACmTp0KYMUCjTFnxRJGGGlpaWHHjh3s27ePhIQELr74YtxutyUKY0yvCKuEEcmjpMrKysjPz6eurg4RIS0tLdghGWPCTFgljEgcJdXc3My2bds4dOgQAIMGDSInJ4chQ4YEOTJjTLgJq4QRaVSV1atXU11djcvlIisriwkTJti8CmNMQFjC6MdEhAkTJnDgwAFycnKsWKAxJqAsYfQjqsrhw4dpbm4mIyMDcOZV2HoVxpi+YAmjn6ivryc/P5/S0lJcLhepqanEx8dbojDG9BlLGCFOVTlw4ACFhYV4PB6io6OZOnUqcXFxwQ7NGBNhLGGEsJqaGvLz86moqAAgLS2N7OxsYmNjgxyZMSYSWcIIYVu3bqWiooIBAwa0FQs0xphgCauEEQ4T91S1rV8iOzub3bt3M2XKFCsWaIwJurAasK+qK1R1UX9cDMjj8bB9+3b+9a9/oaoAJCQkMGPGDEsWxpiQEFYtjP6qoqKC/Px8ampqADh27Fhb4UBjjAkVljCCqKWlhe3bt7N//37gRIvCkoUxJhRZwgiS0tJS8vPzqa+vb5uxnZWVhdvtDnZoxhjTKUsYQVJZWUl9fT2DBg1ixowZ9Md+F2NMZLGE0YcaGhra5lBkZmYyYMAARo8ebcUCjTH9gn1S9YGGhgbWrVvHe++9R2NjIwAul4uxY8dasjDG9BvWwgggVaWoqIht27bR3NyM2+2mqqqK5OTkYIdmjDE9ZgkjQOrq6igoKKC0tBSA5ORkpk+fTnx8fJAjM8aYM2MJIwAOHz5Mfn5+W7HAadOmWQlyY0y/F1YJI1RKg8TGxuLxeBgxYgTZ2dkMGDAgqPEYY0xvkNYyFOEkNzdX161b12fn83q9lJaWkpqa2ratqqqKQYMG9VkMxhhztkRkvarmdvW6DdE5S8ePH+f9999n7dq1lJWVtW23ZGGMCTdhdUuqL3k8Hnbu3MnevXtRVeLi4qyPwhgT1ixhnIGKigo2b95MbW0tABkZGUyaNImoKPtxGmPCl33C9VBRURGbNm0CIDEx0YoFGmMihiWMHkpJSSE2NpbRo0eTmZlpxQKNMRHDEkY3mpqa2LNnDxMnTsTtdhMTE8PHPvYxSxTGmIhjCaMLqsrRo0fZsmULTU1NuFwuJk2aBGDJwhgTkSxhdKKhoYGCggKKi4sBGDZsGOnp6UGOyhhjgssSRjuqyqFDh9i2bRstLS1ERUUxZcoUxowZY0NmjTERzxJGO62r4IHTuT19+nTi4uKCHJUxxoQGSxjtJCcnk56eTkpKCiNHjrRWhTHGtGMJox0R4Zxzzgl2GMYYE5KslpQxxhi/WMIwxhjjF0sYxhhj/BLyCUNEpojIsyLyRxH5RrDjMcaYSBXQhCEivxKREhHZ0mH7lSKyQ0R2i8j9pzuGqhaq6q3ADUCXC3sYY4wJrEC3MF4Army/QUTcwC+ATwJTgQUiMlVEpovIXzr8S/G95xrgfeDvAY7XGGNMFwI6rFZV3xORcR02nwfsVtW9ACLyB+BaVX0MuKqL4/wZ+LOI/BX4XWf7iMgiYBHAmDFjeiV+Y4wxJwRjHkY6cKjd8yLg/K52FpFLgM8AA4CVXe2nqsuB5eCs6d0bgRpjjDkhGAmjs+nTXX7Aq+oqYFVPTrB+/foyETkGHO9il8FdvNbZ9s62JQFl9L2u4u6L4/jznu72Od3rdk0Cc0382a8nP/uutts16dl7QvWajD3Na07BvUD+A8YBW9o9nwO81e75A8ADATjv8p6+1tn2LratC/TPraffU6CP4897utvHrknfX5OzuS52TeyadPwXjGG1a4EsEckQkRjg88CfA3CeFWfwWmfbT3ecvtZbsZzJcfx5T3f72DXp3eP4+54zvS52TQL3nn55TcSXdQJCRH4PXILTDCoGHlbV50Xk34GfA27gV6r6aMCCCAARWaeqNsQ3hNg1CT12TULP2V6TQI+SWtDF9pWcpgO7H1ge7ADMKeyahB67JqHnrK5JQFsYxhhjwkfIlwYxxhgTGixhGGOM8YslDGOMMX6xhNELRCRBRNaLSKelTUzfE5FLROSfvkrHlwQ7HgMi4hKRR0XkaRG5OdjxGBCRi3y/I8+JyOru9reE0YkzqLJ7H/DffRtl5OnhdVGgBojFKT9jAqCH1+RanNJAzdg1CZieXBNV/ac61cD/Avym22PbKKlTicjFOB82L6pqtm+bG9gJXI7zn30tsAAYiTPPJBYoU9W/BCXoCNDD67JdVb0ikgr8TFVvDFLYYa2H1+QaoFJVfykif1TV64MUdljryTVR1W2+1/8b+JqqVp3u2MGoJRXytAdVdoFEIAGnVHu9iKxUVW8fhhsxenJdWn8RgEqcwpUmAHr4u3IIaPLt4+mrGCNND6/JNhEZAxzvLlmAJYye6LTKrqreASAiX8ZpYViy6FudXhcR+QzwCWAIsDQYgUWwripSPwU8LSIXAe8FI7AIdroq4V8Ffu3PQSxh+O+0VXZV9YW+C8W00+l1UdXXgdf7OhgDdH1N6nA+nEzf6/LzS1Uf9vcg1untvyJgdLvno4AjQYrFnGDXJfTYNQk9vXJNLGH4r6+q7JqesesSeuyahJ5euSaWMDrhq7K7BpgkIkUi8lVVbQHuAN4CCoH/VtWtwYwz0th1CT12TUJPIK+JDas1xhjjF2thGGOM8YslDGOMMX6xhGGMMcYvljCMMcb4xRKGMcYYv1jCMMYY4xdLGMYYY/xiCcOEHRHxiMgmEdkiIq+KSHwP31/TxfYXRKRPSnKLyA9E5OO9cJzrROT73eyTLCJvnu25TPizhGHCUb2qzvStBdAE3Nr+RXGE9P99Vf2+qv5vLxzqXmBZN+cqBY6KyNxeOJ8JYyH9S2NML/gnkCki40SkUESWARuA0SKyQEQKfC2RH7d/k4g8KSIbROTvIpLc8aAicq6I5PmW5n1LREb4tq8Skf8Skfd855stIq+LyC4ReaST47h9LZctvlju9m1/QUSuF5FcX2tpk+919b0+QUTe9J3/nyIyuZNjTwQaVbWs3TGXiMhqEdnbobX0P4AtMmVOyxKGCVsiEgV8EijwbZqEswrZOTjLhP4YuBSYCcwWket8+yUAG1R1FpAHPNzhuNHA08D1qnou8Cvg0Xa7NKnqxcCzwJ+A24Fs4MsiMrxDmDOBdFXNVtXpdFiXQFXX+VpLM4E3gZ/6XloO3Ok7/3fovBUxFyc5tjcCuBC4Cni83fZ1wEWdHMOYNrYehglHcSKyyff1P4HncZbSPaCq/+fbPhtY5bsdg4i8DFyM85e2F3jFt99LnLquxiScBPCOiAC4gaPtXm+tAloAbFXVo75z7MUpMV3ebt+9wHgReRr4K/B2Z9+QiNwAzAKuEJFE4ALgVd/5ofNVBUcApR22/Y9vka9tvuVrW5Xg/IyM6ZIlDBOO6n1/kbfxfbDWtt/Ug+N1rNApOIlgThf7N/oeve2+bn1+0u+cqlaKyAyc1QFvB24AbukQ+zTgP4GLVdXj63851vF77EQ9MLiL2Fq/j1axvv2N6ZLdkjKR6kNgnogkiYgbWIBz+wmc34vW+/tfAN7v8N4dQLKIzAHnFpXvQ73HRCQJcKnqa8D3cFoR7V8fDPwBuKm1NeRbe3mfiMz37SO+pNNRIZDpZygTgS1n8j2YyGEtDBORVPWoiDwA/APnL+2Vqvon38u1wDQRWQ8cBz7X4b1Nvg7jJb4P9Cjg58CZrPmQDvy63aitBzq8fh0wFvh/rbeffC2LG4FnROQhIBonqWzu8N73gCdFRLT7dQw+hnNLzJgu2XoYxoQxEXkKWNHdEF0ReQ+4VlUr+yYy0x/ZLSljwtuPgNNOXPQNG/6ZJQvTHWthGGOM8Yu1MIwxxvjFEoYxxhi/WMIwxhjjF0sYxhhj/GIJwxhjjF/+Px6/wfiKFIrSAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Solution\n", "\n", "def lookup_dict(n):\n", " d = {}\n", " for i in range(n):\n", " d[i] = 1\n", " total = 0\n", " for i in range(n):\n", " total += d[i]\n", " return d\n", "\n", "ns, ts = run_timing_test(lookup_dict)\n", "plot_timing_test(ns, ts, 'lookup_dict', exp=1)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "# Solution\n", "\n", "\n", "# Adding `n` elements to a dictionary takes linear time, \n", "# so adding a single element is constant time.\n", "\n", "# Same with looking up `n` elements." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Implementing a hash table\n", "\n", "The reason Python dictionaries can add and look up elements in constant time is that they are based on hash tables. In this section, we'll implement a hash table in Python. Remember that this example is for educational purposes only. There is no practical reason to write a hash table like this in Python.\n", "\n", "We'll start with a simple linear map, which is a list of key-value pairs." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "class LinearMap(object):\n", " \"\"\"A simple implementation of a map using a list of tuples\n", " where each tuple is a key-value pair.\"\"\"\n", "\n", " def __init__(self):\n", " self.items = []\n", "\n", " def add(self, k, v):\n", " \"\"\"Adds a new item that maps from key (k) to value (v).\n", " Assumes that they keys are unique.\"\"\"\n", " self.items.append((k, v))\n", "\n", " def get(self, k):\n", " \"\"\"Looks up the key (k) and returns the corresponding value,\n", " or raises KeyError if the key is not found.\"\"\"\n", " for key, val in self.items:\n", " if key == k:\n", " return val\n", " raise KeyError" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First let's make sure it works:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "scrolled": true }, "outputs": [], "source": [ "def test_map(m):\n", " s = string.ascii_lowercase\n", "\n", " for k, v in enumerate(s):\n", " m.add(k, v)\n", "\n", " for k in range(len(s)):\n", " print(k, m.get(k))" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 a\n", "1 b\n", "2 c\n", "3 d\n", "4 e\n", "5 f\n", "6 g\n", "7 h\n", "8 i\n", "9 j\n", "10 k\n", "11 l\n", "12 m\n", "13 n\n", "14 o\n", "15 p\n", "16 q\n", "17 r\n", "18 s\n", "19 t\n", "20 u\n", "21 v\n", "22 w\n", "23 x\n", "24 y\n", "25 z\n" ] } ], "source": [ "m = LinearMap()\n", "test_map(m)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's see how long it takes to add `n` elements." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024 0.010000000000005116\n", "2048 0.0\n", "4096 0.0\n", "8192 0.0\n", "16384 0.00999999999999801\n", "32768 0.00999999999999801\n", "65536 0.00999999999999801\n", "131072 0.030000000000001137\n", "262144 0.060000000000002274\n", "524288 0.14000000000000057\n", "1048576 0.25\n", "2097152 0.5599999999999987\n", "4194304 1.0800000000000018\n" ] }, { "data": { "image/png": "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5VorEZUojDEm3LRcKyIzE4YPB2fYlDBmTDRz5mzm+98fT2pqaqhDbVdEJQprejLGhJPDa0UkJIDLBStWeGhsFI491sWCBfD97w9A5DiiosL7V3F49JQEiKq+q6o3JCcnhzoUY4zhySchJgZ271a2bm3E42kiLq6OxMQmLr4YoqMl7JMERFiiCKRly+CiiyA31/kZyNWi2rNkyRIWtDPl44AB7Y/E3L59O1OnTgVg9erV3HrrrUGJzxjTNYWFsG2bh/37GxBpYvjwGrKzvezd6w51aF0S/qksBA5XFxMTj1xa8NFHAzsjYzDk5uaSm3vUeJmA8ng8uN1964tuTG9qaoIlS5rYt89LXR0kJTUycmQDgwcPpLY2mnHjQh1h1/TLRHHOOR2/npcH9fXQskbY1ASXXgrHHdf+fu+2Owm64/zzz2fXrl3U1dVx2223ccMNN/D888/z0EMPkZGRwcSJE4mNjQWguLiYyy67jKamJubNm9fxgVtYunQpjzzyCO+99x733XcfO3fuZNu2bezcuZOf/vSnzbWNl19+mYULF9LQ0MCsWbN46qmncLvd/PjHP2bVqlUcOnSICy+8kPvvvx9wxnVcc801fPTRRyxYsIBLLrnkqHPPnTuXGTNmkJeXR1lZGS+++CIPPfQQBQUF/PCHP+SBBx5o9zqAU2u68cYb+fvf/87gwYN59dVXSUtL8/u9GxMOysvh//5f+PTTg6SmejlwII7MTBdDhgympkYCvlZEb4iopicROUdEFldWVvboOLW10PoPZrfbKe+J5557jry8PFavXs3ChQvZvXs39957LytXruTjjz+mqKioedvbbrut+Zf2sGHDun3OjRs38uGHH/LFF19w//3309jYeMTaGGvXrsXtdjfPQPvggw+yevVq8vPzWbZsGfn5+c3HiouLY8WKFW0micNiYmJYvnw5N910E+eddx6LFi2isLCQJUuWUF5e3uZ1OFxeU1PDzJkzWbNmDXPmzGlOUsb0Ff/6F9x6KxQVwciRidxzTwnPPy+MHp3A3r1CenrfaJloLaJqFP6Oo+jsL/+LLnKam5KSvimrqoL0dHjjje7Ht3DhQt5++20Adu3axUsvvcTcuXOb/2r+4Q9/yJdffgnAypUreeuttwC44ooruPPOO7t1zrPOOovY2FhiY2NJT09nz549Ha6N8frrr7N48WKampoo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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def add_linear_map(n):\n", " d = LinearMap()\n", " for i in range(n):\n", " d.add(i, 1)\n", " return d\n", "\n", "ns, ts = run_timing_test(add_linear_map)\n", "plot_timing_test(ns, ts, 'add_linear_map', exp=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Adding `n` elements is linear, so each add is constant time. How about lookup?" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024 0.020000000000003126\n", "2048 0.06999999999999673\n", "4096 0.25\n", "8192 1.0400000000000027\n" ] }, { "data": { "image/png": "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DdHcemtCwFsR9QVRKMYY03kcPermN7/ZxGefdUVVyMiI4De/6cKQIa5Ah/YtIZUoRGQqMDU9PT3QoRhjTJPy8+Hvf3fx9dcpRERUMWNGLDffHEuwrqsVUolCVRcBi8aNGzcz0LEYY0xD27bt4Y03Yvn000RUYfjwOO6+O47Bg4O7QkJIJQpjjAlGVVVVLFq0iWeeiefwYRe9enm46qowrrkmLGhbEfUFdxoLoKVLYdo0GDfO+dgWq0XFx8ef1PuWLFnic8mRk3H22WdT99zJRRddZKXHjWkjqsqWLUX86lcb+ctfenDoUAwZGVE8/LBwww10iCQB1qJoVN3SgnFxxy8t+PDDbVuRMRi99957fj1/bW0t4cE0ncMYP6moqGDhwq954YWuFBf3Ijo6ghkz4rjxxqgOkyDqdMqf2KlTm389KwuqqjhuelptLVx7LZx2WtPvW9RkEfTjqSq//OUvef/99xERHnjgAa6++uom99e3atUqZs2axeuvv86cOXOIj48/VlF25MiRx+pEXXDBBUyYMIE1a9YwePBg5syZQ2xsbIuxpaamsnr1asrKyrjwwgs544wzWL58OSkpKSxcuJCYmBg2b97MnXfeyf79+4mNjeXpp59m6NChLFq0iIceeojq6mp69OjBvHnzSEpK4sEHH2TXrl1s3bqVnj178tJLL33rurNnz+att97C7XaTm5vLvffeS3V1NXPnziUqKor33nuP7t278/TTT/PUU09RXV1Neno6c+fOJTY2lptuuono6Gjy8vLYu3cvf/vb3/zaCjOmOVVVyoMPbmfJkiREwhg6NJYHHohj8ODgeC7iRIVU11Nb1Xo6ehRcDWaouVzO/rbwxhtvsHbtWrKzs/n444+577772L17d5P76yxfvpzbb7+dhQsXMnDgwGavsWHDBmbNmkVOTg6JiYk88cQTJxznxo0bufPOO8nLy6Nr1668/vrrAMyaNYt//vOfZGVl8de//pUf//jHAJxxxhn85z//Yc2aNVxzzTX8+c9/PnaurKwsFi5c2GiSqJObm8tLL73EypUr+a//+i9iY2NZs2YNkyZNYs6cOQBcccUVrFq1iuzsbIYNG8azzz577P1bt25l6dKlvPvuu9x+++1UVlae8D0b01oFBXD33cKaNalERUUzc2ZXnn02vsMmCQixFoWvs55a+st/2jSnuykx8Zt9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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def lookup_linear_map(n):\n", " d = LinearMap()\n", " for i in range(n):\n", " d.add(i, 1)\n", " total = 0\n", " for i in range(n):\n", " total += d.get(i)\n", " return d\n", "\n", "ns, ts = run_timing_test(lookup_linear_map)\n", "plot_timing_test(ns, ts, 'lookup_linear_map', exp=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Looking up `n` elements is $O(n^2)$ (notice that `exp=2`). So each lookup is linear.\n", "\n", "Let's see what happens if we break the list of key-value pairs into 100 lists." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "class BetterMap(object):\n", " \"\"\"A faster implementation of a map using a list of LinearMaps\n", " and the built-in function hash() to determine which LinearMap\n", " to put each key into.\"\"\"\n", "\n", " def __init__(self, n=100):\n", " \"\"\"Appends (n) LinearMaps onto (self).\"\"\"\n", " self.maps = []\n", " for i in range(n):\n", " self.maps.append(LinearMap())\n", "\n", " def find_map(self, k):\n", " \"\"\"Finds the right LinearMap for key (k).\"\"\"\n", " index = hash(k) % len(self.maps)\n", " return self.maps[index]\n", "\n", " def add(self, k, v):\n", " \"\"\"Adds a new item to the appropriate LinearMap for key (k).\"\"\"\n", " m = self.find_map(k)\n", " m.add(k, v)\n", "\n", " def get(self, k):\n", " \"\"\"Finds the right LinearMap for key (k) and looks up (k) in it.\"\"\"\n", " m = self.find_map(k)\n", " return m.get(k)\n" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 a\n", "1 b\n", "2 c\n", "3 d\n", "4 e\n", "5 f\n", "6 g\n", "7 h\n", "8 i\n", "9 j\n", "10 k\n", "11 l\n", "12 m\n", "13 n\n", "14 o\n", "15 p\n", "16 q\n", "17 r\n", "18 s\n", "19 t\n", "20 u\n", "21 v\n", "22 w\n", "23 x\n", "24 y\n", "25 z\n" ] } ], "source": [ "m = BetterMap()\n", "test_map(m)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The run time is better (we get to a larger value of `n` before we run out of time). " ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024 0.0\n", "2048 0.010000000000001563\n", "4096 0.00999999999999801\n", "8192 0.030000000000001137\n", "16384 0.08999999999999986\n", "32768 0.3000000000000007\n", "65536 1.1700000000000017\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def lookup_better_map(n):\n", " d = BetterMap()\n", " for i in range(n):\n", " d.add(i, 1)\n", " total = 0\n", " for i in range(n):\n", " total += d.get(i)\n", " return d\n", "\n", "ns, ts = run_timing_test(lookup_better_map)\n", "plot_timing_test(ns, ts, 'lookup_better_map', exp=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The order of growth is hard to characterize. It looks steeper than the line with slope 1. Let's try slope 2." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "image/png": "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O+/U8Kc/VVFaanA6DVdcUcWdd0YTHt47djnuTWMUp63Vo6dAh6KUUp06etTNPfeU8fHHTRgDyck1/PSnkZx55rhAh3aCoJpEb4xZZYxZOHjw4ECHopRS7XK7YdUqw/z5paxf30RoqIubb67m6adHc+aZ8YEO7yRB1aNQSqne7sABePhh2LVLcDgiyMgo4mc/G8LEiaMCHVq7NFEopVQPaGiApUsrefXVAYSEhBMTA9/7Xjhnnz2WAQN696/i3h1dF+kYhVKqN8rJaeKee45TUNCEiDB/vpOFC0OJjBT6wq9hHaNox5o1cN11kJ1tP/qiWlRUVPdWU77//vtebznSHUlJSRw7dqxL8axbt67l+NVXX2X79u3+CE2pPq26Gn7/+0oWLSqjoKCJ2Ng6fv3ran7wA6en2FDfEFSJwld6orRgX+aLRNHU1OTrsJTqVdasaWT+/BJefrkGcHHxxWU8/fRQrrgiGafTGejwuqT393n8YN68jr++aRPU10Prx4ZNTbBgAZx5ZvvnrWp3y8ITGWP46U9/yptvvomI8Ktf/YpvfvOb7ba3tmHDBhYuXMjKlStZvnw5UVFRLTvKpqent+wTdckllzB9+nQ+++wzJk6cyPLly4mIiGg3pvvuu4/33nsPgGeffZYJEyZQXFzMokWLOHjwIAB//vOfSUhI4LHHHsPpdLJixQoefPBBXn/9ddasWcPdd9/NypUrAbjjjjsoLi4mIiKCv/3tb0yePJmbb76ZmJgYPvvsM8444wweeOCBk+L47W9/S35+PkVFRezevZs//elPfPzxx7z55pskJCSwatUqQkJC+N3vfseqVauora3lvPPO469//SsiwuzZs5k6dSqffvopFRUVLF26lLPPPtu7/zFK+UBJCTz2GLz1VhX19U0kJlbzox85mTFjYp/drblvRt0OEZknIo8fP378tK5TUwNtE77Tadt94eWXX2bLli3k5OTw7rvvctddd1FUVNRue7N169axaNEiXnvtNcaN63ie9a5du1i4cCG5ublER0fz6KOPdvj66OhoPv30UxYvXsyPfvQjAH74wx9y5513smHDBlauXMl3v/tdkpKSWLRoEXfeeSdbtmxh1qxZXHnlldx3331s2bKF8ePHs3DhQh5++GE2bdrE/fffz+23395yn927d/Puu++eMkk027dvH2+88QavvfYaN9xw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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plot_timing_test(ns, ts, 'lookup_better_map', exp=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It might be converging to the line with slope 2, but it's hard to say anything conclusive without running larger problem sizes." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** Go back and run `run_timing_test` with a larger value of `max_time` and see if the run time converges to the line with slope 2. Just be careful not to make `max_time` to big." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we're ready for a complete implementation of a hash map." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "class HashMap(object):\n", " \"\"\"An implementation of a hashtable using a BetterMap\n", " that grows so that the number of items never exceeds the number\n", " of LinearMaps.\n", "\n", " The amortized cost of add should be O(1) provided that the\n", " implementation of sum in resize is linear.\"\"\"\n", "\n", " def __init__(self):\n", " \"\"\"Starts with 2 LinearMaps and 0 items.\"\"\"\n", " self.maps = BetterMap(2)\n", " self.num = 0\n", "\n", " def get(self, k):\n", " \"\"\"Looks up the key (k) and returns the corresponding value,\n", " or raises KeyError if the key is not found.\"\"\"\n", " return self.maps.get(k)\n", "\n", " def add(self, k, v):\n", " \"\"\"Resize the map if necessary and adds the new item.\"\"\"\n", " if self.num == len(self.maps.maps):\n", " self.resize()\n", "\n", " self.maps.add(k, v)\n", " self.num += 1\n", "\n", " def resize(self):\n", " \"\"\"Makes a new map, twice as big, and rehashes the items.\"\"\"\n", " new_map = BetterMap(self.num * 2)\n", "\n", " for m in self.maps.maps:\n", " for k, v in m.items:\n", " new_map.add(k, v)\n", "\n", " self.maps = new_map" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 a\n", "1 b\n", "2 c\n", "3 d\n", "4 e\n", "5 f\n", "6 g\n", "7 h\n", "8 i\n", "9 j\n", "10 k\n", "11 l\n", "12 m\n", "13 n\n", "14 o\n", "15 p\n", "16 q\n", "17 r\n", "18 s\n", "19 t\n", "20 u\n", "21 v\n", "22 w\n", "23 x\n", "24 y\n", "25 z\n" ] } ], "source": [ "m = HashMap()\n", "test_map(m)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** Write a function called `lookup_hash_map`, based on `lookup_better_map`, and characterize its run time.\n", "\n", "If things go according to plan, the results should converge to a line with slope 1. Which means that `n` lookups is linear, which means that each lookup is constant time. Which is pretty much magic." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024 0.0\n", "2048 0.010000000000005116\n", "4096 0.0799999999999983\n", "8192 0.030000000000001137\n", "16384 0.11999999999999744\n", "32768 0.19000000000000483\n", "65536 0.4399999999999977\n", "131072 0.8599999999999994\n", "262144 1.5999999999999943\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Solution\n", "\n", "def lookup_hash_map(n):\n", " d = HashMap()\n", " for i in range(n):\n", " d.add(i, 1)\n", " total = 0\n", " for i in range(n):\n", " total += d.get(i)\n", " return d\n", "\n", "ns, ts = run_timing_test(lookup_hash_map)\n", "plot_timing_test(ns, ts, 'lookup_hash_map', exp=1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "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.7.3" } }, "nbformat": 4, "nbformat_minor": 1 }