{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "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, feed-forward mit zufälligen Gewichten\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "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": 5,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'builtin_function_or_method' object has no attribute 'uniform'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[5], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m mutate(g1)\n\u001b[1;32m      3\u001b[0m visualization\u001b[39m.\u001b[39mgenome(g1)\n",
      "File \u001b[0;32m~/development/ne-assignments/Abschlussprojekt/genome.py:96\u001b[0m, in \u001b[0;36mmutate\u001b[0;34m(genome)\u001b[0m\n\u001b[1;32m     93\u001b[0m mutation \u001b[39m=\u001b[39m choice([MutationType\u001b[39m.\u001b[39mADD_NODE, MutationType\u001b[39m.\u001b[39mADD_CONNECTION])\n\u001b[1;32m     95\u001b[0m \u001b[39mif\u001b[39;00m mutation \u001b[39mis\u001b[39;00m MutationType\u001b[39m.\u001b[39mADD_CONNECTION:\n\u001b[0;32m---> 96\u001b[0m     _mutate_add_connection(genome)\n\u001b[1;32m     97\u001b[0m \u001b[39melif\u001b[39;00m mutation \u001b[39mis\u001b[39;00m MutationType\u001b[39m.\u001b[39mADD_NODE:\n\u001b[1;32m     98\u001b[0m     _mutate_add_node(genome)\n",
      "File \u001b[0;32m~/development/ne-assignments/Abschlussprojekt/genome.py:118\u001b[0m, in \u001b[0;36m_mutate_add_connection\u001b[0;34m(genome)\u001b[0m\n\u001b[1;32m    115\u001b[0m \u001b[39mif\u001b[39;00m creates_cycle(genome\u001b[39m.\u001b[39mconnections\u001b[39m.\u001b[39mkeys(), (from_node\u001b[39m.\u001b[39mid, to_node\u001b[39m.\u001b[39mid)):\n\u001b[1;32m    116\u001b[0m     \u001b[39mreturn\u001b[39;00m\n\u001b[0;32m--> 118\u001b[0m genome\u001b[39m.\u001b[39madd_connection(from_node, to_node, weight\u001b[39m=\u001b[39mrandom\u001b[39m.\u001b[39;49muniform(\u001b[39m0\u001b[39m,\u001b[39m1\u001b[39m))\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'builtin_function_or_method' object has no attribute 'uniform'"
     ]
    }
   ],
   "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": 125,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 42212 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "parent1 = Genome.new(3, 2)\n",
    "for i in range(10):\n",
    "    mutate(parent1)\n",
    "\n",
    "\n",
    "visualization.genome(parent1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 45772 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "parent2 = parent1\n",
    "\n",
    "for i in range(4):\n",
    "    mutate(parent2)\n",
    "    \n",
    "visualization.genome(parent2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO: crossover implementieren"
   ]
  },
  {
   "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
}
