4 Commits

Author SHA1 Message Date
20fa028965 lab10 2025-05-16 23:03:07 +04:00
35e265afbc Merge pull request 'lab9' (#9) from lab_9 into main
Reviewed-on: #9
2025-04-12 11:05:59 +04:00
afe52efad2 lab9 2025-04-11 19:14:37 +04:00
f60cc187e0 Merge pull request 'lab8' (#8) from lab_8 into main
Reviewed-on: #8
2025-04-05 11:50:01 +04:00
2 changed files with 1208 additions and 0 deletions

664
lab_10/lab10.ipynb Normal file
View File

@@ -0,0 +1,664 @@
{
"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
}

544
lab_9/lab9.ipynb Normal file

File diff suppressed because one or more lines are too long