{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "dd2ed0d5-ee09-452b-ace5-89b2be772bb8",
   "metadata": {},
   "source": [
    "# Usando algorítmo genético\n",
    "### Encontrar o máximo de $f(x)=cos(20x) - \\frac{|x|}{2} + \\frac{x^3}{4}$,  $-2 \\le x \\le 2$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f0f670a-282f-4f71-824a-33ca5be6e9b4",
   "metadata": {},
   "source": [
    "# Importando pacotes necessários"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "8d5900cb",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "950a2db7-4386-4538-9f13-04d3107d7675",
   "metadata": {},
   "source": [
    "### Gráfico"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "73c001a9-ee73-4399-9223-978994f6c2ce",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x=np.arange(-2,2.01,0.01)\n",
    "y=np.cos(20*x)-np.abs(x)/2+np.power(x,3)/4\n",
    "plt.plot(x,y)\n",
    "plt.grid('on')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af30d0cb-4fe2-4d02-a464-8893f1bad7fb",
   "metadata": {},
   "source": [
    "# Definindo variáveis"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5136df45-d732-4bbf-bcdc-ccf703f0afad",
   "metadata": {},
   "source": [
    "### Tamanho do cromossomo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a591da6d-011b-4779-95c1-5327880eb768",
   "metadata": {},
   "outputs": [],
   "source": [
    "nBits=22  #número de genes"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4367c004-016c-4e73-9b3c-f26086f7d6d4",
   "metadata": {},
   "source": [
    "### Tamanho da população"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f2035fb3-73cc-4afd-a85e-43658d1ca4ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "nPop=20"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e1760ab2-5870-41ec-a3ef-db1ae2e87fdd",
   "metadata": {},
   "source": [
    "### Probabilidade de mutação"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "1e71a657-88e5-42be-ac68-9701f6d18683",
   "metadata": {},
   "outputs": [],
   "source": [
    "pMut=0.05 #5% de probabilidade de mutar"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0898324a-1f7a-4606-b588-3c9477616ed1",
   "metadata": {},
   "source": [
    "### Convergência"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "efb646ce-bb26-41f1-81a4-89186e957764",
   "metadata": {},
   "source": [
    "#### Intervalo de convergência"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "761b3b8c-1a90-49db-90f2-f986a73637bd",
   "metadata": {},
   "outputs": [],
   "source": [
    "intConvergencia=0.0001"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c2935207-359d-483b-8d2c-e17e8ed29bc2",
   "metadata": {},
   "source": [
    "#### Número de gerações com solução próxima da anterior"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "41cbc6f5-1692-4e96-b07e-843f442e133d",
   "metadata": {},
   "outputs": [],
   "source": [
    "nGeracoesConv = 10"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8b660eb1-61eb-42ec-a442-665b76220f14",
   "metadata": {},
   "source": [
    "### Intervalo da solução"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "f1079e32-7cd1-46e0-a93a-29e7df910fa9",
   "metadata": {},
   "outputs": [],
   "source": [
    "vMin=-2\n",
    "vMax=2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "866db291-5b21-47bc-9827-68061fe45a13",
   "metadata": {},
   "source": [
    "### Gerando uma população inicial"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "6f860c5d",
   "metadata": {},
   "outputs": [],
   "source": [
    "cromossomo=[] #vários cromossomos, vários indivíduos ou soluções\n",
    "acromossomo = np.random.randint(0,2,(nPop,nBits))#array de 22 bits cada\n",
    "for i in range(nPop):\n",
    "    cromossomo.append(''.join(str(x) for x in acromossomo[i]))\n",
    "\n",
    "#processo semelhante ao acima com array    \n",
    "pot=np.power(2,np.arange(nBits-1,-1,-1))#potências de 2²¹ a 2⁰\n",
    "#acromossomo"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "28faca9d-510e-4750-9559-5b872e3cc10d",
   "metadata": {},
   "source": [
    "### População inicial gerada"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "0cb26868-1973-4c91-bbf6-334ca4704d30",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['0110011100001001111010',\n",
       " '1001001101011001001100',\n",
       " '1110010111111100001101',\n",
       " '1010110111011100001110',\n",
       " '1100101101001110000000',\n",
       " '1100010010000111011001',\n",
       " '1011010010011100000101',\n",
       " '1010001100001110110010',\n",
       " '1001110011010011101111',\n",
       " '0111010101110110110010',\n",
       " '0110000110000001011111',\n",
       " '1100100000001011110001',\n",
       " '1100100101000000111000',\n",
       " '0100011000000111000100',\n",
       " '1001011000101011110101',\n",
       " '0100110011111100010000',\n",
       " '0001010100001100110110',\n",
       " '0001111010101011101011',\n",
       " '1000010011101010010010',\n",
       " '1011101111011110100101']"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cromossomo"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc5732ff-4608-4e03-bc9f-863e3a816bb6",
   "metadata": {},
   "source": [
    "### Converter sequência de bits em reais decimais, conforme os valores máximos e mínimos do intervalo de soluções $-2\\le x \\le2$\n",
    "### $$V_r = V_{min} + (V_{max} - V_{min})\\frac{V_{dec}}{2^g - 1}$$\n",
    "### onde\n",
    "### $V_r$: valor em real, que será dentro do intervalo $[V_{min}, V_{max}]$, neste caso $[-2,2]$\n",
    "### $V_{min}$: valor mínimo do intervalo\n",
    "### $V_{max}$: valor máximo \n",
    "### $V_{dec}$: valor decimal do cromossomo\n",
    "### $g$: número de genes (bits) do cromossomo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "f9de50c1-6e1f-47a7-95d8-0c411239a858",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-0.39001999,  0.30231912,  1.59351911,  0.71656673,  1.1766365 ,\n",
       "        1.07076432,  0.82202693,  0.54777778,  0.45042382, -0.16462473,\n",
       "       -0.47647154,  1.12571886,  1.14458541, -0.90581868,  0.34642562,\n",
       "       -0.7971036 , -1.671091  , -1.52077187,  0.07679989,  0.93546079])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#transformando vetor de bits e reais no intervalo [vMin, vMax]\n",
    "dec=acromossomo@pot\n",
    "axr=vMin + (vMax-vMin)*dec/(2**nBits - 1)\n",
    "axr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "16bba39e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-0.39001999  0.30231912  1.59351911  0.71656673  1.1766365   1.07076432\n",
      "  0.82202693  0.54777778  0.45042382 -0.16462473 -0.47647154  1.12571886\n",
      "  1.14458541 -0.90581868  0.34642562 -0.7971036  -1.671091   -1.52077187\n",
      "  0.07679989  0.93546079]\n"
     ]
    }
   ],
   "source": [
    "def bin2float(b):\n",
    "    dec=int(b,2)\n",
    "    return vMin + (vMax-vMin)*dec/(2**nBits - 1)\n",
    "\n",
    "xr=np.array(list(map(bin2float,cromossomo)))     \n",
    "print(xr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c1f8aab8-7658-4455-ac3c-645fd68170ef",
   "metadata": {},
   "source": [
    "### $$f(x)$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "a7a82839-6135-4f6c-9490-c5611904d4ad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-0.15628576,  0.82784117,  1.11334755, -0.45924984, -0.21027351,\n",
       "       -1.06718775, -1.01560134, -0.27280521, -1.11695704, -1.07206364,\n",
       "       -1.25980741, -1.07243001, -0.81859088,  0.10433133,  0.63608401,\n",
       "       -1.49788805, -2.42369328, -1.09978552, -0.00349515,  0.72709045])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fx=np.cos(20*xr)-np.abs(xr)/2+np.power(xr,3)/4\n",
    "fx"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "630c359e-84da-4caf-a8b2-9d3ea61a3c50",
   "metadata": {},
   "source": [
    "### A função de fitness é $f(x)+4$, assim retiramos os valores negativos para poderemos ter a função de distribuição acumulada"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "349975f1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3.84371424, 4.82784117, 5.11334755, 3.54075016, 3.78972649,\n",
       "       2.93281225, 2.98439866, 3.72719479, 2.88304296, 2.92793636,\n",
       "       2.74019259, 2.92756999, 3.18140912, 4.10433133, 4.63608401,\n",
       "       2.50211195, 1.57630672, 2.90021448, 3.99650485, 4.72709045])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fitness = fx+4\n",
    "fitness"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07c60c43-210a-4a3d-ae67-a22db0fd6935",
   "metadata": {},
   "source": [
    "### Calculando a probabilidade de cada elemento $x$ ser a solução"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "8df5924e-8441-4704-9d49-c1f4c5570f04",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.05501821, 0.06910482, 0.07319151, 0.05068164, 0.05424544,\n",
       "       0.04197973, 0.04271813, 0.05335037, 0.04126734, 0.04190994,\n",
       "       0.03922261, 0.04190469, 0.0455381 , 0.05874864, 0.06636005,\n",
       "       0.03581477, 0.02256296, 0.04151313, 0.05720523, 0.0676627 ])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "solucaoAnterior=fx[np.argmin(fitness)] \n",
    "novaSolucao=fx[np.argmax(fitness)]\n",
    "numConv=0\n",
    "if abs(novaSolucao - solucaoAnterior) <= intConvergencia:\n",
    "    numConv += 1\n",
    "#while numConv<nGeracoesConv:\n",
    "px=fitness/np.sum(fitness)\n",
    "px"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bef7bfbf-4881-47b1-8bf5-7be0fc6a76c4",
   "metadata": {},
   "source": [
    "### Calculando a probabilidade acumulada de $x$ ser a solução"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "2e2452ca",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.05501821, 0.12412303, 0.19731454, 0.24799618, 0.30224162,\n",
       "       0.34422135, 0.38693948, 0.44028986, 0.4815572 , 0.52346713,\n",
       "       0.56268974, 0.60459444, 0.65013254, 0.70888117, 0.77524122,\n",
       "       0.81105598, 0.83361895, 0.87513208, 0.9323373 , 1.        ])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "prbAc=np.cumsum(fitness)/np.sum(fitness)\n",
    "prbAc"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ae6d88f-0d4e-4e2b-affd-323b965449c7",
   "metadata": {},
   "source": [
    "### Seleção"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "195fdcf9-6437-40dd-ac09-8d01d01cd9b7",
   "metadata": {},
   "source": [
    "#### Selecionando os pais por roleta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "bc12eef0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['1001001101011001001100',\n",
       " '0001111010101011101011',\n",
       " '0100011000000111000100',\n",
       " '0001010100001100110110',\n",
       " '1010110111011100001110',\n",
       " '1110010111111100001101',\n",
       " '1001110011010011101111',\n",
       " '0111010101110110110010',\n",
       " '1011101111011110100101',\n",
       " '0100110011111100010000']"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pais=[]\n",
    "#poderia gera apais\n",
    "for i in range(10):\n",
    "    r=np.random.uniform()\n",
    "    id=np.argmax(prbAc>r)\n",
    "    sel = cromossomo[id]  \n",
    "    if i>0:\n",
    "        while sel in pais: #evita seleção repetida\n",
    "            r=np.random.uniform()\n",
    "            id=np.argmax(prbAc>r)\n",
    "            sel=cromossomo[id]\n",
    "    pais.append(sel)\n",
    "    \n",
    "pais"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "970dba8e",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "c4357e4c-9dfb-4ddc-bfd7-2e4ac9a366a3",
   "metadata": {},
   "source": [
    "### Cruzamento"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "ceaeaf90",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['0001001101011001001100',\n",
       " '1001111010101011101011',\n",
       " '0100011000001001001100',\n",
       " '1001001101010111000100',\n",
       " '0001011101011001001100',\n",
       " '1001000100001100110110',\n",
       " '1010110111011001001100',\n",
       " '1001001101011100001110',\n",
       " '1110010111111001001100',\n",
       " '1001001101011100001101',\n",
       " '1001110011010011101100',\n",
       " '1001001101011001001111',\n",
       " '0111010101111001001100',\n",
       " '1001001101010110110010',\n",
       " '1011101111011101001100',\n",
       " '1001001101011010100101',\n",
       " '0100110011111001001100',\n",
       " '1001001101011100010000',\n",
       " '0100011000000011101011',\n",
       " '0001111010101111000100',\n",
       " '0001010100001100101011',\n",
       " '0001111010101011110110',\n",
       " '1010110111011100101011',\n",
       " '0001111010101011001110',\n",
       " '1110011010101011101011',\n",
       " '0001110111111100001101',\n",
       " '1001110011011011101011',\n",
       " '0001111010100011101111',\n",
       " '0111010101110110110011',\n",
       " '0001111010101011101010',\n",
       " '1011101111011110101011',\n",
       " '0001111010101011100101',\n",
       " '0100110011101011101011',\n",
       " '0001111010111100010000',\n",
       " '0001010100001100000100',\n",
       " '0100011000000111110110',\n",
       " '1010011000000111000100',\n",
       " '0100110111011100001110',\n",
       " '1110010110000111000100',\n",
       " '0100011001111100001101',\n",
       " '1000011000000111000100',\n",
       " '0101110011010011101111',\n",
       " '0111010000000111000100',\n",
       " '0100011101110110110010',\n",
       " '1011101111000111000100',\n",
       " '0100011000011110100101',\n",
       " '0100110011111111000100',\n",
       " '0100011000000100010000',\n",
       " '1010110111001100110110',\n",
       " '0001010100011100001110',\n",
       " '1110010110001100110110',\n",
       " '0001010101111100001101',\n",
       " '1001110011010010110110',\n",
       " '0001010100001101101111',\n",
       " '0111010101111100110110',\n",
       " '0001010100000110110010',\n",
       " '1011100100001100110110',\n",
       " '0001011111011110100101',\n",
       " '0100110000001100110110',\n",
       " '0001010111111100010000',\n",
       " '1110010111111100001110',\n",
       " '1010110111011100001101',\n",
       " '1001110111011100001110',\n",
       " '1010110011010011101111',\n",
       " '0111010101110100001110',\n",
       " '1010110111011110110010',\n",
       " '1011101111011110101110',\n",
       " '1010110111011100000101',\n",
       " '0100110011111100001110',\n",
       " '1010110111011100010000',\n",
       " '1000010111111100001101',\n",
       " '1111110011010011101111',\n",
       " '0111010101110110110101',\n",
       " '1110010111111100001010',\n",
       " '1010010111111100001101',\n",
       " '1111101111011110100101',\n",
       " '0100110011111100001101',\n",
       " '1110010111111100010000',\n",
       " '0111010011010011101111',\n",
       " '1001110101110110110010',\n",
       " '1011101111010011101111',\n",
       " '1001110011011110100101',\n",
       " '0100110011110011101111',\n",
       " '1001110011011100010000',\n",
       " '1011101111110110110010',\n",
       " '0111010101011110100101',\n",
       " '0100110011110110110010',\n",
       " '0111010101111100010000',\n",
       " '0100110011111110100101',\n",
       " '1011101111011100010000']"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "filhos=[]\n",
    "for p1 in range(len(pais)-1):\n",
    "    for p2 in range(p1+1,len(pais)):\n",
    "        c=np.random.randint(1,20) #ponto de corte\n",
    "          \n",
    "        #afilho1[0:c+1]=apais[p2][0:c+1]\n",
    "        #afilho1[c+1:]=apais[p1][c+1:]\n",
    "        #afilho2[0:c+1]=apais[p1][0:c+1]\n",
    "        #afilho2[c+1:]=apais[p2][c+1:]\n",
    "        filho1=pais[p2][0:c+1]+pais[p1][c+1:]\n",
    "        filho2=pais[p1][0:c+1]+pais[p2][c+1:]\n",
    "        while (filho1 in filhos) or (filho2 in filhos) or (filho1 in cromossomo) or (filho2 in cromossomo):\n",
    "            c=np.random.randint(1,20)\n",
    "            filho1=pais[p2][0:c+1]+pais[p1][c+1:] #concatenando, são caracteres\n",
    "            filho2=pais[p1][0:c+1]+pais[p2][c+1:]\n",
    "            \n",
    "        filhos.append(filho1)\n",
    "        filhos.append(filho2) \n",
    "filhos"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1130b4e6-4c2c-4b87-8347-43a704822573",
   "metadata": {},
   "source": [
    "### Mutação"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "a1f09714",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mutou filho 0100110011111111000100\n",
      "Para        0100110011110111000100\n",
      "Mutou filho 1001110111011100001110\n",
      "Para        1001110101011100001110\n",
      "Mutou filho 1011101111110110110010\n",
      "Para        1011100111110110110010\n"
     ]
    }
   ],
   "source": [
    "#for i,f in enumerate(filhos):\n",
    "#    r=random.uniform()\n",
    "#    if r<pMut:\n",
    "#        bit=np.random.randint(0,nBits-1)\n",
    "#        if filhos[i,bit]==0\n",
    "#            filhos[i,bit]=1\n",
    "#        else:\n",
    "#            filhos[i,bit]=0\n",
    "\n",
    "for f in range(len(filhos)):\n",
    "    i=np.random.randint(0,nBits-1) #indice do gene que poderá ser mutado\n",
    "    lstfilho=[b for b in filhos[f]]\n",
    "    r=np.random.uniform()\n",
    "    if r<pMut: #ocorre mutação\n",
    "        print(f'Mutou filho {filhos[f]}')\n",
    "        \n",
    "        if lstfilho[i] == '0':\n",
    "            lstfilho[i] == '1'\n",
    "        else:\n",
    "            lstfilho[i] = '0'\n",
    "        filhos[f]=''.join(s for s in lstfilho)\n",
    "        print(f'Para        {filhos[f]}')\n",
    "        "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d519603f-1b87-4dbe-b5e5-eab384532089",
   "metadata": {},
   "source": [
    "### Nova população"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "3ee487db-6d2b-4f2c-8742-980e8275cdce",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true,
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['0110011100001001111010',\n",
       " '1001001101011001001100',\n",
       " '1110010111111100001101',\n",
       " '1010110111011100001110',\n",
       " '1100101101001110000000',\n",
       " '1100010010000111011001',\n",
       " '1011010010011100000101',\n",
       " '1010001100001110110010',\n",
       " '1001110011010011101111',\n",
       " '0111010101110110110010',\n",
       " '0110000110000001011111',\n",
       " '1100100000001011110001',\n",
       " '1100100101000000111000',\n",
       " '0100011000000111000100',\n",
       " '1001011000101011110101',\n",
       " '0100110011111100010000',\n",
       " '0001010100001100110110',\n",
       " '0001111010101011101011',\n",
       " '1000010011101010010010',\n",
       " '1011101111011110100101',\n",
       " '0001001101011001001100',\n",
       " '1001111010101011101011',\n",
       " '0100011000001001001100',\n",
       " '1001001101010111000100',\n",
       " '0001011101011001001100',\n",
       " '1001000100001100110110',\n",
       " '1010110111011001001100',\n",
       " '1001001101011100001110',\n",
       " '1110010111111001001100',\n",
       " '1001001101011100001101',\n",
       " '1001110011010011101100',\n",
       " '1001001101011001001111',\n",
       " '0111010101111001001100',\n",
       " '1001001101010110110010',\n",
       " '1011101111011101001100',\n",
       " '1001001101011010100101',\n",
       " '0100110011111001001100',\n",
       " '1001001101011100010000',\n",
       " '0100011000000011101011',\n",
       " '0001111010101111000100',\n",
       " '0001010100001100101011',\n",
       " '0001111010101011110110',\n",
       " '1010110111011100101011',\n",
       " '0001111010101011001110',\n",
       " '1110011010101011101011',\n",
       " '0001110111111100001101',\n",
       " '1001110011011011101011',\n",
       " '0001111010100011101111',\n",
       " '0111010101110110110011',\n",
       " '0001111010101011101010',\n",
       " '1011101111011110101011',\n",
       " '0001111010101011100101',\n",
       " '0100110011101011101011',\n",
       " '0001111010111100010000',\n",
       " '0001010100001100000100',\n",
       " '0100011000000111110110',\n",
       " '1010011000000111000100',\n",
       " '0100110111011100001110',\n",
       " '1110010110000111000100',\n",
       " '0100011001111100001101',\n",
       " '1000011000000111000100',\n",
       " '0101110011010011101111',\n",
       " '0111010000000111000100',\n",
       " '0100011101110110110010',\n",
       " '1011101111000111000100',\n",
       " '0100011000011110100101',\n",
       " '0100110011110111000100',\n",
       " '0100011000000100010000',\n",
       " '1010110111001100110110',\n",
       " '0001010100011100001110',\n",
       " '1110010110001100110110',\n",
       " '0001010101111100001101',\n",
       " '1001110011010010110110',\n",
       " '0001010100001101101111',\n",
       " '0111010101111100110110',\n",
       " '0001010100000110110010',\n",
       " '1011100100001100110110',\n",
       " '0001011111011110100101',\n",
       " '0100110000001100110110',\n",
       " '0001010111111100010000',\n",
       " '1110010111111100001110',\n",
       " '1010110111011100001101',\n",
       " '1001110101011100001110',\n",
       " '1010110011010011101111',\n",
       " '0111010101110100001110',\n",
       " '1010110111011110110010',\n",
       " '1011101111011110101110',\n",
       " '1010110111011100000101',\n",
       " '0100110011111100001110',\n",
       " '1010110111011100010000',\n",
       " '1000010111111100001101',\n",
       " '1111110011010011101111',\n",
       " '0111010101110110110101',\n",
       " '1110010111111100001010',\n",
       " '1010010111111100001101',\n",
       " '1111101111011110100101',\n",
       " '0100110011111100001101',\n",
       " '1110010111111100010000',\n",
       " '0111010011010011101111',\n",
       " '1001110101110110110010',\n",
       " '1011101111010011101111',\n",
       " '1001110011011110100101',\n",
       " '0100110011110011101111',\n",
       " '1001110011011100010000',\n",
       " '1011100111110110110010',\n",
       " '0111010101011110100101',\n",
       " '0100110011110110110010',\n",
       " '0111010101111100010000',\n",
       " '0100110011111110100101',\n",
       " '1011101111011100010000']"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "novageracao=[]\n",
    "novageracao=list(np.append(np.array(cromossomo),np.array(filhos)))\n",
    "novageracao"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c333590-807c-48ac-a8ad-f5760a079bc7",
   "metadata": {},
   "source": [
    "### Novas soluções"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "dd5db0c9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-0.39001999  0.30231912  1.59351911  0.71656673  1.1766365   1.07076432\n",
      "  0.82202693  0.54777778  0.45042382 -0.16462473 -0.47647154  1.12571886\n",
      "  1.14458541 -0.90581868  0.34642562 -0.7971036  -1.671091   -1.52077187\n",
      "  0.07679989  0.93546079 -1.69768135  0.47922861 -0.90568898  0.30218942\n",
      " -1.63518134  0.26640946  0.71638172  0.30250413  1.59333505  0.30250318\n",
      "  0.45042096  0.30232198 -0.16447786  0.30217226  0.93537591  0.302404\n",
      " -0.79729052  0.30250604 -0.90602563 -1.52056492 -1.67110149 -1.52076138\n",
      "  0.71659439 -1.52079952  1.60422888 -1.53148163  0.45090829 -1.52125633\n",
      " -0.16462378 -1.52077282  0.93546651 -1.52077759 -0.79811544 -1.51976002\n",
      " -1.67113869 -0.90577099  0.59418168 -0.78343362  1.58636942 -0.89866898\n",
      "  0.09418156 -0.54957641 -0.18706851 -0.8833749   0.93402551 -0.9043834\n",
      " -0.79742021 -0.90599034  0.71562832 -1.67015259  1.58672228 -1.66429416\n",
      "  0.45036947 -1.67103664 -0.1642547  -1.67146103  0.89140961 -1.62703982\n",
      " -0.8117158  -1.6564788   1.59352007  0.71656578  0.45875417  0.70042388\n",
      " -0.16478113  0.71672314  0.93546937  0.71655815 -0.7971055   0.71656864\n",
      "  0.09351876  1.95042418 -0.16462187  1.59351625  0.59351888  1.93546103\n",
      " -0.79710646  1.59352197 -0.17457632  0.46037542  0.93479894  0.45108568\n",
      " -0.79762335  0.45094358  0.90568802 -0.16610197 -0.79743738 -0.16429094\n",
      " -0.7969615   0.93531869]\n"
     ]
    }
   ],
   "source": [
    "xr=np.array(list(map(bin2float,novageracao)))     \n",
    "print(xr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48d35202-eee9-46d2-bad7-34b7f2029c37",
   "metadata": {},
   "source": [
    "### $f(x)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "0b34724b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-0.15628576,  0.82784117,  1.11334755, -0.45924984, -0.21027351,\n",
       "       -1.06718775, -1.01560134, -0.27280521, -1.11695704, -1.07206364,\n",
       "       -1.25980741, -1.07243001, -0.81859088,  0.10433133,  0.63608401,\n",
       "       -1.49788805, -2.42369328, -1.09978552, -0.00349515,  0.72709045,\n",
       "       -2.8952036 , -1.19935943,  0.10273748,  0.82728532, -1.63130519,\n",
       "        0.44913425, -0.45559652,  0.82862276,  1.11469894,  0.82861877,\n",
       "       -1.11693291,  0.82785336, -1.07242453,  0.82721126,  0.72683831,\n",
       "        0.82820139, -1.49719659,  0.82863075,  0.10686404, -1.10281165,\n",
       "       -2.42391074, -1.09993869, -0.45979572, -1.09938181,  1.01468512,\n",
       "       -0.95726574, -1.12100066, -1.09273798, -1.07206601, -1.0997716 ,\n",
       "        0.72710735, -1.09970198, -1.49398342, -1.11466921, -2.42468162,\n",
       "        0.10374594,  0.53120218, -1.5111567 ,  1.15675351,  0.00931645,\n",
       "       -0.35463908, -0.32033194, -0.92063209, -0.23500184,  0.72244483,\n",
       "        0.08641646, -1.49670885,  0.1064331 , -0.44069301, -2.40416686,\n",
       "        1.15505686, -2.2793368 , -1.11649795, -2.42256611, -1.07295656,\n",
       "       -2.43135284,  0.25357961, -1.45902477, -1.40420942, -2.10691933,\n",
       "        1.11334052, -0.45923101, -1.17422822, -0.13597173, -1.07166995,\n",
       "       -0.46233612,  0.72711579, -0.45908041, -1.49788107, -0.45928749,\n",
       "       -0.3416727 ,  1.13817357, -1.07207075,  1.11336865,  0.52292685,\n",
       "        1.37660192, -1.49787757,  1.11332645, -1.0280137 , -1.18228375,\n",
       "        0.72504902, -1.12245962, -1.49593186, -1.12129181,  0.47418047,\n",
       "       -1.06796027, -1.4966438 , -1.0728715 , -1.49840464,  0.72666672])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fx = np.cos(20*xr)-np.abs(xr)/2+np.power(xr,3)/4\n",
    "fx"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad61eb6c-cdbd-456a-89df-5bf74a6ffd09",
   "metadata": {},
   "source": [
    "### Fitness"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "c1d57124-4e46-43b8-8a4e-7579740f831d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3.84371424, 4.82784117, 5.11334755, 3.54075016, 3.78972649,\n",
       "       2.93281225, 2.98439866, 3.72719479, 2.88304296, 2.92793636,\n",
       "       2.74019259, 2.92756999, 3.18140912, 4.10433133, 4.63608401,\n",
       "       2.50211195, 1.57630672, 2.90021448, 3.99650485, 4.72709045,\n",
       "       1.1047964 , 2.80064057, 4.10273748, 4.82728532, 2.36869481,\n",
       "       4.44913425, 3.54440348, 4.82862276, 5.11469894, 4.82861877,\n",
       "       2.88306709, 4.82785336, 2.92757547, 4.82721126, 4.72683831,\n",
       "       4.82820139, 2.50280341, 4.82863075, 4.10686404, 2.89718835,\n",
       "       1.57608926, 2.90006131, 3.54020428, 2.90061819, 5.01468512,\n",
       "       3.04273426, 2.87899934, 2.90726202, 2.92793399, 2.9002284 ,\n",
       "       4.72710735, 2.90029802, 2.50601658, 2.88533079, 1.57531838,\n",
       "       4.10374594, 4.53120218, 2.4888433 , 5.15675351, 4.00931645,\n",
       "       3.64536092, 3.67966806, 3.07936791, 3.76499816, 4.72244483,\n",
       "       4.08641646, 2.50329115, 4.1064331 , 3.55930699, 1.59583314,\n",
       "       5.15505686, 1.7206632 , 2.88350205, 1.57743389, 2.92704344,\n",
       "       1.56864716, 4.25357961, 2.54097523, 2.59579058, 1.89308067,\n",
       "       5.11334052, 3.54076899, 2.82577178, 3.86402827, 2.92833005,\n",
       "       3.53766388, 4.72711579, 3.54091959, 2.50211893, 3.54071251,\n",
       "       3.6583273 , 5.13817357, 2.92792925, 5.11336865, 4.52292685,\n",
       "       5.37660192, 2.50212243, 5.11332645, 2.9719863 , 2.81771625,\n",
       "       4.72504902, 2.87754038, 2.50406814, 2.87870819, 4.47418047,\n",
       "       2.93203973, 2.5033562 , 2.9271285 , 2.50159536, 4.72666672])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fitness=fx+4\n",
    "fitness"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "5ce502ab",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Melhor solucão: f(1.9354610289242338)=1.3766019224149861\n"
     ]
    }
   ],
   "source": [
    "indMax = np.argmax(fx)\n",
    "maxX=xr[indMax]\n",
    "maxF=fx[indMax]\n",
    "print(f'Melhor solucão: f({maxX})={maxF}') "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c78d3e1-29ff-49cf-8fbb-7710563c6182",
   "metadata": {},
   "source": [
    "### Grafico solução"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "3a409efc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x=np.arange(-2,2.01,0.01)\n",
    "y=np.cos(20*x)-np.abs(x)/2+np.power(x,3)/4\n",
    "plt.plot(x,y)\n",
    "plt.plot(maxX,maxF,'ro')\n",
    "plt.grid('on')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ae6d5c1-abd2-4c90-8d00-484c7d841978",
   "metadata": {},
   "source": [
    "# A seleção natural pode ser feita de várias maneiras, tais como:\n",
    "### 1) Tomando os 20 melhores individuos;\n",
    "### 2) Tomando aleatoriamente 19 indivíduos mais o melhor indivíduo.\n",
    "# O critério de parada pode ser, entre outros:\n",
    "### 1) Arbitrar um determinado número de iterações;\n",
    "### 2) Melhor solução nova não diferencie da anterior por um certo número de repetições;\n",
    "### 3) Melhor solução nova apresente pouca variação com a solução anterior."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3d1506d-1c2d-4097-9099-0178d21cb2f0",
   "metadata": {},
   "source": [
    "# Selecionando os indivíduos de maior fitness da nova geração"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "72173719-577b-41d3-aa7d-cd4db107accf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([50, 86, 33, 23,  1, 31, 35, 29, 27, 37, 44, 97, 80,  2, 93, 28, 91,\n",
       "       70, 58, 95])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ind = np.argsort(fitness)[-nPop:] #toma os nPop melhores indivíduos\n",
    "ind"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "028d843f-6b83-417b-ba70-38a0478c600d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['1011101111011110101011',\n",
       " '1011101111011110101110',\n",
       " '1001001101010110110010',\n",
       " '1001001101010111000100',\n",
       " '1001001101011001001100',\n",
       " '1001001101011001001111',\n",
       " '1001001101011010100101',\n",
       " '1001001101011100001101',\n",
       " '1001001101011100001110',\n",
       " '1001001101011100010000',\n",
       " '1110011010101011101011',\n",
       " '1110010111111100010000',\n",
       " '1110010111111100001110',\n",
       " '1110010111111100001101',\n",
       " '1110010111111100001010',\n",
       " '1110010111111001001100',\n",
       " '1111110011010011101111',\n",
       " '1110010110001100110110',\n",
       " '1110010110000111000100',\n",
       " '1111101111011110100101']"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ind = np.argsort(fx)[-nPop:]\n",
    "cromossomo=[]\n",
    "cromossomo = list(np.array(novageracao)[ind])\n",
    "cromossomo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "63ec31a9-884f-46ef-be78-c9d3b00bd902",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.72710735, 0.72711579, 0.82721126, 0.82728532, 0.82784117,\n",
       "       0.82785336, 0.82820139, 0.82861877, 0.82862276, 0.82863075,\n",
       "       1.01468512, 1.11332645, 1.11334052, 1.11334755, 1.11336865,\n",
       "       1.11469894, 1.13817357, 1.15505686, 1.15675351, 1.37660192])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xr=np.array(list(map(bin2float,cromossomo)))  \n",
    "fx = np.cos(20*xr)-np.abs(xr)/2+np.power(xr,3)/4\n",
    "fx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "949c63a3-bd64-4417-9b06-78c669095e76",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "novaSolucao=fx[-1]\n",
    "numConv += 1\n",
    "if abs(novaSolucao - solucaoAnterior) > intConvergencia:\n",
    "    numConv=0\n",
    "numConv    \n",
    "solucaoAnterior=novaSolucao"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f13a6f58-8aa6-4674-8b73-6927e165dfa0",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "48575349-7368-465f-814a-564afa18dffc",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c23308b-5cd6-434a-b811-d54a45aa402f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
