From d9b21e7fa1cef59977d0aabb99db68592cfa258a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=9F=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=D0=BF=D0=BE=D0=B2?= Date: Sat, 10 May 2025 20:12:35 +0400 Subject: [PATCH] =?UTF-8?q?=D0=B3=D0=BE=D1=82=D0=BE=D0=B2=D0=BE=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab_10/lab10.ipynb | 688 +++++++++++++++++++++++++++++++-------------- 1 file changed, 481 insertions(+), 207 deletions(-) diff --git a/lab_10/lab10.ipynb b/lab_10/lab10.ipynb index 7f4bf29..a6a9979 100644 --- a/lab_10/lab10.ipynb +++ b/lab_10/lab10.ipynb @@ -1,5 +1,15 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "044e75de", + "metadata": {}, + "source": [ + "# Лабортароная работа №10. Генетический алгоритм\n", + "\n", + "Задача оптимизации: подбор оптимального рациона на день (завтрак, обед и ужин) по содержанию белков, жиров и углеводов (БЖУ)." + ] + }, { "cell_type": "code", "execution_count": 1, @@ -9,63 +19,72 @@ "source": [ "import random\n", "import numpy as np\n", + "from pprint import pprint\n", "from deap import base, creator, tools, algorithms\n", "import matplotlib.pyplot as plt" ] }, + { + "cell_type": "markdown", + "id": "f5ebf2cd", + "metadata": {}, + "source": [ + "Список с продуктами и информацией по содержанию в них БЖУ (а также цене и предположительной разовой порции)" + ] + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "ebd621c8", "metadata": {}, "outputs": [], "source": [ - "# 1. База данных продуктов (калории, белки, жиры, углеводы, цена)\n", "products = [\n", - " # Мясо и птица (категория \"meat\")\n", - " {\"name\": \"Курица (грудка)\", \"calories\": 165, \"protein\": 31, \"fat\": 3.6, \"carbs\": 0, \"price\": 30, \"category\": \"meat\"},\n", - " {\"name\": \"Говядина\", \"calories\": 250, \"protein\": 26, \"fat\": 15, \"carbs\": 0, \"price\": 93, \"category\": \"meat\"},\n", - " {\"name\": \"Индейка\", \"calories\": 135, \"protein\": 29, \"fat\": 1.7, \"carbs\": 0, \"price\": 70, \"category\": \"meat\"},\n", - " {\"name\": \"Свинина\", \"calories\": 242, \"protein\": 21, \"fat\": 17, \"carbs\": 0, \"price\": 34, \"category\": \"meat\"},\n", + " {\"name\": \"Курица (грудка)\", \"calories\": 165, \"protein\": 31, \"fat\": 3.6, \"carbs\": 0, \"price\": 30, \"category\": \"meat\", \"portion\": 150},\n", + " {\"name\": \"Говядина\", \"calories\": 250, \"protein\": 26, \"fat\": 15, \"carbs\": 0, \"price\": 93, \"category\": \"meat\", \"portion\": 120},\n", + " {\"name\": \"Индейка\", \"calories\": 135, \"protein\": 29, \"fat\": 1.7, \"carbs\": 0, \"price\": 70, \"category\": \"meat\", \"portion\": 150},\n", + " {\"name\": \"Свинина\", \"calories\": 242, \"protein\": 21, \"fat\": 17, \"carbs\": 0, \"price\": 34, \"category\": \"meat\", \"portion\": 120},\n", " \n", - " # Рыба и морепродукты (категория \"fish\")\n", - " {\"name\": \"Минтай\", \"calories\": 72, \"protein\": 16, \"fat\": 0.9, \"carbs\": 0, \"price\": 36, \"category\": \"fish\"},\n", - " {\"name\": \"Треска\", \"calories\": 69, \"protein\": 16, \"fat\": 0.6, \"carbs\": 0, \"price\": 110, \"category\": \"fish\"},\n", - " {\"name\": \"Скумбрия\", \"calories\": 191, \"protein\": 18, \"fat\": 13.2, \"carbs\": 0, \"price\": 106, \"category\": \"fish\"},\n", + " {\"name\": \"Минтай\", \"calories\": 72, \"protein\": 16, \"fat\": 0.9, \"carbs\": 0, \"price\": 36, \"category\": \"fish\", \"portion\": 180},\n", + " {\"name\": \"Треска\", \"calories\": 69, \"protein\": 16, \"fat\": 0.6, \"carbs\": 0, \"price\": 110, \"category\": \"fish\", \"portion\": 180},\n", + " {\"name\": \"Скумбрия\", \"calories\": 191, \"protein\": 18, \"fat\": 13.2, \"carbs\": 0, \"price\": 106, \"category\": \"fish\", \"portion\": 150},\n", " \n", - " # Крупы и злаки (категория \"grains\")\n", - " {\"name\": \"Рис\", \"calories\": 325, \"protein\": 6.9, \"fat\": 1, \"carbs\": 72.2, \"price\": 6.8, \"category\": \"grains\"},\n", - " {\"name\": \"Гречка\", \"calories\": 330, \"protein\": 13, \"fat\": 2.5, \"carbs\": 68, \"price\": 3.5, \"category\": \"grains\"},\n", - " {\"name\": \"Овсянка\", \"calories\": 352, \"protein\": 12.3, \"fat\": 6.2, \"carbs\": 61.8, \"price\": 4.5, \"category\": \"grains\"},\n", - " {\"name\": \"Перловка\", \"calories\": 317, \"protein\": 10.4, \"fat\": 1.3, \"carbs\": 67, \"price\": 3, \"category\": \"grains\"},\n", + " {\"name\": \"Рис\", \"calories\": 325, \"protein\": 6.9, \"fat\": 1, \"carbs\": 72.2, \"price\": 6.8, \"category\": \"grains\", \"portion\": 100},\n", + " {\"name\": \"Гречка\", \"calories\": 330, \"protein\": 13, \"fat\": 2.5, \"carbs\": 68, \"price\": 3.5, \"category\": \"grains\", \"portion\": 100},\n", + " {\"name\": \"Овсянка\", \"calories\": 352, \"protein\": 12.3, \"fat\": 6.2, \"carbs\": 61.8, \"price\": 4.5, \"category\": \"grains\", \"portion\": 80},\n", + " {\"name\": \"Перловка\", \"calories\": 317, \"protein\": 10.4, \"fat\": 1.3, \"carbs\": 67, \"price\": 3, \"category\": \"grains\", \"portion\": 100},\n", " \n", - " # Овощи (категория \"vegetables\")\n", - " {\"name\": \"Брокколи\", \"calories\": 34, \"protein\": 2.8, \"fat\": 0.4, \"carbs\": 7.0, \"price\": 40, \"category\": \"vegetables\"},\n", - " {\"name\": \"Морковь\", \"calories\": 41, \"protein\": 0.9, \"fat\": 0.2, \"carbs\": 10, \"price\": 0.9, \"category\": \"vegetables\"},\n", - " {\"name\": \"Картофель\", \"calories\": 77, \"protein\": 2, \"fat\": 0.1, \"carbs\": 17, \"price\": 11, \"category\": \"grains\"},\n", - " {\"name\": \"Капуста белокочаная\", \"calories\": 28, \"protein\": 1.8, \"fat\": 0.2, \"carbs\": 4.7, \"price\": 7, \"category\": \"vegetables\"},\n", - " {\"name\": \"Помидоры\", \"calories\": 18, \"protein\": 0.9, \"fat\": 0.2, \"carbs\": 2.7, \"price\": 40, \"category\": \"vegetables\"},\n", - " {\"name\": \"Огурцы\", \"calories\": 15, \"protein\": 0.7, \"fat\": 0.1, \"carbs\": 3.1, \"price\": 38, \"category\": \"vegetables\"},\n", + " {\"name\": \"Брокколи\", \"calories\": 34, \"protein\": 2.8, \"fat\": 0.4, \"carbs\": 7.0, \"price\": 40, \"category\": \"vegetables\", \"portion\": 200},\n", + " {\"name\": \"Морковь\", \"calories\": 41, \"protein\": 0.9, \"fat\": 0.2, \"carbs\": 10, \"price\": 0.9, \"category\": \"vegetables\", \"portion\": 150},\n", + " {\"name\": \"Картофель\", \"calories\": 77, \"protein\": 2, \"fat\": 0.1, \"carbs\": 17, \"price\": 11, \"category\": \"grains\", \"portion\": 150},\n", + " {\"name\": \"Капуста белокочаная\", \"calories\": 28, \"protein\": 1.8, \"fat\": 0.2, \"carbs\": 4.7, \"price\": 7, \"category\": \"vegetables\", \"portion\": 200},\n", + " {\"name\": \"Помидоры\", \"calories\": 18, \"protein\": 0.9, \"fat\": 0.2, \"carbs\": 2.7, \"price\": 40, \"category\": \"vegetables\", \"portion\": 200},\n", + " {\"name\": \"Огурцы\", \"calories\": 15, \"protein\": 0.7, \"fat\": 0.1, \"carbs\": 3.1, \"price\": 38, \"category\": \"vegetables\", \"portion\": 200},\n", " \n", - " # Фрукты (категория \"fruits\")\n", - " {\"name\": \"Яблоки\", \"calories\": 47, \"protein\": 0.4, \"fat\": 0.4, \"carbs\": 9.8, \"price\": 18, \"category\": \"fruits\"},\n", - " {\"name\": \"Бананы\", \"calories\": 96, \"protein\": 1.5, \"fat\": 0.5, \"carbs\": 21, \"price\": 19, \"category\": \"fruits\"},\n", - " {\"name\": \"Апельсины\", \"calories\": 43, \"protein\": 0.9, \"fat\": 0.2, \"carbs\": 8.1, \"price\": 15, \"category\": \"fruits\"},\n", + " {\"name\": \"Яблоки\", \"calories\": 47, \"protein\": 0.4, \"fat\": 0.4, \"carbs\": 9.8, \"price\": 18, \"category\": \"fruits\", \"portion\": 150},\n", + " {\"name\": \"Бананы\", \"calories\": 96, \"protein\": 1.5, \"fat\": 0.5, \"carbs\": 21, \"price\": 19, \"category\": \"fruits\", \"portion\": 120},\n", + " {\"name\": \"Апельсины\", \"calories\": 43, \"protein\": 0.9, \"fat\": 0.2, \"carbs\": 8.1, \"price\": 15, \"category\": \"fruits\", \"portion\": 150},\n", " \n", - " # Молочные продукты (категория \"dairy\")\n", - " {\"name\": \"Творог 5%\", \"calories\": 120, \"protein\": 16, \"fat\": 5, \"carbs\": 3, \"price\": 54, \"category\": \"dairy\"},\n", - " {\"name\": \"Творог 0.5%\", \"calories\": 90, \"protein\": 18, \"fat\": 0.5, \"carbs\": 3.5, \"price\": 38, \"category\": \"dairy\"},\n", - " {\"name\": \"Молоко\", \"calories\": 60, \"protein\": 3, \"fat\": 3.2, \"carbs\": 4.7, \"price\": 9.5, \"category\": \"dairy\"},\n", - " {\"name\": \"Сыр твердый\", \"calories\": 340, \"protein\": 26.3, \"fat\": 26.1, \"carbs\": 0, \"price\": 126, \"category\": \"dairy\"},\n", - " {\"name\": \"Йогурт 5%\", \"calories\": 120, \"protein\": 5.7, \"fat\": 4.8, \"carbs\": 13.9, \"price\": 38, \"category\": \"dairy\"},\n", + " {\"name\": \"Творог 5%\", \"calories\": 120, \"protein\": 16, \"fat\": 5, \"carbs\": 3, \"price\": 54, \"category\": \"dairy\", \"portion\": 150},\n", + " {\"name\": \"Творог 0.5%\", \"calories\": 90, \"protein\": 18, \"fat\": 0.5, \"carbs\": 3.5, \"price\": 38, \"category\": \"dairy\", \"portion\": 150},\n", + " {\"name\": \"Молоко\", \"calories\": 60, \"protein\": 3, \"fat\": 3.2, \"carbs\": 4.7, \"price\": 9.5, \"category\": \"dairy\", \"portion\": 200},\n", + " {\"name\": \"Сыр твердый\", \"calories\": 340, \"protein\": 26.3, \"fat\": 26.1, \"carbs\": 0, \"price\": 126, \"category\": \"dairy\", \"portion\": 50},\n", + " {\"name\": \"Йогурт 5%\", \"calories\": 120, \"protein\": 5.7, \"fat\": 4.8, \"carbs\": 13.9, \"price\": 38, \"category\": \"dairy\", \"portion\": 125},\n", " \n", - " # Другое\n", - " {\"name\": \"Яйца (1 шт. ~60г)\", \"calories\": 157, \"protein\": 12.7, \"fat\": 11.5, \"carbs\": 0.7, \"price\": 15.8, \"category\": \"eggs\"},\n", - " {\"name\": \"Масло сливочное\", \"calories\": 662, \"protein\": 1, \"fat\": 72.5, \"carbs\": 1.4, \"price\": 86, \"category\": \"fats\"},\n", - " {\"name\": \"Масло подсолнечное\", \"calories\": 899, \"protein\": 0, \"fat\": 100, \"carbs\": 0, \"price\": 16, \"category\": \"fats\"},\n", + " {\"name\": \"Яйца (1 шт. ~60г)\", \"calories\": 157, \"protein\": 12.7, \"fat\": 11.5, \"carbs\": 0.7, \"price\": 15.8, \"category\": \"eggs\", \"portion\": 60},\n", + " {\"name\": \"Масло сливочное\", \"calories\": 662, \"protein\": 1, \"fat\": 72.5, \"carbs\": 1.4, \"price\": 86, \"category\": \"fats\", \"portion\": 10},\n", + " {\"name\": \"Масло подсолнечное\", \"calories\": 899, \"protein\": 0, \"fat\": 100, \"carbs\": 0, \"price\": 16, \"category\": \"fats\", \"portion\": 10},\n", "]" ] }, + { + "cell_type": "markdown", + "id": "3f75c690", + "metadata": {}, + "source": [ + "Указываем целевые значения и дополнительные списки с несочетаемыми продуктами " + ] + }, { "cell_type": "code", "execution_count": 3, @@ -73,22 +92,38 @@ "metadata": {}, "outputs": [], "source": [ - "# 2. Целевые значения (суточные нормы)\n", "TARGET_CALORIES = 2000\n", - "TARGET_PROTEIN = 100\n", - "TARGET_FAT = 70\n", - "TARGET_CARBS = 250\n", - "MEAL_PRODUCTS = {\"breakfast\": 3, \"lunch\": 4, \"dinner\": 3} # Кол-во продуктов на прием пищи\n", + "TARGET_PROTEIN = 75\n", + "TARGET_FAT = 67\n", + "TARGET_CARBS = 275\n", + "MEAL_PRODUCTS = {\n", + " \"breakfast\": 3,\n", + " \"lunch\": 4,\n", + " \"dinner\": 3,\n", + "} # Кол-во продуктов на прием пищи\n", "\n", "# Категории, которые не должны повторяться в одном приеме пищи\n", "EXCLUSIVE_CATEGORIES = [\"meat\", \"fish\", \"grains\", \"dairy\"]\n", "\n", "# Категории, которые не должны встречаться в одном приеме пищи\n", - "INCOMPATIBLE_CATEGORIES = [[\"meat\", \"fish\"], [\"fish\", \"dairy\"], [\"vegetables\", \"dairy\"], [\"fats\", \"dairy\"]]\n", + "INCOMPATIBLE_CATEGORIES = [\n", + " [\"meat\", \"fish\"],\n", + " [\"fish\", \"dairy\"],\n", + " [\"vegetables\", \"dairy\"],\n", + " [\"fats\", \"dairy\"],\n", + "]\n", "\n", "INCOMPATIBLE_CATEGORIES = [set(x) for x in INCOMPATIBLE_CATEGORIES]" ] }, + { + "cell_type": "markdown", + "id": "ce8b1155", + "metadata": {}, + "source": [ + "Особь (хромосома) у нас будет являться списком списков (приемов пищи). Внутри списоков приемов пищи будут находиться гены - продукты питания." + ] + }, { "cell_type": "code", "execution_count": 4, @@ -96,54 +131,60 @@ "metadata": {}, "outputs": [], "source": [ - "# 3. Создаем структуру особи\n", + "# Создаем структуру особи\n", "creator.create(\"FitnessMin\", base.Fitness, weights=(-1.0,)) # Минимизируем функцию\n", "creator.create(\"Individual\", list, fitness=creator.FitnessMin)\n", "\n", "toolbox = base.Toolbox()\n", "\n", + "\n", "# Генерация случайного приема пищи с учетом ограничений\n", "def create_meal(meal_type):\n", " meal = []\n", " categories_in_meal = set()\n", - " \n", + "\n", " for _ in range(MEAL_PRODUCTS[meal_type]):\n", " # Фильтруем продукты, чтобы не было конфликтов категорий\n", " available_products = [\n", - " p for p in products \n", - " if (p[\"category\"] not in EXCLUSIVE_CATEGORIES or \n", - " p[\"category\"] not in categories_in_meal)\n", + " p\n", + " for p in products\n", + " if (\n", + " p[\"category\"] not in EXCLUSIVE_CATEGORIES\n", + " or p[\"category\"] not in categories_in_meal\n", + " )\n", " ]\n", - " \n", + "\n", " if not available_products:\n", " break\n", - " \n", + "\n", " product = random.choice(available_products)\n", " meal.append(product)\n", - " \n", + "\n", " if product[\"category\"] in EXCLUSIVE_CATEGORIES:\n", " categories_in_meal.add(product[\"category\"])\n", - " \n", + "\n", " return meal\n", "\n", + "\n", "# Создание особи: [завтрак, обед, ужин]\n", "def create_individual():\n", " individual = []\n", " used_products = set()\n", - " \n", + "\n", " for meal_type in [\"breakfast\", \"lunch\", \"dinner\"]:\n", " while True:\n", " meal = create_meal(meal_type)\n", " meal_product_names = {p[\"name\"] for p in meal}\n", - " \n", + "\n", " # Проверяем, что продукты не повторяются в течение дня\n", " if not meal_product_names & used_products:\n", " individual.append(meal)\n", " used_products.update(meal_product_names)\n", " break\n", - " \n", + "\n", " return individual\n", "\n", + "\n", "toolbox.register(\"individual\", tools.initIterate, creator.Individual, create_individual)\n", "toolbox.register(\"population\", tools.initRepeat, list, toolbox.individual)" ] @@ -151,11 +192,64 @@ { "cell_type": "code", "execution_count": 5, + "id": "662390bd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'name': 'Сыр твердый',\n", + " 'calories': 340,\n", + " 'protein': 26.3,\n", + " 'fat': 26.1,\n", + " 'carbs': 0,\n", + " 'price': 126,\n", + " 'category': 'dairy',\n", + " 'portion': 50},\n", + " {'name': 'Перловка',\n", + " 'calories': 317,\n", + " 'protein': 10.4,\n", + " 'fat': 1.3,\n", + " 'carbs': 67,\n", + " 'price': 3,\n", + " 'category': 'grains',\n", + " 'portion': 100},\n", + " {'name': 'Индейка',\n", + " 'calories': 135,\n", + " 'protein': 29,\n", + " 'fat': 1.7,\n", + " 'carbs': 0,\n", + " 'price': 70,\n", + " 'category': 'meat',\n", + " 'portion': 150}]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# пример создания случайного приема пищи\n", + "create_meal(\"breakfast\")" + ] + }, + { + "cell_type": "markdown", + "id": "946ea3a8", + "metadata": {}, + "source": [ + "В фитнес-функции будем высчитывать общее содержание БЖУ для всех приемов пищи за день и высчитывать отклонение от целевых параметров. Также будем учитывать цену продуктов питания и содержание в одном приеме пищи несочетаемых продуктов (например, и рыба и мясо в одном приеме пищи, или молочная продукция и овощи). Так как у нас есть заданные оптимальные параметры БЖУ, то нам будет удобнее взять эти параметры за нулевую точку и отталкиваться от нее - *будем искать минимум отклонения* от целевых значений." + ] + }, + { + "cell_type": "code", + "execution_count": 6, "id": "ffd94b14", "metadata": {}, "outputs": [], "source": [ - "# 4. Фитнес-функция\n", + "# Фитнес-функция\n", "def evaluate(individual):\n", " total_calories = 0\n", " total_protein = 0\n", @@ -211,12 +305,142 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, + "id": "996243ae", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[{'calories': 60,\n", + " 'carbs': 4.7,\n", + " 'category': 'dairy',\n", + " 'fat': 3.2,\n", + " 'name': 'Молоко',\n", + " 'portion': 200,\n", + " 'price': 9.5,\n", + " 'protein': 3},\n", + " {'calories': 191,\n", + " 'carbs': 0,\n", + " 'category': 'fish',\n", + " 'fat': 13.2,\n", + " 'name': 'Скумбрия',\n", + " 'portion': 150,\n", + " 'price': 106,\n", + " 'protein': 18},\n", + " {'calories': 47,\n", + " 'carbs': 9.8,\n", + " 'category': 'fruits',\n", + " 'fat': 0.4,\n", + " 'name': 'Яблоки',\n", + " 'portion': 150,\n", + " 'price': 18,\n", + " 'protein': 0.4}],\n", + " [{'calories': 90,\n", + " 'carbs': 3.5,\n", + " 'category': 'dairy',\n", + " 'fat': 0.5,\n", + " 'name': 'Творог 0.5%',\n", + " 'portion': 150,\n", + " 'price': 38,\n", + " 'protein': 18},\n", + " {'calories': 242,\n", + " 'carbs': 0,\n", + " 'category': 'meat',\n", + " 'fat': 17,\n", + " 'name': 'Свинина',\n", + " 'portion': 120,\n", + " 'price': 34,\n", + " 'protein': 21},\n", + " {'calories': 96,\n", + " 'carbs': 21,\n", + " 'category': 'fruits',\n", + " 'fat': 0.5,\n", + " 'name': 'Бананы',\n", + " 'portion': 120,\n", + " 'price': 19,\n", + " 'protein': 1.5},\n", + " {'calories': 28,\n", + " 'carbs': 4.7,\n", + " 'category': 'vegetables',\n", + " 'fat': 0.2,\n", + " 'name': 'Капуста белокочаная',\n", + " 'portion': 200,\n", + " 'price': 7,\n", + " 'protein': 1.8}],\n", + " [{'calories': 34,\n", + " 'carbs': 7.0,\n", + " 'category': 'vegetables',\n", + " 'fat': 0.4,\n", + " 'name': 'Брокколи',\n", + " 'portion': 200,\n", + " 'price': 40,\n", + " 'protein': 2.8},\n", + " {'calories': 18,\n", + " 'carbs': 2.7,\n", + " 'category': 'vegetables',\n", + " 'fat': 0.2,\n", + " 'name': 'Помидоры',\n", + " 'portion': 200,\n", + " 'price': 40,\n", + " 'protein': 0.9},\n", + " {'calories': 43,\n", + " 'carbs': 8.1,\n", + " 'category': 'fruits',\n", + " 'fat': 0.2,\n", + " 'name': 'Апельсины',\n", + " 'portion': 150,\n", + " 'price': 15,\n", + " 'protein': 0.9}]]\n" + ] + } + ], + "source": [ + "# пример генерации хромосомы (рациона на день)\n", + "daily_meals = create_individual()\n", + "pprint(daily_meals)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "f2110fe5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(14453.0,)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# расчет фитнес-функции\n", + "val = evaluate(daily_meals)\n", + "val" + ] + }, + { + "cell_type": "markdown", + "id": "d49623dd", + "metadata": {}, + "source": [ + "Опишем функции мутации, будем с определенной вероятностью менять ген (продукт) в приеме пищи" + ] + }, + { + "cell_type": "code", + "execution_count": 9, "id": "05e8df95", "metadata": {}, "outputs": [], "source": [ - "# 5. Генетические операторы\n", + "# функция мутации с учетом несочетаемых продуктов\n", "def mutate_individual(individual, indpb):\n", " for i, meal in enumerate(individual):\n", " if random.random() < indpb:\n", @@ -234,14 +458,54 @@ " \n", " return individual,\n", "\n", - "toolbox.register(\"mate\", tools.cxTwoPoint)\n", - "toolbox.register(\"mutate\", mutate_individual, indpb=0.3)\n", - "toolbox.register(\"select\", tools.selTournament, tournsize=3)" + "\n", + "# функция мутации без учета сочетаемости\n", + "def mutate_individual2(individual, indpb):\n", + " for i, meal in enumerate(individual):\n", + " if random.random() < indpb:\n", + " # Создаем новый прием пищи\n", + " meal_type = [\"breakfast\", \"lunch\", \"dinner\"][i]\n", + " new_meal = create_meal(meal_type)\n", + " \n", + " individual[i] = new_meal\n", + " \n", + " return individual,\n", + "\n", + "toolbox.register(\"mutate\", mutate_individual2, indpb=0.3)" + ] + }, + { + "cell_type": "markdown", + "id": "457e9260", + "metadata": {}, + "source": [ + "Функции кроссинговера и селекции возьмем стандартные, которые предлагает библиотека.\n", + "\n", + "В кроссинговере происходит обмен приемами пищи, а в селекции будем отбирать 3 лучших индивида." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, + "id": "38bf0e0c", + "metadata": {}, + "outputs": [], + "source": [ + "toolbox.register(\"mate\", tools.cxTwoPoint)\n", + "toolbox.register(\"select\", tools.selTournament, tournsize=3)" + ] + }, + { + "cell_type": "markdown", + "id": "70a6f50d", + "metadata": {}, + "source": [ + "Запускаем работу алгоритма и указываем количество особей в популяции 100 штук. Количество поколений - 100." + ] + }, + { + "cell_type": "code", + "execution_count": 11, "id": "bf02bfed", "metadata": {}, "outputs": [ @@ -250,112 +514,112 @@ "output_type": "stream", "text": [ "gen\tnevals\tmin \n", - "0 \t100 \t1180.5\n", - "1 \t79 \t1903.4\n", - "2 \t76 \t500.6 \n", - "3 \t82 \t500.6 \n", - "4 \t74 \t500.6 \n", - "5 \t87 \t500.6 \n", - "6 \t85 \t500.6 \n", - "7 \t82 \t500.6 \n", - "8 \t75 \t500.6 \n", - "9 \t80 \t500.6 \n", - "10 \t77 \t500.6 \n", - "11 \t75 \t500.6 \n", - "12 \t81 \t500.6 \n", - "13 \t69 \t500.6 \n", - "14 \t64 \t500.6 \n", - "15 \t84 \t500.6 \n", - "16 \t86 \t500.6 \n", - "17 \t80 \t500.6 \n", - "18 \t73 \t500.6 \n", - "19 \t72 \t500.6 \n", - "20 \t77 \t500.6 \n", - "21 \t77 \t500.6 \n", - "22 \t88 \t500.6 \n", - "23 \t87 \t500.6 \n", - "24 \t80 \t500.6 \n", - "25 \t86 \t500.6 \n", - "26 \t74 \t500.6 \n", - "27 \t90 \t500.6 \n", - "28 \t79 \t500.6 \n", - "29 \t87 \t500.6 \n", - "30 \t74 \t500.6 \n", - "31 \t79 \t500.6 \n", - "32 \t85 \t500.6 \n", - "33 \t81 \t500.6 \n", - "34 \t75 \t500.6 \n", - "35 \t90 \t500.6 \n", - "36 \t83 \t500.6 \n", - "37 \t86 \t500.6 \n", - "38 \t76 \t500.6 \n", - "39 \t86 \t500.6 \n", - "40 \t83 \t500.6 \n", - "41 \t77 \t500.6 \n", - "42 \t93 \t500.6 \n", - "43 \t78 \t500.6 \n", - "44 \t84 \t500.6 \n", - "45 \t79 \t500.6 \n", - "46 \t79 \t500.6 \n", - "47 \t83 \t500.6 \n", - "48 \t73 \t500.6 \n", - "49 \t79 \t500.6 \n", - "50 \t75 \t500.6 \n", - "51 \t77 \t500.6 \n", - "52 \t87 \t500.6 \n", - "53 \t70 \t500.6 \n", - "54 \t79 \t500.6 \n", - "55 \t66 \t500.6 \n", - "56 \t73 \t500.6 \n", - "57 \t81 \t500.6 \n", - "58 \t73 \t500.6 \n", - "59 \t84 \t500.6 \n", - "60 \t87 \t500.6 \n", - "61 \t77 \t500.6 \n", - "62 \t80 \t500.6 \n", - "63 \t76 \t500.6 \n", - "64 \t81 \t500.6 \n", - "65 \t76 \t500.6 \n", - "66 \t83 \t500.6 \n", - "67 \t92 \t500.6 \n", - "68 \t80 \t500.6 \n", - "69 \t79 \t500.6 \n", - "70 \t92 \t500.6 \n", - "71 \t79 \t500.6 \n", - "72 \t74 \t500.6 \n", - "73 \t78 \t500.6 \n", - "74 \t83 \t500.6 \n", - "75 \t84 \t500.6 \n", - "76 \t84 \t500.6 \n", - "77 \t82 \t500.6 \n", - "78 \t81 \t500.6 \n", - "79 \t79 \t500.6 \n", - "80 \t88 \t500.6 \n", - "81 \t76 \t500.6 \n", - "82 \t79 \t500.6 \n", - "83 \t85 \t500.6 \n", - "84 \t83 \t500.6 \n", - "85 \t81 \t500.6 \n", - "86 \t78 \t500.6 \n", - "87 \t81 \t500.6 \n", - "88 \t80 \t500.6 \n", - "89 \t88 \t500.6 \n", - "90 \t73 \t500.6 \n", - "91 \t81 \t500.6 \n", - "92 \t87 \t500.6 \n", - "93 \t88 \t500.6 \n", - "94 \t85 \t374.9 \n", - "95 \t83 \t374.9 \n", - "96 \t82 \t374.9 \n", - "97 \t83 \t374.9 \n", - "98 \t86 \t374.9 \n", - "99 \t83 \t374.9 \n", - "100\t77 \t374.9 \n" + "0 \t100 \t1444.7\n", + "1 \t79 \t1349.9\n", + "2 \t76 \t703.8 \n", + "3 \t83 \t703.8 \n", + "4 \t81 \t703.8 \n", + "5 \t79 \t703.8 \n", + "6 \t71 \t703.8 \n", + "7 \t76 \t703.8 \n", + "8 \t73 \t703.8 \n", + "9 \t78 \t703.8 \n", + "10 \t75 \t703.8 \n", + "11 \t82 \t703.8 \n", + "12 \t73 \t703.8 \n", + "13 \t80 \t586 \n", + "14 \t69 \t586 \n", + "15 \t87 \t586 \n", + "16 \t76 \t586 \n", + "17 \t82 \t586 \n", + "18 \t80 \t586 \n", + "19 \t70 \t586 \n", + "20 \t84 \t586 \n", + "21 \t79 \t586 \n", + "22 \t71 \t586 \n", + "23 \t79 \t586 \n", + "24 \t73 \t586 \n", + "25 \t83 \t586 \n", + "26 \t72 \t586 \n", + "27 \t82 \t586 \n", + "28 \t86 \t586 \n", + "29 \t82 \t586 \n", + "30 \t78 \t586 \n", + "31 \t78 \t586 \n", + "32 \t68 \t586 \n", + "33 \t71 \t586 \n", + "34 \t82 \t586 \n", + "35 \t70 \t586 \n", + "36 \t76 \t586 \n", + "37 \t87 \t586 \n", + "38 \t76 \t586 \n", + "39 \t75 \t586 \n", + "40 \t86 \t586 \n", + "41 \t89 \t586 \n", + "42 \t82 \t586 \n", + "43 \t77 \t586 \n", + "44 \t80 \t586 \n", + "45 \t82 \t586 \n", + "46 \t82 \t551 \n", + "47 \t80 \t551 \n", + "48 \t81 \t551 \n", + "49 \t83 \t551 \n", + "50 \t77 \t551 \n", + "51 \t79 \t551 \n", + "52 \t78 \t551 \n", + "53 \t76 \t551 \n", + "54 \t79 \t551 \n", + "55 \t83 \t551 \n", + "56 \t81 \t551 \n", + "57 \t80 \t551 \n", + "58 \t79 \t551 \n", + "59 \t85 \t551 \n", + "60 \t86 \t551 \n", + "61 \t83 \t551 \n", + "62 \t74 \t551 \n", + "63 \t77 \t442.3 \n", + "64 \t78 \t442.3 \n", + "65 \t78 \t442.3 \n", + "66 \t89 \t442.3 \n", + "67 \t84 \t442.3 \n", + "68 \t83 \t442.3 \n", + "69 \t78 \t442.3 \n", + "70 \t76 \t442.3 \n", + "71 \t78 \t442.3 \n", + "72 \t84 \t442.3 \n", + "73 \t81 \t442.3 \n", + "74 \t76 \t442.3 \n", + "75 \t84 \t442.3 \n", + "76 \t72 \t442.3 \n", + "77 \t85 \t442.3 \n", + "78 \t83 \t442.3 \n", + "79 \t82 \t442.3 \n", + "80 \t80 \t442.3 \n", + "81 \t80 \t442.3 \n", + "82 \t80 \t442.3 \n", + "83 \t76 \t442.3 \n", + "84 \t74 \t442.3 \n", + "85 \t78 \t442.3 \n", + "86 \t79 \t442.3 \n", + "87 \t73 \t442.3 \n", + "88 \t78 \t442.3 \n", + "89 \t82 \t442.3 \n", + "90 \t74 \t442.3 \n", + "91 \t75 \t442.3 \n", + "92 \t78 \t442.3 \n", + "93 \t87 \t442.3 \n", + "94 \t82 \t442.3 \n", + "95 \t76 \t442.3 \n", + "96 \t75 \t442.3 \n", + "97 \t83 \t442.3 \n", + "98 \t71 \t442.3 \n", + "99 \t87 \t442.3 \n", + "100\t86 \t442.3 \n" ] } ], "source": [ - "# 6. Запуск алгоритма\n", + "# Запуск алгоритма\n", "population = toolbox.population(n=100)\n", "stats = tools.Statistics(lambda ind: ind.fitness.values)\n", "stats.register(\"min\", np.min)\n", @@ -365,9 +629,17 @@ ")" ] }, + { + "cell_type": "markdown", + "id": "43c11006", + "metadata": {}, + "source": [ + "Вывод лучшего решения" + ] + }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 12, "id": "6d1448dd", "metadata": {}, "outputs": [ @@ -379,35 +651,34 @@ "=== Оптимальный рацион на день ===\n", "\n", "Завтрак:\n", - " Бананы: 150 г (144 ккал, 28.5 руб.)\n", - " Сыр твердый: 200 г (680 ккал, 252.0 руб.)\n", - " Овсянка: 100 г (352 ккал, 4.5 руб.)\n", - " Итого: 1176 ккал, 67.2 г белков, 59.2 г жиров, 93.3 г углеводов, 285.0 руб.\n", + " Перловка: 100 г (317 ккал, 3.0 руб.)\n", + " Помидоры: 200 г (36 ккал, 80.0 руб.)\n", + " Капуста белокочаная: 200 г (56 ккал, 14.0 руб.)\n", + " Итого: 409 ккал, 15.8 г белков, 2.1 г жиров, 81.8 г углеводов, 97.0 руб.\n", "\n", "Обед:\n", - " Рис: 100 г (325 ккал, 6.8 руб.)\n", - " Морковь: 200 г (82 ккал, 1.8 руб.)\n", - " Свинина: 150 г (363 ккал, 51.0 руб.)\n", - " Яйца (1 шт. ~60г): 50 г (78 ккал, 7.9 руб.)\n", - " Итого: 848 ккал, 46.6 г белков, 32.6 г жиров, 92.5 г углеводов, 67.5 руб.\n", + " Курица (грудка): 150 г (248 ккал, 45.0 руб.)\n", + " Яблоки: 150 г (70 ккал, 27.0 руб.)\n", + " Овсянка: 80 г (282 ккал, 3.6 руб.)\n", + " Морковь: 150 г (62 ккал, 1.4 руб.)\n", + " Итого: 661 ккал, 58.3 г белков, 11.3 г жиров, 79.1 г углеводов, 76.9 руб.\n", "\n", "Ужин:\n", + " Рис: 100 г (325 ккал, 6.8 руб.)\n", + " Масло сливочное: 10 г (66 ккал, 8.6 руб.)\n", " Апельсины: 150 г (64 ккал, 22.5 руб.)\n", - " Минтай: 150 г (108 ккал, 54.0 руб.)\n", - " Гречка: 100 г (330 ккал, 3.5 руб.)\n", - " Итого: 502 ккал, 38.4 г белков, 4.2 г жиров, 80.2 г углеводов, 80.0 руб.\n", + " Итого: 456 ккал, 8.3 г белков, 8.6 г жиров, 84.5 г углеводов, 37.9 руб.\n", "\n", "=== Суточная сумма ===\n", - "• Калории: 2527 (цель: 2000)\n", - "• Белки: 152.1 г (цель: 100)\n", - "• Жиры: 96.0 г (цель: 70)\n", - "• Углеводы: 266.0 г (цель: 250)\n", - "• Стоимость: 432.5 руб.\n" + "• Калории: 1526 (цель: 2000)\n", + "• Белки: 82.4 г (цель: 75)\n", + "• Жиры: 21.9 г (цель: 67)\n", + "• Углеводы: 245.4 г (цель: 275)\n", + "• Стоимость: 211.8 руб.\n" ] } ], "source": [ - "# 7. Вывод лучшего решения с реалистичными порциями\n", "best_individual = tools.selBest(result, k=1)[0]\n", "print(\"\\n=== Оптимальный рацион на день ===\")\n", "\n", @@ -425,30 +696,34 @@ " meal_fat = 0\n", " meal_carbs = 0\n", " meal_cost = 0\n", - " \n", + "\n", " for product in meal:\n", - " portion = PORTION_SIZES.get(product[\"category\"], 100) # Берем рекомендуемый размер порции\n", - " calories = (portion/100) * product[\"calories\"]\n", - " protein = (portion/100) * product[\"protein\"]\n", - " fat = (portion/100) * product[\"fat\"]\n", - " carbs = (portion/100) * product[\"carbs\"]\n", - " cost = (portion/100) * product[\"price\"]\n", - " \n", - " print(f\" {product['name']}: {portion:.0f} г ({calories:.0f} ккал, {cost:.1f} руб.)\")\n", - " \n", + " portion = product[\"portion\"]\n", + " calories = (portion / 100) * product[\"calories\"]\n", + " protein = (portion / 100) * product[\"protein\"]\n", + " fat = (portion / 100) * product[\"fat\"]\n", + " carbs = (portion / 100) * product[\"carbs\"]\n", + " cost = (portion / 100) * product[\"price\"]\n", + "\n", + " print(\n", + " f\" {product['name']}: {portion:.0f} г ({calories:.0f} ккал, {cost:.1f} руб.)\"\n", + " )\n", + "\n", " meal_calories += calories\n", " meal_protein += protein\n", " meal_fat += fat\n", " meal_carbs += carbs\n", " meal_cost += cost\n", - " \n", + "\n", " total_cost += meal_cost\n", " total_calories += meal_calories\n", " total_protein += meal_protein\n", " total_fat += meal_fat\n", " total_carbs += meal_carbs\n", - " \n", - " print(f\" Итого: {meal_calories:.0f} ккал, {meal_protein:.1f} г белков, {meal_fat:.1f} г жиров, {meal_carbs:.1f} г углеводов, {meal_cost:.1f} руб.\")\n", + "\n", + " print(\n", + " f\" Итого: {meal_calories:.0f} ккал, {meal_protein:.1f} г белков, {meal_fat:.1f} г жиров, {meal_carbs:.1f} г углеводов, {meal_cost:.1f} руб.\"\n", + " )\n", "\n", "print(\"\\n=== Суточная сумма ===\")\n", "print(f\"• Калории: {total_calories:.0f} (цель: {TARGET_CALORIES})\")\n", @@ -458,15 +733,23 @@ "print(f\"• Стоимость: {total_cost:.1f} руб.\")" ] }, + { + "cell_type": "markdown", + "id": "c6545309", + "metadata": {}, + "source": [ + "График сходимости" + ] + }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 13, "id": "a99d926e", "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAHHCAYAAABeLEexAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAATtNJREFUeJzt3QmcTfX/x/HPjGEwjDW7QbJTQkmJGD9rlkgpWcqPFpIlSqFQEZFIaREqWvyKon9+JkSLXShkqSmyTb9kJsswzP0/Pt9+5/7unc3MuMu5zuv5eNzu3HPO3Hvumcl9z+f7+Z4T5nK5XAIAAOBg4cHeAQAAgGAjEAEAAMcjEAEAAMcjEAEAAMcjEAEAAMcjEAEAAMcjEAEAAMcjEAEAAMcjEAEAAMcjEAEAAMcjEMGRdu7cKffcc4+UL19eIiMjpVy5ctKzZ0+zHADgPGFcywxO8/HHH8tdd90lxYsXl379+kmVKlXkl19+kTlz5sgff/wh77//vtx2223B3k0AQAARiOAoP/30k1x99dUSExMja9eulSuuuMK97j//+Y/cfPPNcvDgQdmxY4dceeWVQd1XAEDgMGQGR5kyZYqcPn1aXn/9da8wpEqWLCmvvfaanDp1SiZPnuxe/vTTT0tYWFimt3nz5pnt+vbtm+V2etNKlKpcubLZ3tOiRYvMNrrOottb37tkyRKv7ZOTk6VYsWJm3QsvvJBufz2dPHlSypQpY5Z/+eWX7uUPPPCAVKtWTQoWLGgqZi1btpSvvvrK63s/+eQT6dChgxlW1OHFqlWryoQJE+TChQte291yyy1St27ddMdc983zvSs9ZmmXpaammrDqeUwt//rXv6RRo0ZSuHBhr+Pp+b4zYr2Oht/7779fSpQoIdHR0dK7d2/5888/bfc+V61aZUJ5VFSUFC1aVDp37iy7d+/22sb6+WqA97R58+Z0z6nBXn/PNNznz5/f/A7cd999phJ6Mfp7os+nxz6tQoUKef3+Hj9+XB599FGpV6+eWafHuF27drJ9+/aLvk7a18voltahQ4fM+yhdurT5WdWpU0feeuutXO+/9XPSYwjnigj2DgCBtHTpUhM49EMnI82aNTPrP/vss3TrXn31VfMPqSU+Pl7Gjh3rfqwfuK1atXI/7tWrlxl669q1q3tZ2hBmOX/+vDz55JOZ7rd+mM2dO1e6dOniNfSnoSg7pk6dKseOHUu3/Ny5c6aXqkKFCuZDTQNh27ZtzYewVtGsDwt938OGDTP3+qGt7zspKckETF9555135Pvvv0+3fN26dXLHHXfINddcI5MmTZIiRYqYMDB06NBsP/egQYNMwNAwsWfPHvOz/PXXX90fmnZ4n1988YUJERpedD/PnDkjM2fOlJtuukm2bt3qFZSzKy4uTn7++We59957TRjSHjn9Y0Dv169fn2HYyA19DQ3s3bt3N0PQ+rumv0vNmzeXXbt2mZCZXYMHD5brrrvOfP3222+b9+BJn/uGG24w+64/V/1/6vPPPzfD3/qzGjJkiE/eExxIh8wAJzhx4oQOD7s6d+6c5XadOnUy2yUlJZnHTz31lHn8+++/e223adMms3zu3LkZPo+u0+/NSKVKlVx9+vRxP37llVdckZGRrhYtWph1lvj4ePM8d911lysiIsJ19OhR97rY2FjX3XffbdZPmTLFvdzaX0tCQoKrcOHCrnbt2pnlq1evzvS9b9y40Wzzr3/9y73s9OnT6ba7//77XQULFnQlJye7lzVv3txVp06ddNvqvulz6nux6DHzXKbPExMT495Hz2M6atQos+zIkSPpjovn+86I9ToNGzZ0nTt3zr188uTJZvknn3xim/dZv359V6lSpVx//PGHe9n27dtd4eHhrt69e7uX5eT3MaP39N5775nt1q5dm+Wx098T3W7RokXp1kVFRXn9/ur7unDhgtc2+p71d3r8+PGu7FixYkW6372BAwd6/S6rfv36ucqWLev6z3/+47W8R48eriJFirjfc0723/o56TGEczFkBsf466+/zL0Ou2TFWq9/bQaCDuGNHz/e/LVrVWXSatCggRkW0OqC0urG6tWr0w27ZUSHfbSqon95Z0SrTFpx0arQSy+9JAUKFDDDUxZ97HkMrV4r3e8ff/xRfGHWrFlmGOepp55Kt05fMzw83FR4cmvAgAGSN29e9+MHH3xQIiIi5P/+7/9s8T6PHDki27ZtMz9PHbq06NDaP/7xD6/9tGhFT/fRuiUmJqbbxvM9WT9nra4orTplh3UsPG9p6bCV/oyUDjHqe9QqW40aNbL9Ola1U6uhmdG/Mz766CPp2LGj+dpzn9q0aWOOQdrXy87+W/T7db31bwWchUAEx7CCzsX+sctucPKVadOmmQ+DJ554IsvtdNhDh82s4Z0b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njwp/fv352r3OcSQGQAAIRqItHk6NjbWnJVaxcXFSZ06deTHH3+U7777ztf76Ighs8wCEUNmAADYNBD93//9n5QuXVqaNWsm//znP01V6JFHHpG1a9dKtWrVfL+XDqgQZdZDRIUIAACbNlXny5dPPvroI+nbt69psP7888+ldevWvt87B6CHCACAEA1EO3bsMPfDhw+XI0eOmCrRO++8Yy76qq6++mrf7uVljB4iAABCNBDVr1/ffTV7l8tl7lu0aGHudfkFGl+yjR4iAABCNBDFx8f7fk8cih4iAABCNBBVqlTJ93viUPQQAQAQooHo008/zXJ9p06dcrs/jkMPEQAAIRqIPE++qD1DVh+R9Zgeouzj0h0AAITwiRmtW8GCBWX//v3ux4ShnKFCBABAiAYi+A49RAAABB+BKMioEAEAEKI9RElJSV49Q3phV89l0dHRvtk7B6CHCACAEK0QFS1a1JyVWm8ahq699lrztbU8u/TaZx07dpRy5cqZYLVkyRL3upSUFHnsscekXr16EhUVZbbp3bu3HD582Os5jh8/Lj179jQhTF+/X79+Zp/Snln75ptvlvz580vFihVl8uTJYhdUiAAACNEK0apVq9xnqr4Up06dkmuuuUbuu+8+6dq1q9e606dPy9atW2XMmDFmmz///NNcQFan9G/evNm9nYYhvXxIXFycCVH33nuvDBgwQBYuXGjWa+VKr7PWqlUrmT17tnz//ffm9TQ86XbBRg8RAAAhGohuueUWn7x4u3btzC0jRYoUMSHH08svvyzXX3+9HDhwQGJiYmT37t2yfPly2bRpkzRq1MhsM3PmTGnfvr288MILpqq0YMECOXfunLz11lvmorR16tSRbdu2ybRp02wRiC526Q4CEQAANh0yq1KliowfP94Ek0BKTEw0lSmt7qh169aZr60wpLQSFB4eLhs2bHBv06xZMxOGLG3atJE9e/aYqpPdL91BDxEAADYNRDp09fHHH8uVV14p//jHP+T999+Xs9Ynu58kJyebnqK77rrL3bR99OhRKVWqlNd2ERERUrx4cbPO2qZ06dJe21iPrW0you9Hh9s8b/5ADxEAACEaiIYMGWKGnTZu3Ci1atWShx9+WMqWLSuDBg0yfT++pr1Bd9xxhzkj9quvviqBMHHiRDNsZ920Gdsf6CECACDEz0PUoEEDmTFjhpn5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cfjwYXf1J62TJ09Knjx5zBCX3nvSwGLRELN161b340OHDsktt9yS7vm0GjVy5Eh59tlnTSUq7Ws1bNhQFixYkO77rrjiihy/LwA5RyACYCs69KVhx5M+1kqNZzB5/PHH5fbbb5eYmBhp1qyZdO3aVa677rpsP4cOUWmQGThwYIb7ce2115oKUUJCgtx8882Z7m94eLhcddVV7scRERn/s/rqq6+aIKUN1Wk1aNDAhLtSpUpJdHR0pq8FwH8YMgNgKzqctHLlSpkwYYLs3btX5s+fLy+//LLp3/FkzUy7/vrrZciQIXLvvfe6G5Av9hw6o6t///4m7Nx5550Z7oeGp549e0rv3r3l448/lvj4eNm4caOpRH322Wc5fl+TJ082DeBWj5AnfZ2SJUuamWXaVK2vpb1DgwcPlt9++y3HrwUg5whEAGxFqyUffvihmdmlvUE6JKaN02kbqj2NGzfOVHx06Cw7z/HSSy+Znp0VK1aYClNmtLFZA5EGrBo1apgp+Zs2bcryezLTokULc8tIwYIFZe3ateZ5tdKlFa5+/fqZHiIqRkBghLl03ikAAICDUSECAACORyACAACORyACAACORyACAACORyACAACORyACAACORyACAACORyACAACORyACAACORyACAACORyACAACORyACAADidP8PHSus+FLKgqsAAAAASUVORK5CYII=", + "image/png": "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L16UXLlyZfpxGFQNAEFmjxnSniEAWWOXyvSDRlYQiAAgRCiTAc75f0QgAgAAARUOMykJRAAAwK8++OADueOOO8xAZy0NP/jgg+J0BCIAgM+6d+9uShSPPPJIivv69Olj7tN9ELkefvhhefHFF+Whhx6SJUuWyJYtW+Sdd94Rp2OWWYidOCFy4IBI9eqhbgkA+EbPHj5z5kx59dVXJW/evGbb2bNn5eOPPzY9Aohc33zzjcydO1c2b94spUqVknBCD1EIbdsmUqSISOPGukhbqFsDAL6pU6eOCUWffvqpa5t+rWGodu3aHvvefvvt0r9/f9ftHTt2mKnRtWrVcm3THqX27dt7fN/UqVOlUKFCrtsvvPCCx/ecP39errnmGtMjZS9uqd+jt9u2bevxWBMmTEjRc/Xhhx9KvXr1pGDBglKyZEm5//775ciRIyle69VXX22+1/0yb948c99XX33l8fze9uzZY+7ftGlTisd87bXXXLfHjx8vNWvWlPz585vj+thjj8nJkyc9vmfKlClSpUoVM6PKbof7cU1tfZ7hw4dL2bJlJSYmxhy7xYsXp9u29u3bexwj79fn/TNRt956q8fjLFy40LyWf/3rX2bfIkWKmMdMTExM8+e9aNEiKVCggLm2DR48WK677jpTbqtUqZIMHTo04OOQCEQhVLFi8rX+nhw7FurWAAgl/VB06lRoLpn5QKblEH2Tdh8z0qNHjyt+31NPPSV58uSRrHrjjTfk8OHDKbbrG+jq1atl//79rm1arilTpozHfvrmOmLECNOToQFHA0JqpT5dUVyDhS78p5dArbQ8ceJE2bp1q0ybNk2WL18uTz/9tOv+n3/+2QQMPea//vqraUejRo3SfUwNgePGjZP//Oc/pmTVokULExR37tzpt3Z/+umn8sMPP3hsO3r0qGm//oy1t0iP7ffff2/anhrd57777pP3339fWrVq5dquQVUD2LZt28xreffdd02PZCARiEJIe5rLlUv+2o+/owDC0OnTIgUKhOaiz51RDzzwgHz77bfy+++/m8uqVavMtvSsWLFCvvvuO/PmnhXHjx+Xl156yfQieNPep86dO5uAprSNOXPmNL1B7vQNWt+AtfehYcOGJpBoD4V3z4wGJ+3l0F4kvQSC9vQ0bdrU9BzpQGR9bZ988onrfg00+hr09WovnLbjSqep0CCk+3fq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", "text/plain": [ "
" ] @@ -476,7 +759,6 @@ } ], "source": [ - "# 8. График сходимости\n", "gen = logbook.select(\"gen\")\n", "fit_min = logbook.select(\"min\")\n", "plt.plot(gen, fit_min, \"b-\", label=\"Минимальная ошибка\")\n", @@ -486,14 +768,6 @@ "plt.legend()\n", "plt.show()" ] - }, - { - "cell_type": "markdown", - "id": "5ba3b8f3", - "metadata": {}, - "source": [ - "![супер мега детокс на ужин](docs/img/Снимок%20экрана%202025-05-10%20172044.png)" - ] } ], "metadata": {