Add files via upload

This commit is contained in:
Peter Norvig authored and GitHub committed 2017-09-10 00:05:22 -07:00
1 parent bca17cda91
commit 1727294cc0
1 file changed
+180 -285
+180 -285
View File
@@ -25,17 +25,17 @@
" \n",
"Now the first person chooses one of the four houses (which are all acceptable). We'll indicate an occupied house by a `1`, so the four equiprobable choices are:\n",
"\n",
" 1...\n",
" .1..\n",
" ..1.\n",
" ...1\n",
" Choice 0: 1...\n",
" Choice 1: .1..\n",
" Choice 2: ..1.\n",
" Choice 3: ...1\n",
" \n",
"When a house is occupied, any adjacent houses become unacceptable. We'll indicate that with a `0`:\n",
"\n",
" 10..\n",
" 010.\n",
" .010\n",
" ..01\n",
" Choice 0: 10..\n",
" Choice 1: 010.\n",
" Choice 2: .010\n",
" Choice 3: ..01\n",
" \n",
"In all four cases, a second occupant has a place to move in, but then there is no place for a third occupant. \n",
"The occupancy is 2 in all cases, and thus the *expected occpancy* is 2. The occupancy fraction, or *density*, is 2/*N* = 2/4 = 1/2.\n",
@@ -45,35 +45,35 @@
"\n",
"With *N*=7 houses, there are 7 equiprobable choices for the first occupant:\n",
"\n",
" 10.....\n",
" 010....\n",
" .010...\n",
" ..010..\n",
" ...010.\n",
" ....010\n",
" .....01\n",
" Choice 0: 10.....\n",
" Choice 1: 010....\n",
" Choice 2: .010...\n",
" Choice 3: ..010..\n",
" Choice 4: ...010.\n",
" Choice 5: ....010\n",
" Choice 6: .....01\n",
" \n",
"Now we'll add something new: the lengths of the **runs** of consecutive acceptable houses to the left and right of the chosen house:\n",
"\n",
" 10..... runs = (0, 5)\n",
" 010.... runs = (0, 4)\n",
" .010... runs = (1, 3)\n",
" ..010.. runs = (2, 2)\n",
" ...010. runs = (3, 1)\n",
" ....010 runs = (4, 0)\n",
" .....01 runs = (5, 0)\n",
" Choice 0: 10..... runs = (0, 5)\n",
" Choice 1: 010.... runs = (0, 4)\n",
" Choice 2: .010... runs = (1, 3) \n",
" Choice 3: ..010.. runs = (2, 2) \n",
" Choice 4: ...010. runs = (3, 1) \n",
" Choice 5: ....010 runs = (4, 0) \n",
" Choice 6: .....01 runs = (5, 0) \n",
" \n",
"# Defining `occ(n)`\n",
"\n",
"This gives me a key hint as to how to analyze the problem. I'll define `occ(n)` to be the expected number of occupied houses in a row of `n` houses. So:\n",
"\n",
" 10..... runs = (0, 5); occupancy = occ(0) + 1 + occ(5)\n",
" 010.... runs = (0, 4); occupancy = occ(0) + 1 + occ(4)\n",
" .010... runs = (1, 3); occupancy = occ(1) + 1 + occ(3)\n",
" ..010.. runs = (2, 2); occupancy = occ(2) + 1 + occ(2)\n",
" ...010. runs = (3, 1); occupancy = occ(3) + 1 + occ(1)\n",
" ....010 runs = (4, 0); occupancy = occ(4) + 1 + occ(0)\n",
" .....01 runs = (5, 0); occupancy = occ(5) + 1 + occ(0) \n",
" Choice 0: 10..... runs = (0, 5); occupancy = occ(0) + 1 + occ(5)\n",
" Choice 1: 010.... runs = (0, 4); occupancy = occ(0) + 1 + occ(4)\n",
" Choice 2: .010... runs = (1, 3); occupancy = occ(1) + 1 + occ(3)\n",
" Choice 3: ..010.. runs = (2, 2); occupancy = occ(2) + 1 + occ(2)\n",
" Choice 4: ...010. runs = (3, 1); occupancy = occ(3) + 1 + occ(1)\n",
" Choice 5: ....010 runs = (4, 0); occupancy = occ(4) + 1 + occ(0)\n",
" Choice 6: .....01 runs = (5, 0); occupancy = occ(5) + 1 + occ(0) \n",
" \n",
"So we can say that `occ(n)` is:\n",
"\n",
@@ -88,9 +88,7 @@
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [],
"source": [
"from statistics import mean\n",
@@ -115,44 +113,47 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's check that `occ(4)` is 2, as we computed it should be:"
"Let's check that `occ(4)` is 2, as we computed it should be, and for other small values, up to 7:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": false
},
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2.0"
"{0: 0,\n",
" 1: 1,\n",
" 2: 1,\n",
" 3: 1.6666666666666667,\n",
" 4: 2,\n",
" 5: 2.466666666666667,\n",
" 6: 2.888888888888889,\n",
" 7: 3.323809523809524}"
]
},
"execution_count": 30,
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"occ(4)"
"{n: occ(n) for n in range(8)}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And that `runs(7)` is what we described above:"
"That looks good, although I can't prove the value above 4 are ccorrect. Now check that `runs(7)` is what we described above:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"metadata": {},
"outputs": [
{
"data": {
@@ -173,75 +174,15 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's check on `n = 7`:"
"# Dynamic Programming Version of `occ`\n",
"\n",
"The computation of `occ(n)` makes multiple calls to `occ(n-1), occ(n-2),` etc. To avoid re-computing the same calls over and over, we will modify `occ` to save previous results using [dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming). I could implement that in one line with the decorator [`@functools.lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache), but then I would have to worry about the recursion limit. Instead I will explicitly manage a list, `cache`, such that `cache[n]` holds `occ(n)`:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"3.3238095238095235"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"occ(7)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"0.47482993197278905"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"density(7)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"That seems reasonable, but I don't know for sure that it is correct. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Dynamic Programming Version of `occ`\n",
"\n",
"The computation of `occ(n)` makes multiple calls to `occ(n-1), occ(n-2),` etc. To avoid re-computing the same calls over and over, we will modify `occ` to save previous results using [dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming). I could implement that in one line with the decorator [`@functools.lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache), but instead I will explicitly manage a list, `cache`, such that `cache[n]` holds `occ(n)`:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def occ(n, cache=[0, 1]):\n",
@@ -262,10 +203,8 @@
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"collapsed": false
},
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
@@ -273,7 +212,7 @@
"True"
]
},
"execution_count": 32,
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
@@ -284,46 +223,42 @@
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": false
},
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.47482993197278905"
"3.323809523809524"
]
},
"execution_count": 33,
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"density(7)"
"occ(7)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's make sure the caching makes computation faster the second time:"
"Let's make sure the caching makes computation pretty fast the first time, and *very* fast the second time:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 6.23 s, sys: 115 ms, total: 6.34 s\n",
"Wall time: 6.97 s\n"
"CPU times: user 2.68 s, sys: 13.5 ms, total: 2.7 s\n",
"Wall time: 2.71 s\n"
]
},
{
@@ -332,7 +267,7 @@
"864.9617138385324"
]
},
"execution_count": 9,
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
@@ -343,17 +278,15 @@
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 5 µs, sys: 0 ns, total: 5 µs\n",
"Wall time: 9.06 µs\n"
"CPU times: user 4 µs, sys: 0 ns, total: 4 µs\n",
"Wall time: 5.01 µs\n"
]
},
{
@@ -362,7 +295,7 @@
"864.9617138385324"
]
},
"execution_count": 10,
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
@@ -382,14 +315,13 @@
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"plt.style.use('fivethirtyeight')\n",
"\n",
"def plot_density(ns):\n",
" \"Plot density(n) for each n in the list of numbers ns.\"\n",
@@ -400,10 +332,8 @@
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
@@ -411,15 +341,15 @@
"0.4353323288377046"
]
},
"execution_count": 12,
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<matplotlib.figure.Figure at 0x1043b8eb8>"
"<matplotlib.figure.Figure at 0x11202c0b8>"
]
},
"metadata": {},
@@ -439,10 +369,8 @@
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
@@ -450,15 +378,15 @@
"0.46203174603174607"
]
},
"execution_count": 13,
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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 truncated
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAcAAAAEtCAYAAACf/7AvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XlYVPX+B/D3mYUdYkA2UVwRRk1Qy7DFSK9aN03Npcyl\nK6mpVFfvz/LazYo0d71tYiV6KzMtC9PUupqKWZItZnlLETVwQ0Bk2JdZzu8PdGAWltGBM8O8X8/j\ng+fMOWc+g8Wb7znfRdBoNCKIiIhcjEzqAoiIiKTAACQiIpfEACQiIpfEACQiIpfEACQiIpfEACQi\nIpfEACQiIpckeQAePnwY48ePR/fu3aFSqbB58+ZGz/njjz/w4IMPIiwsDD169MDy5ctboFIiImpN\nJA/AsrIy9OjRA0uXLoWXl1ejx5eUlGDUqFEIDQ1FWloalixZgjfffBNr1qxpgWqJiKi1UEhdwODB\ngzF48GAAwKxZsxo9/pNPPkFFRQXWrl0LNzc3REVF4dSpU0hOTkZiYmJzl0tERK2E5C1AW/3444/o\n378/3NzcjPsGDRqEnJwcnDt3TsLKiIjImThdAObl5SE4ONhkX1BQEERRRF5enkRVERGRs3G6ACQi\nIrIHpwvA4OBgi5Zefn4+BEGwaBkSERHVx+kCsF+/fkhPT0d1dbVx3/79+xEWFoaIiAgJKyMiImci\neQCWlZXh+PHj+O2332AwGHDhwgUcP34cFy5cAAAkJSVhxIgRxuPHjBkDLy8vzJo1CydOnMCOHTvw\n+uuvN9oDNH5HHkb/I6lZP8vNyMzMlLqEJmGd9uMMNQKs095Yp+OQPAB/+eUXDBgwAPHx8aisrMSS\nJUtw7733YsmSJQCA3NxcZGdnG4/38/PDtm3bkJOTg4EDB2LevHl4+umnGx1CkZP6Bnw9PZr1sxAR\nkfOQfBzg3XffjcLCwnpfT05OttinVquxa9cum94n7OFnMDDa2+b6iIiodZK8BdiSThZqpS6BiIgc\nhEsF4AmNDqIoSl0GERE5AJcKwMIqA/IrDVKXQUREDsClAhAATvA2KBERwQUD8KRGJ3UJRETkAFww\nANkCJCIiFwzADI0OenaEISJyeS4XgOU6EedL9VKXQUREEnO5AAQ4HpCIiFw1ANkRhojI5blkAJ5g\nRxgiIpfnkgF4pkiHaj07whARuTKXCcAQz9qPqhOBM8W8DUpE5MpcJgCj/ZUm27wNSkTk2lwmANUq\n05WfMgrZAiQicmUuE4BsARIRUV0uE4Dd/BUQ6myfK9WjVMuVIYiIXJXLBKCXQoYOvnKTfac4HpCI\nyGW5TAACgJq3QYmI6BqXCsBof9OOMCfZEYaIyGW5VgCqTFuAXBqJiMh1uVQAdvZTQFnnE+dXGnCl\nkitDEBG5IpcKQKVMQNdbeBuUiIhcLAABy44wvA1KROSaXC4AzQfEMwCJiFyT6wWg2ZRoJzU6iCJX\nhiAicjUuF4DtvOXwVtTOCVOqFXGxjB1hiIhcjcsFoEwQLMYDnuCMMERELsflAhCwMh6wkM8BiYhc\njUMEYEpKCmJiYhAaGor4+Hikp6c3ePy2bdtwzz33oG3btujVqxfefPNNm96PHWGIiEjyAExNTcX8\n+fMxd+5cHDp0CP369cPYsWNx8eJFq8fv3bsX06ZNQ0JCAtLT07Fq1SokJycjJSWlye9pvjbgqSId\ndAZ2hCEiciWSB2BycjImTpyISZMmITIyEsuXL0dISAg2bNhg9fhPPvkEDzzwAKZMmYIOHTpg8ODB\nmDNnDl577bUmv2cbDznaeNR+dK0BOFvM54BERK5E0gDUarU4duwY4uPjTfYPHDgQR44csXpOVVUV\nPDw8TPZ5eHjg0qVLOH/+fJPf22JibHaEISJyKZIGYEFBAfR6PYKDg032BwUFIS8vz+o5gwYNwu7d\nu3HgwAGIoojTp09jzZo1AIDc3Nwmv7eaE2MTEbk0yW+B2urxxx/H9OnTMWHCBAQFBWHIkCEYPXo0\nAEAma/rHiTJfG5A9QYmIXIqg0Wgk6/2h1WoRFhaG9evXY8SIEcb9zz77LE6cOIGdO3fWe64oisjN\nzUWbNm2QlpaGcePG4fTp0wgICLB6fGZmpsl2uR74+6lbjNsCRLwRVQwPp/uVgIjI9URGRt70NRSN\nH9J8lEolYmNjkZaWZhKABw4cwMiRIxs8VxAEhIaGAgC2bt2Kfv361Rt+gPVvVvtLBThfWjMLjAgB\nhjYdEBnodiMf5aZlZmba5R+0ubFO+3GGGgHWaW+s03FIGoAAkJiYiBkzZqB3796Ii4vD+vXrkZub\niylTpgAAkpKScPToUWzfvh0AcPXqVXz++ee4++67UVVVhQ8//BBffPEFdu/ebfN7R/srjAEIACcK\ndYiRKACJiKhlSR6Ao0aNQmFhIVatWoXc3Fyo1Wps3boV4eHhAGo6tmRnZ5ucs2XLFrz00ksQRRG3\n3347du3ahdjYWJvfW+2vxN4LVcbtDHaEISJyGZIHIAAkJCQgISHB6mvJyckm2wEBAdizZ49d3td8\nSrQTDEAiIpfh0l0+uvgpIK9dGAKXyw3QVBmkK4iIiFqMSwegu1xAFz/zAfFsBRIRuQKXDkDAckA8\nxwMSEbkGlw9ATolGROSaGIBWlkYSRa4MQUTU2rl8AEb4yuFZpydMUbWIy+XsCENE1Nq5fADKBQHd\nzG6DcjgEEVHr5/IBCNQMiK+LPUGJiFo/BiCAaLMV4k8WsiMMEVFrxwCEZUeYU0Va6AzsCENE1Jox\nAAGEeMqgcqvtCFOpB87VmSSbiIhaHwYgapZWspgXlAPiiYhaNQbgNdbGAxIRUevFALzGoiMMZ4Qh\nImrVGIDXmLcAzxTrUKVnRxgiotaKAXjNLW4ytPWq/XYYRCCziK1AIqLWigFYh3lHGD4HJCJqvRiA\ndVjMCMOeoERErRYDsI4oizlBeQuUiKi1YgDWEXmLErLa8fC4WKZHcTVXhiAiao0YgHV4KgR08jVt\nBWbwOSARUavEADRjvkI8b4MSEbVODEAzarOeoGwBEhG1TgxAM+YtwD8KdRBFDognImptGIBmOvoq\n4C6v3S6sMiC/kh1hiIhaGwagGYVMQOQtHA9IRNTaMQCtULMjDBFRq8cAtIJLIxERtX4MQCvMl0bK\n0OhgYEcYIqJWxSECMCUlBTExMQgNDUV8fDzS09MbPH7fvn0YMmQI2rdvjy5duuCxxx7DmTNn7FZP\nWy85/JS1U8KU60ScL9Xb7fpERCQ9yQMwNTUV8+fPx9y5c3Ho0CH069cPY8eOxcWLF60en52djQkT\nJuCuu+7CoUOHsH37dlRVVWHcuHF2q0kQBESZ3QY9wY4wREStiuQBmJycjIkTJ2LSpEmIjIzE8uXL\nERISgg0bNlg9/tixY9DpdHjxxRfRsWNH9OzZE7Nnz8aff/6JwsJCu9Wl5grxREStmqQBqNVqcezY\nMcTHx5vsHzhwII4cOWL1nD59+kCpVOKDDz6AwWBASUkJPvroI/Tt2xcqlcputbEjDBFR6yZpABYU\nFECv1yM4ONhkf1BQEPLy8qye0759e6SmpmLx4sUIDg5Ghw4dcPLkSWzZssWutZkH4OkiHar17AhD\nRNRaKBo/xLHk5eXh6aefxvjx4zF69GiUlpZi8eLFePzxx7Fz5856z8vMzLT5vQIUvriqq/kdQScC\nab//iU6ezdcZ5kZqlALrtB9nqBFgnfbGOm9eZGTkTV/DpgAURRG///47MjIyUFBQAEEQEBgYiG7d\nuqFHjx4QBKHxi9QRGBgIuVxu0drLz8+3aBVet27dOnh7e+Pll1827nvnnXfQo0cPHDlyBHfccYfV\n827km3WrpggHc6qM22W+oYjs5GXzdZoiMzPTLv+gzY112o8z1AiwTntjnY6jSQH4zTffYNOmTfjy\nyy9RWlpqMTm0IAjw8fHB/fffjwkTJuDee+9t0psrlUrExsYiLS0NI0aMMO4/cOAARo4cafWciooK\nyOVyk30yWU0rzWCw75yd0f4KkwA8WagDOtn1LYiISCINBuDXX3+NV199FceOHYNarcakSZMQGxuL\njh07wt/fH6IoQqPRIDs7G8eOHTMGV0xMDBYsWIBBgwY1WkBiYiJmzJiB3r17Iy4uDuvXr0dubi6m\nTJkCAEhKSsLRo0exfft2AMCQIUOwdu1aLF++HGPGjEFxcTEWLlyIdu3aITY21g7fklrRKnaEISJq\nrRoMwMmTJ2PSpEl4++23ERUVVe9x18fuAUBGRgbWr1+PyZMn1zuWr65Ro0ahsLAQq1atQm5uLtRq\nNbZu3Yrw8HAAQG5uLrKzs43HDxgwACkpKXj99dfx5ptvwtPTE7fddhs+++wzeHp6NulDN1WUvwIC\ngOvt3XOlepRqDfBRSj56hIiIbpKg0Wjq7dpYUFCAwMDAG7rwzZzrSP52oABZJbUdX1b390efIDe7\nv4+z3G9nnfbjDDUCrNPeWKfjaLApczMB1hrCD+B4QCKi1or38hphvjQSZ4QhImodbB4G8d5772Hj\nxo3IysqCRqOxOEYQBBQUFNitQKlFqTgnKBFRa2RTAL744otYs2YNbr31VowbNw7+/v7NVZfD6OKn\ngFIGaK+NsMivNKCgUo9AD3nDJxIRkUOzKQA3b96Mhx56CO+9914zleN4lDIBXW9R4ERh7a3Pkxod\n7gplABIROTObngFWVlZaTFztCsw7wvA2KBGR87MpAAcMGICjR482Vy0Oy7wjTAY7whAROT2bAnDV\nqlX46aefsHLlynpXa2iNzGeEOaHRWkwHR0REzsWmZ4C9e/eGKIpYvHgxFi9eDKVSaZyH8zpBEHDp\n0iW7Fim1dt5yeCsElOlqQq9UK+JimR7tfJxuMQ0iIrrGpp/go0aNsnnFh9ZAJgiI8Line truncated
"text/plain": [
"<matplotlib.figure.Figure at 0x10c5ac940>"
"<matplotlib.figure.Figure at 0x1120519e8>"
]
},
"metadata": {},
@@ -478,10 +406,8 @@
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
@@ -489,15 +415,15 @@
"0.43240754751464183"
]
},
"execution_count": 14,
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<matplotlib.figure.Figure at 0x10ca875c0>"
"<matplotlib.figure.Figure at 0x1149702e8>"
]
},
"metadata": {},
@@ -523,7 +449,7 @@
"\n",
"# lim <sub>n &rarr; &infin;</sub> density(n)\n",
"\n",
"[Thes puzzle](http://fivethirtyeight.com/features/can-you-solve-the-puzzle-of-your-misanthropic-neighbors/)\n",
"[The puzzle](http://fivethirtyeight.com/features/can-you-solve-the-puzzle-of-your-misanthropic-neighbors/)\n",
"is to figure out the limit of `density(n)` as `n` goes to infinity. The plot above makes it look like 0.432+something, but we can't answer the question just by plotting; we'll need to switch modes from *computational* thinking to *mathematical* thinking.\n",
"\n",
"At this point I started playing around with `density(n)`, looking at various values, differences of values, ratios of values, and ratios of differences of values, hoping to achieve some mathematical insight. Mostly I got dead ends.\n",
@@ -532,10 +458,8 @@
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
@@ -543,7 +467,7 @@
"0.0014849853757253895"
]
},
"execution_count": 15,
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
@@ -563,10 +487,8 @@
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
@@ -574,7 +496,7 @@
"0.0007424926878626947"
]
},
"execution_count": 16,
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
@@ -592,10 +514,8 @@
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
@@ -603,7 +523,7 @@
"2.0"
]
},
"execution_count": 17,
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
@@ -621,10 +541,8 @@
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false
},
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
@@ -632,7 +550,27 @@
"2.0"
]
},
"execution_count": 18,
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"n = 250; diff(n, 2*n) / diff(2*n, 4*n)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2.0"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
@@ -641,28 +579,6 @@
"n = 500; diff(n, 2*n) / diff(2*n, 4*n)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"1.9999999999992524"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"n = 1000; diff(n, 2*n) / diff(2*n, 4*n)"
]
},
{
"cell_type": "markdown",
"metadata": {},
@@ -682,24 +598,22 @@
"\n",
" density(n) = A + B / n \n",
" \n",
"would fit the patterm. I can try a `curve_fit` to estimate the parameters *A* and *B*:"
"would fit the patterm. I can try a `scipy.optimize.curve_fit` to estimate the parameters *A* and *B*:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false
},
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 7.64810902e-34, -2.42654280e-31],\n",
" [ -2.42654280e-31, 4.67778766e-28]])"
"array([[ 4.70916321e-33, -1.30373854e-30],\n",
" [ -1.30373854e-30, 1.44885627e-27]])"
]
},
"execution_count": 20,
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
@@ -707,7 +621,7 @@
"source": [
"from scipy.optimize import curve_fit\n",
"\n",
"Ns = list(range(100, 10001, 100))\n",
"Ns = list(range(100, 5001, 100))\n",
"\n",
"def f(n, A, B): return A + B / n\n",
"\n",
@@ -725,18 +639,16 @@
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false
},
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(0.43233235838169343, 0.29699707514520357)"
"(0.43233235838169332, 0.29699707514503415)"
]
},
"execution_count": 21,
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
@@ -754,10 +666,8 @@
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false
},
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"def estimated_density(n): return A + B / n"
@@ -772,18 +682,16 @@
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3.8857805861880479e-16"
"6.106226635438361e-16"
]
},
"execution_count": 23,
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
@@ -801,7 +709,7 @@
"\n",
"We now have a plausible answer to the puzzle:\n",
"\n",
"> lim<sub style=\"font-size:large\"> <tt>n</tt>&rarr;&infin;</sub> <tt>density(n) &cong; A = 0.43233235838169343</tt>"
"> lim<sub style=\"font-size:large\"> <tt>n</tt>&rarr;&infin;</sub> <tt>density(n) &cong; A = 0.43233235838169</tt>"
]
},
{
@@ -812,7 +720,7 @@
"\n",
"Theis answer is empirically strong (15 decimal places of accuracy) but theoretically weak: we don't have a **proof**, and we don't have an explanation for **why** the density function has this form. We need some more mathematical thinking. \n",
"\n",
"I didn't have any ideas, so I looked to see if anyone else had written something about the number 0.43233235838169343. I tried several searches and found two interesting formulas:\n",
"I didn't have any ideas, so I looked to see if anyone else had written something about the number 0.432332358169 I tried several searches and found two interesting formulas:\n",
"\n",
"- Search: [`[0.4323323]`](https://www.google.com/search?q=0.4323323) Formula: `sinh(1) / exp(1)` [(Page)](http://arxiv.org/pdf/1310.4360.pdf)\n",
"- Search: [`[0.432332358]`](https://www.google.com/search?q=0.432332358) Formula: `0.5(1-e^(-2))` [(Page)](http://www.actuarialoutpost.com/actuarial_discussion_forum/archive/index.php/t-52095.html)\n",
@@ -822,18 +730,16 @@
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false
},
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(0.43233235838169365, 0.43233235838169365, 0.43233235838169343)"
"(0.43233235838169365, 0.43233235838169365, 0.43233235838169332)"
]
},
"execution_count": 24,
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
@@ -844,8 +750,6 @@
"S = sinh(1) / exp(1)\n",
"E = 0.5 * (1 - e ** (-2))\n",
"\n",
"assert S == E\n",
"\n",
"S, E, A"
]
},
@@ -933,9 +837,9 @@
"\n",
"Is our implementation of `occ(n)` correct? I think it is, but I can anticipate some objections and answer them:\n",
"\n",
"- In `occ(n)`, is it ok to start from all empty houses, rather than considering layouts of partially-occupied houses? Yes, I think it is ok, because the problem states that initially all houses are empty, and each choice of a house breaks the street up into runs of acceptable houses, flanked by unacceptable houses. If we get the computation right for a run of `n` acceptable houses, then we can get the whole answer right. A key point is that the chosen first house breaks the row of houses into 2 runs of *acceptable* houses, not 2 runs of *unoccupied* houses. If it were unoccupied houses, then we would have to also keep track of whether there were occupied houses to the right and/or left of the runs. By considering runs of acceptable houses, eveything is clean and simple.\n",
"- *In `occ(n)`, is it ok to start from all empty houses, rather than considering layouts of partially-occupied houses?* Yes, because the problem states that initially all houses are empty, and each choice of a house breaks the street up into runs of acceptable houses, flanked by unacceptable houses. If we get the computation right for a run of `n` acceptable houses, then we can get the whole answer right. A key point is that the chosen first house breaks the row of houses into 2 runs of *acceptable* houses, not 2 runs of *unoccupied* houses. If it were unoccupied houses, then we would have to also keep track of whether there were occupied houses to the right and/or left of the runs. By considering runs of acceptable houses, eveything is clean and simple.\n",
"\n",
"- In `occ(7)`, if the first house chosen is 2, that breaks the street up into runs of 1 and 3 acceptable houses. There is only one way to occupy the 1 house, but there are several ways to occupy the 3 houses. Shouldn't the average give more weight to the 3 houses, since there are more possibilities there? No, I don't think so. We are caclulating occupancy, and there is a specific number (5/3) which is the expected occupancy of 3 houses; it doesn't matter if there is one combination or a million combinations that contribute to that expected value, all that matters is what the expected value is.\n",
"- *In `occ(7)`, if the first house chosen is 2, that breaks the street up into runs of 1 and 3 acceptable houses. There is only one way to occupy the 1 house, but there are several ways to occupy the 3 houses. Shouldn't the average give more weight to the 3 houses, since there are more possibilities there?* No. We are caclulating occupancy, and there is a specific number (5/3) which is the expected occupancy of 3 houses; it doesn't matter if there is one combination or a million combinations that contribute to that expected value, all that matters is what the expected value is.\n",
"\n",
"\n"
]
@@ -948,19 +852,17 @@
"\n",
"\n",
"A simulation can add credence to our implementation of `density(n)`, for two reasons:\n",
"- The code for the simulation can have a more direct corresponance to the problem statement.\n",
"- The code for the simulation can have a more direct correspondance to the problem statement.\n",
"- When two very different implementations get the same result, that is evidence supporting both of them.\n",
"\n",
"\n",
"The simulation will start with an empty set of occupied houses. Following Lamping's suggestion, we sample <i>n</i> houses (to get a random ordering) and go through them, occupying just the ones that have no neighbor\" "
"The simulation will start with an empty set of occupied houses. We then go through the houses in random order, occupying just the ones that have no neighbor. (Note that `random.sample(range(n), n)` gives a random ordering of `range(n)`.)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false
},
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"import random\n",
@@ -988,28 +890,27 @@
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false
},
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" n simul density estimated\n",
" 25 0.444 0.444 0.444\n",
" 50 0.438 0.438 0.438\n",
"100 0.435 0.435 0.435\n",
"200 0.434 0.434 0.434\n",
"400 0.433 0.433 0.433\n"
" n simulate density estimated\n",
" 10 0.4621 0.4620 0.4620\n",
" 25 0.4442 0.4442 0.4442\n",
" 50 0.4383 0.4383 0.4383\n",
" 100 0.4354 0.4353 0.4353\n",
" 200 0.4339 0.4338 0.4338\n",
" 400 0.4331 0.4331 0.4331\n"
]
}
],
"source": [
"print(' n simul density estimated')\n",
"for n in (25, 50, 100, 200, 400):\n",
" print('{:3} {:.3} {:.3} {:.3}'\n",
"print(' n simulate density estimated')\n",
"for n in (10, 25, 50, 100, 200, 400):\n",
" print('{:4d} {:.4f} {:.4f} {:.4f}'\n",
" .format(n, simulated_density(n), density(n), estimated_density(n)))"
]
},
@@ -1017,17 +918,15 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"We got perfect agreement (at least to 3 decimal places), suggesting that either our three implementations are all correct, or we've made mistakes in all three. \n",
"We get good agreement (at least to 3 decimal places), suggesting that either our three implementations are all correct, or we've made mistakes in all three. \n",
"\n",
"The `simulate` function can also give us insights when we look at the results it produces:"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
@@ -1035,7 +934,7 @@
"[0, 2, 4, 6]"
]
},
"execution_count": 27,
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
@@ -1053,24 +952,22 @@
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false
},
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Counter({(0, 2, 4, 6): 3303,\n",
" (0, 2, 5): 1255,\n",
" (0, 3, 5): 959,\n",
" (0, 3, 6): 783,\n",
" (1, 3, 5): 1426,\n",
" (1, 3, 6): 974,\n",
" (1, 4, 6): 1300})"
"Counter({(0, 2, 4, 6): 3220,\n",
" (0, 2, 5): 1214,\n",
" (0, 3, 5): 1029,\n",
" (0, 3, 6): 827,\n",
" (1, 3, 5): 1417,\n",
" (1, 3, 6): 976,\n",
" (1, 4, 6): 1317})"
]
},
"execution_count": 28,
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
@@ -1099,10 +996,8 @@
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"collapsed": false
},
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
@@ -1110,7 +1005,7 @@
"'ok'"
]
},
"execution_count": 29,
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
@@ -1135,9 +1030,9 @@
" occupied = set(occupied) # coerce to set\n",
" for house in range(n):\n",
" if house in occupied:\n",
" assert (house - 1) not in occupied and (house + 1) not in occupied\n",
" assert not ((house - 1) in occupied or (house + 1) in occupied)\n",
" else:\n",
" assert (house - 1) in occupied or (house + 1) in occupied\n",
" assert (house - 1) in occupied or (house + 1) in occupied\n",
"\n",
"test()"
]
@@ -1172,9 +1067,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.1"
"version": "3.5.3"
}
},
"nbformat": 4,
"nbformat_minor": 0
"nbformat_minor": 1
}