{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "from genome import Genome, mutate\n",
    "import visualization"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Agenda\n",
    "\n",
    "1. Ausgangssituation NEAT\n",
    "2. Mutation\n",
    "3. Reproduktion\n",
    "4. Selektion\n",
    "5. Rekombination"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ausgangssituation zum Start\n",
    "NEAT startet ohne hidden nodes, fully connected mit zufälligen Gewichten\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 34332 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "g1 = Genome.new(3, 2)\n",
    "\n",
    "visualization.genome(g1)\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Mutation\n",
    "\n",
    "Neben der normalen Mutation von Gewichten, gibt es zwei Arten von struktureller Mutationen beim Neat-Algorithmus:\n",
    "- Einen Knoten hinzufügen (Kante zum Knoten erhält Gewicht 1, Kante vom neuen Knoten weg erhält das vorige Gewicht)\n",
    "- Eine Kante hinzufügen (mit einem zufälligen Gewicht)\n",
    "\n",
    "Neue Kanten erhalten eine 'Innovation number' um den Ursprung der Gene über die Evolution hinweg zu erhalten."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 51192 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "mutate(g1)\n",
    "\n",
    "visualization.genome(g1)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Reproduktion\n",
    "\n",
    "Dank der 'Innovation number' kann nachvollzogen werden, welche Gene zusammenpassen. Alle anderen Gene sind entweder disjoint oder excess. Anhand dessen kann man mit unterschiedlich strukturierten Eltern einen Offspring generieren.\n",
    "\n",
    "TODO: An einem Beispiel zeigen, wie Gene zugeordet werden und 2 Eltern einen Offspring erzeugen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'module' object is not callable",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[91], line 10\u001b[0m\n\u001b[1;32m      7\u001b[0m \u001b[39mfor\u001b[39;00m i \u001b[39min\u001b[39;00m \u001b[39mrange\u001b[39m(\u001b[39m4\u001b[39m):\n\u001b[1;32m      8\u001b[0m     mutate(parent2)\n\u001b[0;32m---> 10\u001b[0m visualization(parent1)\n\u001b[1;32m     11\u001b[0m visualization(parent2)\n",
      "\u001b[0;31mTypeError\u001b[0m: 'module' object is not callable"
     ]
    }
   ],
   "source": [
    "parent1 = Genome.new(3, 2)\n",
    "for i in range(10):\n",
    "    mutate(parent1)\n",
    "\n",
    "parent2 = parent1\n",
    "\n",
    "for i in range(4):\n",
    "    mutate(parent2)\n",
    "\n",
    "visualization.genome(parent1)\n",
    "visualization.genome(parent2)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Selektion\n",
    "\n",
    "Für die Selektion treten nur Genome gegeneinander an, die eine vergleichbare Topologie haben => Species.\n",
    "TODO: Mehrere Genome in Spezien einteilen, ggf. mehrere Durchläufe mit verschiedenen c-Werten\n",
    "\n",
    "Die Fitness wird immer relativ zur Spezies berechnet, sodass Spezien erhalten bleiben und die stärkste Spezies nicht alle anderen Spezien verdrängt.\n",
    "TODO: Zwei Spezien - eine große, eine kleine - mitsamt Fitnesswerten. Zeigen wer rausfliegt und wer nicht"
   ]
  }
 ],
 "metadata": {
  "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.10.12"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "bd385fe162c5ca0c84973b7dd5c518456272446b2b64e67c2a69f949ca7a1754"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
