1 Commits

Author SHA1 Message Date
fd8b462b01 lab11 2025-05-16 23:04:13 +04:00
2 changed files with 1319 additions and 664 deletions

View File

@@ -1,664 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "0c5af2a3",
"metadata": {},
"source": [
"## Лабораторная 10\n",
"Датасет: Knapsack Problem Data (https://www.kaggle.com/datasets/warcoder/knapsack-problem)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "b54c40b4",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Weights</th>\n",
" <th>Prices</th>\n",
" <th>Capacity</th>\n",
" <th>Best picks</th>\n",
" <th>Best price</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>[46 40 42 38 10]</td>\n",
" <td>[12 19 19 15 8]</td>\n",
" <td>40</td>\n",
" <td>[0. 1. 0. 0. 0.]</td>\n",
" <td>19.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>[11 31 4 6 7]</td>\n",
" <td>[ 2 8 18 16 3]</td>\n",
" <td>64</td>\n",
" <td>[1. 1. 1. 1. 1.]</td>\n",
" <td>47.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>[32 49 27 37 24]</td>\n",
" <td>[19 16 16 4 1]</td>\n",
" <td>87</td>\n",
" <td>[1. 0. 1. 0. 1.]</td>\n",
" <td>36.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>[20 35 22 23 16]</td>\n",
" <td>[19 17 19 9 1]</td>\n",
" <td>21</td>\n",
" <td>[1. 0. 0. 0. 0.]</td>\n",
" <td>19.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>[ 7 12 19 13 20]</td>\n",
" <td>[10 11 18 15 5]</td>\n",
" <td>50</td>\n",
" <td>[0. 1. 1. 1. 0.]</td>\n",
" <td>44.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9995</th>\n",
" <td>[18 12 11 49 32]</td>\n",
" <td>[12 3 17 19 7]</td>\n",
" <td>41</td>\n",
" <td>[1. 1. 1. 0. 0.]</td>\n",
" <td>32.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9996</th>\n",
" <td>[20 2 24 7 7]</td>\n",
" <td>[17 12 4 3 8]</td>\n",
" <td>17</td>\n",
" <td>[0. 1. 0. 1. 1.]</td>\n",
" <td>23.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9997</th>\n",
" <td>[43 43 5 15 23]</td>\n",
" <td>[15 5 7 2 7]</td>\n",
" <td>62</td>\n",
" <td>[1. 0. 1. 0. 0.]</td>\n",
" <td>22.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9998</th>\n",
" <td>[49 9 15 21 39]</td>\n",
" <td>[11 15 3 12 19]</td>\n",
" <td>65</td>\n",
" <td>[0. 1. 1. 0. 1.]</td>\n",
" <td>37.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9999</th>\n",
" <td>[25 36 42 19 39]</td>\n",
" <td>[15 12 7 18 12]</td>\n",
" <td>79</td>\n",
" <td>[1. 0. 0. 1. 0.]</td>\n",
" <td>33.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>10000 rows × 5 columns</p>\n",
"</div>"
],
"text/plain": [
" Weights Prices Capacity Best picks \\\n",
"0 [46 40 42 38 10] [12 19 19 15 8] 40 [0. 1. 0. 0. 0.] \n",
"1 [11 31 4 6 7] [ 2 8 18 16 3] 64 [1. 1. 1. 1. 1.] \n",
"2 [32 49 27 37 24] [19 16 16 4 1] 87 [1. 0. 1. 0. 1.] \n",
"3 [20 35 22 23 16] [19 17 19 9 1] 21 [1. 0. 0. 0. 0.] \n",
"4 [ 7 12 19 13 20] [10 11 18 15 5] 50 [0. 1. 1. 1. 0.] \n",
"... ... ... ... ... \n",
"9995 [18 12 11 49 32] [12 3 17 19 7] 41 [1. 1. 1. 0. 0.] \n",
"9996 [20 2 24 7 7] [17 12 4 3 8] 17 [0. 1. 0. 1. 1.] \n",
"9997 [43 43 5 15 23] [15 5 7 2 7] 62 [1. 0. 1. 0. 0.] \n",
"9998 [49 9 15 21 39] [11 15 3 12 19] 65 [0. 1. 1. 0. 1.] \n",
"9999 [25 36 42 19 39] [15 12 7 18 12] 79 [1. 0. 0. 1. 0.] \n",
"\n",
" Best price \n",
"0 19.0 \n",
"1 47.0 \n",
"2 36.0 \n",
"3 19.0 \n",
"4 44.0 \n",
"... ... \n",
"9995 32.0 \n",
"9996 23.0 \n",
"9997 22.0 \n",
"9998 37.0 \n",
"9999 33.0 \n",
"\n",
"[10000 rows x 5 columns]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"\n",
"df = pd.read_csv(\".//static//csv//knapsack_5_items.csv\")\n",
"\n",
"df"
]
},
{
"cell_type": "markdown",
"id": "44d383ce",
"metadata": {},
"source": [
"Хромосома - набор 0 и 1, 1 - предмет выбран, 0 - не выбран.\n",
"Ген - одно значение в хромосоме."
]
},
{
"cell_type": "markdown",
"id": "5b9bb0e1",
"metadata": {},
"source": [
"Функция генерации начальной популяции"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "de8b8b81",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[0, 0, 1, 1, 1],\n",
" [1, 0, 0, 1, 1],\n",
" [0, 1, 1, 1, 0],\n",
" [1, 1, 0, 1, 1],\n",
" [0, 0, 0, 0, 1],\n",
" [0, 1, 0, 1, 1],\n",
" [1, 1, 0, 0, 1],\n",
" [1, 0, 1, 1, 1],\n",
" [1, 0, 0, 0, 0],\n",
" [1, 0, 1, 1, 0]]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import random\n",
"\n",
"def create_individual(length):\n",
" individual = []\n",
" for _ in range(length):\n",
" individual.append(random.randint(0, 1))\n",
" return individual\n",
"\n",
"def create_population(length, size):\n",
" population = []\n",
" for _ in range(size):\n",
" population.append(create_individual(length))\n",
" return population\n",
"\n",
"create_population(5, 10)"
]
},
{
"cell_type": "markdown",
"id": "f27534fb",
"metadata": {},
"source": [
"Фитнес-функция"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "da1c3553",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"44"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def evaluate_fitness(individual, weights, prices, capacity):\n",
" total_value = 0\n",
" total_weight = 0\n",
" \n",
" for selected, weight, price in zip(individual, weights, prices):\n",
" if selected:\n",
" total_value += price\n",
" total_weight += weight\n",
" \n",
" if total_weight > capacity:\n",
" return 0\n",
" return total_value\n",
"\n",
"evaluate_fitness([0, 1, 1, 1, 0], [7, 12, 19, 13, 20], [10, 11, 18, 15, 5], 50)"
]
},
{
"cell_type": "markdown",
"id": "c9ef1b7b",
"metadata": {},
"source": [
"Оператор кроссинговера"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "37486d57",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"([0, 1, 1, 0, 0], [1, 0, 1, 1, 0])"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def crossover(parent1, parent2):\n",
" point = random.randint(1, len(parent1) - 1)\n",
" return (parent1[:point] + parent2[point:], parent2[:point] + parent1[point:])\n",
"\n",
"crossover([0, 1, 1, 1, 0], [1, 0, 1, 0, 0])"
]
},
{
"cell_type": "markdown",
"id": "87c1a74a",
"metadata": {},
"source": [
"Операторы мутации"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "95d1068f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"До мутации: [0, 1, 1, 1, 0]\n",
"После побитовой мутации: [1, 1, 0, 1, 0]\n",
"После свапа генов: [1, 0, 1, 1, 0]\n"
]
}
],
"source": [
"import random\n",
"\n",
"def mutate_flip_bits(individual, mutation_rate):\n",
" for i in range(len(individual)):\n",
" chance = random.random()\n",
" if chance < mutation_rate:\n",
" individual[i] = 1 - individual[i]\n",
"\n",
"def mutate_swap_genes(individual, mutation_rate):\n",
" chance = random.random()\n",
" if chance < mutation_rate and len(individual) >= 2:\n",
" i, j = random.sample(range(len(individual)), 2)\n",
" individual[i], individual[j] = individual[j], individual[i]\n",
"\n",
"individual = [0, 1, 1, 1, 0]\n",
"print(\"До мутации:\", individual)\n",
"\n",
"mutate_flip_bits(individual, 0.5)\n",
"print(\"После побитовой мутации:\", individual)\n",
"\n",
"mutate_swap_genes(individual, 1)\n",
"print(\"После свапа генов:\", individual)"
]
},
{
"cell_type": "markdown",
"id": "5d2d9f69",
"metadata": {},
"source": [
"Реализация генетического алгоритма и его применение"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "3f4d52de",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Weights</th>\n",
" <th>Prices</th>\n",
" <th>Capacity</th>\n",
" <th>Best picks</th>\n",
" <th>Best price</th>\n",
" <th>algorithmPicks</th>\n",
" <th>algorithmPrice</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>[46 40 42 38 10]</td>\n",
" <td>[12 19 19 15 8]</td>\n",
" <td>40</td>\n",
" <td>[0. 1. 0. 0. 0.]</td>\n",
" <td>19.0</td>\n",
" <td>[0, 1, 0, 0, 0]</td>\n",
" <td>19</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>[11 31 4 6 7]</td>\n",
" <td>[ 2 8 18 16 3]</td>\n",
" <td>64</td>\n",
" <td>[1. 1. 1. 1. 1.]</td>\n",
" <td>47.0</td>\n",
" <td>[1, 1, 1, 1, 1]</td>\n",
" <td>47</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>[32 49 27 37 24]</td>\n",
" <td>[19 16 16 4 1]</td>\n",
" <td>87</td>\n",
" <td>[1. 0. 1. 0. 1.]</td>\n",
" <td>36.0</td>\n",
" <td>[1, 0, 1, 0, 1]</td>\n",
" <td>36</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>[20 35 22 23 16]</td>\n",
" <td>[19 17 19 9 1]</td>\n",
" <td>21</td>\n",
" <td>[1. 0. 0. 0. 0.]</td>\n",
" <td>19.0</td>\n",
" <td>[1, 0, 0, 0, 0]</td>\n",
" <td>19</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>[ 7 12 19 13 20]</td>\n",
" <td>[10 11 18 15 5]</td>\n",
" <td>50</td>\n",
" <td>[0. 1. 1. 1. 0.]</td>\n",
" <td>44.0</td>\n",
" <td>[0, 1, 1, 1, 0]</td>\n",
" <td>44</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9995</th>\n",
" <td>[18 12 11 49 32]</td>\n",
" <td>[12 3 17 19 7]</td>\n",
" <td>41</td>\n",
" <td>[1. 1. 1. 0. 0.]</td>\n",
" <td>32.0</td>\n",
" <td>[1, 1, 1, 0, 0]</td>\n",
" <td>32</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9996</th>\n",
" <td>[20 2 24 7 7]</td>\n",
" <td>[17 12 4 3 8]</td>\n",
" <td>17</td>\n",
" <td>[0. 1. 0. 1. 1.]</td>\n",
" <td>23.0</td>\n",
" <td>[0, 1, 0, 1, 1]</td>\n",
" <td>23</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9997</th>\n",
" <td>[43 43 5 15 23]</td>\n",
" <td>[15 5 7 2 7]</td>\n",
" <td>62</td>\n",
" <td>[1. 0. 1. 0. 0.]</td>\n",
" <td>22.0</td>\n",
" <td>[1, 0, 1, 0, 0]</td>\n",
" <td>22</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9998</th>\n",
" <td>[49 9 15 21 39]</td>\n",
" <td>[11 15 3 12 19]</td>\n",
" <td>65</td>\n",
" <td>[0. 1. 1. 0. 1.]</td>\n",
" <td>37.0</td>\n",
" <td>[0, 1, 1, 0, 1]</td>\n",
" <td>37</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9999</th>\n",
" <td>[25 36 42 19 39]</td>\n",
" <td>[15 12 7 18 12]</td>\n",
" <td>79</td>\n",
" <td>[1. 0. 0. 1. 0.]</td>\n",
" <td>33.0</td>\n",
" <td>[1, 0, 0, 1, 0]</td>\n",
" <td>33</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Weights Prices Capacity Best picks \\\n",
"0 [46 40 42 38 10] [12 19 19 15 8] 40 [0. 1. 0. 0. 0.] \n",
"1 [11 31 4 6 7] [ 2 8 18 16 3] 64 [1. 1. 1. 1. 1.] \n",
"2 [32 49 27 37 24] [19 16 16 4 1] 87 [1. 0. 1. 0. 1.] \n",
"3 [20 35 22 23 16] [19 17 19 9 1] 21 [1. 0. 0. 0. 0.] \n",
"4 [ 7 12 19 13 20] [10 11 18 15 5] 50 [0. 1. 1. 1. 0.] \n",
"9995 [18 12 11 49 32] [12 3 17 19 7] 41 [1. 1. 1. 0. 0.] \n",
"9996 [20 2 24 7 7] [17 12 4 3 8] 17 [0. 1. 0. 1. 1.] \n",
"9997 [43 43 5 15 23] [15 5 7 2 7] 62 [1. 0. 1. 0. 0.] \n",
"9998 [49 9 15 21 39] [11 15 3 12 19] 65 [0. 1. 1. 0. 1.] \n",
"9999 [25 36 42 19 39] [15 12 7 18 12] 79 [1. 0. 0. 1. 0.] \n",
"\n",
" Best price algorithmPicks algorithmPrice \n",
"0 19.0 [0, 1, 0, 0, 0] 19 \n",
"1 47.0 [1, 1, 1, 1, 1] 47 \n",
"2 36.0 [1, 0, 1, 0, 1] 36 \n",
"3 19.0 [1, 0, 0, 0, 0] 19 \n",
"4 44.0 [0, 1, 1, 1, 0] 44 \n",
"9995 32.0 [1, 1, 1, 0, 0] 32 \n",
"9996 23.0 [0, 1, 0, 1, 1] 23 \n",
"9997 22.0 [1, 0, 1, 0, 0] 22 \n",
"9998 37.0 [0, 1, 1, 0, 1] 37 \n",
"9999 33.0 [1, 0, 0, 1, 0] 33 "
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import ast\n",
"import re\n",
"\n",
"population_size = 100\n",
"num_generations = 10\n",
"mutation_rate = 0.1\n",
"mutation_strategy = 'flip'\n",
"\n",
"def select_parents(population, weights, prices, capacity):\n",
" fitness_list = [evaluate_fitness(ind, weights, prices, capacity) for ind in population]\n",
" total_fitness = sum(fitness_list)\n",
"\n",
" if total_fitness == 0:\n",
" return random.choice(population), random.choice(population)\n",
"\n",
" selection_probs = [fitness / total_fitness for fitness in fitness_list]\n",
" selected = random.choices(population, weights=selection_probs, k=2)\n",
" return selected[0], selected[1]\n",
"\n",
"def genetic_algorithm(weights, prices, capacity,\n",
" population_size=100, num_generations=10,\n",
" mutation_rate=0.1, mutation_strategy='flip'):\n",
"\n",
" num_elements = len(weights)\n",
" population = create_population(num_elements, population_size)\n",
"\n",
" for generation in range(num_generations):\n",
" next_population = []\n",
"\n",
" for _ in range(population_size // 2):\n",
" parent1, parent2 = select_parents(population, weights, prices, capacity)\n",
" child1, child2 = crossover(parent1, parent2)\n",
"\n",
" if mutation_strategy == 'flip':\n",
" mutate_flip_bits(child1, mutation_rate)\n",
" mutate_flip_bits(child2, mutation_rate)\n",
" elif mutation_strategy == 'swap':\n",
" mutate_swap_genes(child1, mutation_rate)\n",
" mutate_swap_genes(child2, mutation_rate)\n",
"\n",
" next_population.append(child1)\n",
" next_population.append(child2)\n",
"\n",
" population = next_population\n",
"\n",
" best_individual = None\n",
" best_fitness = -1\n",
"\n",
" for individual in population:\n",
" fitness = evaluate_fitness(individual, weights, prices, capacity)\n",
" if fitness > best_fitness:\n",
" best_fitness = fitness\n",
" best_individual = individual\n",
"\n",
" return best_individual, best_fitness\n",
"\n",
"picks = []\n",
"best_prices = []\n",
"\n",
"def fix_list_string(s):\n",
" s = re.sub(r'\\[\\s*', '[', s)\n",
" s = re.sub(r'\\s*\\]', ']', s)\n",
" s = re.sub(r'\\s+', ',', s)\n",
" return s\n",
"\n",
"for _, row in df.iterrows():\n",
" weights = ast.literal_eval(fix_list_string(row['Weights']))\n",
" prices = ast.literal_eval(fix_list_string(row['Prices']))\n",
" capacity = row['Capacity']\n",
"\n",
" best_individual, best_value = genetic_algorithm(\n",
" weights, prices, capacity,\n",
" population_size, num_generations,\n",
" mutation_rate, mutation_strategy\n",
" )\n",
" \n",
" picks.append(best_individual)\n",
" best_prices.append(best_value)\n",
"\n",
"df['algorithmPicks'] = picks\n",
"df['algorithmPrice'] = best_prices\n",
"\n",
"pd.concat([df.head(5), df.tail(5)])"
]
},
{
"cell_type": "markdown",
"id": "e60888a3",
"metadata": {},
"source": [
"Ответы алгоритма совпадают с теми ответами, которые уже имелись в наборе данных"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "aimvenv",
"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.12.5"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

1319
lab_11/lab11.ipynb Normal file

File diff suppressed because one or more lines are too long