diff --git a/README.md b/README.md index 6eadd2f..b13948a 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,14 @@ ![](https://user-images.githubusercontent.com/35543500/111094823-74c67200-8512-11eb-912b-8e90c0995334.mp4) -This purpose of this project is to test different research ideas for cellular automata. This is in the form of hypotheses, demos, simulations, and unstructured trial/error. Some of these hypotheses are: +This purpose of this project is to test different research ideas for cellular automata. This is in the form of hypotheses, demos, simulations, and unstructured trial/error. The main ideas that have been developed in this repo are: - How can we detect the self-producing cycles? - How can we detect moving cycles? (mobiles) - Can a Reinforcement Learning Agent interact with a CA environment to create a desired state? + + ## How to Use You can utilize these functions and programs by cloning/forking this repository. Depending on future development, the structure of this project might change into a Python package available on PyPI. diff --git a/app/ml_app.py b/app/ml_app.py new file mode 100644 index 0000000..c239856 --- /dev/null +++ b/app/ml_app.py @@ -0,0 +1,15 @@ +from flask import Flask +import numpy as np + +import sys +sys.path.append('../src/') + +from path_handler import PathHandler as PH +import sim.automata as atm +from sim.rules import Rules + +app = Flask(__name__) + +@app.route('/') +def hello_world(): + return "

Hello world

" \ No newline at end of file diff --git a/nb/automata-analysis-v0.ipynb b/nb/automata-analysis-v0.ipynb index 638c465..7a282d2 100644 --- a/nb/automata-analysis-v0.ipynb +++ b/nb/automata-analysis-v0.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "6d13da26", + "id": "62ebc07b", "metadata": {}, "source": [ "*This notebook is my own notes / development playground. It will be disorganized in nature. Feel free to skim through.*" @@ -21,9 +21,11 @@ "\n", "import sys\n", "sys.path.append('../src')\n", - "import automata as atm\n", - "import analysis as ans\n", - "from rules import Rules" + "import sim.automata as atm\n", + "import analysis.analysis as ans\n", + "import analysis.stats as stats\n", + "from sim.rules import Rules\n", + "import sim.sim as sim\n" ] }, { @@ -45,7 +47,7 @@ { "cell_type": "code", "execution_count": 24, - "id": "6f4c7b39", + "id": "65ad9432", "metadata": {}, "outputs": [ { @@ -98,7 +100,7 @@ }, { "cell_type": "markdown", - "id": "85bae9cf", + "id": "2b0cd07e", "metadata": {}, "source": [ "### Cycle Detection\n", @@ -136,7 +138,7 @@ { "cell_type": "code", "execution_count": 24, - "id": "615b1ade", + "id": "74f9eba7", "metadata": {}, "outputs": [], "source": [ @@ -147,7 +149,7 @@ { "cell_type": "code", "execution_count": 41, - "id": "765a7122", + "id": "d2438b6e", "metadata": {}, "outputs": [ { @@ -171,7 +173,7 @@ { "cell_type": "code", "execution_count": 27, - "id": "282d1836", + "id": "ebe7688b", "metadata": {}, "outputs": [ { @@ -193,7 +195,7 @@ { "cell_type": "code", "execution_count": 28, - "id": "b6bd8818", + "id": "8790872c", "metadata": {}, "outputs": [ { @@ -215,7 +217,7 @@ { "cell_type": "code", "execution_count": 7, - "id": "8fc3a363", + "id": "e4f45f26", "metadata": {}, "outputs": [ { @@ -241,7 +243,7 @@ { "cell_type": "code", "execution_count": 13, - "id": "cfa03711", + "id": "423b910d", "metadata": {}, "outputs": [ { @@ -266,7 +268,7 @@ { "cell_type": "code", "execution_count": 24, - "id": "1a71c907", + "id": "397df0bc", "metadata": {}, "outputs": [ { @@ -294,7 +296,7 @@ { "cell_type": "code", "execution_count": 22, - "id": "47b21960", + "id": "ef1b8cd7", "metadata": {}, "outputs": [ { @@ -329,7 +331,7 @@ }, { "cell_type": "markdown", - "id": "15cfba73", + "id": "fc9d4509", "metadata": {}, "source": [ "### Testing Rule Integration" @@ -338,7 +340,7 @@ { "cell_type": "code", "execution_count": 2, - "id": "b2ee2e99", + "id": "5f301f1d", "metadata": {}, "outputs": [ { @@ -360,7 +362,7 @@ { "cell_type": "code", "execution_count": 3, - "id": "be5c2199", + "id": "e42577c3", "metadata": {}, "outputs": [ { @@ -395,7 +397,7 @@ { "cell_type": "code", "execution_count": 9, - "id": "21f9d915", + "id": "d7aa9251", "metadata": {}, "outputs": [], "source": [ @@ -406,7 +408,7 @@ { "cell_type": "code", "execution_count": 11, - "id": "ae73a168", + "id": "acd48c9f", "metadata": {}, "outputs": [ { @@ -429,7 +431,7 @@ { "cell_type": "code", "execution_count": 15, - "id": "dd3b7c8c", + "id": "d9054d01", "metadata": {}, "outputs": [ { @@ -454,7 +456,7 @@ { "cell_type": "code", "execution_count": 26, - "id": "481183f3", + "id": "0aa0022c", "metadata": {}, "outputs": [ { @@ -477,7 +479,7 @@ { "cell_type": "code", "execution_count": 35, - "id": "6564f077", + "id": "f62c5f18", "metadata": {}, "outputs": [], "source": [ @@ -487,7 +489,7 @@ { "cell_type": "code", "execution_count": 39, - "id": "8f809a1e", + "id": "6c79138d", "metadata": {}, "outputs": [ { @@ -512,7 +514,7 @@ { "cell_type": "code", "execution_count": 40, - "id": "91d3e52f", + "id": "110fb79a", "metadata": {}, "outputs": [ { @@ -537,7 +539,7 @@ { "cell_type": "code", "execution_count": 72, - "id": "edece9a0", + "id": "96dbf82a", "metadata": {}, "outputs": [ { @@ -559,7 +561,7 @@ { "cell_type": "code", "execution_count": 77, - "id": "6bbde2aa", + "id": "a4f65937", "metadata": {}, "outputs": [ { @@ -584,7 +586,7 @@ { "cell_type": "code", "execution_count": 79, - "id": "e2cde96c", + "id": "6351938d", "metadata": {}, "outputs": [ { @@ -606,7 +608,7 @@ { "cell_type": "code", "execution_count": 59, - "id": "3b58c967", + "id": "4d2d1964", "metadata": {}, "outputs": [ { @@ -630,7 +632,7 @@ { "cell_type": "code", "execution_count": 54, - "id": "d7a778ae", + "id": "1d8afd75", "metadata": {}, "outputs": [], "source": [ @@ -640,7 +642,7 @@ { "cell_type": "code", "execution_count": 55, - "id": "745885f1", + "id": "2d69bfbf", "metadata": {}, "outputs": [ { @@ -661,7 +663,7 @@ { "cell_type": "code", "execution_count": 57, - "id": "76365ec8", + "id": "16f19223", "metadata": {}, "outputs": [ { @@ -682,13 +684,304 @@ "plt.show()" ] }, + { + "cell_type": "markdown", + "id": "350b2f5d", + "metadata": {}, + "source": [ + "---\n", + "# Detecting Cycles" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "f1d284e5", + "metadata": {}, + "outputs": [], + "source": [ + "state = np.array([\n", + " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],\n", + " [0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n", + "], dtype = int)" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "3d1b98ec", + "metadata": {}, + "outputs": [], + "source": [ + "state_no_cycle = atm.get_random_state((11,11))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ef92f1aa", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(3, 11, 22)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "states.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "5829018b", + "metadata": {}, + "outputs": [], + "source": [ + "states = sim.play(state, steps = 3, rule = Rules.CONWAY)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "2acc4202", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWAAAAC5CAYAAAAWJ+UfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFOUlEQVR4nO3dMWojZxjH4XdSK7gJGIN7HUA5017Abn0Dn2AvowusDqAy4MYkpfpJk2KDN0w0s9Z/Xul5QM2Gl2++sfZHcODNMI5jAXB5v6QfAOBWCTBAiAADhAgwQIgAA4QIMEDKOI7/+1NV49zPw8NDu9muz+19ufNaZ7s+99I7V9WfP2rqxf4N+Onpqd1s8uyOs8mz3bnHbPLs5J2r6o8f/aFfQQCECDBAiAADhAgwQIgAA4QIMECIAAOECDBAiAADhAgwQIgAA4QIMECIAAOEDFP/V+RhGL5U1Zeqqru7u93Ly8usgx4fH+vt7a3VbPLsjrPJs925x2zy7OSdn5+fD+M4/v7hH1xqH/Dr62u72a7P7X2581pnuz730jtX1bfoPmAA/k2AAUIEGCBEgAFCBBggRIABQgQYIESAAUIEGCBEgAFCBBggRIABQgQYIMQ6ygnb7bY2m82s2dPpFJs9Ho+zZq0a7HN2x9nk2dZRNputqnG/349zJWdT76vjz9mdva/PvnNZRwmwLgIMECLAACECDBAiwAAhAgwQIsAAIQIMECLAACECDBAiwAAhAgwQIsAAIQI84XA41DAMsz7JWa7fbrc7a5vh95+ls/wc9gGv9OyOs8mzb/HOyV3Vc/dNV/X8OdsHbHfp6me7PnfXO3fcN93152wfMMCVEWCAEAEGCBFggBABBggRYIAQAQYIEWCAEAEGCBFggBABBggRYICQFgG2Ou+y5r7rcWKzHh8t+W4n1536jvwcLdZRLl27Z3XeebP39/ezZquq3t/fW945tY5yyXc7+a59R87Teh2l1XmXnV2i651T35El323fkR6z/3ysowRYEwEGCBFggBABBggRYIAQAQYIEWCAEAEGCBFggBABBggRYIAQAQYIEWAIWrIWkv6so5zQcf2dVYOXm02e7TvSY7bKOsp2K+ysGuwx2/W5fUcu+x0p6ygB1kWAAUIEGCBEgAFCBBggRIABQgQYIESAAUIEGCBEgAFCBBggRIABQgQYIMQ6ygkd199ZNXi52eTZS/9eJGarbvM7Yh1lsxV2Vg32mE2evfTvRWJ2HG/zO1LWUQKsiwADhAgwQIgAA4QIMECIAAOECDBAiAADhAgwQIgAA4QIMECIAAOECDBASIt1lLe4arDjbPJsd+4xmzzbOspms12f2/ty57XOdn1u6ygBrowAA4QIMECIAAOECDBAiAADhAgwQIgAA4QIMECIAAOECDBAiAADhAgwQIgAT9jtdmdtjPv+k5wF1s8+4Anb7bY2m82s2dPpFJs9Ho+zZu167XN2x9nk2fYBN5utqnG/349zJWdT76vjz9mdva/PvnPZBwywLgIMECLAACECDBAiwAAhAgwQIsAAIQIMECLAACECDBAiwAAhAgwQIsATDodDDcMw65OcBdbPOsqVnt1xNnm2O/eYTZ5tHWWz2a7P7X2581pnuz63dZQAV0aAAUIEGCBEgAFCBBggRIABQgQYIESAAUIEGCBEgAFCBBggRIABQgQYIMQ6ypWe3XE2ebY795hNnm0dZbPZrs/tfbnzWme7Prd1lABXRoABQgQYIESAAUIEGCBEgAFCBBggRIABQgQYIESAAUIEGCBEgAFCBBgg5Kx1lFW1rarjzLN+q6q/ms0mz+44mzzbnXvMJs9O3nk7juOvH/70nHWUSz71H+vY1jzb9bm9L3de62zX5/6sO/sVBECIAAOEXDLAXxvOJs/uOJs82517zCbPXt2dJ/8jHACfw68gAEIEGCBEgAFCBBggRIABQv4GykHyBtO685wAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWAAAAC5CAYAAAAWJ+UfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFaklEQVR4nO3cPW4bVxSG4cPUCtQEEASw5wKYNXkDVqsdcAXZjDYQLoBlADVCUqqfVPm1A5lzQ35zOM8DsLFxcOeO6ReGDJzNNE0FwPV9l34AgLUSYIAQAQYIEWCAEAEGCBFggJRpmr75U1XT3M/j42O72a7P7X2581Jnuz736J2r6tevNfVq/wL+/Plzu9nk2R1nk2e7c4/Z5NnJO1fVL1/7RT+CAAgRYIAQAQYIEWCAEAEGCBFggBABBggRYIAQAQYIEWCAEAEGCBFggBABvqD9fn/Wtrl/bZ4Dbtzmo7/sm83mU1V9qqq6v7/fPz8/zzpou93W6+trq9nR+d1uV3d3d7Nm397eVve+Os4mz+44mzw7eeenp6fjNE0/fvEb19oHfDgc2s2Ozr+8vExzrfF9dZzt+tze13XvXFU/R/cBA/BPAgwQIsAAIQIMECLAACECDBAiwAAhAgwQIsAAIQIMECLAACECDBAiwAAh1lFecN46ytufTZ7dcTZ5tnWUzWZH562jvP3Zrs/tfV33zmUdJcCyCDBAiAADhAgwQIgAA4QIMECIAAOECDBAiAADhAgwQIgAA4QIMECIAAOECDA0td/vz9pm+PfP6Cz/D/uALzhvH/DtzybPHvl+vb+/D82eTqdZs1U9/5ztA264u9Q+4NufTZ498v0ane34vuwDBuBPAgwQIsAAIQIMECLAACECDBAiwAAhAgwQIsAAIQIMECLAACECDBAiwBd0PB5rs9nM+sClzf1uHo/H2asspw+2L66NdZQLPbvjbPLsNd55dB3l3JWS2+22Hh4eZs1W9Vy1ah1laI1cx+f2vtZx59RKycPhMPvcaeq5atU6SoAbI8AAIQIMECLAACECDBAiwAAhAgwQIsAAIQIMECLAACECDBAiwAAhVwvwfr+fvb4uNTs1Xp2Xel8j86yD78hfrraOcnR1XmK2qu/qvLnrAkff18h8x3edPLvrOso1fkfi6yhHV+clZqep7+q81Psame/4rpNnd11HucbvSFlHCbAsAgwQIsAAIQIMECLAACECDBAiwAAhAgwQIsAAIQIMECLAACECDBAiwAAhV1tHmVzN2HHVYMfZ5NnufP5samVpx5WS7ddRdl0j1/G5vS93/pbZuda64nXkO1LWUQIsiwADhAgwQIgAA4QIMECIAAOECDBAiAADhAgwQIgAA4QIMECIAAOECDBAiHWUF5zf7Xaz1/Z1XNmXPNudz58dWUd5Op1mzf5xdsf3ZR1lYI3cyPzI2r41vq+Os12fe3Qd5Rrf18idyzpKgGURYIAQAQYIEWCAEAEGCBFggBABBggRYIAQAQYIEWCAEAEGCBFggBABBggRYFipzWYz63M8HtOPfjPsA77gvH3Atz+bPLvjbPJs+4CbzY7O2wd8+7Ndn9v7uu6dyz5ggGURYIAQAQYIEWCAEAEGCBFggBABBggRYIAQAQYIEWCAEAEGCBFggBABBgixjvKC89ZR3v5s8uyOs8mzraNsNjs6bx3l7c92fW7v67p3LusoAZZFgAFCBBggRIABQgQYIESAAUIEGCBEgAFCBBggRIABQgQYIESAAUIEGCDEOsqFnt1xNnm2O/eYTZ5tHWWz2a7P7X2581Jnuz63dZQAN0aAAUIEGCBEgAFCBBggRIABQgQYIESAAUIEGCBEgAFCBBggRIABQgQYIOSsdZRVtauq08yzfqiq35rNJs/uOJs82517zCbPTt55N03T91/86jnrKEc+9R/r2JY82/W5vS93Xups1+e+1J39CAIgRIABQq4Z4J8azibP7jibPNude8wmz17cnT/8TzgALsOPIABCBBggRIABQgQYIESAAUJ+B32OgtLhfFpYAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "for i in range(3):\n", + " ans.plot_state(states[i])" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "a13c2518", + "metadata": {}, + "outputs": [], + "source": [ + "states_no_cycle = sim.play(state_no_cycle, steps = 3, rule = Rules.CONWAY)" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "f4fdc4a8", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, axs = plt.subplots(2, 2, figsize = (20, 10))\n", + "s0 = axs[0, 0].imshow(states_no_cycle[0] == states_no_cycle[1], cmap = 'gray')\n", + "s1 = axs[0, 1].imshow(states_no_cycle[0] & states_no_cycle[1], cmap = 'gray')\n", + "s2 = axs[1, 0].imshow(states_no_cycle[0] != states_no_cycle[1], cmap = 'gray')\n", + "s3 = axs[1, 1].imshow(states_no_cycle[0] | states_no_cycle[1], cmap = 'gray')\n", + "\n", + "# a ==b is equiv ! (a xor b)\n", + "axs[0, 0].set_title('a == b')\n", + "axs[0, 1].set_title('a & b')\n", + "axs[1, 0].set_title('a != b')\n", + "axs[1, 1].set_title('a | b')\n", + "\n", + "\n", + "fig.colorbar(s0, ax = axs[0], ticks = [0, 1], shrink = 0.5)\n", + "fig.colorbar(s1, ax = axs[1], ticks = [0, 1], shrink = 0.5)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "0e94c8ec", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# T = 2 oscillating cycle\n", + "plt.imshow(states[0] == states[2], cmap = 'gray')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "95568420", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, axs = plt.subplots(2, 2, figsize = (20, 10))\n", + "s0 = axs[0, 0].imshow(states[0] == states[1], cmap = 'gray')\n", + "s1 = axs[0, 1].imshow(states[0] & states[1], cmap = 'gray')\n", + "s2 = axs[1, 0].imshow(states[0] != states[1], cmap = 'gray')\n", + "s3 = axs[1, 1].imshow(states[0] | states[1], cmap = 'gray')\n", + "\n", + "# a ==b is equiv ! (a xor b)\n", + "axs[0, 0].set_title('a == b')\n", + "axs[0, 1].set_title('a & b')\n", + "axs[1, 0].set_title('a != b')\n", + "axs[1, 1].set_title('a | b')\n", + "\n", + "\n", + "fig.colorbar(s0, ax = axs[0], ticks = [0, 1], shrink = 0.5)\n", + "fig.colorbar(s1, ax = axs[1], ticks = [0, 1], shrink = 0.5)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "74e2311e", + "metadata": {}, + "source": [ + "Idea -- Consider the $a \\lor b$ chart. It is the union of the cells in a and b right. It is symmetrical in 2 dimensions. Does this imply that it will always be a cycle?" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "13607e9c", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.imshow(stats.get_alive_matrix(states[1]) - stats.get_alive_matrix(states[0]), cmap = 'gray')\n", + "plt.colorbar()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "ed9be12c", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.imshow(stats.get_alive_matrix(states_no_cycle[1]) - stats.get_alive_matrix(states_no_cycle[0]), cmap = 'gray')\n", + "plt.colorbar()\n", + "plt.show()" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "13ecc371", + "id": "4ca6e951", "metadata": {}, "outputs": [], - "source": [] + "source": [ + "states_no_cycle" + ] } ], "metadata": { diff --git a/nb/q-learning-v0.ipynb b/nb/q-learning-v0.ipynb index 632cb08..b782579 100644 --- a/nb/q-learning-v0.ipynb +++ b/nb/q-learning-v0.ipynb @@ -176,6 +176,48 @@ "agent = run(init_state, action_func, reward_func, num_training = 1000, num_testing = 500)" ] }, + { + "cell_type": "code", + "execution_count": 15, + "id": "dda8f4c4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "agent.is_in_testing()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "ff27c8fd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(40, 47)" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "agent.get_action(init_state) // 50, agent.get_action(init_state) % 50" + ] + }, { "cell_type": "code", "execution_count": 3, @@ -186,6 +228,14 @@ "states = sim.play(init_state.values, steps = 100)" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "1ac594b3", + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": 7, @@ -258,13 +308,59 @@ "ans.plot_state(init_state.values)" ] }, + { + "cell_type": "markdown", + "id": "40f79b79", + "metadata": {}, + "source": [ + " --- " + ] + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "id": "7f78f0a0", "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAOsAAADrCAYAAACICmHVAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAE1klEQVR4nO3dMW4bVxhG0TdBSgZuAhgG3HMBzJq8Abn1DryCbGa8gHAB7N0YSMl+UgdyIikYi++G5wCsDHx+knBhpfmzbNs2gPn9dOsHAM8jVogQK0SIFSLEChFihYpt2579GWNse33evXu325a9ebbubW/vt40xtn/q72b/sj48PNibZG/mt82+t/fb/o1fgyFCrBAhVogQK0SIFSLEChFihQixQoRYIUKsECFWiBArRIgVIsQKEWKFCLFChFgh4udbP4D/5nQ6jb3+bwpfvnzZZYcfa3nqB74sy4cxxocxxnjz5s3p06dPu/zF79+/H1+/ft1l6x73jsfjOBwOu2xdr9dxuVx22Rpj/u/dnnt7v+3jx49j27blu394q4Npnz9/3vXI1L3treu67WVd16m/1pn39n7bGBMeTANeRqwQIVaIECtEiBUixAoRYoUIsUKEWCFCrBAhVogQK0SIFSLEChFihQixQoRYIcJZl+iesy5z7DnrYu/Jj7Muc+w56wI8IlaIECtEiBUixAoRYoUIsUKEWCFCrBAhVogQK0SIFSLEChFihQixQoRYIUKsECFWiHCDKbrnBtMce24w2Xvy4wbTHHtuMAGPiBUixAoRYoUIsUKEWCFCrBAhVogQK0SIFSLEChFihQixQoRYIUKsECFWiBArRIg16nw+j2VZdvmcz+dbfzk8gxtM9qZ+2+x7bjDZe9W9md82+54bTMAjYoUIsUKEWCFCrBAhVogQK0SIFSLEChFihQixQoRYIUKsECFWiBArRIgVIsQKETeN9SVXKp76nE6nqffuzcw/iz33TqfTq31Pb3qD6e3bt7tsjTHG9Xodh8Nh2r1v377dzR2he/rZXq/XcblcdtkaY+IbTHta13XqvXu6I3RPP9t1Xd1gAv5OrBAhVogQK0SIFSLEChFihQixQoRYIUKsECFWiBArRIgVIsQKEWKFCLFChFgh4qZnXWY9c3JvezO/bfa9vd827VkXe3Pszfy22ff2ftsYzrpAnlghQqwQIVaIECtEiBUixAoRYoUIsUKEWCFCrBAhVogQK0SIFSLEChFihQixQoRYIcINpuje8Xgch8Nhl63r9Toul8suW2PM/71zg+l/dFensLeu67aXdV2n/lpn3nODCXhErBAhVogQK0SIFSLEChFihQixQoRYIUKsECFWiBArRIgVIsQKEWKFCLFChFghQqwQ4QZTdM8Npjn23GCy9+THDaY59txgAh4RK0SIFSLEChFihQixQoRYIUKsECFWiBArRIgVIsQKEWKFCLFChFghQqwQIVaIECtEuMEU3XODaY49N5jsPflxg2mOPTeYgEfEChFihQixQoRYIUKsECFWiBArRIgVIsQKEWKFCLFChFghQqwQIVaIECtEiBUixBp1Pp/Hsiy7fM7n862/HJ7BDSZ7U79t9j03mOy96t7Mb5t9zw0m4BGxQoRYIUKsECFWiBArRIgVIsQKEWKFCLFChFghQqwQIVaIECtEiBUixAoRYoWIF511GWMcxxiXnf7uX8cYf+60ZW+erXvb2/ttx23bfvneHzwZ64+yLMsf27b9Zu/2ezO/bfa913ybX4MhQqwQcctYf7c3zd7Mb5t979XedrP/ZgVexq/BECFWiBArRIgVIsQKEX8B8esbOrdlY1cAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "state = np.array([\n", + " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0],\n", + " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],\n", + " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n", + "], dtype = int)\n", + "ans.plot_state(state)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3aa86906", + "metadata": {}, "outputs": [], - "source": [] + "source": [ + "\"\"" + ] } ], "metadata": { diff --git a/src/analysis/analysis.py b/src/analysis/analysis.py index d058b81..e433495 100644 --- a/src/analysis/analysis.py +++ b/src/analysis/analysis.py @@ -40,8 +40,8 @@ def plot_state(state): else: axs.imshow(state[0], cmap = 'gray') - axs.set_xticks(np.arange(len(state))+0.5) - axs.set_yticks(np.arange(len(state))+0.5) + axs.set_xticks(np.arange(state.shape[1])+0.5) + axs.set_yticks(np.arange(state.shape[0])+0.5) axs.set_xticklabels([]) axs.set_yticklabels([]) axs.grid() diff --git a/src/analysis/feature_extract.py b/src/analysis/feature_extract.py index d574d64..2a9406f 100644 --- a/src/analysis/feature_extract.py +++ b/src/analysis/feature_extract.py @@ -6,3 +6,5 @@ import sim.automata as atm from sim.rules import Rules +def num_cycles(states): + ... \ No newline at end of file diff --git a/src/sim/automata.py b/src/sim/automata.py index 7af8dfd..7d25b6d 100644 --- a/src/sim/automata.py +++ b/src/sim/automata.py @@ -53,7 +53,10 @@ def np_update(state): def get_neighbors(i, j, shape): # list comp generates all neighbors including center. If center or invalid neighbor, # does i-10, j-10 as coord to remove in next step - neighbors = np.reshape([[[i + u, j + v] if in_range(i + u, j + v, shape = shape) else [i - 10, j - 10] for u in [-1, 0, 1]] for v in [-1, 0, 1]], (-1, 2)) + neighbors = np.reshape( + [[[i + u, j + v] if in_range(i + u, j + v, shape = shape) else [i - 10, j - 10] for u in [-1, 0, 1]] for v in [-1, 0, 1]], + size = (-1, 2) + ) return neighbors[~np.all(np.logical_or(neighbors == [i, j], neighbors == [i - 10, j - 10]), axis = 1)] # make sure to exlude center and not in-range values '''