709 lines
44 KiB
Plaintext
709 lines
44 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"source": [
|
|
"# ജനിതക ആൽഗോറിതങ്ങൾ\n",
|
|
"\n",
|
|
"ഈ നോട്ട്ബുക്ക് [AI for Beginners Curriculum](http://github.com/microsoft/ai-for-beginners) എന്ന കോഴ്സിന്റെ ഭാഗമാണ്.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import random\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"import numpy as np\n",
|
|
"import math\n",
|
|
"import time"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## ചില സിദ്ധാന്തങ്ങൾ\n",
|
|
"\n",
|
|
"**ജനിതക ആൽഗോറിതങ്ങൾ** (GA) **വംശവികാസ സമീപനം** അടിസ്ഥാനമാക്കിയുള്ള AI-യുടെ ഒരു രീതിയാണ്, ഇതിൽ ജനസംഖ്യയുടെ വംശവികാസ രീതികൾ ഉപയോഗിച്ച് ഒരു നൽകിയ പ്രശ്നത്തിന് ഏറ്റവും അനുയോജ്യമായ പരിഹാരം കണ്ടെത്തുന്നു. 1975-ൽ [ജോൺ ഹെൻറി ഹോളണ്ട്](https://en.wikipedia.org/wiki/John_Henry_Holland) ഇവയെ നിർദ്ദേശിച്ചു.\n",
|
|
"\n",
|
|
"ജനിതക ആൽഗോറിതങ്ങൾ താഴെപ്പറയുന്ന ആശയങ്ങളെ അടിസ്ഥാനമാക്കുന്നു:\n",
|
|
"* പ്രശ്നത്തിന് സാധുവായ പരിഹാരങ്ങൾ **ജീനുകൾ** ആയി പ്രതിനിധീകരിക്കാം\n",
|
|
"* **ക്രോസോവർ** ഉപയോഗിച്ച് രണ്ട് പരിഹാരങ്ങൾ ചേർത്ത് പുതിയ സാധുവായ പരിഹാരം ലഭ്യമാക്കാം\n",
|
|
"* **തിരഞ്ഞെടുപ്പ്** ചില **ഫിറ്റ്നസ് ഫംഗ്ഷൻ** ഉപയോഗിച്ച് കൂടുതൽ അനുയോജ്യമായ പരിഹാരങ്ങൾ തിരഞ്ഞെടുക്കാൻ ഉപയോഗിക്കുന്നു\n",
|
|
"* **മ്യൂട്ടേഷനുകൾ** പരിഹാരത്തിന്റെ സ്ഥിരത തകർക്കാനും ലോക്കൽ മിനിമത്തിൽ നിന്ന് പുറത്തുവരാനും ഉപയോഗിക്കുന്നു\n",
|
|
"\n",
|
|
"ജനിതക ആൽഗോറിതം നടപ്പിലാക്കാൻ നിങ്ങൾക്ക് താഴെപ്പറയുന്നവ വേണം:\n",
|
|
"\n",
|
|
" * പ്രശ്ന പരിഹാരങ്ങളെ **ജീനുകൾ** $g\\in\\Gamma$ ആയി കോഡുചെയ്യാനുള്ള ഒരു രീതി കണ്ടെത്തുക\n",
|
|
" * ജീനുകളുടെ സെറ്റ് $\\Gamma$-യിൽ **ഫിറ്റ്നസ് ഫംഗ്ഷൻ** $\\mathrm{fit}: \\Gamma\\to\\mathbb{R}$ നിർവചിക്കുക. ചെറിയ ഫംഗ്ഷൻ മൂല്യങ്ങൾ മികച്ച പരിഹാരങ്ങളെ സൂചിപ്പിക്കും.\n",
|
|
" * രണ്ട് ജീനുകൾ ചേർത്ത് പുതിയ സാധുവായ പരിഹാരം ലഭ്യമാക്കാൻ **ക്രോസോവർ** സംവിധാനം നിർവചിക്കുക $\\mathrm{crossover}: \\Gamma^2\\to\\Gamma$.\n",
|
|
" * **മ്യൂട്ടേഷൻ** സംവിധാനം നിർവചിക്കുക $\\mathrm{mutate}: \\Gamma\\to\\Gamma$.\n",
|
|
"കഴിഞ്ഞ പല സാഹചര്യങ്ങളിലും, ക്രോസോവർ, മ്യൂട്ടേഷൻ എന്നിവ ജീനുകളെ സംഖ്യാത്മക ശ്രേണികളോ ബിറ്റ് വെക്ടറുകളോ ആയി കൈകാര്യം ചെയ്യാനുള്ള ലളിതമായ ആൽഗോറിതങ്ങളാണ്.\n",
|
|
"\n",
|
|
"ഒരു ജനിതക ആൽഗോറിതത്തിന്റെ പ്രത്യേക നടപ്പാക്കൽ സാഹചര്യത്തിനനുസരിച്ച് വ്യത്യാസപ്പെടാം, പക്ഷേ പൊതുവായ ഘടന താഴെപ്പറയുന്നവയാണ്:\n",
|
|
"\n",
|
|
"1. പ്രാരംഭ ജനസംഖ്യ $G\\subset\\Gamma$ തിരഞ്ഞെടുക്കുക\n",
|
|
"2. ഈ ഘട്ടത്തിൽ നടത്തേണ്ട പ്രവർത്തനങ്ങളിൽ നിന്ന് ക്രോസോവർ അല്ലെങ്കിൽ മ്യൂട്ടേഷൻ യാദൃച്ഛികമായി തിരഞ്ഞെടുക്കുക\n",
|
|
"3. **ക്രോസോവർ**:\n",
|
|
" * ജനസംഖ്യയിൽ നിന്ന് രണ്ട് ജീനുകൾ $g_1, g_2 \\in G$ യാദൃച്ഛികമായി തിരഞ്ഞെടുക്കുക\n",
|
|
" * ക്രോസോവർ കണക്കാക്കുക $g=\\mathrm{crossover}(g_1,g_2)$\n",
|
|
" * $\\mathrm{fit}(g)<\\mathrm{fit}(g_1)$ അല്ലെങ്കിൽ $\\mathrm{fit}(g)<\\mathrm{fit}(g_2)$ ആണെങ്കിൽ - ജനസംഖ്യയിലെ അനുയോജ്യമായ ജീൻ $g$-ൽ മാറ്റുക.\n",
|
|
"4. **മ്യൂട്ടേഷൻ** - യാദൃച്ഛികമായി ഒരു ജീൻ $g\\in G$ തിരഞ്ഞെടുക്കുക, അതിനെ $\\mathrm{mutate}(g)$-ൽ മാറ്റുക\n",
|
|
"5. ഘട്ടം 2 മുതൽ ആവർത്തിക്കുക, $\\mathrm{fit}$-ന്റെ മൂല്യം ആവശ്യത്തിന് ചെറുതായോ അല്ലെങ്കിൽ ഘട്ടങ്ങളുടെ പരമാവധി പരിധി എത്തിച്ചേരുകയോ ചെയ്യുന്നത് വരെ.\n",
|
|
"\n",
|
|
"GA ഉപയോഗിച്ച് സാധാരണ പരിഹരിക്കുന്ന ജോലികൾ:\n",
|
|
"1. ഷെഡ്യൂൾ മെച്ചപ്പെടുത്തൽ\n",
|
|
"1. ഏറ്റവും അനുയോജ്യമായ പാക്കിംഗ്\n",
|
|
"1. ഏറ്റവും അനുയോജ്യമായ മുറിക്കൽ\n",
|
|
"1. സമഗ്രമായ തിരച്ചിൽ വേഗത്തിലാക്കൽ\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## പ്രശ്നം 1: നീതിപൂർവം നിധി വിഭജനം\n",
|
|
"\n",
|
|
"**പ്രവൃത്തി**: \n",
|
|
"രണ്ടുപേർ വ്യത്യസ്ത വലിപ്പത്തിലുള്ള (അതിനനുസരിച്ച് വ്യത്യസ്ത വിലയുള്ള) ഡയമണ്ടുകൾ അടങ്ങിയ ഒരു നിധി കണ്ടെത്തി. വിലയുടെ വ്യത്യാസം 0 (അഥവാ ഏറ്റവും കുറഞ്ഞത്) ആകുന്ന വിധത്തിൽ നിധി രണ്ട് ഭാഗങ്ങളായി വിഭജിക്കേണ്ടതാണ്.\n",
|
|
"\n",
|
|
"**സൂത്രവാക്യം**: \n",
|
|
"നമുക്ക് ഒരു സംഖ്യകളുടെ സമുച്ചയം $S$ ഉണ്ട്. അതിനെ രണ്ട് ഉപസമുച്ചയങ്ങളായി വിഭജിക്കണം, $S_1$യും $S_2$യും, ഇങ്ങനെ: \n",
|
|
"$$\\left|\\sum_{i\\in S_1}i - \\sum_{j\\in S_2}j\\right|\\to\\min$$ \n",
|
|
"മറ്റുപക്ഷം, $S_1\\cup S_2=S$, $S_1\\cap S_2=\\emptyset$.\n",
|
|
"\n",
|
|
"ആദ്യം, സമുച്ചയം $S$ നിശ്ചയിക്കാം:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[8344 2197 9335 3131 5863 9429 3818 9791 15 5455 1396 9538 4872 6549\n",
|
|
" 8587 5986 6021 9764 8102 5083 5739 7684 8498 3007 6599 820 7490 2372\n",
|
|
" 9370 5235 3525 3154 859 1906 8159 3950 2173 2988 2050 349 8713 2284\n",
|
|
" 4177 6033 1651 9176 5049 8201 171 5081 1216 3756 4711 2757 7738 1272\n",
|
|
" 5650 6584 5395 9004 7797 969 8104 1283 1392 4001 5768 445 274 256\n",
|
|
" 8239 8015 4381 9021 1189 8879 1411 3539 6526 8011 136 7230 2332 451\n",
|
|
" 5702 2989 4320 2446 9578 8486 4027 2410 9588 8981 2177 1493 3232 9151\n",
|
|
" 4835 5594 6859 8394 369 3200 126 4259 2283 7755 2014 2458 8327 8082\n",
|
|
" 7413 7622 1206 5533 8751 3495 5868 8472 6850 3958 3149 4672 4810 6274\n",
|
|
" 4700 6134 4627 4616 6656 9949 884 2256 7419 1926 7973 5319 5967 9158\n",
|
|
" 3823 7697 9466 5675 5412 9784 5426 8209 3421 1136 6047 4429 8001 4417\n",
|
|
" 1381 722 7350 6018 6235 7860 5853 7660 5937 6242 1 9552 3971 8302\n",
|
|
" 2633 9227 7283 154 8599 4269 9392 8539 1630 368 2409 9351 3838 9814\n",
|
|
" 6186 5743 5083 1325 1610 779 3643 3262 5768 8725 961 4611 6310 4788\n",
|
|
" 1648 5951 8118 7779]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"N = 200\n",
|
|
"S = np.array([random.randint(1,10000) for _ in range(N)])\n",
|
|
"print(S)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"പ്രശ്നത്തിന്റെ ഓരോ സാധ്യതാപരമായ പരിഹാരത്തെയും ബൈനറി വെക്ടർ $B\\in\\{0,1\\}^N$ ഉപയോഗിച്ച് എൻകോഡ് ചെയ്യാം, ഇവിടെ $i$-ആം സ്ഥാന上的 സംഖ്യ, മൗലിക സെറ്റ് $S$-യിലെ $i$-ആം സംഖ്യ ഏത് സെറ്റിൽ ($S_1$ അല്ലെങ്കിൽ $S_2$) പെടുന്നു എന്ന് കാണിക്കുന്നു. `generate` ഫംഗ്ഷൻ ആ റാൻഡം ബൈനറി വെക്ടറുകൾ സൃഷ്ടിക്കും.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[1 0 0 1 1 1 1 1 0 1 1 1 0 0 1 0 1 1 1 0 0 1 1 0 1 1 0 0 1 0 1 0 1 0 1 1 1\n",
|
|
" 0 1 1 1 0 1 0 0 1 0 0 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 0 1 1 0 0 0 0 1 0 1 0\n",
|
|
" 1 0 0 0 0 0 1 1 0 1 0 0 1 0 1 0 0 1 1 0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 1 1\n",
|
|
" 1 0 1 0 0 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 0 1 0 1 0 1 0 0 1 1 1 0 0 1 1\n",
|
|
" 0 1 1 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 1 1 0 1 1 0 0 1 1 0\n",
|
|
" 0 0 0 1 0 1 1 0 1 1 0 1 0 0 0]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def generate(S):\n",
|
|
" return np.array([random.randint(0,1) for _ in S])\n",
|
|
"\n",
|
|
"b = generate(S)\n",
|
|
"print(b)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"ഇപ്പോൾ നമുക്ക് `fit` ഫംഗ്ഷൻ നിർവചിക്കാം, ഇത് പരിഹാരത്തിന്റെ \"ചെലവ്\" കണക്കാക്കും. ഇത് രണ്ട് സെറ്റുകളുടെ, $S_1$ ഉം $S_2$ ഉം, സംഖ്യകളുടെ വ്യത്യാസമായിരിക്കും:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"133784"
|
|
]
|
|
},
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"def fit(B,S=S):\n",
|
|
" c1 = (B*S).sum()\n",
|
|
" c2 = ((1-B)*S).sum()\n",
|
|
" return abs(c1-c2)\n",
|
|
"\n",
|
|
"fit(b)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"ഇപ്പോൾ നമുക്ക് മ്യൂട്ടേഷൻക്കും ക്രോസോവറിനും ഫംഗ്ഷനുകൾ നിർവചിക്കേണ്ടതുണ്ട്:\n",
|
|
"* മ്യൂട്ടേഷനായി, നാം ഒരു റാൻഡം ബിറ്റ് തിരഞ്ഞെടുക്കും, അത് നിഷേധിക്കും (0-ൽ നിന്ന് 1-ലേക്ക് അല്ലെങ്കിൽ 1-ൽ നിന്ന് 0-ലേക്ക് മാറ്റം)\n",
|
|
"* ക്രോസോവറിനായി, നാം ഒരു വെക്ടറിൽ നിന്നുള്ള ചില ബിറ്റുകളും മറ്റൊരു വെക്ടറിൽ നിന്നുള്ള ചില ബിറ്റുകളും എടുക്കും. ഏത് ബിറ്റ് ഏത് ഇൻപുട്ട് മാസ്കിൽ നിന്നെടുക്കണമെന്ന് റാൻഡമായി തിരഞ്ഞെടുക്കാൻ നാം അതേ `generate` ഫംഗ്ഷൻ ഉപയോഗിക്കും.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def mutate(b):\n",
|
|
" x = b.copy()\n",
|
|
" i = random.randint(0,len(b)-1)\n",
|
|
" x[i] = 1-x[i]\n",
|
|
" return x\n",
|
|
"\n",
|
|
"def xover(b1,b2):\n",
|
|
" x = generate(b1)\n",
|
|
" return b1*x+b2*(1-x)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"പരിഹാരങ്ങളുടെ പ്രാഥമിക ജനസംഖ്യ $P$ സൃഷ്ടിക്കാം, വലുപ്പം `pop_size`:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"pop_size = 30\n",
|
|
"P = [generate(S) for _ in range(pop_size)]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"ഇപ്പോൾ, വളർച്ച നടത്താനുള്ള പ്രധാന ഫംഗ്ഷൻ. `n` എന്നത് വളർച്ചയുടെ ഘട്ടങ്ങളുടെ എണ്ണം ആണ്. ഓരോ ഘട്ടത്തിലും:\n",
|
|
"* 30% സാധ്യതയോടെ ഒരു മ്യൂട്ടേഷൻ നടത്തുകയും, ഏറ്റവും മോശം `fit` ഫംഗ്ഷൻ ഉള്ള ഘടകത്തെ മ്യൂട്ടേറ്റുചെയ്ത ഘടകത്തോടെ മാറ്റിസ്ഥാപിക്കുകയും ചെയ്യുന്നു\n",
|
|
"* 70% സാധ്യതയോടെ ക്രോസോവർ നടത്തുന്നു\n",
|
|
"\n",
|
|
"ഫംഗ്ഷൻ ഏറ്റവും മികച്ച പരിഹാരം (മികച്ച പരിഹാരത്തിന് അനുയോജ്യമായ ജീൻ) മടങ്ങിച്ചേർക്കുകയും, ഓരോ ആവർത്തനത്തിലും ജനസംഖ്യയിലെ കുറഞ്ഞ fit ഫംഗ്ഷന്റെ ചരിത്രവും മടങ്ങിച്ചേർക്കുകയും ചെയ്യുന്നു.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[0 0 0 1 1 0 0 0 0 1 1 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 1 0 0 0 0 0 1 0 1 1 0\n",
|
|
" 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 0 0 0\n",
|
|
" 0 1 1 1 0 1 0 1 1 1 1 1 0 0 0 1 1 0 1 0 0 1 0 0 1 1 1 1 1 1 1 1 0 1 0 1 1\n",
|
|
" 0 1 1 0 0 0 0 1 1 1 1 0 1 0 0 1 0 1 1 1 0 1 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0\n",
|
|
" 1 0 1 1 1 1 1 0 1 0 1 0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 1 1 1 0 1 0 0 0 1 0 1\n",
|
|
" 0 1 0 1 0 0 1 1 1 0 1 1 0 0 1] 4\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def evolve(P,S=S,n=2000):\n",
|
|
" res = []\n",
|
|
" for _ in range(n):\n",
|
|
" f = min([fit(b) for b in P])\n",
|
|
" res.append(f)\n",
|
|
" if f==0:\n",
|
|
" break\n",
|
|
" if random.randint(1,10)<3:\n",
|
|
" i = random.randint(0,len(P)-1)\n",
|
|
" b = mutate(P[i])\n",
|
|
" i = np.argmax([fit(z) for z in P])\n",
|
|
" P[i] = b\n",
|
|
" else:\n",
|
|
" i = random.randint(0,len(P)-1)\n",
|
|
" j = random.randint(0,len(P)-1)\n",
|
|
" b = xover(P[i],P[j])\n",
|
|
" if fit(b)<fit(P[i]):\n",
|
|
" P[i]=b\n",
|
|
" elif fit(b)<fit(P[j]):\n",
|
|
" P[j]=b\n",
|
|
" else:\n",
|
|
" pass\n",
|
|
" i = np.argmin([fit(b) for b in P])\n",
|
|
" return (P[i],res)\n",
|
|
"\n",
|
|
"(s,hist) = evolve(P)\n",
|
|
"print(s,fit(s))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"നാം `fit` ഫംഗ്ഷനെ വളരെ കുറച്ചതായി നിങ്ങൾ കാണാം! പ്രക്രിയയുടെ സമയത്ത് മുഴുവൻ ജനസംഖ്യയ്ക്കുള്ള `fit` ഫംഗ്ഷൻ എങ്ങനെ പെരുമാറുന്നു എന്ന് കാണിക്കുന്ന ഗ്രാഫ് ഇതാ.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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",
|
|
"text/plain": [
|
|
"<Figure size 432x288 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {
|
|
"needs_background": "light"
|
|
},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"plt.plot(hist)\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## പ്രശ്നം 2: എൻ ക്വീൻസ് പ്രശ്നം\n",
|
|
"\n",
|
|
"**പ്രവൃത്തി**: \n",
|
|
"നിങ്ങൾക്ക് $N \\times N$ വലുപ്പമുള്ള ചെസ് ബോർഡിൽ $N$ ക്വീൻസ് ഇങ്ങനെ വയ്ക്കേണ്ടതാണ്, അവ പരസ്പരം ആക്രമിക്കാതിരിക്കണം.\n",
|
|
"\n",
|
|
"ആദ്യമായി, ജെനറ്റിക് ആൽഗോരിതങ്ങൾ ഉപയോഗിക്കാതെ, പൂർണ്ണ തിരച്ചിൽ ഉപയോഗിച്ച് പ്രശ്നം പരിഹരിക്കാം. ബോർഡിന്റെ അവസ്ഥയെ ലിസ്റ്റ് $L$ ഉപയോഗിച്ച് പ്രതിനിധീകരിക്കാം, ഇവിടെ ലിസ്റ്റിലെ $i$-ആം സംഖ്യ $i$-ആം വരിയിലെ ക്വീന്റെ ആഡംബര സ്ഥാനം ആണ്. ഓരോ പരിഹാരത്തിലും ഓരോ വരിയിലും ഒരു ക്വീൻ മാത്രമേ ഉണ്ടാകൂ എന്നും ഓരോ വരിയിലും ക്വീൻ ഉണ്ടാകുമെന്നും ഇത് വ്യക്തമാണ്.\n",
|
|
"\n",
|
|
"നമ്മുടെ ലക്ഷ്യം പ്രശ്നത്തിന് ആദ്യ പരിഹാരം കണ്ടെത്തുക എന്നതാണ്, അതിന് ശേഷം തിരച്ചിൽ നിർത്തും. നിങ്ങൾക്ക് ഈ ഫംഗ്ഷൻ എളുപ്പത്തിൽ വിപുലീകരിച്ച് ക്വീൻമാരുടെ എല്ലാ സാധ്യതാ സ്ഥാനങ്ങളും സൃഷ്ടിക്കാം.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[1, 5, 8, 6, 3, 7, 2, 4]\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"True"
|
|
]
|
|
},
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"N = 8\n",
|
|
"\n",
|
|
"def checkbeats(i_new,j_new,l):\n",
|
|
" for i,j in enumerate(l,start=1):\n",
|
|
" if j==j_new:\n",
|
|
" return False\n",
|
|
" else:\n",
|
|
" if abs(j-j_new) == i_new-i:\n",
|
|
" return False\n",
|
|
" return True\n",
|
|
"\n",
|
|
"def nqueens(l,N=8,disp=True):\n",
|
|
" if len(l)==N:\n",
|
|
" if disp: print(l)\n",
|
|
" return True\n",
|
|
" else:\n",
|
|
" for j in range(1,N+1):\n",
|
|
" if checkbeats(len(l)+1,j,l):\n",
|
|
" l.append(j)\n",
|
|
" if nqueens(l,N,disp): return True\n",
|
|
" else: l.pop()\n",
|
|
" return False\n",
|
|
" \n",
|
|
"nqueens([],8)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"10.6 s ± 2.17 s per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"%timeit nqueens([],20,False)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"ഇപ്പോൾ നമുക്ക് ജെനറ്റിക് ആൽഗോരിതം ഉപയോഗിച്ച് സമാന പ്രശ്നം പരിഹരിക്കാം. ഈ പരിഹാരം [ഈ ബ്ലോഗ് പോസ്റ്റ്](https://kushalvyas.github.io/gen_8Q.html) പ്രചോദനമായാണ്.\n",
|
|
"\n",
|
|
"നാം ഓരോ പരിഹാരത്തെയും നീളം $N$ ഉള്ള ഒരേ ലിസ്റ്റ് ആയി പ്രതിനിധീകരിക്കും, കൂടാതെ `fit` ഫംഗ്ഷനായി പരസ്പരം ആക്രമിക്കുന്ന ക്വീൻകളുടെ എണ്ണം എടുക്കും:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def fit(L):\n",
|
|
" x=0\n",
|
|
" for i1,j1 in enumerate(L,1):\n",
|
|
" for i2,j2 in enumerate(L,1):\n",
|
|
" if i2>i1:\n",
|
|
" if j2==j1 or (abs(j2-j1)==i2-i1): x+=1\n",
|
|
" return x"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"ഫിറ്റ്നസ് ഫംഗ്ഷൻ കണക്കാക്കുന്നത് സമയം ആവശ്യപ്പെടുന്നതിനാൽ, ഫിറ്റ്നസ് ഫംഗ്ഷന്റെ മൂല്യത്തോടൊപ്പം ജനസംഖ്യയിലെ ഓരോ പരിഹാരവും സൂക്ഷിക്കാം. ആദ്യം ജനസംഖ്യ സൃഷ്ടിക്കാം:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[(array([2, 3, 8, 7, 5, 4, 1, 6]), 4),\n",
|
|
" (array([3, 4, 5, 1, 2, 8, 6, 7]), 8),\n",
|
|
" (array([1, 3, 7, 4, 5, 8, 6, 2]), 6),\n",
|
|
" (array([1, 5, 4, 6, 8, 3, 7, 2]), 4),\n",
|
|
" (array([3, 5, 7, 1, 8, 6, 4, 2]), 3)]"
|
|
]
|
|
},
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"def generate_one(N):\n",
|
|
" x = np.arange(1,N+1)\n",
|
|
" np.random.shuffle(x)\n",
|
|
" return (x,fit(x))\n",
|
|
"\n",
|
|
"def generate(N,NP):\n",
|
|
" return [generate_one(N) for _ in range(NP)]\n",
|
|
"\n",
|
|
"generate(8,5)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"ഇപ്പോൾ നമുക്ക് മ്യൂട്ടേഷൻ ഫംഗ്ഷനും ക്രോസോവർ ഫംഗ്ഷനും നിർവചിക്കേണ്ടതുണ്ട്. ക്രോസോവർ രണ്ട് ജീനുകളെ ഒരു യാദൃച്ഛിക സ്ഥാനത്ത് തകർത്തു, വ്യത്യസ്ത ജീനുകളിൽ നിന്നുള്ള രണ്ട് ഭാഗങ്ങൾ ചേർത്ത് കൂട്ടിച്ചേർക്കുന്നതാണ്.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"array([1, 2, 7, 8])"
|
|
]
|
|
},
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"def mutate(G):\n",
|
|
" x=random.randint(0,len(G)-1)\n",
|
|
" G[x]=random.randint(1,len(G))\n",
|
|
" return G\n",
|
|
" \n",
|
|
"def xover(G1,G2):\n",
|
|
" x=random.randint(0,len(G1))\n",
|
|
" return np.concatenate((G1[:x],G2[x:]))\n",
|
|
"\n",
|
|
"xover([1,2,3,4],[5,6,7,8])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"നാം മികച്ച ഫിറ്റ്നസ് ഫംഗ്ഷൻ ഉപയോഗിച്ച് കൂടുതൽ ജീനുകൾ തിരഞ്ഞെടുക്കുന്നതിലൂടെ ജീൻ തിരഞ്ഞെടുപ്പ് പ്രക്രിയ മെച്ചപ്പെടുത്തും. ഒരു ജീൻ തിരഞ്ഞെടുക്കാനുള്ള സാധ്യത ഫിറ്റ്നസ് ഫംഗ്ഷനിൽ ആശ്രയിച്ചിരിക്കും:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def choose_rand(P):\n",
|
|
" N=len(P[0][0])\n",
|
|
" mf = N*(N-1)//2 # max fitness fn\n",
|
|
" z = [mf-x[1] for x in P]\n",
|
|
" tf = sum(z) # total fitness\n",
|
|
" w = [x/tf for x in z]\n",
|
|
" p = np.random.choice(len(P),2,False,p=w)\n",
|
|
" return p[0],p[1]\n",
|
|
"\n",
|
|
"def choose(P):\n",
|
|
" def ch(w):\n",
|
|
" p=[]\n",
|
|
" while p==[]:\n",
|
|
" r = random.random()\n",
|
|
" p = [i for i,x in enumerate(P) if x[1]>=r]\n",
|
|
" return random.choice(p)\n",
|
|
" N=len(P[0][0])\n",
|
|
" mf = N*(N-1)//2 # max fitness fn\n",
|
|
" z = [mf-x[1] for x in P]\n",
|
|
" tf = sum(z) # total fitness\n",
|
|
" w = [x/tf for x in z]\n",
|
|
" p1=p2=0\n",
|
|
" while p1==p2:\n",
|
|
" p1 = ch(w)\n",
|
|
" p2 = ch(w)\n",
|
|
" return p1,p2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"ഇപ്പോൾ പ്രധാന എവല്യൂഷണറി ലൂപ്പ് നിർവചിക്കാം. മുമ്പത്തെ ഉദാഹരണത്തിൽ നിന്നു് ലജിക് അല്പം വ്യത്യസ്തമാക്കാം, സൃഷ്ടിപരമായ സമീപനം കാണിക്കാൻ. നാം പൂർണ്ണമായ പരിഹാരം (fitness function=0) ലഭിക്കുന്നതുവരെ ലൂപ്പ് നടത്തും, ഓരോ ഘട്ടത്തിലും നിലവിലെ തലമുറ എടുത്ത് അതിന്റെ തുല്യമായ പുതിയ തലമുറ സൃഷ്ടിക്കും. ഇത് `nxgeneration` ഫംഗ്ഷൻ ഉപയോഗിച്ച് താഴെപ്പറയുന്ന ഘട്ടങ്ങൾ വഴി ചെയ്യുന്നു:\n",
|
|
"\n",
|
|
"1. ഏറ്റവും അനുയോജ്യമല്ലാത്ത പരിഹാരങ്ങൾ ഒഴിവാക്കുക - ഇത് ചെയ്യാൻ `discard_unfit` ഫംഗ്ഷൻ ഉണ്ട്\n",
|
|
"1. തലമുറയിൽ കുറച്ച് കൂടുതൽ യാദൃച്ഛിക പരിഹാരങ്ങൾ ചേർക്കുക\n",
|
|
"1. ഓരോ പുതിയ ജീനിനും താഴെപ്പറയുന്ന ഘട്ടങ്ങൾ ഉപയോഗിച്ച് `gen_size` വലുപ്പമുള്ള പുതിയ തലമുറ പൂരിപ്പിക്കുക:\n",
|
|
" - ഫിറ്റ്നസ് ഫംഗ്ഷനുമായി അനുപാതമുള്ള സാധ്യതയോടെ രണ്ട് യാദൃച്ഛിക ജീനുകൾ തിരഞ്ഞെടുക്കുക\n",
|
|
" - ഒരു ക്രോസോവർ കണക്കാക്കുക\n",
|
|
" - `mutation_prob` സാധ്യതയോടെ ഒരു മ്യൂട്ടേഷൻ പ്രയോഗിക്കുക\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"(array([4, 7, 5, 3, 1, 6, 8, 2]), 0)"
|
|
]
|
|
},
|
|
"execution_count": 20,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"mutation_prob = 0.1\n",
|
|
"\n",
|
|
"def discard_unfit(P):\n",
|
|
" P.sort(key=lambda x:x[1])\n",
|
|
" return P[:len(P)//3]\n",
|
|
"\n",
|
|
"def nxgeneration(P):\n",
|
|
" gen_size=len(P)\n",
|
|
" P = discard_unfit(P)\n",
|
|
" P.extend(generate(len(P[0][0]),3))\n",
|
|
" new_gen = []\n",
|
|
" for _ in range(gen_size):\n",
|
|
" p1,p2 = choose_rand(P)\n",
|
|
" n = xover(P[p1][0],P[p2][0])\n",
|
|
" if random.random()<mutation_prob:\n",
|
|
" n=mutate(n)\n",
|
|
" nf = fit(n)\n",
|
|
" new_gen.append((n,nf))\n",
|
|
" '''\n",
|
|
" if (nf<=P[p1][1]) or (nf<=P[p2][1]):\n",
|
|
" new_gen.append((n,nf))\n",
|
|
" elif (P[p1][1]<P[p2][1]):\n",
|
|
" new_gen.append(P[p1])\n",
|
|
" else:\n",
|
|
" new_gen.append(P[p2])\n",
|
|
" '''\n",
|
|
" return new_gen\n",
|
|
" \n",
|
|
"def genetic(N,pop_size=100):\n",
|
|
" P = generate(N,pop_size)\n",
|
|
" mf = min([x[1] for x in P])\n",
|
|
" n=0\n",
|
|
" while mf>0:\n",
|
|
" #print(\"Generation {0}, fit={1}\".format(n,mf))\n",
|
|
" n+=1\n",
|
|
" mf = min([x[1] for x in P])\n",
|
|
" P = nxgeneration(P)\n",
|
|
" mi = np.argmin([x[1] for x in P])\n",
|
|
" return P[mi]\n",
|
|
"\n",
|
|
"genetic(8)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"അധികഭാഗം സമയങ്ങളിൽ നാം വളരെ വേഗത്തിൽ ഒരു പരിഹാരം കണ്ടെത്താൻ കഴിയുന്നത് രസകരമാണ്, പക്ഷേ ചില അപൂർവ സാഹചര്യങ്ങളിൽ ഓപ്റ്റിമൈസേഷൻ ലോക്കൽ മിനിമത്തിൽ എത്തുകയും പ്രക്രിയ ദീർഘകാലം തടസ്സപ്പെടുകയും ചെയ്യുന്നു. ശരാശരി സമയം അളക്കുമ്പോൾ ഇത് പരിഗണിക്കേണ്ടത് പ്രധാനമാണ്: അധികഭാഗം കേസുകളിൽ ജനിതക ആൽഗോരിതം പൂർണ്ണ തിരച്ചിലിനേക്കാൾ വേഗമേറിയതായിരിക്കും, ചില കേസുകളിൽ അത് കൂടുതൽ സമയം എടുക്കാം. ഈ പ്രശ്നം മറികടക്കാൻ, പരിഗണിക്കേണ്ട തലമുറകളുടെ എണ്ണം പരിമിതപ്പെടുത്തുന്നത് സാധാരണയായി ബുദ്ധിമുട്ടില്ല, പരിഹാരം കണ്ടെത്താൻ കഴിയാത്ത പക്ഷം നാം തുടക്കം മുതൽ തുടങ്ങാം.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"metadata": {
|
|
"trusted": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"The slowest run took 18.71 times longer than the fastest. This could mean that an intermediate result is being cached.\n",
|
|
"26.4 s ± 28.7 s per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"%timeit genetic(10)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**അസൂയാ**: \nഈ രേഖ AI വിവർത്തന സേവനം [Co-op Translator](https://github.com/Azure/co-op-translator) ഉപയോഗിച്ച് വിവർത്തനം ചെയ്തതാണ്. നാം കൃത്യതയ്ക്ക് ശ്രമിച്ചിട്ടുണ്ടെങ്കിലും, സ്വയം പ്രവർത്തിക്കുന്ന വിവർത്തനങ്ങളിൽ പിശകുകൾ അല്ലെങ്കിൽ തെറ്റുകൾ ഉണ്ടാകാമെന്ന് ദയവായി ശ്രദ്ധിക്കുക. അതിന്റെ മാതൃഭാഷയിലുള്ള യഥാർത്ഥ രേഖയാണ് പ്രാമാണികമായ ഉറവിടം എന്ന് പരിഗണിക്കേണ്ടതാണ്. നിർണായകമായ വിവരങ്ങൾക്ക്, പ്രൊഫഷണൽ മനുഷ്യ വിവർത്തനം ശുപാർശ ചെയ്യപ്പെടുന്നു. ഈ വിവർത്തനം ഉപയോഗിക്കുന്നതിൽ നിന്നുണ്ടാകുന്ന ഏതെങ്കിലും തെറ്റിദ്ധാരണകൾക്കോ തെറ്റായ വ്യാഖ്യാനങ്ങൾക്കോ ഞങ്ങൾ ഉത്തരവാദികളല്ല.\n<!-- CO-OP TRANSLATOR DISCLAIMER END -->\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"interpreter": {
|
|
"hash": "86193a1ab0ba47eac1c69c1756090baa3b420b3eea7d4aafab8b85f8b312f0c5"
|
|
},
|
|
"kernelspec": {
|
|
"display_name": "Python 3.6",
|
|
"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.9.5"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "1012c117808753433f6e2696e775ff4b",
|
|
"translation_date": "2025-11-26T02:35:16+00:00",
|
|
"source_file": "lessons/6-Other/21-GeneticAlgorithms/Genetic.ipynb",
|
|
"language_code": "ml"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
} |