Skip to content

Instantly share code, notes, and snippets.

@fagonzalezo
Last active September 12, 2018 18:07
Show Gist options
  • Save fagonzalezo/460b7311f84a94750414 to your computer and use it in GitHub Desktop.
Save fagonzalezo/460b7311f84a94750414 to your computer and use it in GitHub Desktop.
Ordenamiento por mezcla (merge sort)
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ordenamiento por mezcla\n",
"==========================\n",
"\n",
"El ordenamiento por mezcla (*merge sort*) utiliza una estrategia *dividir y conquistar*. El algoritmo inicialmente divide el arreglo en dos partes (sub-arreglos) y llama recursivamente la función de ordenamiento para ordenar cada parte por separado. Después las dos subarreglos son *mezclados* para obtener un arreglo totalment ordenado al final. \n",
"\n",
"La siguiente función se encarga de hacer la mezcla de dos sub arreglos adyacentes que deben estar ordenados inicialmente. Los subarreglos se encuentran en las posiciones `A[p:q + 1]` y `A[q + 1:r + 1]` respectivamente. Al finalizar el subarreglo `A[p:r + 1]` debe estar ordenado ascendentemente."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def merge(A, p, q, r):\n",
"# print 'merging (%d, %d, %d)'%(p, q, r)\n",
" L = A[p:q+1]+[float('inf')]\n",
" R = A[q+1:r+1]+[float('inf')]\n",
" i = 0\n",
" j = 0\n",
" for k in range(p, r + 1):\n",
"# print 'k=', k, 'i=', i, 'j=', j\n",
"# print 'A=', A, 'L=', L, 'R=', R\n",
" if L[i] <= R[j]:\n",
" A[k] = L[i]\n",
" i += 1\n",
" else:\n",
" A[k] = R[j]\n",
" j += 1"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4, 5, 7, 8, 10, 11]\n"
]
}
],
"source": [
"B = [1, 3, 5, 7, 2, 4, 8, 10, 11]\n",
"merge(B, 0, 3, 8)\n",
"print B"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La siguiente función, `merge_sort_main(A, p, r)`, implementa el algoritmo de ordenamiento por mezcla. Inicialmente divide el subarreglo `A[p:r +1]` en dos subarreglos calculando `q`. Llama recursivamente la función sobre los dos subarreglos y finalmente mezcla los resultados mediante un llamado a la función `merge(A, p, q, r)`."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"\n",
"def merge_sort_main(A, p, r):\n",
"# print \"Entra p=\",p,\"r=\",r,A[p:r+1] \n",
" if p < r:\n",
" q = int((p + r) / 2.0)\n",
" merge_sort_main(A, p, q)\n",
" merge_sort_main(A, q + 1, r)\n",
" merge(A, p, q, r)\n",
"# print \"Sale p=\",p,\"r=\",r,A[p:r+1] \n",
"\n",
"\n",
"def merge_sort(A):\n",
" merge_sort_main(A, 0, len(A) - 1)\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]\n",
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n"
]
}
],
"source": [
"B = range(10, 0, -1)\n",
"print B\n",
"merge_sort(B)\n",
"print B"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Análisis del tiempo de ejecución\n",
"--------------------------------"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Para analizar el tiempo de ejecución del ordenamiento por mezcla definimos una función que recibe una función de ordenamiento y un arreglo y calcula el tiempo que toma la función para ordenar el arreglo. La función `time.time()` calcula el tiempo actual en segundos. Esta función es usada para calcular el tiempo antes y después de invocar el función de ordenamiento. Este proceso se realiza 10 veces y se reporta el promedio. La función `gc.collect()` invoca el recolector de basura en memoria de manera que una eventual recolección de basura no afecte el cálculo del tiempo."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import time \n",
"import gc\n",
"\n",
"def calc_time(sort_function, array):\n",
" timesum = 0\n",
" gc.collect()\n",
" for i in range(10):\n",
" array_copy = list(array)\n",
" tic = time.time();\n",
" sort_function(array_copy)\n",
" toc = time.time();\n",
" timesum += toc - tic\n",
" return timesum/10\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Función de ordenamiento por inserción para comparar con el ordenamiento por mezcla."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def insertion_sort(A):\n",
" j = 1\n",
" while j < len(A):\n",
" key = A[j]\n",
" i = j - 1\n",
" while (i >= 0) and (A[i] > key):\n",
" A[i + 1] = A[i]\n",
" i = i -1\n",
" A[i + 1] = key\n",
" j = j + 1"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.132558107376\n"
]
}
],
"source": [
"print calc_time(insertion_sort, range(1000,1,-1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La siguiente función calcula tiempos de ordenamiento para diferentes arreglos de diferente tamaño."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import random as rnd\n",
"\n",
"def exper_analysis(sizes):\n",
" results_merge = []\n",
" results_insertion = []\n",
" for i in sizes:\n",
" list1 = range(i)\n",
" rnd.shuffle(list1)\n",
" results_merge.append(calc_time(merge_sort, list1))\n",
" results_insertion.append(calc_time(insertion_sort, list1)) \n",
" return (results_merge, results_insertion)\n",
" \n",
" "
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x10a46c390>"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAZoAAAEPCAYAAAB7rQKTAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXuYFNWZ/z8vMBhApLktd5hBMYooXmYFnSidBFEHFaMZ\nxQUlCcvgqhvd34pA2AjZSDRgLqvGC0qMJiqOSVQER0EFdHE1GmW8ICI6gwiCxkxLVEQu7++Pqp6p\nafpSfe+Zfj/P009XnTrn1OkC6st7znveV1QVwzAMw8gW7fI9AMMwDKNtY0JjGIZhZBUTGsMwDCOr\nmNAYhmEYWcWExjAMw8gqJjSGYRhGVsm60IjIGSKyQUTeEZGZMerc5F6vE5HjErUVkSoReVNE9onI\nCZ7y00TkZRF5zf3+ZnZ/nWEYhpGIrAqNiLQHbgHOAIYDF4nIkRF1KoHDVHUYUA3c5qPt68B3gGcB\n70agj4GzVPUYYArw+yz9NMMwDMMnHbLc/4nAJlVtABCRJcAE4C1PnXOAewBU9UURCYhIX6AsVltV\n3eCWtbiZqq7znK4HOolIiaruyfxPMwzDMPyQ7amzAcAWz/kHbpmfOv19tI3H+cBfTWQMwzDyS7Yt\nGr/xbSRxFf+IyFHADcBpmezXMAzDSJ5sC81WYJDnfBCOZRKvzkC3TomPtgcgIgOBPwMXq2p9lOsW\n3M0wDCMFVDUloyDbU2cvA8NEpFREOgIXAksj6iwFLgEQkdFASFV3+GwLHmtIRALAcmCmqv5frEGp\nqn1UmTt3bt7HUCgfexb2LOxZxP+kQ1aFRlX3AlcAT+Iszj+oqm+JyHQRme7WeRx4T0Q2AXcAl8Vr\nCyAi3xGRLcBoYLmI1Lq3vAI4FJgrIq+6n17Z/I2GYRhGfLI9dYaq1gK1EWV3RJxf4betW/4w8HCU\n8uuA69IZr2EYhpFZLDJAERMMBvM9hILBnkUz9iyasWeRGSTdubfWhohosf1mwzCMdBERNEVngKxP\nnbUWIjd/Gm0b+8+GYeQOExoP9vIpDvLxn4rly6GiAgKB5rJQCNauhfHjcz4cw8gptkZjGDmgogLm\nzHHEBZzvOXOccsNo69gaTXO5WTRFQr7+rMPiMmMGLFwI8+e3tHAMo5BJZ43GhKa53ISmSMjnn3VD\nA5SVQX09lJbmZQiGkRLpCI1NnRlGjgiFHEumvt75Dk+jGUZbx4SmFVBaWspBBx3EJ5980qL8uOOO\no127drz//vt5Gll2aNeuHe+9916+h5FRwtNm8+c7lsz8+S3XbAyjLWNC0woQEYYOHcoDDzzQVPb6\n66+za9eulD2o9u7dm6nhZQzvmNraNObatS3XZAIB53zt2vyOyzBygQlNK2Hy5Mnce++9Tef33HMP\nl1xySYsX8u7du7n66qsZMmQIffv25d/+7d/48ssvAVi9ejUDBw5kwYIF9OvXj6lTp/Lll18yZcoU\nevTowfDhw1mwYAGDBjUHzN62bRvnn38+//RP/8TQoUO5+eabY47v8ccf56ijjuKQQw5h4MCB/OIX\nv2i6dueddzJs2DB69uzJhAkT+PDDD5uutWvXjltvvZXDDz+cww8/nDFjxgAwcuRIunbtykMPPZT+\nwysAxo8/cOE/EDDXZqNIyHdE0DxEINVoxCpXVZ02bZqOGTNGzzzzTG1sbIxZLx7p9FFaWqpPPfWU\nfv3rX9e33npL9+7dqwMHDtTNmzeriOjmzZtVVfWqq67SCRMmaGNjo/7jH//Qs88+W2fPnq2qqqtW\nrdIOHTrorFmz9KuvvtJdu3bpzJkzNRgMaigU0g8++ECPPvpoHTRokKqq7tu3T48//nj96U9/qnv2\n7NH33ntPhw4dqk8++WTUMfbt21f/93//V1VVQ6GQvvLKK6qq+vTTT2uvXr301Vdf1d27d+u///u/\n66mnntrUTkR03Lhx2tjYqF9++WVT2bvvvpvUM0qGeH/WhmFEx/13k9p7N9WGrfWTitCMGTNGcZK4\naVVVVcx68Uinj7DQXHfddTp79mytra3VcePG6d69e5uEZv/+/dqlS5cWL+jnn39ey8rKVNURmo4d\nO+ru3bubrg8dOlRXrFjRdH7XXXfpwIEDVVX1hRde0MGDB7cYx89+9jP9/ve/H3WMgwcP1jvuuEM/\n/fTTFuU/+MEPdObMmU3nn332mZaUlDSJo4joqlWrWrQxoTGMwiMdobHIAD7o3LkzAOXl5SxatCgv\nfYgIF198Maeccgr19fUHTJt9/PHHfPHFF5xwwglNZarK/v37m8579+5Nx44dm863bdvWYqps4MCB\nTcebN29m27ZtdO/evals3759nHrqqVHH96c//YnrrruOWbNmccwxx3DDDTcwevRoPvzwQ8rLy5vq\ndenShZ49e7J161YGDx4M0GIMhmG0PWyNxgf3338/VVVVrFy5kkCKO+wy0cfgwYMZOnQotbW1nHfe\neS2u9erVi06dOrF+/XoaGxtpbGwkFAqxc+fOpjqRjgP9+vVjy5YtTefe40GDBlFWVtbUV2NjIzt3\n7mTZsmVRx1ZeXs4jjzzCxx9/zLnnnssFF1wAQP/+/WloaGiq9/nnn/PJJ58wYMCAmOMyDKNtYULj\ng0AgQE1NTcoCkak+ABYvXswzzzxDp06dWpS3a9eOadOmcdVVV/Hxxx8DsHXrVlasWBGzrwsuuIDr\nr7+eUCjE1q1bueWWW5pe+ieeeCJdu3ZlwYIF7Nq1i3379vHGG2/w8ssvH9DPnj17uO+++/j0009p\n3749Xbt2pX379gBcdNFF3H333dTV1bF7925+9KMfMXr06CZrJhp9+vTh3XffTfrZGIZRmJjQtDKG\nDh3K8ccf33TutQZ+/vOfc9hhhzF69Gi6devGaaedxsaNG6PWBbj22msZOHAgZWVljBs3jqqqqqap\ntfbt27Ns2TLWrVvH0KFD6d27N9XV1S0sJC9/+MMfKCsro1u3bixatIj77rsPgG9/+9v89Kc/5fzz\nz6d///7U19ezZMmSmGMCmDdvHlOmTKF79+788Y9/TOEpGYZRSFgImuZyiu1ZRHLbbbdRU1PDqlWr\n8j2UrGJ/1oaRPBaCxkiJ7du3s3btWvbv38/bb7/NL3/5S77zne/ke1iGYbQxzOusiPnqq6+49NJL\nqa+vJxAIcNFFF3HZZZfle1iGYbQxbOqsudymU4oE+7M2jOSxqTPDMAyjYDGhMQzDMLKKCY1hGIaR\nVUxoDMMwWjnV1dUEg0EqKysJFWCSIxMawzCMVs7GjRtZs2YNtbW1VFdX53s4B2BCY/jmueee44gj\njsj3MAzDiCATgX+ziQlNK6C0tJSnn3465/eNTKl8yimnsGHDhpyPIxnmzZvHxRdfnO9hGEZOyUTQ\n3mySVaERkTNEZIOIvCMiM2PUucm9XicixyVqKyJVIvKmiOwTkeMj+prt1t8gIuPSHf/y5QfmdA+F\nnPJc9iEiOY1w3FpTKhdiemrDyAWZCtqbNVJNZJPoA7QHNgGlQAmwDjgyok4l8Lh7PAp4IVFb4Ajg\ncGAVcLynr+FuvRK33SagXZRxxUvq04LGRtXLLnO+o537IRN9lJaW6tNPP62qqnfffbdWVFTo1Vdf\nrd27d9eysjKtra1tqnv33Xfr0KFDtWvXrlpWVqb33Xdf07XFixfrkUceqd27d9fTTz+9KfmYqpNs\n7De/+Y0OGzZMy8rK9NRTT1UR0S5duujBBx+sNTU1umrVqqbEaKqq69ev1zFjxmggENCjjjpKly5d\n2nRtypQpetlll+n48eO1a9euOmrUqJjJzHbt2qWTJk3Snj17aiAQ0H/+53/WHTt2qKrq1q1b9eyz\nz9YePXroYYcdpnfeeWdTu7lz5+r555+vkydP1kMOOURvueUW7dixo5aUlOjBBx+sxx57bNT7xfo7\nYBhGM5FZgSnEDJvAScATnvNZwKyIOrcDF3rONwB9fbaNFJrZwEzP+RPA6CjjivpQY5WHhaG+PnmB\nyFQfkUJTUlKid911l+7fv19vu+027d+/v6o62SsPOeQQ3bhxo6qqbt++Xd98801VVX3kkUf0sMMO\n0w0bNui+ffv0uuuu05NPPrnpHn5SKnuF5quvvtJDDz1Ur7/+et2zZ48+88wz2rVrV3377bdV1RGa\nnj176ksvvaR79+7VSZMm6cSJE6P+vttvv13PPvts3bVrl+7fv19feeUV3blzp6qqnnLKKXr55Zfr\n7t27dd26ddq7d2995plnVNURmpKSEn300UdV1RGsefPm6cUXXxz3eZrQGEZiIrMCpyM02Zw6GwBs\n8Zx/4Jb5qdPfR9tI+rv1kmmTkEAAZsyAsjLnOxXLNBN9eBkyZAhTp05FRLjkkkv48MMP+eijjwBn\nXeX1119n165d9OnTh+HDhwNw++23M3v2bL7+9a/Trl07Zs+ezbp161okO5s9ezaBQICDDjoo4Rhe\neOEFPv/8c2bNmkWHDh345je/yVlnncUDDzzQVOe8886jvLyc9u3bM2nSJNatWxe1r44dO/LJJ5/w\nzjvvICIcd9xxdO3alS1btvD888/z85//nI4dOzJy5Ej+9V//lXvvvbep7cknn8w555wDwNe+9jXv\nfygMw0iDTDoYZFNo/P5rz+biQ9pvnFAIFi6E+nrnOxUX9Uz04aVv375Nx+G/DJ999hldunThwQcf\n5Pbbb6d///6cddZZvP3224CTmvnKK6+ke/fudO/enZ49ewJOcrQwyaRUjkwDDY4Abtu2DXDWlfr0\n6dN0rVOnTnz22WdR+7r44os5/fTTmThxIgMGDGDmzJns3buXbdu20aNHD7p06dJUd/DgwS3G7E0/\nbRhG5sikg0E2hWYr4H0TDaKlxRGtzkC3jp+2ie430C07gHnz5jV9Vq9eHbPDUAjmzIH586G01Pme\nMyc5ochEH8kwbtw4VqxYwfbt2zniiCOYNm0a4LygFy1a1CI18+eff87o0aOb2ibjcNC/f3+2bNnS\nwnrYvHlzixTNfunQoQPXXnstb775Js8//zzLli3j3nvvZcCAAfz9739vIVDvv/9+C3GJHHO7duZI\naRiZYN26dQwfPpxf//rXzJs3L62+svmv8mVgmIiUikhH4EJgaUSdpcAlACIyGgip6g6fbaGlNbQU\nmCgiHUWkDBgG/CXawLxCEwwGY/6AtWsdYQiLeSDgnK9dm+CXZ7gPv3z00Uc8+uijfP7555SUlNCl\nS5emlMqXXnopP/vZz1i/fj0An376KQ899FDc/uKlVB41ahSdO3dmwYIF7Nmzh9WrV7Ns2TImTpwI\nJOettnr1al5//XX27dtH165dKSkpoX379gwcOJCTTz6Z2bNns3v3bl577TV++9vfMnny5Lhjbmho\nsOkzw0iTYDDY4l2ZDlkTGlXdC1wBPAmsBx5U1bdEZLqITHfrPA68JyKbgDuAy+K1BRCR74jIFmA0\nsFxEat0264Eat34tcJmm+bYZP/7A9ZRAwCnPZR9eork6h8/379/Pr371KwYMGEDPnj157rnnuO22\n2wA499xzmTlzJhMnTqRbt24cffTRPPnkkwf04SUypbL33h07duSxxx6jtraW3r17c8UVV/D73/+e\nww8/POE4I9m+fTtVVVV069aN4cOHEwwGm/bCPPDAAzQ0NNC/f3/OO+88/vu//5tvfetbMe9RVVUF\nQM+ePSkvL/fxRA3DyDaWj6a53P4XXCTYn7VhJI/lozEMwzAKFhMawzAMI6uY0BiGYRQxmQiTlQgT\nGsMwjCKmoqLllovwloyKiszdw5wBmsttgbhIsD9rw2hJWFxmzHA2lXu3ZIRJxxnAhKa53F4+RYL9\nWRutjeXLHQvD+/IPhZz9eKlulYikocEJk1Vf72wuj8S8zjJEeF+Gfdr2xzBaG9me3sp0mKxIzKIx\nDMNoBfiZ3kqn33B/kedhbOosCUxoDMNorSSa3koFv9NyNnVmGIbRxsnW9Famw2RFw4TGMAyjwMl1\nFPhMY1NnhmEYBU4uvM4SYWs0SWBCYxiGkTy2RmMYhmEULCY0hmEYRlYxoTEMwzCyigmNYRiGkVVM\naAzDMIysYkJjGIZhZBUTGsMwDCOrmNAYhmEYWcWExjAMw8gqJjSGYRhGVjGhMQzDMKiuriYYDFJZ\nWUkow9E6TWgMwzAMNm7cyJo1a6itraW6ujqjfZvQGIZhtEIybYF07twZgPLychYtWpR2f14serNh\nGEYrobq6mo0bN9K5c2d27tzJ2rVrAaiqqqKmpiatvkOhENXV1SxatIhAlBzRliYgCUxoDMNorQSD\nQdasWQNA37592b59O+Xl5axcuTKqOGQSSxNgGIZRBHint1544QWqqqpyIjLpklWhEZEzRGSDiLwj\nIjNj1LnJvV4nIsclaisiPURkpYhsFJEVIhJwy78mIg+IyGsisl5EZmXztxmGYeSa+++/v0lchgwZ\nQk1NTcGLDGRx6kxE2gNvA2OBrcBLwEWq+panTiVwhapWisgo4H9UdXS8tiKyAPibqi5wBai7qs4S\nke8Bp6vqRSLSCVgPjFHV9yPGZVNnhmEYSVKoU2cnAptUtUFV9wBLgAkRdc4B7gFQ1ReBgIj0TdC2\nqY37fa57/CHQxRWpLsBXwM6s/DLDMAzDN9kUmgHAFs/5B26Znzr947Tto6o73OMdQB8AVX0SR1g+\nBBqAhaqa2V1HhmEYRtJ0yGLffuen/JhiEq0/VVURUQARmQx0AvoBPYDnRORpVa2PbDdv3rym42Aw\nSDAY9DlUwzCM4mD16tWsXr06I31lU2i2AoM854NwLJN4dQa6dUqilG91j3eISF9V3S4i/YCP3PKT\ngYdVdR/wsYisBcqBuEJjGIZhHEjkf8J/8pOfpNxXNqfOXgaGiUipiHQELgSWRtRZClwCICKjgZA7\nLRav7VJgins8BXjEPd4AfMvtqwswGmhyPDAMwzDyQ9YsGlXdKyJXAE8C7YHFrtfYdPf6Har6uIhU\nisgm4HPg+/Haul3fANSIyFSctZgL3PI7gMUi8jqOgP5WVd/I1u8zDMMw/GGRAQzDMIyEFKp7s2EY\nhpFhli+HyBiaoZBTXqiY0BiGYbQiKipgzpxmsQmFnPOKivyOKx4mNIZhGK2IQADmz3fEpaHB+Z4/\n3ymPRb6tIBMawzCMVkYgADNmQFmZ850o3FkyVlAsUUoHExrDMIxWRigECxdCfb3znUgIkrGCYolS\nOpjXmWEYRisi/OIPC0XkeTwaGhwrqL4eSksT32PGDEfI5s+H7t0t8ZlvTGgMw2jNLF/uWB1eUQmF\nYO1aGD8+drto4hFPmCJFydybDcMwioTx4w8UiEDAn8jMn++IRngaLdaUW7JTc4kwi8YwDKONk4wV\nFGtq7tZbberMNyY0hmEYsYklSrZGkwQmNIZhGMljazSGYRhGwWJCYxiGYWSVhEIjIgeLSHv3+Osi\nco6IlGR/aIZhGEZbIOEajYi8AnwD6A6sBV4CvlLVSdkfXuaxNRrDMIzkyfYajajqF8B5wK2qWgWM\nSOVmhmEYRubId7BMv/haoxGRk4BJQHj4trZjGIaRZ1pLygA/gnEVMBt4WFXfFJFDgVXZHZZhGIaR\niHjBMgvJ2rF9NIZhGK2caMEy0wm+GY101mhiCo2IPOY5VcB7A1XVc1K5Yb4xoTEMoy0RL1hmsoE0\n45EtoQm6h98B+gJ/wBGbi4AdqnpVKjfMNyY0hmG0FfxYLX5TAyQiK0Lj6fyvqnpCorLWggmNYRht\nhUTBMgveovF0/hZwlqq+654PBZar6pGp3DDfmNAYhlEMtIo1Gk/nZwCLgHq3qBSoVtUnU7lhvjGh\nMQyjGEg1QVossio07g2+BhyB4xSwQVV3p3KzQsCExjCMtk51dTUbN26kc+fO3H///QRSnS/zkI7Q\ndPBZ73igzK0/0r3hvanc0DAMw8guGzduZM2aNYAjOjU1NXkdT0KhEZE/AEOBdcA+zyUTGsMwjAKk\nc+fOAJSXl7No0aI8j8a/M8DwtjLfZFNnhmG0dUKhENXV1SxatCgj02aQ/aCabwD9UulcRM4QkQ0i\n8o6IzIxR5yb3ep2IHJeorYj0EJGVIrJRRFaISMBz7RgR+T8ReUNEXhORg1IZt2EYRiFQXV1NMBik\nsrKSUGQ8mTgEAgFqamoyJjLp4kdoegPr3Zf6Y+5naaJGbg6bW4AzgOHARSJyZESdSuAwVR0GVAO3\n+Wg7C1ipqocDT7vniEgH4Pc4HnEjgDHAHh+/zzAMoyAJr7XU1tZSXV2d7+GkjB9ngHnud3i+STzH\n8TgR2KSqDQAisgSYALzlqXMOcA+Aqr4oIgER6YvjeBCr7Tk4IoLbdjWO2IwDXlPV193+Gn2M0TAM\nI2ck63JcaGstqZLQolHV1cAG4BCgK7BeVdf46HsAsMVz/oFb5qdO/zht+6jqDvd4B9DHPT4cUBF5\nQkT+KiIzfIzRMAyfpDqNYzSTbFj/+++/n6qqKlauXFkw02Cp4Mfr7AJgIRAWl1tEZIaqPpSgqd8V\ndz+LS1GtKFVVEQmXd8DJBFoO7AKedkPlPBPZbt68eU3HwWCQYDDoc6iGUbyk6zKbjb0drQ1vWH8/\nYWHCay35YPXq1axevTojffmZOvsv4J9V9SMAEemNszaSSGi2AoM854NwLJN4dQa6dUqilG91j3eI\nSF9V3S4i/YCP3PItwLOq+nd3nI/j7P+JKzSGYfgj3WmcQtvbkS8CAUdkwoEuC1VvI/8T/pOf/CTl\nvnylcgY+9px/gj8r5GVgmIiUikhH4EIg0olgKXAJgIiMBkLutFi8tkuBKe7xFOAR93gFcLSIdHId\nA8YAb/oYp2EYPkh3GqetrDekSyjkWDL19c53UcxCqmrcD8602Qrge8D3gSeABYnauW3PBN4GNgGz\n3bLpwHRPnVvc63XA8fHauuU9gKeAje64Ap5rk3DcsV8HbogxJjUMI/c0NjZqVVWVNjY25nsoeaOx\nUfWyy5zvaOfpsmzZgX01NjrlqdTz4r47E773o338xjo7HwgvVz2nqg+npGoFgG3YNAwjX2Q60GUk\nfiM2pxLZOdvRm8uA7aq6yz3vhOP51ZDKDfONCY1hGG0Zvzloks1Vk/XEZ8BJqvqVe34QsFZVy1O5\nYb4xoTEMo9BJ1/Lxm1Uzmeyb2Q5B0z4sMgDqpAgoSeVmhlFs2N4TI1mqq6u5/vqzGDlyGZs3fwok\n3m/jxa+zQU6dEhIt4uAsvE/wnE8Ank51USjfH8wZwMghY8aMUZw9YFpVVZXv4RitgOa/M9300EOf\n0Pp6/w4Dfp0NUnFKIA1nAD8WzaXAj0Rki4hswQn3Mj3zkmcYbQ9z6TWSpfnvzDD+/OeTKCtz1lH8\neJSvXdtyrSW8QXTt2tTqZQpfXmcAInKwW/8f2RlKbrA1GiOXZCNcu9G2Cf+dWbjwThYs6OZ7sT7b\nZNsZoC8wHxigqmeIyHAc54DFqdww35jQGIZR6KTifpxtsi00TwB3A3NU9RgRKQFeVScUf6vDhMYw\njEIn2/ttwiQTfy7bQvOyqpaLyKuqepxbtk5Vj03lhvnGhMYwjEzSmoOFBoPBpvhzVVVVcePPZdu9\n+TMR6em52Wjg01RuZhiG0dZozcnJcuWs4kdo/hN4DBgqIs8D9wI/zNqIDMMwChzv/qiSEmdbYXl5\nOZ06dSIYDFJePrdpD0yYUMiZEotsH95ftXz5gXtZvG2yQc7y3cTye8bJkNnPPS4BLscJuf8boEeq\n/tT5/mD7aAzDSBPv/qgJEyY0BQuN3AMTDlTZ0NByn0pFxXiFyhb7q7IdcDNdyNI+mjuA3e7xSTh5\naX4DNAK2IcAwjKLFO+X0u9/9jpqaGgKBQIs9ME8/PZo5c2DQIDjrLLjmmmYPsi1bLgXWtpiy8iZF\na2jIv5dZRomlQECd5/g3wLxo11rbB7NoDMNIk1gpDyLL6+tVQbWuzrFOwrv8GxpCMVMmhNvU12f9\nZyQF2UgTICJvAMep6h4ReRuoVtU17rU3VfWorKtgFjCvM8No3eTK9TddIqMjT58OI0fGD2CZbETl\nXJItr7MHgDUishT4AnjOvdkwwKIDGoaRFyoqnJdxeOHcT8DJXAc39W6wLC11ps0mTYK6utgBLCPb\nhKfRMjncvAV5jWfu4KzNfAfo4ik7HE8mzNb2wabODCNtpk2bpmPGjNEzzzwzLxkzwwvlfgNO5jq4\naTiD5bRp07SiYrwOHvyYnnfef+iIETN17Njv6tSpXx4w5lSyXiZLOs+BNKbO8v7iz/XHhMYw0qcQ\nolIns5Zx5plnKqDl5eVxhTHTAuo8p0qFbtqrVy+Pp9qUjAqIX/w+h2iY0JjQGEZOSeeFlQmStWgi\nF+ljWQ8jRszMqIB6n9PYsWPz8sy84tnQ0BDTCSERJjQmNIaRU2J5XeXm3unvN4nVx9ix382oGHif\nU76eWaasTxMaExrDKBiyvX6TqbWMaFZRrsUgF+symbI+TWhMaAyjYMjn+k28F3e0a3V1mtc9K7mI\nBpAp8UxHaPzEOjMMw/BNPrOKxnN9jry2eXN0l+NcxhwLRwOoqFjF6NETGTlyGddc82lG984EAoGm\nyAV5I1WFaq0fzKIxjKySz/Ub5/6xHQXC1+rqVEeMcGKQecud6bPcxxwbNepCBVUYkjcvvkSQjcgA\nbRWLDGAYmaUQ87E0NEBZWfRd+OFrdXVwzDHN5d7oArncoR8KwciRy3j//Svo3XshL700jiFDumXn\nZmmQ7Xw0hmEYMSm0fCyhkCMO9fUH7sIPhWD8+FWMGjWRs89e1iKUfyDQHMImEHBEpqzM+c6myMyZ\nA88+ewpVVSfy0kvjWLCgW0ajARQCJjSGYaRFPtdkIgm/uD/77Eq+970gGzdWcfXVuwmFmq917/4L\nXnzxQd5/fzLf/vYLMcPBxBKrMJlYy1m71rGWhgzpRk1NDUOGdGP+fKe8TZHqnFtr/WBrNIaRUXKx\nJuPXDThcr2W+mCktvM687r4NDaED+vC7RlPo+WMyDYXq3gycAWwA3gFmxqhzk3u9DidadNy2QA9g\nJbARWAEEIvobDHwG/GeM+2Xw0RuGkQvCL/FLLvmhjhkzJma8sDDx9o4kEsZk9rYkG6GgNZOO0GTN\nGUBE2gMHBcPLAAAZjUlEQVRvA2OBrcBLwEWq+panTiVwhapWisgo4H9UdXS8tiKyAPibqi4QkZlA\nd1Wd5enzj8A+4C+q+oso49Js/WbDMLJHKARHHfUw27b9BzCDCRNe4pFHfhejbojq6moWLVqUsnOC\n18mhd+/ebN68OarDgx/ngrZAoToDnAhsUtUGVd0DLAEmRNQ5B7gHQFVfBAIi0jdB26Y27ve54c5E\n5FzgPWB9dn6SYRj5IhCAYcMeBRo4+ugn+d3vfh2nbvp7Rxwnhy7U1j7P448/7jo8CJMm/ahpHSYU\nguuug5tvdvbkbN7cXJ4odUExkU2hGQBs8Zx/4Jb5qdM/Tts+qrrDPd4B9AEQkYOBa4B5GRi7YRgF\nRigEhx12B5WVl3PiiQ8BjojEW5RPZ8HecXJYS+/ed3LUUY5ijBgh1NffzIgRTj9XX+3UnTwZli1z\nUja/9lobS8OcATpksW+/81N+TDGJ1p+qqoiEy+cBv1LVL0Qkbp/z5s1rOg4GgwSDQZ9DNQwjH4Qt\nhBtvPIhA4DctkoSFd/yHX+zeaxD/Wjzuv/9+qqurWbhwHD/96Tl06fL/6Nfvl/z4x+1ZsABOOMGp\nd+ONTt+BANx3X3MWzdYuMqtXr2b16tWZ6SzVxZ1EH2A08ITnfDYRDgHA7cBEz/kGHAslZlu3Tl/3\nuB+wwT1+Fqh3P43AJ8BlUcaV8mKYYRj5IdECvZ9oAPEW7BP1H5n7JlounLbuGEAhep3hWEvvAqVA\nR2AdcGREnUrgcW0WphcStQUWeERnFnBDlHvPBf5fjHFl9OEbhlEYxEuElihJWjxX5UgBaWiIFvW5\n7bs6F6TQOOPiTBzvsU3AbLdsOjDdU+cW93odnhTR0dq65T2Ap4jh3qwmNIZRdKRq0bRMChZKKCAN\nDdFjpC1Zkv1w//mmYIWmED8mNIZR2CSbz8aPNRLL0ohMaRBp+UROqS1b5oiMV0DamqDEwoTGhMYw\nWj3xdvVHIyxIJ5xwrTY0hA6wTmLloPEKQ2SUgLa8xpIuJjQmNIaRcTKRKTOZPiLTKR97bDDu7v9I\naySVhGvhKAFhkWnLayzpYkJjQmMYKRNLDDKRKTPZPhobVadO/VIrKy+LKzKqB4aZSSdlcS5SKrd2\n0hEay0djGEVOMBhkzZo1AFRVVVFTUwNAZWUltbW1lJeXs3LlypR22Tt9CMce+wWrVj3c1EcoBBMn\n3syXX/7pgBAvN9ywhJEjD4maS8ZLZJiZTISdMWKTTgiavFsYuf5gFo1RIGRiaioTxLIEMhGVubGx\nUSdMmNLCOglPS1VUjG+ydnr16uUed9NDD33C1kkKEGzqzITGaH1kYmoqE+QizH80F2OvwI0dO1ah\nm/buXaMNDaEWbcIRm/MtyMWOCY0JjdEKSWdNIVkKwXqKdB32ClxjY6N+4xs/axKZMI2NqiNGzCwI\nQS52TGhMaIxWSC4siTD5tp7SCc+SS0E2YpOO0JgzgGEUAZlY2E8VbyDLyMCWfoZhi/yFQTrOACY0\nhlEEJPOyXr7ciYjsrZZOEq9M92fkBxOaJDChMbKNNzNjZDbG1kC6FojRNinUDJuGUZQ4mRnXUFtb\nS3V1dVbvVV1dTTAYpLKyklBkhq8UCQQcUZkzx0lTnIrIpJNwLJN9GIWBCY1hZBgnMyOUl5ezaNGi\ntPuLJybZErVAAGbMgLIy59uPyHiFIZyMbPPm5vJkUxuH+wj3aemRWzGpehG01g/mdWZkmUx7k8Xz\nGIvnkZWOS3MqXmKxQurX1bUsTybcS1tPJtaawNybTWiMwiLWy/T0029K+uUfT0ziiVqqLs3pJPGK\nFIa6Oo2ZiTIsLuFEYt77eUUnUdIyIzeY0JjQGAVGrJe1N+xKshGGw2Li11JJZf/JtGnTdMSImTp2\n7HcjwtGor7D7qs3CELZk4iUjq6uLnkgs8rmZRZN/TGhMaIwc4+dlnyjsSqpTa34tlVSm8KL17RWX\n8G8KJ/+KJQyJBEQ1sSAVQ3rk1oQJjQmNkWP8vuzjhV1JlXTFKppIhkUjMhFYNDGJtfaSzJSYnyk2\nC91fWJjQmNAYOcbPyz5b0z7pilU0kWy2VEJxE4FFCkNdXXO/ftMc+xUuo7AwoTGhMXJMopd9vGmf\nfP1PPZ7V4h1jLGGMnOryMz0WbxzeNrGm4ozCwYTGhMbIAcm4C8cTk2ytPSQaXyKrRTW2h1estZd0\nrRGbHms9mNCY0Bg5IJMRkLMxreZnfPHuG+taorWXaOsrRtvDhMaExsgBmQ5XH29/SCqbLf2OL3zf\nxYv9TWH5sc7M/bjtY0JjQmPkgEzu+I98QUdmkUzFevIzPu99p051Pn43Tsbqy9yPiwMTGhMaoxUR\n7QXdv/+fFbo1CYtjnVTqsccGW7gg+/HqSua+YbFJxSKx9ZXiIh2hsTQBRqujtYfhj5af5bTTqnjq\nqS8oL/+IlStXAvC9711Fr153cOONBxEIOAEqzzoLli2DIUOSD98fKy/Mn/8MU6dCfT2Ulmb2txpt\nh3TSBOTdwsj1B7NoWj25TEucTmDKZIg17RU5xRae3srUmoitsRh+wabOTGiKCb+L3pkQiWyLWjKx\nw8JOA5kKMmlrLEYyFLTQAGcAG4B3gJkx6tzkXq8DjkvUFugBrAQ2AiuAgFt+GvAy8Jr7/c0o98ro\nwzdyj99F+UyIRKY9zSJJ9LL3Y9GkulZiayxGMhSs0ADtgU1AKVACrAOOjKhTCTzuHo8CXkjUFlgA\nXOMezwRucI+PBfq6x0cBH0QZU4Yfv1GoZMLyyXRumWj42b+i2rw5MnInfjRvMbNMjExTyEJzEvCE\n53wWMCuizu3AhZ7zDUDfeG3dOn3c477Ahij3FuAToCSiPHNP3sg7mRCJTFg+6U7TRZsOi7Q4vF5n\n4Wtei2bqVGdvjImMkQ3SEZpsp3IeAGzxnH/glvmp0z9O2z6qusM93gH0iXLv84G/quqe1IZutAbi\npTIOBALU1NQk9ErLROrldFIqh0KwcKHj9XX55Y53GcD48Y6HWCjkeIyNH+94m40f35zmOFwPYPdu\nx3vshBOi32P58pR+mmGkTbaFxq8fsR+XOYnWX1hpW1QUOQq4AZju8/5GKyVVkaiuriYYDFJZWclt\nt91GVVUVK1euTNlVOtVxeF2US0vh1lsdF+aw2ISvV1S0bBcIOG3mzIGGBrj6ajjoIEesnn/eOQ+F\n4vdhGDkjVVPIzwcYTcvpr9lEOATgTJ1N9JxvwLFQYrZ164TXYvrhmToDBgJvAyfFGJPOnTu36bNq\n1aqMmJVGfvCbfTKyPNZ0WapTYKmu5URbkG9oUB0/3p/LcXjKbfLkzG3ENAxV1VWrVrV4V1LAazQd\ngHdxFvQ7ktgZYDTNzgAx2+I4A4RFZxbNzgABHM+1c+OMKbN/GkZO8CsAsQQksjyWo0Au9+jEw48L\nc3jRf/Hi5lAy3muLF+sBOWPC18yzzEiWghUaZ2yc6VoYm4DZbtl0YLqnzi3u9Trg+Hht3fIewFMc\n6N78X8BnwKueT6+I8WT6+Rs5wK8AxBKQyPJYFki23Zn94GcTpV+36FRzxhhGJAUtNIX2MaHJPZnY\nOOlXAGLvsPc3tZULd+b49/fnqpxMvhvLYGlkgnSExmKdGVknGAyyZs0aAKqqqqipqUm6j1AoRHV1\nNYsWLWp1sc2SIVY8srVrm73LUunjtddg5EiLZ2akTjqxzkxojKxTWVlJbW0t5eXlaXl2GakR9jqb\nMcNxo/YbhNMwvJjQJIEJTfaJjK4cLmvr1kghEhnhOdmIz4YRxoQmCUxosk8mpspaI5mY9iqGMRmt\nk3SEJtsbNo0iJBM77XPN8uXNGxzDRNtNH69eeLd+IW2UDEcX8BIImMgYucUsGiMjeKfLbrvtNmbM\nmJH0VJm3j969e7N58+acJTeLnFJ68EFYuRJuvLH5RR0KwZNPwrPPxp6KsvUQo61iic/MvTnvZGKj\no7ePXr16ZX3jZKSLsDcwZXhnfTQ340T7XDKVL8YwCgnScG/ukBmtM4oRrwVSUlICJJ4ui3QUuOaa\na6L2EQgEeOqpp2L2l4m1h/BUl9fqCAemrK93yubMcYJUPv98S+tm+nQoK2uu5x1DOECmWTSG4ZKq\nQrXWD2bRqGrms09OmDAhpZD8sfpItHEyExsbve3q66PHB4sWSyzWBkjLWGm0ZbDIACY0yeJ3qiue\nIKUSriWyTTohXzIRqkXVX2DK8HG8kC6WsdJoy5jQmNAkjd8XfDxBSiVcS2SbdEO+JBN8MpogxQpM\nGRaaJUuazydP1gOCVHqTkXn7NHEx2homNCY0SeN9wUdaLd7zsWPH5j3IZCxiCUg0y6Kuzvnbvnjx\ngdZNWCjiWSexMljadJlRLJjQmNA0kcrai991k0ys66SD9+UfKRJLljRbJJHXvGsqXm+y8LVIoYi0\nRvxGSrbcL0ZbxoTGhKYJr0iUlZX5Ega/6yb5yNUSS1zmzm0pEpFTXWFxee65A9dUkk0K5mftxVya\njbaOCY0JTRNekaioqPAlDH7XTXKRqyXWlFWkgEQLeR9pWYSny6Il/gonBcuEMJhFYxQDJjRFLjTe\nKa2GhoYmkci0MKSzcO/XIyvatFSkBRIWkGgiEbYswkIUzwEgE8JgazRGsWBCU+RCE2tKK1IY8rnG\nEvkC9q6phEXIexy58J6MgMRzQc60MJhLs1EsmNAUgdB4ReKSSy5pIRiZcFXOBV5Lwrso77Vawudh\nV+L6+uQFJN4ivwmDYaSGCU0RCE28OGB+p7SyscYS78Udz83YKyCRu/KjHZuAGEZ+MaFpo0ITaz9L\nqntbIgUpWZFI1vU38lq0hXyvt1a0HfreKbZ44zAMI7uY0LRRoUk1DphfkhGJeGsZ8RbX4017RbNc\nInfoh+uasBhGfjGhaaNCkwt3Yq9IVFY2C0H42tSpqj/8YeKXf7x9JN6F/Mi+lyyJvkZjnluGUViY\n0BS40MTz9oq3yJ8pyyURkR5dXismvCgfGXAymrUTzRppaFAdPz5+mJhIr7Nwn2bFGEbhkI7QWIbN\nHBAMBlmzZg0AVVVVBAKBphwsO3fuZO3atQD06tWLv/3tb031ampqMj6WyDwuoRBcfTWcfDL89a9w\nzTWwYIGTIfK665w6//VfLY8vvxxuvRWGDGnOKHnNNfDCC05WSnByt3z6KZx1Fixb1rKu5WgxjNaH\nZdgscIsmcgrMu/bSt2/ftBf5ExErjEt4oT1yyirsGRZpxXijF8dyJfbugYmcigv3Y5aKYbQ+sKmz\nwhCaWNNg3t36qi2Fx3stWzvvY3l/3Xxz7KmuWGHzw5sow+ISzQHA4n4ZRtvDhKZAhMZvzvtEghJL\nNObObVnuzYXitVQiA06qHrhWEi2MS6y1l2h7VxL1YXG/DKNtYUKTQ6Hxu0M/2jRYrAXwsIB4LZCw\nR5Z3asr77Q1/H56eihexODLIpN88LtEELnyvyEX+ZFyiDcNoXRSs0ABnABuAd4CZMerc5F6vA45L\n1BboAawENgIrgIDn2my3/gZgXIz7JXyg8cTEsVoqFbp5rJZKraz8N12y5B/6jW/8TBsaQtrQENLh\nwx/UhoZQVAHxuvQ2NMQOyRK5/yRy02PkFFYsMQnXixfGxS+xBCX8uyLr2pqMYbR+ClJogPbAJqAU\nKAHWAUdG1KkEHnePRwEvJGoLLACucY9nAje4x8PdeiVuu01Auyjjijn9FBaDiorxCnMVummPHkNd\nYXHE5IQTrlXopr1712hFxb8oVOqIEeP1yCP3akODfwGJF3YlUSDJyCmrRPViLd4/9tgqVU1eDNpi\nuJdVq1blewgFgz2LZuxZNFOoQnMS8ITnfBYwK6LO7cCFnvMNQN94bd06fdzjvsAGbbZmvJbPE8Do\nKOOKujA+ceJMragYrwMH1mr//ssVBmuvXg+7x92axKSuLqRVVVVaVxfSI4/cq6ed9p86deqXLSwL\nvwLiDbsSeRy51pGspeK1fGJ5f1100dwk/pq1bebOnZvvIRQM9iyasWfRTDpC04HsMQDY4jn/AMdq\nSVRnANA/Tts+qrrDPd4B9HGP+wMvROnrAObPh4qKVXTtegcffjiZxx47hTPPHMW2bUuALQweXEpl\n5Vn06HEmIvDJJ5Po1++X/PjH7VmwoBsLFtSwcCEsWQIjR95Ifb2zT2TGDCgrg/p65z6xjhcudI7D\ne1NiHd94o7Pf5JprnP0ozz0HkyY170sJly9bBm+84XwvWNC8FyZcft99B+5fCQTg8MOjPR3DMIzM\nkk2h8bsr0s8GIInWn6qqiMS7T9RrgQB07XoHL764BCjluutOZNiwzmzb1sDRR5/DH/7wB0aOPM0j\nEr85QEzq6uCOOxxhWLjQebknIyAtfpznCQQCcNppzRsfQ6Fm0bj77mYxmT+/WVzeeAPGj3fqz58P\nv/51s6gMGdJcvnZtcz3DMIyckaoplOgDjKbl9FeLqS1tnjqb6DnfgGOhxGzr1unrHvejeeqsxdQc\nztTZqCjjUvvYxz72sU/yn0KcOnsZGCYipcA24ELgoog6S4ErgCUiMhoIqeoOEfkkTtulwBTg5+73\nI57y+0XklzhTZsOAv0QOSlMNoWAYhmGkRNaERlX3isgVwJM4XmSLVfUtEZnuXr9DVR8XkUoR2QR8\nDnw/Xlu36xuAGhGZCjQAF7ht1otIDbAe2Atc5i5gGYZhGHmk6IJqGoZhGLmlXb4HkEtE5AwR2SAi\n74jIzHyPJ1eIyCARWSUib4rIGyLyQ7e8h4isFJGNIrJCRIomprKItBeRV0XkMfe8KJ+FiARE5I8i\n8paIrBeRUUX8LGa7/0ZeF5H7ReSgYnkWIvJbEdkhIq97ymL+dvdZveO+T8cl6r9ohEZE2gO34EQc\nGA5cJCJH5ndUOWMP8B+qehSOo8Xl7m+fBaxU1cOBp93zYuFKnGnWsElfrM/if3A2TR8JHIPjbFN0\nz8JdD54GHK+qR+NM2U+keJ7F3TjvRi9Rf7uIDMdZNx/utrlVROJqSdEIDXAisElVG1R1D7AEmJDn\nMeUEVd2uquvc48+At3AcJs4B7nGr3QOcm58R5hYRGYgTleIumt3ri+5ZiEg34BRV/S04a6Oq+ilF\n+CyAnTj/IessIh2AzjiOSEXxLFT1OaAxojjWb58APKCqe1S1AScKy4nx+i8moYm1ObSocP/ndhzw\nIrE3v7Z1fgXMAPZ7yorxWZQBH4vI3SLyiojcKSJdKMJnoap/B34BvI8jMCFVXUkRPgsP8TbHf+Cp\nl/BdWkxCU/ReDyJyMPAn4EpV/Yf3WjjERF4GlkNE5CzgI1V9lRibhYvlWeB4nR4P3Kqqx+N4fraY\nGiqWZyEihwJX4cRJ7A8cLCKTvXWK5VlEw8dvj/tciklotgKDPOeDaKnKbRoRKcERmd+ranjv0Q4R\n6ete7wd8lK/x5ZCTgXNEpB54APiWiPye4nwWHwAfqOpL7vkfcYRnexE+i3LgeVX9RFX3An/GiblY\njM8iTKx/E5Hv0oFuWUyKSWiaNpCKSEecxayleR5TThARARYD61X1155L4c2v0HLza5tFVX+kqoNU\ntQxnsfcZVb2Y4nwW24EtIhKOejcWeBN4jCJ7FjhOEKNFpJP772UsjrNIMT6LMLH+TSwFJopIRxEp\nI8bmeC9FtY9GRM4Efk3zJtDr8zyknCAi3wCeBV6j2cSdjfOXowYYjLv5VVVD+RhjPhCRMcB/quo5\nItKDInwWIjISxymiI/Auzqbp9hTns7gG54W6H3gF+FegK0XwLETkAWAM0AtnPeZa4FFi/HYR+RHw\nA5zN8Veq6pNx+y8moTEMwzByTzFNnRmGYRh5wITGMAzDyComNIZhGEZWMaExDMMwsooJjWEYhpFV\nTGgMwzCMrGJCYxhJIiLnish+Efl6nsfxExH5dj7HYBh+sH00hpEkIvIg0Al4RVXnRbnewQ1jEvXc\nMIoNs2gMIwncwKSjgCtwwhiFy4Mi8pyIPAq8KSJjPOdvuHUeEZGX3eRz09yyH4jIrzz9TBORX0bc\ns72I/M5NyPWaiFzplv9ORM4XkRPcJG6vunX2u9cPFZFa957P5tsCM4qXDvkegGG0MiYAT6jq+yLy\nsYgcr6qvuNeOA45S1c0iEvSeu9e/r6qNItIJ+IuI/BF4EPiRiFytqvuA7wHVEfc8FujvJuRCRA5x\nyxUnsO5f3XshIguAx93ri4DpqrpJREYBtwI21WbkHBMaw0iOi3Dy2QA85J6HheYvHlGJdn6liIST\nRw0ChqnqX0TkGeBsEdkAlKjqmxH3fBcYKiI3AcuBFZ5rTakORORCnOjLp7mW10nAQ06MSMCJZ2YY\nOceExjB84gbe/CYwQkQUJ/ik4iRRAyefi5fPPW2DONbEaFX9UkRWAV9zL98FzMHJfPrbyPuqakhE\njsFJm3spcAEwNWJsI4C5OBkz1U2tG1LV41L/xYaRGWyNxjD8813gXlUtVdUyVR0M1IvIKT7aHgI0\nuiJzBDA6fEFV/4KT0+NfcHLktEBEegIdVPXPwI9xp8nCzUUk4La7WFU/cfvc6Y7tu24f4oqVYeQc\nExrD8M9E4OGIsj/hTJ9FZiCMPH8C6CAi64Hrgf+L6KcG+F9V/TTKfQcAq0TkVeD3OCkevJyDE8r9\nLtchIDyVNwmYKiLrcBwSzkn8Ew0j85h7s2EUACLyGPBLVV2V77EYRqYxi8Yw8oiIBETkbeALExmj\nrWIWjWEYhpFVzKIxDMMwsooJjWEYhpFVTGgMwzCMrGJCYxiGYWQVExrDMAwjq5jQGIZhGFnl/wO+\n0BezaUN1owAAAABJRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x108659fd0>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import numpy as np\n",
"import pylab as pl\n",
"%matplotlib inline\n",
"pl.clf()\n",
"sizes = np.arange(1,100,1)\n",
"(y1,y2) = np.array(exper_analysis(sizes))\n",
"pl.plot(sizes, y1, 'k.', label = 'Merge sort')\n",
"pl.plot(sizes, y2, 'bx', label = 'Insertion sort')\n",
"pl.xlabel('Array size')\n",
"pl.ylabel('Seconds')\n",
"pl.legend(loc = 'upper left')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"El ordenamiento por mezcla funciona más efecientemente que el ordenamiento por inserción para arreglos suficientemente grandes, para arreglos con tamaños por debajo de 80, funciona más eficientemente ordenamiento por inserción **¿Como podemos mejorar el ordenamiento por mezcla teniendo esto en cuenta?**"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment