[{"data":1,"prerenderedAt":6056},["ShallowReactive",2],{"navigation":3,"index":386,"index-blogs":531,"mdc--nztds7-key":6026,"mdc--bv2yds-key":6038,"mdc--ybl11d-key":6047},[4],{"title":5,"path":6,"stem":7,"children":8,"page":114},"Blog","\u002Fblog","blog",[9,115,184,329],{"title":10,"path":11,"stem":12,"children":13,"page":114},"Ege","\u002Fblog\u002Fege","blog\u002Fege",[14,18,22,26,30,34,38,42,46,50,54,58,62,66,70,74,78,82,86,90,94,98,102,106,110],{"title":15,"path":16,"stem":17},"ЕГЭ Задание 1","\u002Fblog\u002Fege\u002Ftask1","blog\u002Fege\u002Ftask1",{"title":19,"path":20,"stem":21},"ЕГЭ Задание 10","\u002Fblog\u002Fege\u002Ftask10","blog\u002Fege\u002Ftask10",{"title":23,"path":24,"stem":25},"ЕГЭ Задание 11","\u002Fblog\u002Fege\u002Ftask11","blog\u002Fege\u002Ftask11",{"title":27,"path":28,"stem":29},"ЕГЭ Задание 12","\u002Fblog\u002Fege\u002Ftask12","blog\u002Fege\u002Ftask12",{"title":31,"path":32,"stem":33},"ЕГЭ Задание 13","\u002Fblog\u002Fege\u002Ftask13","blog\u002Fege\u002Ftask13",{"title":35,"path":36,"stem":37},"ЕГЭ Задание 14","\u002Fblog\u002Fege\u002Ftask14","blog\u002Fege\u002Ftask14",{"title":39,"path":40,"stem":41},"ЕГЭ Задание 15","\u002Fblog\u002Fege\u002Ftask15","blog\u002Fege\u002Ftask15",{"title":43,"path":44,"stem":45},"ЕГЭ Задание 16","\u002Fblog\u002Fege\u002Ftask16","blog\u002Fege\u002Ftask16",{"title":47,"path":48,"stem":49},"ЕГЭ Задание 17","\u002Fblog\u002Fege\u002Ftask17","blog\u002Fege\u002Ftask17",{"title":51,"path":52,"stem":53},"ЕГЭ Задание 18","\u002Fblog\u002Fege\u002Ftask18","blog\u002Fege\u002Ftask18",{"title":55,"path":56,"stem":57},"ЕГЭ Задание 19, 20, 21","\u002Fblog\u002Fege\u002Ftask19_20_21","blog\u002Fege\u002Ftask19_20_21",{"title":59,"path":60,"stem":61},"ЕГЭ Задание 2","\u002Fblog\u002Fege\u002Ftask2","blog\u002Fege\u002Ftask2",{"title":63,"path":64,"stem":65},"ЕГЭ Задание 22","\u002Fblog\u002Fege\u002Ftask22","blog\u002Fege\u002Ftask22",{"title":67,"path":68,"stem":69},"ЕГЭ Задание 23","\u002Fblog\u002Fege\u002Ftask23","blog\u002Fege\u002Ftask23",{"title":71,"path":72,"stem":73},"ЕГЭ Задание 24","\u002Fblog\u002Fege\u002Ftask24","blog\u002Fege\u002Ftask24",{"title":75,"path":76,"stem":77},"ЕГЭ Задание 25","\u002Fblog\u002Fege\u002Ftask25","blog\u002Fege\u002Ftask25",{"title":79,"path":80,"stem":81},"ЕГЭ Задание 26","\u002Fblog\u002Fege\u002Ftask26","blog\u002Fege\u002Ftask26",{"title":83,"path":84,"stem":85},"ЕГЭ Задание 27","\u002Fblog\u002Fege\u002Ftask27","blog\u002Fege\u002Ftask27",{"title":87,"path":88,"stem":89},"ЕГЭ Задание 3","\u002Fblog\u002Fege\u002Ftask3","blog\u002Fege\u002Ftask3",{"title":91,"path":92,"stem":93},"ЕГЭ Задание 4","\u002Fblog\u002Fege\u002Ftask4","blog\u002Fege\u002Ftask4",{"title":95,"path":96,"stem":97},"ЕГЭ Задание 5","\u002Fblog\u002Fege\u002Ftask5","blog\u002Fege\u002Ftask5",{"title":99,"path":100,"stem":101},"ЕГЭ Задание 6","\u002Fblog\u002Fege\u002Ftask6","blog\u002Fege\u002Ftask6",{"title":103,"path":104,"stem":105},"ЕГЭ Задание 7","\u002Fblog\u002Fege\u002Ftask7","blog\u002Fege\u002Ftask7",{"title":107,"path":108,"stem":109},"ЕГЭ Задание 8","\u002Fblog\u002Fege\u002Ftask8","blog\u002Fege\u002Ftask8",{"title":111,"path":112,"stem":113},"ЕГЭ Задание 9","\u002Fblog\u002Fege\u002Ftask9","blog\u002Fege\u002Ftask9",false,{"title":116,"path":117,"stem":118,"children":119,"page":114},"Oge","\u002Fblog\u002Foge","blog\u002Foge",[120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180],{"title":121,"path":122,"stem":123},"ОГЭ Задание 1","\u002Fblog\u002Foge\u002Ftask1","blog\u002Foge\u002Ftask1",{"title":125,"path":126,"stem":127},"ОГЭ Задание 10","\u002Fblog\u002Foge\u002Ftask10","blog\u002Foge\u002Ftask10",{"title":129,"path":130,"stem":131},"ОГЭ Задание 11","\u002Fblog\u002Foge\u002Ftask11","blog\u002Foge\u002Ftask11",{"title":133,"path":134,"stem":135},"ОГЭ Задание 12","\u002Fblog\u002Foge\u002Ftask12","blog\u002Foge\u002Ftask12",{"title":137,"path":138,"stem":139},"ОГЭ Задание 13","\u002Fblog\u002Foge\u002Ftask13","blog\u002Foge\u002Ftask13",{"title":141,"path":142,"stem":143},"ОГЭ Задание 14","\u002Fblog\u002Foge\u002Ftask14","blog\u002Foge\u002Ftask14",{"title":145,"path":146,"stem":147},"ОГЭ Задание 15","\u002Fblog\u002Foge\u002Ftask15","blog\u002Foge\u002Ftask15",{"title":149,"path":150,"stem":151},"ОГЭ Задание 16","\u002Fblog\u002Foge\u002Ftask16","blog\u002Foge\u002Ftask16",{"title":153,"path":154,"stem":155},"ОГЭ Задание 2","\u002Fblog\u002Foge\u002Ftask2","blog\u002Foge\u002Ftask2",{"title":157,"path":158,"stem":159},"ОГЭ Задание 3","\u002Fblog\u002Foge\u002Ftask3","blog\u002Foge\u002Ftask3",{"title":161,"path":162,"stem":163},"ОГЭ Задание 4","\u002Fblog\u002Foge\u002Ftask4","blog\u002Foge\u002Ftask4",{"title":165,"path":166,"stem":167},"ОГЭ Задание 5","\u002Fblog\u002Foge\u002Ftask5","blog\u002Foge\u002Ftask5",{"title":169,"path":170,"stem":171},"ОГЭ Задание 6","\u002Fblog\u002Foge\u002Ftask6","blog\u002Foge\u002Ftask6",{"title":173,"path":174,"stem":175},"ОГЭ Задание 7","\u002Fblog\u002Foge\u002Ftask7","blog\u002Foge\u002Ftask7",{"title":177,"path":178,"stem":179},"ОГЭ Задание 8","\u002Fblog\u002Foge\u002Ftask8","blog\u002Foge\u002Ftask8",{"title":181,"path":182,"stem":183},"ОГЭ Задание 9","\u002Fblog\u002Foge\u002Ftask9","blog\u002Foge\u002Ftask9",{"title":185,"path":186,"stem":187,"children":188,"page":114},"Python","\u002Fblog\u002Fpython","blog\u002Fpython",[189,193,197,201,205,209,213,217,221,225,229,233,237,241,245,249,253,257,261,265,269,273,277,281,285,289,293,297,301,305,309,313,317,321,325],{"title":190,"path":191,"stem":192},"Знакомство с синтаксисом","\u002Fblog\u002Fpython\u002Fst1","blog\u002Fpython\u002Fst1",{"title":194,"path":195,"stem":196},"Отладка","\u002Fblog\u002Fpython\u002Fst10","blog\u002Fpython\u002Fst10",{"title":198,"path":199,"stem":200},"Модули и пакеты","\u002Fblog\u002Fpython\u002Fst11","blog\u002Fpython\u002Fst11",{"title":202,"path":203,"stem":204},"Кортежи","\u002Fblog\u002Fpython\u002Fst12","blog\u002Fpython\u002Fst12",{"title":206,"path":207,"stem":208},"Знакомство со списками","\u002Fblog\u002Fpython\u002Fst13","blog\u002Fpython\u002Fst13",{"title":210,"path":211,"stem":212},"Списки и циклы","\u002Fblog\u002Fpython\u002Fst14","blog\u002Fpython\u002Fst14",{"title":214,"path":215,"stem":216},"Использование списков ч.1","\u002Fblog\u002Fpython\u002Fst15","blog\u002Fpython\u002Fst15",{"title":218,"path":219,"stem":220},"Использование списков ч.2","\u002Fblog\u002Fpython\u002Fst16","blog\u002Fpython\u002Fst16",{"title":222,"path":223,"stem":224},"Использование списков ч.3","\u002Fblog\u002Fpython\u002Fst17","blog\u002Fpython\u002Fst17",{"title":226,"path":227,"stem":228},"Словари","\u002Fblog\u002Fpython\u002Fst18","blog\u002Fpython\u002Fst18",{"title":230,"path":231,"stem":232},"Множества","\u002Fblog\u002Fpython\u002Fst19","blog\u002Fpython\u002Fst19",{"title":234,"path":235,"stem":236},"Переменные","\u002Fblog\u002Fpython\u002Fst2","blog\u002Fpython\u002Fst2",{"title":238,"path":239,"stem":240},"Хеш-таблицы","\u002Fblog\u002Fpython\u002Fst20","blog\u002Fpython\u002Fst20",{"title":242,"path":243,"stem":244},"Решето Эратосфена","\u002Fblog\u002Fpython\u002Fst21","blog\u002Fpython\u002Fst21",{"title":246,"path":247,"stem":248},"Длинная арифметика","\u002Fblog\u002Fpython\u002Fst22","blog\u002Fpython\u002Fst22",{"title":250,"path":251,"stem":252},"Декораторы функций","\u002Fblog\u002Fpython\u002Fst23","blog\u002Fpython\u002Fst23",{"title":254,"path":255,"stem":256},"Знакомство с алгоритмами","\u002Fblog\u002Fpython\u002Fst24","blog\u002Fpython\u002Fst24",{"title":258,"path":259,"stem":260},"Бинарный поиск – примеры задач","\u002Fblog\u002Fpython\u002Fst25","blog\u002Fpython\u002Fst25",{"title":262,"path":263,"stem":264},"Сортировка выбором","\u002Fblog\u002Fpython\u002Fst26","blog\u002Fpython\u002Fst26",{"title":266,"path":267,"stem":268},"Рекурсия и стек","\u002Fblog\u002Fpython\u002Fst27","blog\u002Fpython\u002Fst27",{"title":270,"path":271,"stem":272},"Быстрая сортировка","\u002Fblog\u002Fpython\u002Fst28","blog\u002Fpython\u002Fst28",{"title":274,"path":275,"stem":276},"Поиск в ширину","\u002Fblog\u002Fpython\u002Fst29","blog\u002Fpython\u002Fst29",{"title":278,"path":279,"stem":280},"Работа со строками","\u002Fblog\u002Fpython\u002Fst3","blog\u002Fpython\u002Fst3",{"title":282,"path":283,"stem":284},"Поиск в глубину","\u002Fblog\u002Fpython\u002Fst30","blog\u002Fpython\u002Fst30",{"title":286,"path":287,"stem":288},"Сбалансированные деревья","\u002Fblog\u002Fpython\u002Fst31","blog\u002Fpython\u002Fst31",{"title":290,"path":291,"stem":292},"Алгоритм Дейкстры","\u002Fblog\u002Fpython\u002Fst32","blog\u002Fpython\u002Fst32",{"title":294,"path":295,"stem":296},"Жадные алгоритмы","\u002Fblog\u002Fpython\u002Fst33","blog\u002Fpython\u002Fst33",{"title":298,"path":299,"stem":300},"Динамическое программирование","\u002Fblog\u002Fpython\u002Fst34","blog\u002Fpython\u002Fst34",{"title":302,"path":303,"stem":304},"Алгоритм k ближайших соседей","\u002Fblog\u002Fpython\u002Fst35","blog\u002Fpython\u002Fst35",{"title":306,"path":307,"stem":308},"Типы данных","\u002Fblog\u002Fpython\u002Fst4","blog\u002Fpython\u002Fst4",{"title":310,"path":311,"stem":312},"О функциях","\u002Fblog\u002Fpython\u002Fst5","blog\u002Fpython\u002Fst5",{"title":314,"path":315,"stem":316},"Свойства и методы","\u002Fblog\u002Fpython\u002Fst6","blog\u002Fpython\u002Fst6",{"title":318,"path":319,"stem":320},"Определение функций","\u002Fblog\u002Fpython\u002Fst7","blog\u002Fpython\u002Fst7",{"title":322,"path":323,"stem":324},"Логика","\u002Fblog\u002Fpython\u002Fst8","blog\u002Fpython\u002Fst8",{"title":326,"path":327,"stem":328},"Циклы","\u002Fblog\u002Fpython\u002Fst9","blog\u002Fpython\u002Fst9",{"title":330,"path":331,"stem":332,"children":333,"page":114},"Toi","\u002Fblog\u002Ftoi","blog\u002Ftoi",[334,338,342,346,350,354,358,362,366,370,374,378,382],{"title":335,"path":336,"stem":337},"Информация и информационные процессы","\u002Fblog\u002Ftoi\u002Fst1","blog\u002Ftoi\u002Fst1",{"title":339,"path":340,"stem":341},"Электронные таблицы","\u002Fblog\u002Ftoi\u002Fst10","blog\u002Ftoi\u002Fst10",{"title":343,"path":344,"stem":345},"Система, её свойства и компоненты. Моделирование","\u002Fblog\u002Ftoi\u002Fst11","blog\u002Ftoi\u002Fst11",{"title":347,"path":348,"stem":349},"Представление информации в компьютере","\u002Fblog\u002Ftoi\u002Fst12","blog\u002Ftoi\u002Fst12",{"title":351,"path":352,"stem":353},"Средства информационно-коммуникационных технологий. Файловая система","\u002Fblog\u002Ftoi\u002Fst13","blog\u002Ftoi\u002Fst13",{"title":355,"path":356,"stem":357},"Комбинаторика","\u002Fblog\u002Ftoi\u002Fst2","blog\u002Ftoi\u002Fst2",{"title":359,"path":360,"stem":361},"Адресация в интернете","\u002Fblog\u002Ftoi\u002Fst3","blog\u002Ftoi\u002Fst3",{"title":363,"path":364,"stem":365},"Измерение количества информации","\u002Fblog\u002Ftoi\u002Fst4","blog\u002Ftoi\u002Fst4",{"title":367,"path":368,"stem":369},"Системы счисления","\u002Fblog\u002Ftoi\u002Fst5","blog\u002Ftoi\u002Fst5",{"title":371,"path":372,"stem":373},"Диаграммы Эйлера — Венна","\u002Fblog\u002Ftoi\u002Fst6","blog\u002Ftoi\u002Fst6",{"title":375,"path":376,"stem":377},"Условие Фано","\u002Fblog\u002Ftoi\u002Fst7","blog\u002Ftoi\u002Fst7",{"title":379,"path":380,"stem":381},"Теория графов","\u002Fblog\u002Ftoi\u002Fst8","blog\u002Ftoi\u002Fst8",{"title":383,"path":384,"stem":385},"Алгебра логики","\u002Fblog\u002Ftoi\u002Fst9","blog\u002Ftoi\u002Fst9",{"id":387,"title":388,"about":389,"blog":392,"body":395,"description":396,"experience":397,"extension":439,"faq":440,"hero":479,"meta":512,"navigation":513,"path":514,"seo":515,"stem":518,"testimonials":519,"__hash__":530},"index\u002Findex.yml","Привет, Я Альберт Игоревич учитель информатики и FullStack разработчик.",{"title":390,"description":391},"Обо мне","Как учитель и разработчик с 10-летним опытом работы, я использую свою степень магистра и преподавателя исследователя Белгородского государственного университета.\nМой подход сочетает творческую стратегию с техническими знаниями, превращая концепции в функциональные, целенаправленные цифровые продукты и решения, которые органично сочетают дизайн и технологии.\n",{"title":393,"description":394},"Блог","Последние статьи на сайте",null,"Я обучаю информатике и информационным технологиям, а также создаю интуитивно понятные цифровые решения, в которых функциональность сочетается с дизайном. Я живу в Белгороде и воплощаю идеи в жизнь с помощью кода и креатива.",{"title":398,"items":399},"Опыт работы",[400,407,414,421,425,432],{"position":401,"date":402,"company":403},"Учитель","2022 - ...",{"name":404,"url":405,"color":406},"Формула Успеха","https:\u002F\u002Fformula.gosuslugi.ru\u002F","#0000ff",{"position":408,"date":409,"company":410},"Лаборант","2020 - 2021",{"name":411,"url":412,"color":413},"НИУ БелГУ","https:\u002F\u002Fbsuedu.ru\u002Fbsu\u002F","#144F16",{"position":415,"date":416,"company":417},"Программист","2019 - 2020",{"name":418,"url":419,"color":420},"Нефтегазметрология","https:\u002F\u002Foilgm.ru\u002F","#1e5374",{"position":422,"date":423,"company":424},"Инженер КИПиА","2018",{"name":411,"url":412,"color":413},{"position":426,"date":427,"company":428},"Диспетчер ПДО","2016 - 2017",{"name":429,"url":430,"color":431},"ЗАО Сокол-АТС","https:\u002F\u002Fwww.sokol-ats.ru","#302958",{"position":433,"date":434,"company":435},"Оператор","2015",{"name":436,"url":437,"color":438},"АО \"ЗВЕЗДА-ЭНЕРГЕТИКА\"","https:\u002F\u002Fwww.zvec.ru","#a41e1f","yml",{"title":441,"description":442,"categories":443},"Часто задаваемые вопросы","Ответы на распространенные вопросы о моем процессе и услугах.",[444,456,471],{"title":445,"questions":446},"Услуги",[447,450,453],{"label":448,"content":449},"Какие услуги вы предлагаете?","Я специализируюсь на обучении информатики\u002Fпрограммирования на Python и fullstack разработке. Это включает в себя обучение учащихся для сдачи единого государственного экзамена ОГЭ\u002FЕГЭ по информатике. В области разработки это \"скрапинг и парсинг\" данных, интерактивное прототипирование, создание интуитивно понятных пользовательских интерфейсов, создание адаптивных приложений, веб-сайтов и веб-приложений. Моя цель – успешное обучение учащихся для сдачи экзаменов и создание цифровых продуктов от разработки концепции до внедрения.\n",{"label":451,"content":452},"Почему стоит пользоваться вашими услугами?","Мой процесс является совместным и итеративным и обычно включает в себя такие этапы, как поиск и исследование, формирование идей, прототипирование, разработка, проверка и тестирование, визуальный контакт и тесное сотрудничество. Я адаптирую процесс в соответствии с потребностями и всегда уделяя особое внимание решениям, ориентированным на конечного пользователя моих услуг.\n",{"label":454,"content":455},"Вы работаете с новичками?","Конечно! Мне нравится работать с начинающими, помогая им формировать знания в области программирования и учить создавать решения с нуля. Я могу адаптировать свой процесс к быстро меняющейся среде обучения.\n",{"title":457,"questions":458},"Цена и сроки",[459,462,465,468],{"label":460,"content":461},"Сколько обычно стоит ваша услуга?","Стоимость проекта варьируется в зависимости от объема, сложности, функций и сроков реализации. Стоимость комплексных проектов по Разработке, как правило, составляет от 30000 рублей, а средние проекты варьируются от 40000 до 100000 рублей. За консультации или выполнение конкретных задач моя дневная ставка составляет 1000-1500 рублей.\n",{"label":463,"content":464},"Каковы ваши условия оплаты?","Как правило, для планирования проекта и начала работы мне требуется внести предоплату в размере 40%, а оставшиеся 60% выплачиваются после успешного завершения проекта и сдачи его в эксплуатацию. Я принимаю платежи банковским переводом.\n",{"label":466,"content":467},"Сколько времени занимает проект или обучение?","Сроки сильно зависят от масштаба и сложности проекта\u002Fобучения. На выполнение небольших проектов\u002Fобучения может уйти 3-4 недели, в то время как на выполнение более крупных проектов\u002Fобучения или с большим количеством участников может уйти от 2 до 12 месяцев. Я всегда предоставляю подробную оценку сроков после первоначального этапа исследования сложности проекта\u002Fобучения.\n",{"label":469,"content":470},"Предоставляете ли вы постоянную поддержку?","Да, для клиентов, нуждающихся в постоянной поддержке, разработке функциональных возможностей или техническом обслуживании, я предлагаю варианты ежемесячной оплаты с учетом конкретных потребностей. Давайте обсудим, что конкретно вас интересует.\n",{"title":390,"questions":472},[473,476],{"label":474,"content":475},"Что вам больше всего нравится в вашей работе?","Мне нравится решать сложные задачи с помощью обучения и технологий. Невероятно приятно видеть, как люди взаимодействуют с тем, что я создал или чему научил, и находят это действительно полезным. Мне по-настоящему нравится преодолевать разрыв между потребностями и техническими возможностями.\n",{"label":477,"content":478},"Чем вы увлекаетесь вне работы?","Вне профессиональной деятельности я люблю играть на гитаре или отправляться на рыбалку.\n",{"links":480,"images":484},[481],{"label":482,"to":405,"color":483},"Тавровская СОШ \"Формула Успеха\"","info",[485,488,491,494,497,500,503,506,509],{"src":486,"alt":487},"\u002Fhero\u002Frandom-1.avif","Random Image 1",{"src":489,"alt":490},"\u002Fhero\u002Frandom-2.avif","Random Image 2",{"src":492,"alt":493},"\u002Fhero\u002Frandom-3.avif","Random Image 3",{"src":495,"alt":496},"\u002Fhero\u002Frandom-4.avif","Random Image 4",{"src":498,"alt":499},"\u002Fhero\u002Frandom-5.avif","Random Image 5",{"src":501,"alt":502},"\u002Fhero\u002Frandom-6.avif","Random Image 6",{"src":504,"alt":505},"\u002Fhero\u002Frandom-7.avif","Random Image 7",{"src":507,"alt":508},"\u002Fhero\u002Frandom-8.avif","Random Image 8",{"src":510,"alt":511},"\u002Fhero\u002Frandom-9.avif","Random Image 9",{},true,"\u002F",{"title":516,"description":517},"Штана Альберт Игоревич","Я Альберт Игоревич, учитель информатики и FullStack разработчик из Белгорода. Я специализируюсь на обучении информатики и создании красивых и функциональных цифровых приложений, ориентированных на пользователя.","index",[520,523,526],{"quote":521,"description":411,"src":522,"srcset":522},"Диплом аспиранта","\u002Fimages\u002Fdocuments\u002Fdiplom_aspirant.jpg",{"quote":524,"description":411,"src":525,"srcset":525},"Диплом магистра","\u002Fimages\u002Fdocuments\u002Fdiplom_magister.jpg",{"quote":527,"description":528,"src":529,"srcset":529},"Диплом специалиста","БГТУ им.Шухова","\u002Fimages\u002Fdocuments\u002Fdiplom_specialist.jpg","0vV30edgVQDtugcASJVUViv-oZ8JQonUojckakiLUEU",[532,1490,4636],{"id":533,"title":302,"author":534,"body":538,"date":1482,"description":1483,"extension":1484,"image":1485,"meta":1486,"minRead":785,"navigation":513,"num":1487,"path":303,"seo":1488,"stem":304,"__hash__":1489},"blog\u002Fblog\u002Fpython\u002Fst35.md",{"name":516,"avatar":535},{"src":536,"alt":537},"me.jpg","@ashtana",{"type":539,"value":540,"toc":1442},"minimark",[541,545,550,562,565,570,573,578,969,974,977,980,983,991,995,998,1056,1059,1069,1072,1083,1086,1089,1098,1102,1105,1113,1116,1119,1124,1129,1132,1136,1139,1142,1151,1154,1158,1161,1165,1168,1172,1175,1194,1197,1202,1205,1209,1213,1216,1220,1223,1234,1237,1243,1246,1250,1253,1257,1266,1270,1288,1308,1311,1315,1318,1322,1329,1333,1336,1344,1347,1351,1354,1358,1361,1364,1367,1378,1381,1385,1398,1412,1416,1426,1430,1433,1438],[542,543,302],"h2",{"id":544},"алгоритм-k-ближайших-соседей",[546,547],"card-collapsible",{":isList":548,"title":549},"[\"Научитесь строить системы классификации на базе алгоритма k ближайших соседей.\",\"Узнаете об извлечении признаков.\",\"Узнаете о регрессии: прогнозировании чисел (например, завтрашних биржевых котировок или успеха фильма у зрителей).\",\"Познакомитесь с типичными сценариями использования и ограничениями алгоритма k ближайших соседей.\"]","Из этой статьи вы",[551,552,553],"blockquote",{},[554,555,556,557,561],"p",{},"В предыдущей статье было про: ",[558,559,560],"a",{"href":299},"динамическое программирование",".\nЗдесь далее текст пойдёт об алгоритме k ближайших соседей.",[554,563,564],{},"Алгоритм k ближайших соседей прост и полезен! Если вы пытаетесь выполнить классификацию чего-либо, сначала попробуйте применить алгоритм k ближайших соседей.\nРассмотрим реалистичный пример.",[566,567,569],"h4",{"id":568},"построение-рекомендательной-системы","Построение рекомендательной системы",[554,571,572],{},"Представьте, что вы работаете с сайтом о кино и хотите построить систему, которая будет рекомендовать фильмы для ваших пользователей.\nПоложение пользователя определяется его вкусами, поэтому пользователи с похожими вкусами располагаются недалеко друг от друга.\nПредположим, вы хотите порекомендовать фильмы Алексею. Найдите 5 пользователей, ближайших к нему.\nДопустим, окажется, что у Ивана, Сергея, Анны, Ларисы и Анатолия похожие вкусы.\nЗначит, те фильмы, которые нравятся им, с большой вероятностью понравятся и Алексею!\nПосле того как у вас появится такая диаграмма, построить рекомендательную систему будет несложно.\nЕсли Анатолию нравится какой-нибудь фильм, порекомендуйте этот фильм Алексею.\nОднако в картине не хватает одного важного фрагмента.\nВы сравнивали вкусы двух пользователей. Но как определить, насколько они близки?",[574,575,577],"h5",{"id":576},"извлечение-признаков","Извлечение признаков",[554,579,580,581,788,789,968],{},"В примере с фруктами можно сравнивать фрукты на основании их размера и цвета кожуры.\nРазмер и цвет — признаки, по которым ведется сравнение.\nТеперь предположим, что у вас есть три фрукта.\nВы можете извлечь из них информацию, то есть провести извлечение признаков.\nДанные этих фруктов наносятся на график.\nПредположим, что из диаграммы хорошо видно, что фрукты A и B похожи.\nДавайте измерим степень их сходства.\nДля вычисления расстояния между двумя точками применяется формула Пифагора: ",[582,583,587],"mjx-container",{"className":584,"jax":586},[585],"MathJax","SVG",[588,589,598,638],"svg",{"style":590,"xmlns":591,"width":592,"height":593,"role":594,"focusable":595,"viewBox":596,"xmlnsXLink":597},"vertical-align: -1.094ex;","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","24.857ex","4.208ex","img","false","0 -1376.5 10986.7 1860","http:\u002F\u002Fwww.w3.org\u002F1999\u002Fxlink",[599,600,601,606,610,614,618,622,626,630,634],"defs",{},[602,603],"path",{"id":604,"d":605},"MJX-1-TEX-LO-221A","M1001 1150Q1017 1150 1020 1132Q1020 1127 741 244L460 -643Q453 -650 436 -650H424Q423 -647 423 -645T421 -640T419 -631T415 -617T408 -594T399 -560T385 -512T367 -448T343 -364T312 -259L203 119L138 41L111 67L212 188L264 248L472 -474L983 1140Q988 1150 1001 1150Z",[602,607],{"id":608,"d":609},"MJX-1-TEX-N-28","M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z",[602,611],{"id":612,"d":613},"MJX-1-TEX-I-1D465","M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z",[602,615],{"id":616,"d":617},"MJX-1-TEX-N-31","M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z",[602,619],{"id":620,"d":621},"MJX-1-TEX-N-2212","M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z",[602,623],{"id":624,"d":625},"MJX-1-TEX-N-32","M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z",[602,627],{"id":628,"d":629},"MJX-1-TEX-N-29","M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z",[602,631],{"id":632,"d":633},"MJX-1-TEX-N-2B","M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z",[602,635],{"id":636,"d":637},"MJX-1-TEX-I-1D466","M21 287Q21 301 36 335T84 406T158 442Q199 442 224 419T250 355Q248 336 247 334Q247 331 231 288T198 191T182 105Q182 62 196 45T238 27Q261 27 281 38T312 61T339 94Q339 95 344 114T358 173T377 247Q415 397 419 404Q432 431 462 431Q475 431 483 424T494 412T496 403Q496 390 447 193T391 -23Q363 -106 294 -155T156 -205Q111 -205 77 -183T43 -117Q43 -95 50 -80T69 -58T89 -48T106 -45Q150 -45 150 -87Q150 -107 138 -122T115 -142T102 -147L99 -148Q101 -153 118 -160T152 -167H160Q177 -167 186 -165Q219 -156 247 -127T290 -65T313 -9T321 21L315 17Q309 13 296 6T270 -6Q250 -11 231 -11Q185 -11 150 11T104 82Q103 89 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z",[639,640,644],"g",{"stroke":641,"fill":641,"stroke-width":642,"transform":643},"currentColor","0","scale(1,-1)",[639,645,647],{"dataMmlNode":646},"math",[639,648,650,774,781],{"dataMmlNode":649},"msqrt",[639,651,653,719,726],{"transform":652},"translate(1020,0)",[639,654,656,714],{"dataMmlNode":655},"msup",[639,657,660,668,687,694,707],{"dataMmlNode":658,"dataMjxTexclass":659},"TeXAtom","ORD",[639,661,663],{"dataMmlNode":662},"mo",[664,665],"use",{"dataC":666,"xLinkHref":667},"28","#MJX-1-TEX-N-28",[639,669,672,679],{"dataMmlNode":670,"transform":671},"msub","translate(389,0)",[639,673,675],{"dataMmlNode":674},"mi",[664,676],{"dataC":677,"xLinkHref":678},"1D465","#MJX-1-TEX-I-1D465",[639,680,683],{"dataMmlNode":681,"transform":682},"mn","translate(605,-150) scale(0.707)",[664,684],{"dataC":685,"xLinkHref":686},"31","#MJX-1-TEX-N-31",[639,688,690],{"dataMmlNode":662,"transform":689},"translate(1619.8,0)",[664,691],{"dataC":692,"xLinkHref":693},"2212","#MJX-1-TEX-N-2212",[639,695,697,701],{"dataMmlNode":670,"transform":696},"translate(2620,0)",[639,698,699],{"dataMmlNode":674},[664,700],{"dataC":677,"xLinkHref":678},[639,702,703],{"dataMmlNode":681,"transform":682},[664,704],{"dataC":705,"xLinkHref":706},"32","#MJX-1-TEX-N-32",[639,708,710],{"dataMmlNode":662,"transform":709},"translate(3628.6,0)",[664,711],{"dataC":712,"xLinkHref":713},"29","#MJX-1-TEX-N-29",[639,715,717],{"dataMmlNode":681,"transform":716},"translate(4050.6,477.1) scale(0.707)",[664,718],{"dataC":705,"xLinkHref":706},[639,720,722],{"dataMmlNode":662,"transform":721},"translate(4676.3,0)",[664,723],{"dataC":724,"xLinkHref":725},"2B","#MJX-1-TEX-N-2B",[639,727,729,769],{"dataMmlNode":655,"transform":728},"translate(5676.5,0)",[639,730,731,735,748,753,764],{"dataMmlNode":658,"dataMjxTexclass":659},[639,732,733],{"dataMmlNode":662},[664,734],{"dataC":666,"xLinkHref":667},[639,736,737,743],{"dataMmlNode":670,"transform":671},[639,738,739],{"dataMmlNode":674},[664,740],{"dataC":741,"xLinkHref":742},"1D466","#MJX-1-TEX-I-1D466",[639,744,746],{"dataMmlNode":681,"transform":745},"translate(523,-150) scale(0.707)",[664,747],{"dataC":685,"xLinkHref":686},[639,749,751],{"dataMmlNode":662,"transform":750},"translate(1537.8,0)",[664,752],{"dataC":692,"xLinkHref":693},[639,754,756,760],{"dataMmlNode":670,"transform":755},"translate(2538,0)",[639,757,758],{"dataMmlNode":674},[664,759],{"dataC":741,"xLinkHref":742},[639,761,762],{"dataMmlNode":681,"transform":745},[664,763],{"dataC":705,"xLinkHref":706},[639,765,767],{"dataMmlNode":662,"transform":766},"translate(3464.6,0)",[664,768],{"dataC":712,"xLinkHref":713},[639,770,772],{"dataMmlNode":681,"transform":771},"translate(3886.6,477.1) scale(0.707)",[664,773],{"dataC":705,"xLinkHref":706},[639,775,777],{"dataMmlNode":662,"transform":776},"translate(0,166.5)",[664,778],{"dataC":779,"xLinkHref":780},"221A","#MJX-1-TEX-LO-221A",[782,783],"rect",{"width":784,"height":785,"x":786,"y":787},9966.7,60,"1020","1256.5","\nФормула расстояния подтверждает то, что мы видим: между фруктами есть или отсутствует сходство.\nДопустим, вместо фруктов вы сравниваете пользователей. Пользователей нужно будет как-то нанести на график.\nСледовательно, каждого пользователя нужно будет преобразовать в координаты.\nКогда вы сможете нанести пользователей на график, вы также сможете измерить расстояние между ними.\nНачнем с преобразования пользователей в набор чисел.\nКогда пользователь регистрируется на сайте, предложите ему оценить несколько категорий фильмов: нравятся они лично ему или нет.\nТаким образом у вас появляется набор оценок для каждого пользователя!\nИ в итоге каждый пользователь представляется набором из чисел.\nВместо вычисления расстояния в двух измерениях вы теперь вычисляете расстояние в n измерениях(зависит от категорий жанров у фильмов).\nТем не менее формула расстояния остается неизменной:\n",[582,790,792],{"className":791,"jax":586},[585],[588,793,796,830],{"style":590,"xmlns":591,"width":794,"height":593,"role":594,"focusable":595,"viewBox":795,"xmlnsXLink":597},"29.127ex","0 -1376.5 12874.2 1860",[599,797,798,801,804,807,810,813,816,819,822,826],{},[602,799],{"id":800,"d":605},"MJX-2-TEX-LO-221A",[602,802],{"id":803,"d":609},"MJX-2-TEX-N-28",[602,805],{"id":806,"d":613},"MJX-2-TEX-I-1D465",[602,808],{"id":809,"d":617},"MJX-2-TEX-N-31",[602,811],{"id":812,"d":621},"MJX-2-TEX-N-2212",[602,814],{"id":815,"d":625},"MJX-2-TEX-N-32",[602,817],{"id":818,"d":629},"MJX-2-TEX-N-29",[602,820],{"id":821,"d":633},"MJX-2-TEX-N-2B",[602,823],{"id":824,"d":825},"MJX-2-TEX-N-2E","M78 60Q78 84 95 102T138 120Q162 120 180 104T199 61Q199 36 182 18T139 0T96 17T78 60Z",[602,827],{"id":828,"d":829},"MJX-2-TEX-I-1D45B","M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z",[639,831,832],{"stroke":641,"fill":641,"stroke-width":642,"transform":643},[639,833,834],{"dataMmlNode":646},[639,835,836,960,965],{"dataMmlNode":649},[639,837,838,884,890,897,902,907,912],{"transform":652},[639,839,840,880],{"dataMmlNode":655},[639,841,842,847,859,864,875],{"dataMmlNode":658,"dataMjxTexclass":659},[639,843,844],{"dataMmlNode":662},[664,845],{"dataC":666,"xLinkHref":846},"#MJX-2-TEX-N-28",[639,848,849,854],{"dataMmlNode":670,"transform":671},[639,850,851],{"dataMmlNode":674},[664,852],{"dataC":677,"xLinkHref":853},"#MJX-2-TEX-I-1D465",[639,855,856],{"dataMmlNode":681,"transform":682},[664,857],{"dataC":685,"xLinkHref":858},"#MJX-2-TEX-N-31",[639,860,861],{"dataMmlNode":662,"transform":689},[664,862],{"dataC":692,"xLinkHref":863},"#MJX-2-TEX-N-2212",[639,865,866,870],{"dataMmlNode":670,"transform":696},[639,867,868],{"dataMmlNode":674},[664,869],{"dataC":677,"xLinkHref":853},[639,871,872],{"dataMmlNode":681,"transform":682},[664,873],{"dataC":705,"xLinkHref":874},"#MJX-2-TEX-N-32",[639,876,877],{"dataMmlNode":662,"transform":709},[664,878],{"dataC":712,"xLinkHref":879},"#MJX-2-TEX-N-29",[639,881,882],{"dataMmlNode":681,"transform":716},[664,883],{"dataC":705,"xLinkHref":874},[639,885,887],{"dataMmlNode":662,"transform":886},"translate(4454.1,0)",[664,888],{"dataC":724,"xLinkHref":889},"#MJX-2-TEX-N-2B",[639,891,893],{"dataMmlNode":662,"transform":892},"translate(5232.1,0)",[664,894],{"dataC":895,"xLinkHref":896},"2E","#MJX-2-TEX-N-2E",[639,898,900],{"dataMmlNode":662,"transform":899},"translate(5676.8,0)",[664,901],{"dataC":895,"xLinkHref":896},[639,903,905],{"dataMmlNode":662,"transform":904},"translate(6121.4,0)",[664,906],{"dataC":895,"xLinkHref":896},[639,908,910],{"dataMmlNode":662,"transform":909},"translate(6566.1,0)",[664,911],{"dataC":724,"xLinkHref":889},[639,913,915,955],{"dataMmlNode":655,"transform":914},"translate(7344.1,0)",[639,916,917,921,934,939,950],{"dataMmlNode":658,"dataMjxTexclass":659},[639,918,919],{"dataMmlNode":662},[664,920],{"dataC":666,"xLinkHref":846},[639,922,923,929],{"dataMmlNode":670,"transform":671},[639,924,925],{"dataMmlNode":674},[664,926],{"dataC":927,"xLinkHref":928},"1D45B","#MJX-2-TEX-I-1D45B",[639,930,932],{"dataMmlNode":681,"transform":931},"translate(633,-150) scale(0.707)",[664,933],{"dataC":685,"xLinkHref":858},[639,935,937],{"dataMmlNode":662,"transform":936},"translate(1647.8,0)",[664,938],{"dataC":692,"xLinkHref":863},[639,940,942,946],{"dataMmlNode":670,"transform":941},"translate(2648,0)",[639,943,944],{"dataMmlNode":674},[664,945],{"dataC":927,"xLinkHref":928},[639,947,948],{"dataMmlNode":681,"transform":931},[664,949],{"dataC":705,"xLinkHref":874},[639,951,953],{"dataMmlNode":662,"transform":952},"translate(3684.6,0)",[664,954],{"dataC":712,"xLinkHref":879},[639,956,958],{"dataMmlNode":681,"transform":957},"translate(4106.6,477.1) scale(0.707)",[664,959],{"dataC":705,"xLinkHref":874},[639,961,962],{"dataMmlNode":662,"transform":776},[664,963],{"dataC":779,"xLinkHref":964},"#MJX-2-TEX-LO-221A",[782,966],{"width":967,"height":785,"x":786,"y":787},11854.2,"\nФормула расстояния универсальна: даже если вы используете набор из миллиона чисел, расстояние вычисляется по той же формуле.\nЕстественно спросить: какой смысл передает метрика расстояния с пятью числами?\nОна сообщает, насколько близки между собой эти наборы из пяти чисел.",[551,970,971],{},[554,972,973],{},"Массивы чисел, такие как(2, 2) или (3, 4, 4, 1, 4) называются векторами.\nЕсли вам встретится статья о машинном обучении и вы увидите, что авторы говорят о векторах, знайте, что они имеют в виду подобный массив чисел.",[554,975,976],{},"Теперь порекомендовать фильм Алексею будет несложно: если Сергею понравился какой-то фильм, мы рекомендуем его Алексею, и наоборот.\nВы только что построили систему, рекомендующую фильмы.",[554,978,979],{},"Если вы являетесь пользователем приложения с фильмами, то оно постоянно напоминает вам:\n«Пожалуйста, оценивайте больше фильмов. Чем больше фильмов вы оцените, тем точнее будут наши рекомендации».\nТеперь вы знаете почему: чем больше фильмов вы оцениваете, тем точнее рекомендательная система определяет, с какими пользователями у вас общие вкусы.",[566,981],{"id":982},"",[984,985],"card-collapsible-num-answers",{":isAnswers":986,":isList":987,":startOl":988,"isText":989,"title":990},"[\"Можно воспользоваться нормализацией: вы вычисляете среднюю оценку для каждого человека и используете ее для масштабирования оценок. Например, вы определили, что средняя оценка первого равна 3, а средняя оценка второго — 3,5. Соответственно оценки первого немного увеличиваются так, чтобы ее средняя оценка тоже была равна 3,5. После этого оценки можно сравнивать по единой шкале.\",\"При применении алгоритма k ближайших соседей можно увеличить вес оценок авторитетов. Предположим, у вас трое соседей: Антон, Олег и Сергей(авторитет). Они поставили фильму оценки 3, 4 и 5 соответственно. Вместо того чтобы вычислять среднее арифметическое их оценок (3 + 4 + 5 \u002F 3 = 4 звезды), вы просто повышаете вес оценки авторитета Сергея: 3 + 4 + 5 + 5 + 5 \u002F 5 = 4,4 звезды.\"]","[\"В примере с приложением просмотра фильмов сходство между двумя пользователями оценивалось по формуле расстояния. Но не все пользователи оценивают фильмы одинаково. Допустим, есть два пользователя, вкусы которых совпадают. Но первый ставит 5 баллов любому фильму, который ему понравился, а второй более разборчив и ставит пятерки только самым лучшим фильмам. Вроде бы вкусы одинаковые, но по метрике расстояния они не являются соседями. Как учесть различия в стратегиях выставления оценок?\",\"Предположим, рекомендательная система определяет группу «авторитетов». Скажем, Иван и Сергей относятся к числу авторитетов приложения просмотра фильмов, поэтому их оценки оказывают более сильное влияние, чем оценки рядовых пользователей. Как изменить систему рекомендаций, чтобы она учитывала повышенную ценность оценок авторитетов?\"]","1","Попробуйте ответить на следующие вопросы","УПРАЖНЕНИЯ",[566,992,994],{"id":993},"регрессия","Регрессия",[554,996,997],{},"А теперь предположим, что просто порекомендовать фильм недостаточно: вы хотите спрогнозировать, какую оценку Алексей поставит фильму.\nВозьмите 5 пользователей, находящихся вблизи от нее.\nВ числе «5» нет ничего особенного: с таким же успехом можно взять 2 ближайших пользователей, 10 или 10 000.\nПоэтому-то алгоритм и называется «алгоритмом k ближайших пользователей», а не «алгоритмом 5 ближайших пользователей»!\nДопустим, вы пытаетесь угадать оценку Алексея для фильма «». Как этот фильм оценили Иван, Сергей, Лариса, Ольга и Антон?",[999,1000,1001,1014],"table",{},[1002,1003,1004],"thead",{},[1005,1006,1007,1011],"tr",{},[1008,1009,1010],"th",{},"Имя",[1008,1012,1013],{},"Оценка",[1015,1016,1017,1026,1034,1041,1048],"tbody",{},[1005,1018,1019,1023],{},[1020,1021,1022],"td",{},"Сергей",[1020,1024,1025],{},"4",[1005,1027,1028,1031],{},[1020,1029,1030],{},"Иван",[1020,1032,1033],{},"5",[1005,1035,1036,1039],{},[1020,1037,1038],{},"Лариса",[1020,1040,1025],{},[1005,1042,1043,1046],{},[1020,1044,1045],{},"Ольга",[1020,1047,1033],{},[1005,1049,1050,1053],{},[1020,1051,1052],{},"Антон",[1020,1054,1055],{},"3",[554,1057,1058],{},"Если вычислить среднее арифметическое их оценок, вы получите 4,2. Такой метод прогнозирования называется регрессией.\nУ алгоритма k ближайших соседей есть два основных применения — классификация и регрессия:",[1060,1061,1062,1066],"ul",{},[1063,1064,1065],"li",{},"классификация = распределение по категориям;",[1063,1067,1068],{},"регрессия = прогнозирование ответа (в числовом выражении).",[554,1070,1071],{},"Регрессия чрезвычайно полезна. Представьте, что вы открыли маленькую булочную и каждый день выпекаете свежий хлеб.\nВы пытаетесь предсказать, сколько буханок следует испечь на сегодня. Есть несколько признаков:",[1060,1073,1074,1077,1080],{},[1063,1075,1076],{},"погода по шкале от 1 до 5 (1 = плохая, 5 = отличная);",[1063,1078,1079],{},"праздник или выходной (1, если сегодня праздник или выходной, 0 в противном случае);",[1063,1081,1082],{},"проходят ли сегодня спортивные игры (1 = да, 0 = нет).",[554,1084,1085],{},"И вы знаете, сколько буханок хлеба было продано в прошлом при разных сочетаниях признаков.\nA(5,1,0) = 300 буханок; B(3,1,1) = 225; C(1,1,0) = 75; D(4,0,1) = 200; E(4,0,0) = 150; F(2,0,0) = 50.",[554,1087,1088],{},"Сегодня выходной и хорошая погода. Сколько буханок вы продадите на основании только что приведенных данных?\nИспользуем алгоритм k ближайших соседей для k = 4. Сначала определим четырех ближайших соседей для этой точки: (4,1,0) = ?.\nНиже перечислены расстояния. Точки A, B, D и E являются ближайшими: A - 1, B - 2, C - 9, D - 2, E - 1, F - 5.\nВычисляя среднее арифметическое продаж в эти дни, вы получаете ≈ 218.\nЗначит, именно столько буханок нужно выпекать на сегодня!",[551,1090,1091],{},[554,1092,1093,1094],{},"Выше мы использовали формулу расстояния для вычисления степени сходства.\nНо является ли эта формула лучшей?\nНа практике также часто применяется метрика близости косинусов.\nМетрика близости косинусов не измеряет расстояния между двумя векторами.\nВместо этого она сравнивает углы двух векторов и в целом лучше подходит для подобных случаев.\n",[1095,1096,1097],"em",{},"Тема метрики близости косинусов выходит за рамки этой статьи, вам стоит самостоятельно поискать информацию, если вы будете применять алгоритм k ближайших соседей!",[574,1099,1101],{"id":1100},"выбор-признаков","Выбор признаков",[554,1103,1104],{},"Чтобы подобрать рекомендации, вы предлагаете пользователям ставить оценки категориям фильмов.\nА если бы вы вместо этого предлагали им ставить оценки картинкам?\nНаверное, вам удалось бы найти пользователей, которые ставили похожие оценки этим картинкам.\nОднако у вас получилась бы самая плохая рекомендательная система в мире, потому что эти «признаки» не имеют никакого отношения к их вкусам в области кино!\nИли представьте, что вы предлагаете пользователям оценить фильмы для формирования рекомендаций — но только «Игру престолов», «Игру\nпрестолов-2» и «Игру престолов-3». Эти оценки ничего не скажут вам о вкусах пользователей.\nКогда вы работаете с алгоритмом k ближайших соседей, очень важно правильно выбрать признаки для сравнения.\nПод правильным выбором признаков следует понимать:",[1060,1106,1107,1110],{},[1063,1108,1109],{},"признаки, напрямую связанные с фильмами, которые вы пытаетесь рекомендовать;",[1063,1111,1112],{},"признаки, не содержащие смещения (например, если предлагать пользователям оценивать только комедии, вы не получите никакой информации об их отношении к боевикам).",[554,1114,1115],{},"Как вы думаете, оценки хорошо подходят для рекомендации фильмов? Возможно, я поставил «Золушке» более высокую оценку, чем «Охотникам за\nприведениями», но на самом деле я провел больше времени за просмотром «Охотников».\nКак улучшить рекомендательную систему?\nВозвращаясь к примеру с пекарней: сможете ли вы придумать два хороших и два плохих признака, которые можно было бы выбрать для прогнозирования объема выпечки?\nВозможно, нужно выпечь побольше хлеба после рекламы в газете. Или увеличить объем производства по понедельникам.\nВ том, что касается выбора хороших признаков, не существует единственно правильного ответа.\nТщательно продумайте все факторы, которые необходимо учесть при прогнозировании.",[566,1117],{"id":1118},"_1",[984,1120],{":isAnswers":1121,":isList":1122,":startOl":1055,"isText":989,"title":1123},"[\"Слишком мало. Если ограничиться малым числом соседей, существует высокая вероятность того, что результаты будут искажены. Существует хорошее эмпирическое правило: для N пользователей следует рассматривать корень из N соседей.\"]","[\"У сервиса просмотра фильмов миллионы пользователей. В приведенном ранее примере рекомендательная система строилась для пяти ближайших соседей. Пять — это слишком мало? Слишком много?\"]","УПРАЖНЕНИЕ",[1125,1126,1128],"h3",{"id":1127},"знакомство-с-машинным-обучением","Знакомство с машинным обучением",[554,1130,1131],{},"Мало того, что алгоритм k ближайших соседей полезен — он открывает путь в волшебный мир машинного обучения!\nСуть машинного обучения — сделать ваш компьютер более разумным.\nВы уже видели один пример машинного обучения: построение рекомендательной системы.\nРассмотрим другие примеры.",[566,1133,1135],{"id":1134},"ocr","OCR",[554,1137,1138],{},"Сокращение OCR означает «Optical Character Recognition», то есть «оптическое распознавание текста».\nИначе говоря, вы берете фотографию страницы текста, а компьютер автоматически преобразует изображение в текст.\nGoogle использует OCR для оцифровки книг. Как работает OCR?\nДля примера возьмем следующую цифру: 7.",[554,1140,1141],{},"Как автоматически определить, что это за цифра? Можно воспользоваться алгоритмом k ближайших соседей:",[1143,1144,1145,1148],"ol",{},[1063,1146,1147],{},"Переберите изображения цифр и извлеките признаки.",[1063,1149,1150],{},"Получив новое изображение, извлеките признаки и проверьте ближайших соседей.",[554,1152,1153],{},"По сути, это та же задача, что и задача классификации.\nВ общем случае алгоритмы OCR основаны на выделении линий, точек и кривых.\nЗатем при получении нового символа из него можно извлечь те же признаки.\nИзвлечение признаков в OCR происходит сложнее чем в задачах классификации.\nОднако важно понимать, что даже сложные технологии строятся на основе простых идей(таких, как алгоритм k ближайших соседей).\nТе же принципы могут использоваться для распознавания речи или лиц.\nКогда вы отправляете фотографию на Яндекс Диск, иногда сервису Яндекса хватает сообразительности для автоматической пометки людей на фото.\nДа это машинное обучение в действии!\nПервый шаг OCR, в ходе которого перебираются изображения цифр и происходит извлечение признаков, называется тренировкой.\nВ большинстве алгоритмов машинного обучения присутствует фаза тренировки: прежде чем компьютер сможет решить свою задачу, его необходимо натренировать.\nВ следующем примере рассмотрим создание спам-фильтров, и в нем тоже есть шаг тренировки.",[566,1155,1157],{"id":1156},"построение-спам-фильтра","Построение спам-фильтра",[554,1159,1160],{},"Спам-фильтры используют другой простой алгоритм, называемый наивным классификатором Байеса.\nСначала наивный классификатор Байеса тренируется на данных.\nПредположим, вы получили сообщение с темой «Получите свой миллион прямо сейчас!» Это спам?\nПредложение можно разбить на слова, а затем для каждого слова проверить вероятность присутствия этого слова в спам сообщении.\nНапример, в нашей очень простой модели слово «миллион» встречается только в спаме.\nНаивный классификатор Байеса вычисляет вероятность того, что сообщение с большой вероятностью является спамом.\nНа практике он применяется примерно для тех же целей, что и алгоритм k ближайших соседей.\nНапример, наивный классификатор Байеса может использоваться для классификации фруктов: есть большой и красный фрукт.\nКакова вероятность того, что он окажется грейпфрутом?\nЭто простой, но весьма эффективный алгоритм — из тех, что нравятся больше всего!",[566,1162,1164],{"id":1163},"прогнозы-на-биржевых-торгах","Прогнозы на биржевых торгах",[554,1166,1167],{},"Есть одна задача, в которой трудно добиться успеха машинным обучением: точно спрогнозировать курсы акций на бирже.\nКак выбрать хорошие признаки? Предположим, вы говорите, что если курс акций рос вчера, то он будет расти и сегодня.\nХороший это признак или нет? Или, предположим, вы утверждаете, что курс всегда снижается в апреле. Сработает или нет?\nНе существует гарантированного способа прогнозировать будущее на основании прошлых данных.\nПрогнозирование будущего — сложное дело, а при таком количестве переменных оно становится почти невозможным.",[1125,1169,1171],{"id":1170},"тренировка-модели-машинного-обучения","Тренировка модели машинного обучения",[554,1173,1174],{},"Тренировка нейросети МО состоит из нескольких основных этапов:",[1143,1176,1177,1180,1183,1185,1188,1191],{},[1063,1178,1179],{},"Сбор данных",[1063,1181,1182],{},"Анализ и очистка данных",[1063,1184,577],{},[1063,1186,1187],{},"Процесс обучения на тестовых данных",[1063,1189,1190],{},"Проверка на новых данных",[1063,1192,1193],{},"Проверка(валидация) и корректировка модели",[554,1195,1196],{},"Рассмотрим последовательность действий по тренировке модели МО. Все начинается со сбора данных.\nВ примере с рекомендательной системой по фильмам данными были оценки пользователей.\nЗатем необходимо провести очистку данных, то есть удаление неподходящих данных.\nНапример, какой-нибудь пользователь не пожелал оценивать фильмы, поэтому расставил случайные оценки и перешел к следующему экрану.\nТакие данные необходимо удалить из набора. После этого требуется извлечь из данных признаки.\nПолучив признаки, можно переходить к тренировке модели.\nВыберите модель — например, k ближайших соседей, создайте структуру нейронов и саму нейросеть — и проведите ее тренировку на 90% данных.\nОставьте около 10% данных для проверки модели.\nПосле того как модель пройдет обучение, протестируйте ее, предложив ей составить прогноз.\nЧтобы оценить качество прогноза, используйте зарезервированные или новые данные.\nНапример, вы хотите проверить рекомендательную модель фильмов.\nМожно спросить, понравились ли некоторому пользователю некоторые фильмы и сериалы. Модель выдаёт прогнозы.\nА мы при этом заранее знаем, какие фильмы нравятся пользователю, — эта информация содержится в 10 % данных, которые мы зарезервировали.\nЭти зарезервированные данные сравниваются с прогнозами модели.\nПосле сравнения результатов модели и реальных данных, можно сделать вывод о том, что модель выдала хороший результат или не очень.\nХороший результат у модели получается тогда, когда числа достаточно близки к реальным оценкам пользователя.\nЭтот шаг тестирования модели называется проверкой (или валидацией) модели.\nПосле проверки можно вернуться к модели и скорректировать ее.\nПредставьте, что вы построили модель k ближайших соседей, в которой k = 5.\nМожно опробовать ее с k = 7, чтобы посмотреть, не даст ли она лучший результат. Это называется корректировкой(или подкруткой) параметров.\nПосле того как вы завершите тренировку и оценку модели, ваша модель будет готова к работе.\nТак выглядит процедура построения модели МО в общем случае.",[554,1198,1199],{},[1095,1200,1201],{},"Надеюсь, вы хотя бы в общих чертах поняли, что можно сделать с помощью алгоритма k ближайших соседей и машинного обучения!\nМашинное обучение — интересная область, и при желании в нее можно зайти достаточно глубоко.",[566,1203],{"id":1204},"_2",[546,1206],{":isList":1207,"title":1208},"[\"Алгоритм k ближайших соседей применяется для классификации и регрессии. В нем используется проверка k ближайших соседей.;\",\"Классификация = распределение по категориям;\",\"Регрессия = прогнозирование результата (например, в виде числа);\",\"«Извлечением признаков» называется преобразование элемента (например, пользователя) в список чисел, которые могут использоваться для сравнения;\",\"Качественный выбор признаков — важная часть успешного алгоритма k ближайших соседей;\"]","ШПАРГАЛКА",[1125,1210,1212],{"id":1211},"ещё-об-алгоритмах","Ещё об алгоритмах",[554,1214,1215],{},"Ниже краткий обзор 10 алгоритмов, которые не рассматривались. Вы узнаете, для чего нужны эти алгоритмы.\nА также рекомендация книг, которые стоит читать дальше в зависимости от того, какие темы вам интересны.",[566,1217,1219],{"id":1218},"линейная-регрессия","Линейная регрессия",[554,1221,1222],{},"Представьте, что вы хотите продать свой дом.\nЕго площадь составляет 300 квадратных метров.\nВы изучаете описания домов, недавно проданных по соседству:",[1143,1224,1225,1228,1231],{},[1063,1226,1227],{},"100 кв. метров 10 миллионов рублей;",[1063,1229,1230],{},"200 кв. метров 13 миллионов рублей;",[1063,1232,1233],{},"400 кв. метров 25 миллионов рублей.",[554,1235,1236],{},"Какую цену вы бы назначили за свой дом, исходя из этой информации?\nНиже представлено одно из возможных решений. Сначала вы наносите все точки на график.\nЗатем соединяете их прямой линией(отсюда и название линейная).",[554,1238,1239],{},[594,1240],{"alt":1241,"src":1242},"Пример линейной регрессии","\u002Fimages\u002Fblog\u002Fpython\u002Fst35\u002Fimg_1.png",[554,1244,1245],{},"Теперь вы видите, где на этой линии находится точка 300 квадратных метров.\nСоответствующую ей цену можно сделать начальной ценой.\nТак работает линейная регрессия. Она выстраивает линию из заданной группы точек, а затем использует эту линию для вычисления прогнозов.\nЛинейная регрессия уже давно применяется в статистике, а теперь и в машинном обучении, поскольку это метод, с которого легко начинать.\nЛинейная регрессия полезна, если значения непрерывны. Если вам нужно сделать прогноз, проще всего использовать именно линейную регрессию.",[566,1247,1249],{"id":1248},"инвертированные-индексы","Инвертированные индексы",[554,1251,1252],{},"Перед вами сильно упрощенное объяснение того, как работает поисковая система.\nДопустим, имеются три веб-страницы с простым содержимым.\nСтроиться хеш-таблица для этого содержимого или проще python словарь.\nКлючами словаря являются слова, а значения указывают, на каких страницах встречается каждое слово.\nТеперь предположим, что пользователь ищет слово \"python\".\nДалее проверяется, на каких страницах это слово встречается.\nПусть, слово встречается на страницах А и B. Выведем эти страницы в результатах поиска.\nИли предположим, что пользователь ищет слово \"питон\".\nИ система проверяет, что это слово встречается на страницах A и C.\nНесложно, верно?\nХеш-таблица — это очень полезная структура данных: хеш-таблица, связывающая слова с местами, в которых эти слова встречаются.\nТакая структура данных, называемая инвертированным индексом, часто используется для построения поисковых систем.\nЕсли вас интересует область поиска, эта тема станет хорошей отправной точкой для дальнейшего изучения.",[566,1254,1256],{"id":1255},"преобразование-фурье","Преобразование Фурье",[554,1258,1259,1260],{},"Преобразование Фурье — действительно выдающийся алгоритм: великолепный, элегантный и имеющий миллион практических применений.\nПример для преобразования Фурье: если у вас есть коктейль, преобразование Фурье сообщает, из каких ингредиентов он состоит.\nИли для заданной песни преобразование разделяет ее на отдельные частоты.\nОказывается, эта простая идея находит множество практических применений.\nНапример, если песню можно разложить на частоты, вы можете усилить тот диапазон, который вас интересует, — скажем, усилить низкие частоты и приглушить высокие.\nПреобразование Фурье прекрасно подходит для обработки сигналов.\nТакже оно может применяться для сжатия музыки: сначала звуковой файл разбивается на составляющие.\nПреобразование Фурье сообщает, какой вклад вносит каждая составляющая в музыку, что позволяет исключить несущественные составляющие.\nСобственно, именно так работает музыкальный формат MP3!\nМузыка — не единственный вид цифровых сигналов.\nГрафический формат JPG также использует сжатие и работает по тому же принципу.\nКроме того, преобразование Фурье применяется для прогнозирования землетрясений и анализа ДНК.\nС его помощью можно построить приложение, которое находит песни по отрывкам.\nПреобразование Фурье очень часто применяется на практике!\n",[558,1261,1265],{"href":1262,"rel":1263},"https:\u002F\u002Fproglib.io\u002Fp\u002Fpreobrazovaniya-fure-dlya-obrabotki-signalov-s-pomoshchyu-python-2020-11-03",[1264],"nofollow","Подробнее о преобразовании Фурье в работе со звуком есть отличная статья.",[566,1267,1269],{"id":1268},"параллельные-алгоритмы","Параллельные алгоритмы",[554,1271,1272,1273,1276,1277,1280,1281,1283,1284,1287],{},"Следующие три темы связаны с масштабируемостью и обработкой больших объемов данных.\nКогда-то компьютеры становились все быстрее и быстрее.\nЕсли вы хотели, чтобы ваш алгоритм работал быстрее, можно было подождать несколько месяцев и запустить программу на более мощном компьютере.\nНо сейчас этот период подошел к концу.\nСовременные компьютеры и ноутбуки оснащаются многоядерными процессорами. Чтобы алгоритм заработал быстрее,\nнеобходимо преобразовать его в форму, подходящую для параллельного выполнения сразу на всех ядрах!\nРассмотрим простой пример. Лучшее время выполнения для алгоритма сортировки равно приблизительно ",[1095,1274,1275],{},"O(n log n)",".\nИзвестно, что массив невозможно отсортировать за время ",[1095,1278,1279],{},"O(n)",", если только не воспользоваться параллельным алгоритмом!\nСуществует параллельная версия быстрой сортировки, которая сортирует массив за время ",[1095,1282,1279],{},".\nПараллельный алгоритм трудно разработать.\nИ так же трудно убедиться в том, что он работает правильно, и понять, какой прирост скорости он обеспечивает.\nОдно можно заявить твердо: ",[1095,1285,1286],{},"выигрыш по времени нелинеен",".\nСледовательно, если процессор вашего компьютера имеет два ядра вместо одного, из этого не следует, что ваш алгоритм по волшебству заработает вдвое быстрее.\nЭто объясняется несколькими причинами:",[1060,1289,1290,1296,1302],{},[1063,1291,1292,1295],{},[1095,1293,1294],{},"Затраты ресурсов на управление параллелизмом"," — допустим, нужно отсортировать массив из 1000 элементов. Как разбить эту задачу для выполнения на двух ядрах? Выделить каждому ядру 500 элементов, а затем объединить два отсортированных массива в один большой отсортированный массив? Слияние двух массивов требует времени.",[1063,1297,1298,1301],{},[1095,1299,1300],{},"Закон Амдала"," — представьте, что вы пишете картину. Это занимает очень много времени, допустим около 30 часов. В идеале вам хотелось бы уложиться в 10 часов. Вы решаете оптимизировать процесс. Для этого разбиваете его на два шага: (1) эскиз и (2) рисование красками. Исходный эскиз не обязательно рисовать вручную — конечно, с помощью трейсинга(обводки) это делается быстрее. Но при следующей попытке на картину уходит 29 часов и 5 минут! Что произошло? Раньше эскиз занимал 1 час. Вы сократили его до 5 минут, что стало значительным улучшением. Тем не менее бóльшая часть времени приходится на рисование красками, так что оптимизация оказалась незначительной. Это проявление так называемого закона Амдала. Он гласит, что при оптимизации одной части системы выигрыш в производительности ограничивается тем, какую долю времени занимает эта часть. В данном случае время создания эскиза сокращается до 1\u002F12 исходного значения. При этом экономятся 55 минут. Если бы нам удалось сократить время рисования красками в той же степени, это сэкономило бы 2090 минут!Ускоряя алгоритм за счет параллелизации, подумайте, какую его часть следует распараллелить — создание эскиза или рисование?",[1063,1303,1304,1307],{},[1095,1305,1306],{},"Распределение нагрузки"," — допустим, необходимо выполнить 10 задач, и вы назначаете каждому ядру 5 задач. Однако ядру A достаются все простые задачи, поэтому оно выполняет свою работу за 10 секунд, тогда как ядро B справится со сложными задачами только за минуту. Это означает, что ядро A целых 50 секунд простаивает, пока ядро B выполняет всю работу! Как организовать равномерное распределение работы, чтобы оба ядра трудились с одинаковой интенсивностью?",[554,1309,1310],{},"Если вас интересует теоретическая сторона производительности и масштабируемости, возможно, параллельные алгоритмы — именно то, что вам нужно!",[574,1312,1314],{"id":1313},"mapreduce","MapReduce",[554,1316,1317],{},"Существует разновидность параллельных алгоритмов, которая в последнее время активно набирает популярность: распределенные алгоритмы.\nКонечно, параллельный алгоритм удобно запускать на компьютере, если для его выполнения требуется от двух до четырех ядер. Но если нужны сотни?\nТогда алгоритм записывают так, чтобы он мог выполняться на множестве машин.\nКомпания Google популяризировала распределенный алгоритм, который называется MapReduce, но его функции известны уже давно.\nДля чего нужны распределенные алгоритмы?\nПредположим, имеется таблица с миллиардами или триллионами записей и к ней нужно сделать сложный запрос SQL.\nВ MySQL это сделать не удастся, потому что MySQL начнет «тормозить» уже после нескольких миллиардов записей.\nИспользуйте MapReduce!\nИли, предположим, вам нужно обработать длинный список задач.\nОбработка каждой задачи занимает 10 секунд, а всего в списке 1 миллион задач.\nЕсли выполнять эту работу на одном компьютере, она займет несколько месяцев!\nЕсли бы ее можно было выполнить на 100 машинах, работа завершилась бы за несколько дней.\nРаспределенные алгоритмы хорошо работают в ситуациях, когда нужно выполнить большой объем работы за максимально короткое время.",[566,1319,1321],{"id":1320},"фильтры-блума-и-hyperloglog","Фильтры Блума и HyperLogLog",[554,1323,1324,1325,1328],{},"Представьте себя на месте сайта Reddit. Когда пользователь публикует ссылку, нужно проверить, публиковалась ли эта ссылка ранее.\nИстории, которые еще не публиковались, считаются более ценными.\nИли представьте себя на месте поискового бота Google.\nОбрабатывать веб-страницу нужно только в том случае, если она еще не обрабатывалась ранее.\nИтак, нужно проверить, обрабатывалась ли страница ранее.\nИли представьте себя на месте bit.ly — сервиса сокращения URL.\nПользователи не должны перенаправляться на вредоносные сайты.\nУ вас имеется набор URL-адресов, которые считаются вредоносными.\nТеперь нужно выяснить, не направляется ли пользователь на URL-адрес из этого набора.\nВо всех этих примерах возникает одна проблема.\nИмеется очень большой набор данных.\nПоявляется новый объект, и вы хотите узнать, содержится ли он в существующем наборе.\nЭта задача быстро решается при помощи хеша.\nНапример, представьте, что Google создает большой хеш, ключами которого являются все обработанные страницы.\nКак узнать, обрабатывался ли сайт ashtana.ru? Нужно заглянуть в хеш.\nУ ashtana.ru имеется свой ключ в хеше, а значит, адрес уже обрабатывался.\nСреднее время обращения к элементам в хеш-таблице составляет ",[1095,1326,1327],{},"O(1)",".\nТаким образом, вы узнали о том, что страница ashtana.ru уже проиндексирована за постоянное время. Неплохо!\nВот только этот хеш получится просто огромным.\nGoogle индексирует триллион веб-страниц. Если хеш содержит все URL-адреса, индексируемые Google, он займет слишком много места.\nУ Reddit и bit.ly возникает аналогичная проблема. Сталкиваясь с такими объемами данных, приходится действовать более изобретательно!",[574,1330,1332],{"id":1331},"фильтры-блума","Фильтры Блума",[554,1334,1335],{},"Для решения проблемы можно воспользоваться вероятностными структурами данных, которые называются фильтрами Блума.\nОни дают ответ, который может оказаться ложным, но с большой вероятностью является правильным.\nВместо того чтобы обращаться к хешу, вы спрашиваете у фильтра Блума, обрабатывался ли этот URL-адрес ранее.\nХеш-таблица даст точный ответ. Фильтр Блума дает ответ, правильный с высокой вероятностью:",[1060,1337,1338,1341],{},[1063,1339,1340],{},"возможны ложноположительные срабатывания. Фильтр скажет: «Этот сайт уже обрабатывался», хотя этого не было;",[1063,1342,1343],{},"ложноотрицательные срабатывания исключены. Если фильтр утверждает, что сайт не обрабатывался, вы можете быть в этом уверены.",[554,1345,1346],{},"Фильтры Блума хороши тем, что занимают очень мало места.\nХеш-таблице пришлось бы хранить все URL-адреса, обрабатываемые Google, а фильтру Блума это не нужно.\nФильтр Блума очень удобен тогда, когда нет необходимости в точном ответе(как во всех приведенных примерах).",[574,1348,1350],{"id":1349},"hyperloglog","HyperLogLog",[554,1352,1353],{},"Примерно так же действует другой алгоритм, который называется HyperLogLog.\nПредположим, Google хочет подсчитать количество уникальных поисков, выполненных пользователями.\nИли Amazon хочет подсчитать количество уникальных предметов, просмотренных пользователями за сегодняшний день.\nДля получения ответов на эти вопросы потребуется очень много места!\nТак, в примере с Google придется вести журнал всех уникальных вариантов поиска.\nКогда пользователь что-то ищет, вы сначала проверяете, присутствует ли условие в журнале, и если нет, добавляете его.\nДаже для одного дня этот журнал получится гигантским.\nHyperLogLog аппроксимирует количество уникальных элементов в множестве.\nКак и фильтры Блума, он не дает точного ответа, но выдает достаточно близкий результат с использованием малой части памяти, которую обычно занимает такая задача.\nЕсли вы используете большие объемы данных и вас устраивают приближенные ответы — воспользуйтесь вероятностными алгоритмами!",[566,1355,1357],{"id":1356},"https-и-обмен-ключами-диффи-хеллмана","HTTPS и обмен ключами Диффи — Хеллмана",[554,1359,1360],{},"HTTPS — опора современного интернета.\nЭтот протокол обеспечивает безопасные онлайн-транзакции, от ввода пароля до оплаты покупок.\nРабота HTTPS основана на шифровании сообщений между клиентом и сервером.\nКак же работает шифрование? Функции передаются сообщение и секретный ключ.\nЗатем функция генерирует зашифрованное сообщение.\nЧтобы расшифровать его, передайте зашифрованное сообщение и тот же ключ функции, и вы получите исходное сообщение.\nКогда вы отправляете данные серверу, ваш браузер зашифровывает сообщение, после чего сервер расшифровывает его.\nДа, кроме одного: как проверить, что браузер и сервер используют один и тот же ключ?\nПомните, что для работы HTTPS обе стороны должны иметь одинаковые ключи.\nНо как задать ключ, чтобы никто его не видел? Если отправить ключ серверу, злоумышленник сможет перехватить этот ключ.\nКак задать ключ, чтобы только браузер и сервер знали его? Задача кажется неразрешимой, но это не так!\nДля ее решения существует очень умный алгоритм, называемый обменом ключей Диффи — Хеллмана.",[554,1362,1363],{},"Ниже описано, как работает алгоритм Диффи — Хеллмана.\nНа шаге 1 мы генерируем собственные ключи. Я — клиент, и я генерирую ключ для себя. Сервис также генерирует ключ.\nЭти ключи разные. Мы не знаем ключи друг друга, они закрытые. В реальности ключи представляют собой байты.\nНа шаге 2 генерируется общий шаблон. Это открытый шаблон. Он виден обеим сторонам и всем остальным. Нам неважно, кто его видит.\nНа шаге 3 этот шаблон совмещается с закрытыми ключами.\nВ результате мы получаем открытые ключи. Раз они открытые, нас не интересует, кто их видит.\nСервер видит мой открытый ключ, а я вижу его открытый ключ.\nНаконец, на шаге 4 я получаю открытый ключ сервера и совмещаю его со своим закрытым ключом.\nСервис делает то же самое с моим открытым ключом.\nТеперь у нас одинаковые ключи! У каждого из нас есть ключ, объединяющий три шаблона.\nНам удалось задать ключ, не отправляя ключи друг другу.\nЗаданный ключ называется общим секретом; так работает обмен ключами Диффи — Хеллмана.",[554,1365,1366],{},"HTTPS — интересная и важная часть нашей повседневной жизни. Вот немного терминологии, связанной с HTTPS:",[1060,1368,1369,1372,1375],{},[1063,1370,1371],{},"TLS — протокол безопасности транспортного уровня (Transport Layer Security). TLS используется для установления безопасного соединения.",[1063,1373,1374],{},"SSL — прежнее название TLS, но люди часто не различают их. Если вы слышите, как кто-то упоминает SSL, то, скорее всего, речь идет о TLS. В этом протоколе часто находят дефекты безопасности, поэтому его постоянно приходится обновлять. Протокол TLS впервые появился в 1999 году. Все версии протокола SSL, выпущенные до TLS, небезопасны.",[1063,1376,1377],{},"Шифрование с симметричным ключом — в нашем примере выше обе стороны используют одинаковые ключи. Но существует и асимметричное шифрование с открытым ключом, когда обе стороны используют разные ключи. Я говорю о шифровании с симметричным ключом, потому что оно используется HTTPS.",[554,1379,1380],{},"HTTPS использует измененную версию обмена ключей Диффи — Хеллмана, называемую эфемерным обменом ключей Диффи — Хеллмана.\nОна работает так же, как было показано, кроме того, что закрытые ключи генерируются заново для каждого соединения.\nЭто означает, что даже если злоумышленнику станет известен один из закрытых ключей, он сможет расшифровать сообщения только одного соединения.\nКриптография — интересная и глубокая тема, в которую можно сильно погрузиться.",[566,1382,1384],{"id":1383},"локально-чувствительное-хеширование","Локально-чувствительное хеширование",[554,1386,1387,1388,1391,1392,1394,1395,1397],{},"Многие хеш-функции имеют одну важную особенность: они являются локально-нечувствительными.\nПредположим, имеется строка, для которой генерируется хеш-код с помощью алгоритма SHA-256: dog → cd6357.\nЕсли изменить в строке всего один символ, а потом сгенерировать хеш заново, строка полностью изменяется!\nИ это хорошо, потому что сравнение хешей не позволит атакующему определить, насколько он близок к взлому пароля.\nИногда требуется обратный результат: локально-чувствительная функция хеширования.\nЗдесь на помощь приходит алгоритм ",[1095,1389,1390],{},"Simhash",".\nПри незначительном изменении строки ",[1095,1393,1390],{}," генерирует хеш-код, который почти не отличается от исходного.\nЭто позволяет сравнивать хеш-коды и определять, насколько похожи две строки, — весьма полезная возможность!\nПримеры использования ",[1095,1396,1390],{},":",[1060,1399,1400,1403,1406,1409],{},[1063,1401,1402],{},"Google использует Simhash для выявления дубликатов в процессе индексирования.",[1063,1404,1405],{},"Система проверки на антиплагиат может использовать Simhash для обнаружения плагиата(копирования рефератов из интернета).",[1063,1407,1408],{},"Книжное издательство позволяет пользователям загружать документы или книги, чтобы они стали доступны для других пользователей. Но издатель не хочет, чтобы пользователи размещали информацию, защищенную авторским правом! С помощью Simhash сайт может обнаружить, что отправленная информация похожа на изданную книгу, и при обнаружении сходства автоматически запретить ее размещение.",[1063,1410,1411],{},"Simhash используется для выявления сходства между фрагментами текста.",[566,1413,1415],{"id":1414},"минимальные-кучи-и-приоритетные-очереди","Минимальные кучи и приоритетные очереди",[554,1417,1418,1419,1421,1422,1425],{},"Минимальная куча — структура данных, построенная на базе деревьев. В таких кучах хранятся числа.\nМинимальные кучи позволяют быстро найти наименьший элемент кучи, потому что наименьшее значение всегда находится в корне.\nЭто самое важное свойство минимальной кучи, и наименьший элемент находится за время ",[1095,1420,1327],{},".\nИли же за время ",[1095,1423,1424],{},"O(log n)"," его можно удалить из кучи, заменив новым минимумом.\nБлагодаря кучам проводить сортировку очень легко — просто продолжая запрашивать минимальное значение.\nИ сохранять значения по порядку. В конце куча будет пустой, а у вас появится отсортированный список чисел!\nТакой алгоритм называется пирамидальной сортировкой, или сортировкой кучей.\nМаксимальные кучи (невозрастающие пирамиды) очень похожи на минимальные, но у них в корне хранится наибольшее значение.\nКучи отлично подходят для реализации приоритетных очередей.\nВспомните, что очереди относятся к категории FIFO (First In, First Out — «первым пришел, первым вышел»).\nС другой стороны, стек относится к структуре данных LIFO(Last In, First Out — «последним пришел, первым вышел»).\nПриоритетная очередь похожа на обычную очередь, не считая того, что при запросе элемента приоритетная очередь выдает элемент с наибольшим приоритетом.\nПриоритетная очередь отлично подходит для реализации списка задач.\nСначала вы сохраняете в списке задачи, а затем запрашиваете задачу для работы; приоритетная очередь выдает задачу с наибольшим приоритетом.\nПриоритетные очереди также используются для реализации эффективной версии алгоритма Дейкстры.",[566,1427,1429],{"id":1428},"линейное-программирование","Линейное программирование",[554,1431,1432],{},"Линейное программирование — одна из самых интересных областей, которые мне известны.\nЛинейное программирование используется для максимизации некоторой характеристики при заданных ограничениях.\nПредположим, ваша компания выпускает два продукта: рубашки и сумки.\nНа рубашку требуется 1 метр ткани и 5 пуговиц. На изготовление сумки необходимо 2 метра ткани и 2 пуговицы.\nУ вас есть 11 метров ткани и 20 пуговиц.\nРубашка приносит прибыль 200 рублей, а сумка — 300.\nСколько рубашек и сумок следует изготовить для получения максимальной прибыли?\nЗдесь мы пытаемся максимизировать прибыль, а ограничения определяют количество имеющихся материалов.\nДругой пример: вы политик, пытающийся получить максимальное количество голосов.\nПредположим, что исследования показали, что на каждый голос жителя Белгорода требуется примерно 1 час работы (маркетинг, исследования и т.д.), а на каждый голос жителя Курска — 1,5 часа.\nВам нужны голоса как минимум 500 жителей Белгорода и как минимум 300 жителей Курска.\nВ вашем распоряжении 50 дней. Кроме того, затраты на жителя Белгорода составляют 200 рублей, а на жителя Курска — 100.\nВаш бюджет составляет 1500000 рублей. Какое максимальное количество голосов вы сможете получить от жителей двух городов?\nНа этот раз вы стремитесь к максимуму голосов при ограничениях по времени и деньгам.\nВозможно, вы подумаете: «Есть много задач решающие вопросы оптимизации. Как они связаны с линейным программированием?»\nВсе алгоритмы, работающие с графами, могут быть реализованы средствами линейного программирования.\nЛинейное программирование — намного более общая область, а задачи с графами составляют ее подмножество.\nВ линейном программировании используется симплекс-метод. Этот алгоритм достаточно сложен, поэтому я не привожу его.\nЕсли вы заинтересуетесь различными задачами оптимизации, поищите информацию о линейном программировании!",[551,1434,1435],{},[554,1436,1437],{},"Надеюсь, этот краткий обзор показал, как много всего ещё можно узнать.\nЯ считаю, что лучший способ узнать что-то — найти тему, которая вас интересует, и постоянно изучать её!",[1439,1440,1441],"style",{},"\nmjx-container[jax=\"SVG\"] {\n  direction: ltr;\n}\n\nmjx-container[jax=\"SVG\"] > svg {\n  overflow: visible;\n  min-height: 1px;\n  min-width: 1px;\n}\n\nmjx-container[jax=\"SVG\"] > svg a {\n  fill: blue;\n  stroke: blue;\n}\n\nmjx-container[jax=\"SVG\"][display=\"true\"] {\n  display: block;\n  text-align: center;\n  margin: 1em 0;\n}\n\nmjx-container[jax=\"SVG\"][display=\"true\"][width=\"full\"] {\n  display: flex;\n}\n\nmjx-container[jax=\"SVG\"][justify=\"left\"] {\n  text-align: left;\n}\n\nmjx-container[jax=\"SVG\"][justify=\"right\"] {\n  text-align: right;\n}\n\ng[data-mml-node=\"merror\"] > g {\n  fill: red;\n  stroke: red;\n}\n\ng[data-mml-node=\"merror\"] > rect[data-background] {\n  fill: yellow;\n  stroke: none;\n}\n\ng[data-mml-node=\"mtable\"] > line[data-line], svg[data-table] > g > line[data-line] {\n  stroke-width: 70px;\n  fill: none;\n}\n\ng[data-mml-node=\"mtable\"] > rect[data-frame], svg[data-table] > g > rect[data-frame] {\n  stroke-width: 70px;\n  fill: none;\n}\n\ng[data-mml-node=\"mtable\"] > .mjx-dashed, svg[data-table] > g > .mjx-dashed {\n  stroke-dasharray: 140;\n}\n\ng[data-mml-node=\"mtable\"] > .mjx-dotted, svg[data-table] > g > .mjx-dotted {\n  stroke-linecap: round;\n  stroke-dasharray: 0,140;\n}\n\ng[data-mml-node=\"mtable\"] > g > svg {\n  overflow: visible;\n}\n\n[jax=\"SVG\"] mjx-tool {\n  display: inline-block;\n  position: relative;\n  width: 0;\n  height: 0;\n}\n\n[jax=\"SVG\"] mjx-tool > mjx-tip {\n  position: absolute;\n  top: 0;\n  left: 0;\n}\n\nmjx-tool > mjx-tip {\n  display: inline-block;\n  padding: .2em;\n  border: 1px solid #888;\n  font-size: 70%;\n  background-color: #F8F8F8;\n  color: black;\n  box-shadow: 2px 2px 5px #AAAAAA;\n}\n\ng[data-mml-node=\"maction\"][data-toggle] {\n  cursor: pointer;\n}\n\nmjx-status {\n  display: block;\n  position: fixed;\n  left: 1em;\n  bottom: 1em;\n  min-width: 25%;\n  padding: .2em .4em;\n  border: 1px solid #888;\n  font-size: 90%;\n  background-color: #F8F8F8;\n  color: black;\n}\n\nforeignObject[data-mjx-xml] {\n  font-family: initial;\n  line-height: normal;\n  overflow: visible;\n}\n\nmjx-container[jax=\"SVG\"] path[data-c], mjx-container[jax=\"SVG\"] use[data-c] {\n  stroke-width: 3;\n}\n",{"title":982,"searchDepth":1443,"depth":1444,"links":1445},2,5,[1446],{"id":544,"depth":1443,"text":302,"children":1447},[1448,1452,1453,1456,1457,1463,1466],{"id":568,"depth":1449,"text":569,"children":1450},4,[1451],{"id":576,"depth":1444,"text":577},{"id":982,"depth":1449,"text":982},{"id":993,"depth":1449,"text":994,"children":1454},[1455],{"id":1100,"depth":1444,"text":1101},{"id":1118,"depth":1449,"text":982},{"id":1127,"depth":1458,"text":1128,"children":1459},3,[1460,1461,1462],{"id":1134,"depth":1449,"text":1135},{"id":1156,"depth":1449,"text":1157},{"id":1163,"depth":1449,"text":1164},{"id":1170,"depth":1458,"text":1171,"children":1464},[1465],{"id":1204,"depth":1449,"text":982},{"id":1211,"depth":1458,"text":1212,"children":1467},[1468,1469,1470,1471,1474,1478,1479,1480,1481],{"id":1218,"depth":1449,"text":1219},{"id":1248,"depth":1449,"text":1249},{"id":1255,"depth":1449,"text":1256},{"id":1268,"depth":1449,"text":1269,"children":1472},[1473],{"id":1313,"depth":1444,"text":1314},{"id":1320,"depth":1449,"text":1321,"children":1475},[1476,1477],{"id":1331,"depth":1444,"text":1332},{"id":1349,"depth":1444,"text":1350},{"id":1356,"depth":1449,"text":1357},{"id":1383,"depth":1449,"text":1384},{"id":1414,"depth":1449,"text":1415},{"id":1428,"depth":1449,"text":1429},"2026-05-21","Сценарии использования и ограничениями алгоритма k ближайших соседей. Рекомендации по темам, которые стоит изучать дальше.","md","images\u002Fblog\u002Fpython\u002Fst35\u002Fimg.png",{},35,{"title":302,"description":1483},"XxXV74jrfia4THoFmW400WVVaOY2oEv_sinQl05bgbA",{"id":1491,"title":298,"author":1492,"body":1494,"date":4628,"description":4629,"extension":1484,"image":4630,"meta":4631,"minRead":4632,"navigation":513,"num":4633,"path":299,"seo":4634,"stem":300,"__hash__":4635},"blog\u002Fblog\u002Fpython\u002Fst34.md",{"name":516,"avatar":1493},{"src":536,"alt":537},{"type":539,"value":1495,"toc":4593},[1496,1499,1502,1511,1515,1520,1523,1562,1565,1569,1630,1633,1636,1639,1642,1645,1701,1704,1707,1710,1713,1768,1771,1825,1828,1882,1885,1888,1891,1945,1948,2002,2005,2060,2063,2066,2069,2123,2126,2181,2184,2239,2242,2246,2249,2253,2256,2310,2313,2381,2384,2450,2453,2520,2523,2527,2530,2534,2537,2541,2544,2655,2659,2662,2666,2669,2737,2740,2823,2826,2910,2914,2917,2999,3002,3005,3009,3012,3016,3019,3023,3026,3034,3037,3048,3052,3055,3059,3062,3073,3076,3146,3150,3153,3219,3222,3226,3229,3295,3298,3306,3309,3569,3572,3779,3782,3863,3866,3870,3873,3940,3943,3947,3950,3958,3961,4027,4094,4097,4319,4537,4540,4551,4554,4562,4564,4567,4569,4573,4585,4588,4590],[542,1497,298],{"id":1498},"динамическое-программирование",[546,1500],{":isList":1501,"title":549},"[\"Узнаете про динамическое программирование — метод решения сложных задач, разбиваемых на подзадачи, которые решаются в первую очередь.\",\"Рассматриваются примеры, которые научат вас искать решения новых задач, основанные на методе динамического программирования.\"]",[551,1503,1504],{},[554,1505,1506,1507,1510],{},"В предыдущей статье было о: ",[558,1508,1509],{"href":291},"жадных алгоритмах",".\nЗдесь далее текст пойдёт о динамическом программировании.",[1125,1512,1514],{"id":1513},"задача-о-рюкзаке","Задача о рюкзаке",[551,1516,1517],{},[554,1518,1519],{},"Задача о рюкзаке была описана в предыдущей статье.",[554,1521,1522],{},"Вернёмся к задаче о рюкзаке. У вас есть рюкзак, в котором можно унести товары общим весом до 4 кг.\nЕсть 3 предмета, которые можно положить в рюкзак.",[999,1524,1525,1538],{},[1002,1526,1527],{},[1005,1528,1529,1532,1535],{},[1008,1530,1531],{},"Магнитофон",[1008,1533,1534],{},"Ноутбук",[1008,1536,1537],{},"Гитара",[1015,1539,1540,1551],{},[1005,1541,1542,1545,1548],{},[1020,1543,1544],{},"3000 руб",[1020,1546,1547],{},"2000 руб",[1020,1549,1550],{},"1500 руб",[1005,1552,1553,1556,1559],{},[1020,1554,1555],{},"4 кг",[1020,1557,1558],{},"3 кг",[1020,1560,1561],{},"1 кг",[554,1563,1564],{},"Какие предметы следует положить в рюкзак, чтобы стоимость добычи была максимальной?",[566,1566,1568],{"id":1567},"простое-решение","Простое решение",[554,1570,1571,1572,1629],{},"Простой способ решения выглядит так: вы перебираете все возможные множества товаров и находите множество с максимальной стоимостью.\nТакое решение работает очень медленно. Для 3 предметов приходится обработать 8 множеств, для 4 — 16 и т.д.\nС каждым добавленным предметом количество множеств удваивается. Такое решение будет выполняться за время: ",[582,1573,1575],{"className":1574,"jax":586},[585],[588,1576,1581,1596],{"style":1577,"xmlns":591,"width":1578,"height":1579,"role":594,"focusable":595,"viewBox":1580,"xmlnsXLink":597},"vertical-align: -0.566ex;","5.765ex","2.262ex","0 -750 2548.3 1000",[599,1582,1583,1587,1589,1591,1594],{},[602,1584],{"id":1585,"d":1586},"MJX-1-TEX-I-1D442","M740 435Q740 320 676 213T511 42T304 -22Q207 -22 138 35T51 201Q50 209 50 244Q50 346 98 438T227 601Q351 704 476 704Q514 704 524 703Q621 689 680 617T740 435ZM637 476Q637 565 591 615T476 665Q396 665 322 605Q242 542 200 428T157 216Q157 126 200 73T314 19Q404 19 485 98T608 313Q637 408 637 476Z",[602,1588],{"id":608,"d":609},[602,1590],{"id":624,"d":625},[602,1592],{"id":1593,"d":829},"MJX-1-TEX-I-1D45B",[602,1595],{"id":628,"d":629},[639,1597,1598],{"stroke":641,"fill":641,"stroke-width":642,"transform":643},[639,1599,1600,1606,1611,1624],{"dataMmlNode":646},[639,1601,1602],{"dataMmlNode":674},[664,1603],{"dataC":1604,"xLinkHref":1605},"1D442","#MJX-1-TEX-I-1D442",[639,1607,1609],{"dataMmlNode":662,"transform":1608},"translate(763,0)",[664,1610],{"dataC":666,"xLinkHref":667},[639,1612,1614,1618],{"dataMmlNode":655,"transform":1613},"translate(1152,0)",[639,1615,1616],{"dataMmlNode":681},[664,1617],{"dataC":705,"xLinkHref":706},[639,1619,1621],{"dataMmlNode":674,"transform":1620},"translate(533,363) scale(0.707)",[664,1622],{"dataC":927,"xLinkHref":1623},"#MJX-1-TEX-I-1D45B",[639,1625,1627],{"dataMmlNode":662,"transform":1626},"translate(2159.3,0)",[664,1628],{"dataC":712,"xLinkHref":713},".\nЭто слишком медленно!",[554,1631,1632],{},"Для любого сколько-нибудь значительного количества предметов это неприемлемо долго!\nМожно воспользоваться приближённым решением, но такое решение может существенно не совпадать с оптимальным.\nКак вычислить оптимальное решение? С помощью динамического программирования!",[1125,1634,298],{"id":1635},"динамическое-программирование-1",[554,1637,1638],{},"Рассмотрим как работает данный способ решения задачи.\nПроцедура решения начинается с решения подзадач с постепенным переходом к решению полной задачи.\nВ задаче о рюкзаке начать следует с решения задачи для меньшего рюкзака(или \"подрюкзака\"), а потом на этой основе попытаться решить исходную задачу.",[554,1640,1641],{},"Динамическое программирование — достаточно сложная концепция.\nДополнительные примеры помогут вам в дальнейшем лучше разобраться с этой темой.",[554,1643,1644],{},"Для начала рассмотрим алгоритм в действии.\nКаждый алгоритм динамического программирования начинается с таблицы. Вот как выглядит таблица для задачи о рюкзаке:",[999,1646,1647,1663],{},[1002,1648,1649],{},[1005,1650,1651,1654,1656,1659,1661],{},[1008,1652,1653],{},"-",[1008,1655,988],{},[1008,1657,1658],{},"2",[1008,1660,1055],{},[1008,1662,1025],{},[1015,1664,1665,1677,1689],{},[1005,1666,1667,1669,1671,1673,1675],{},[1020,1668,1537],{},[1020,1670],{},[1020,1672],{},[1020,1674],{},[1020,1676],{},[1005,1678,1679,1681,1683,1685,1687],{},[1020,1680,1531],{},[1020,1682],{},[1020,1684],{},[1020,1686],{},[1020,1688],{},[1005,1690,1691,1693,1695,1697,1699],{},[1020,1692,1534],{},[1020,1694],{},[1020,1696],{},[1020,1698],{},[1020,1700],{},[554,1702,1703],{},"Строки таблицы представляют предметы, а столбцы — ёмкость рюкзака от 1 до 4 кг.\nВсе эти столбы нужны, потому что они упрощают вычисление стоимостей \"подкрюкзаков\".\nВ исходном состоянии таблица пуста. Нам предстоит заполнить каждую ячейку таблицы.\nПосле того как таблица будет заполнена, вы получите ответ на свою задачу.\nПожалуйста, внимательно разберитесь в происходящем. Нарисуйте собственную таблицу.",[574,1705,1537],{"id":1706},"гитара",[554,1708,1709],{},"Точная формула для вычисления значений в таблице будет приведена позднее, а пока ограничимся общим описанием.\nНачнём с первой строки.\nСтрока снабжена пометкой «гитара»; это означает, что вы пытаетесь уложить гитару в рюкзак.\nВ каждой ячейке принимается простое решение:класть гитару в рюкзак или нет?\nПомните: мы пытаемся найти множество элементов с максимальной стоимостью.",[554,1711,1712],{},"В первой ячейке емкость рюкзака равна 1 кг. Гитара также весит 1 кг — значит, она поместится в рюкзак!\nИтак, стоимость этой ячейки составляет 1500₽, а в рюкзаке лежит гитара.\nНачнем заполнять ячейку:",[999,1714,1715,1729],{},[1002,1716,1717],{},[1005,1718,1719,1721,1723,1725,1727],{},[1008,1720,1653],{},[1008,1722,988],{},[1008,1724,1658],{},[1008,1726,1055],{},[1008,1728,1025],{},[1015,1730,1731,1744,1756],{},[1005,1732,1733,1735,1738,1740,1742],{},[1020,1734,1537],{},[1020,1736,1737],{},"1500",[1020,1739],{},[1020,1741],{},[1020,1743],{},[1005,1745,1746,1748,1750,1752,1754],{},[1020,1747,1531],{},[1020,1749],{},[1020,1751],{},[1020,1753],{},[1020,1755],{},[1005,1757,1758,1760,1762,1764,1766],{},[1020,1759,1534],{},[1020,1761],{},[1020,1763],{},[1020,1765],{},[1020,1767],{},[554,1769,1770],{},"По тому же принципу каждая ячейка в таблице содержит список всех элементов, которые помещаются в рюкзаке на данный момент.\nПосмотрим на следующую ячейку. На этот раз емкость рюкзака составляет 2 кг. Понятно, что гитара здесь поместится!",[999,1772,1773,1787],{},[1002,1774,1775],{},[1005,1776,1777,1779,1781,1783,1785],{},[1008,1778,1653],{},[1008,1780,988],{},[1008,1782,1658],{},[1008,1784,1055],{},[1008,1786,1025],{},[1015,1788,1789,1801,1813],{},[1005,1790,1791,1793,1795,1797,1799],{},[1020,1792,1537],{},[1020,1794,1737],{},[1020,1796,1737],{},[1020,1798],{},[1020,1800],{},[1005,1802,1803,1805,1807,1809,1811],{},[1020,1804,1531],{},[1020,1806],{},[1020,1808],{},[1020,1810],{},[1020,1812],{},[1005,1814,1815,1817,1819,1821,1823],{},[1020,1816,1534],{},[1020,1818],{},[1020,1820],{},[1020,1822],{},[1020,1824],{},[554,1826,1827],{},"Процедура повторяется для остальных ячеек строки.\nВспомните, что текущей является первая строка, поэтому выбирать приходится только из одного предмета — гитары.\nСчитайте, что два других предмета пока недоступны.\nПочему все это делается для рюкзаков с емкостью 1, 2 и т.д., если в задаче речь идет о рюкзаке с емкостью 4 кг?\nМетод динамического программирования начинает с малых задач, а затем переходит к большой задаче.\nВы решаете подзадачи, которые помогут в решении большой задачи.\nПосле того как первая строка будет заполнена, таблица будет выглядеть так:",[999,1829,1830,1844],{},[1002,1831,1832],{},[1005,1833,1834,1836,1838,1840,1842],{},[1008,1835,1653],{},[1008,1837,988],{},[1008,1839,1658],{},[1008,1841,1055],{},[1008,1843,1025],{},[1015,1845,1846,1858,1870],{},[1005,1847,1848,1850,1852,1854,1856],{},[1020,1849,1537],{},[1020,1851,1737],{},[1020,1853,1737],{},[1020,1855,1737],{},[1020,1857,1737],{},[1005,1859,1860,1862,1864,1866,1868],{},[1020,1861,1531],{},[1020,1863],{},[1020,1865],{},[1020,1867],{},[1020,1869],{},[1005,1871,1872,1874,1876,1878,1880],{},[1020,1873,1534],{},[1020,1875],{},[1020,1877],{},[1020,1879],{},[1020,1881],{},[554,1883,1884],{},"Помните, что мы стремимся обеспечить максимальную стоимость предметов в рюкзаке.\nЭта строка представляет текущую лучшую оценку максимума.\nИтак, на данный момент из этой строки следует, что для рюкзака с емкостью 4 кг максимальная стоимость предметов составит 1500₽.\nЭто решение неокончательно. В процессе работы алгоритма оценка будет уточняться.",[574,1886,1531],{"id":1887},"магнитофон",[554,1889,1890],{},"Займемся следующей строкой, которая относится к магнитофону.\nТеперь, когда вы перешли ко второй строке, появляется выбор между магнитофоном и гитарой.\nВ каждой строке можно взять предмет этой строки или предметы, находящиеся в верхних строках.\nТаким образом, сейчас нельзя выбрать ноутбук, но можно выбрать магнитофон и\u002Fили гитару.\nНачнем с первой ячейки (рюкзак с емкостью 1 кг).\nТекущая максимальная стоимость предметов, которые можно положить в рюкзак с емкостью 1 кг, составляет 1500₽.\nБрать магнитофон или нет?\nЕмкость рюкзака составляет 1 кг. Поместится туда магнитофон? Нет, он слишком тяжел!\nТак как магнитофон не помещается в рюкзак, максимальная оценка для 1-кг рюкзака остается равной 1500₽.",[999,1892,1893,1907],{},[1002,1894,1895],{},[1005,1896,1897,1899,1901,1903,1905],{},[1008,1898,1653],{},[1008,1900,988],{},[1008,1902,1658],{},[1008,1904,1055],{},[1008,1906,1025],{},[1015,1908,1909,1921,1933],{},[1005,1910,1911,1913,1915,1917,1919],{},[1020,1912,1537],{},[1020,1914,1737],{},[1020,1916,1737],{},[1020,1918,1737],{},[1020,1920,1737],{},[1005,1922,1923,1925,1927,1929,1931],{},[1020,1924,1531],{},[1020,1926,1737],{},[1020,1928],{},[1020,1930],{},[1020,1932],{},[1005,1934,1935,1937,1939,1941,1943],{},[1020,1936,1534],{},[1020,1938],{},[1020,1940],{},[1020,1942],{},[1020,1944],{},[554,1946,1947],{},"То же самое происходит со следующими двумя клетками.\nЕмкость этих рюкзаков составляет 2 и 3 кг соответственно.\nМаксимальная стоимость для обеих ячеек была равна 1500₽.",[999,1949,1950,1964],{},[1002,1951,1952],{},[1005,1953,1954,1956,1958,1960,1962],{},[1008,1955,1653],{},[1008,1957,988],{},[1008,1959,1658],{},[1008,1961,1055],{},[1008,1963,1025],{},[1015,1965,1966,1978,1990],{},[1005,1967,1968,1970,1972,1974,1976],{},[1020,1969,1537],{},[1020,1971,1737],{},[1020,1973,1737],{},[1020,1975,1737],{},[1020,1977,1737],{},[1005,1979,1980,1982,1984,1986,1988],{},[1020,1981,1531],{},[1020,1983,1737],{},[1020,1985,1737],{},[1020,1987,1737],{},[1020,1989],{},[1005,1991,1992,1994,1996,1998,2000],{},[1020,1993,1534],{},[1020,1995],{},[1020,1997],{},[1020,1999],{},[1020,2001],{},[554,2003,2004],{},"Магнитофон все равно не помещается, так что оценка остается неизменной.\nА если емкость рюкзака увеличивается до 4 кг?\nАга, магнитофон наконец-то войдет в рюкзак!\nСтарая максимальная стоимость была равна 1500₽, но если вместо гитары положить магнитофон, она увеличится до 3000₽!\nБерем магнитофон.",[999,2006,2007,2021],{},[1002,2008,2009],{},[1005,2010,2011,2013,2015,2017,2019],{},[1008,2012,1653],{},[1008,2014,988],{},[1008,2016,1658],{},[1008,2018,1055],{},[1008,2020,1025],{},[1015,2022,2023,2035,2048],{},[1005,2024,2025,2027,2029,2031,2033],{},[1020,2026,1537],{},[1020,2028,1737],{},[1020,2030,1737],{},[1020,2032,1737],{},[1020,2034,1737],{},[1005,2036,2037,2039,2041,2043,2045],{},[1020,2038,1531],{},[1020,2040,1737],{},[1020,2042,1737],{},[1020,2044,1737],{},[1020,2046,2047],{},"3000",[1005,2049,2050,2052,2054,2056,2058],{},[1020,2051,1534],{},[1020,2053],{},[1020,2055],{},[1020,2057],{},[1020,2059],{},[554,2061,2062],{},"Оценка только что обновилась! Имея рюкзак емкостью 4 кг, вы можете положить в него товары стоимостью по крайней мере 3000₽.\nИз таблицы видно, что оценка постепенно возрастает.",[574,2064,1534],{"id":2065},"ноутбук",[554,2067,2068],{},"А теперь проделаем то же для ноутбука! Ноутбук весит 3 кг, поэтому он не поместится в рюкзак с емкостью 1 или 2 кг.\nОценка для первых двух ячеек остается на уровне 1500₽.",[999,2070,2071,2085],{},[1002,2072,2073],{},[1005,2074,2075,2077,2079,2081,2083],{},[1008,2076,1653],{},[1008,2078,988],{},[1008,2080,1658],{},[1008,2082,1055],{},[1008,2084,1025],{},[1015,2086,2087,2099,2111],{},[1005,2088,2089,2091,2093,2095,2097],{},[1020,2090,1537],{},[1020,2092,1737],{},[1020,2094,1737],{},[1020,2096,1737],{},[1020,2098,1737],{},[1005,2100,2101,2103,2105,2107,2109],{},[1020,2102,1531],{},[1020,2104,1737],{},[1020,2106,1737],{},[1020,2108,1737],{},[1020,2110,2047],{},[1005,2112,2113,2115,2117,2119,2121],{},[1020,2114,1534],{},[1020,2116,1737],{},[1020,2118,1737],{},[1020,2120],{},[1020,2122],{},[554,2124,2125],{},"Для 3 кг старая оценка составляла 1500₽.\nНо теперь вы можете выбрать ноутбук, который стоит 2000₽.\nСледовательно, новая максимальная оценка равна 2000₽!",[999,2127,2128,2142],{},[1002,2129,2130],{},[1005,2131,2132,2134,2136,2138,2140],{},[1008,2133,1653],{},[1008,2135,988],{},[1008,2137,1658],{},[1008,2139,1055],{},[1008,2141,1025],{},[1015,2143,2144,2156,2168],{},[1005,2145,2146,2148,2150,2152,2154],{},[1020,2147,1537],{},[1020,2149,1737],{},[1020,2151,1737],{},[1020,2153,1737],{},[1020,2155,1737],{},[1005,2157,2158,2160,2162,2164,2166],{},[1020,2159,1531],{},[1020,2161,1737],{},[1020,2163,1737],{},[1020,2165,1737],{},[1020,2167,2047],{},[1005,2169,2170,2172,2174,2176,2179],{},[1020,2171,1534],{},[1020,2173,1737],{},[1020,2175,1737],{},[1020,2177,2178],{},"2000",[1020,2180],{},[554,2182,2183],{},"При 4 кг ситуация становится по-настоящему интересной. Это очень важная часть.\nВ настоящее время оценка составляет 3000₽.\nВ рюкзак можно положить ноутбук, но он стоит всего 2000₽.\nВ соответствии с последней оценкой в свободном месте емкостью в 1 кг можно разместить гитару стоимостью 1500₽.\nСледовательно, настоящее сравнение выглядит так: 3000₽(магнитофон) или (2000₽(ноутбук) + 1500₽(гитара)).\nЗачем мы вычисляем максимальную стоимость для рюкзаков меньшей емкости? Надеюсь, теперь всё ясно!\nЕсли в рюкзаке остается свободное место, вы можете использовать ответы на эти подзадачи для определения того, чем заполнить это пространство.\nВместо магнитофона лучше взять ноутбук + гитару за 3500₽.\nВ завершающем состоянии таблица выглядит так:",[999,2185,2186,2200],{},[1002,2187,2188],{},[1005,2189,2190,2192,2194,2196,2198],{},[1008,2191,1653],{},[1008,2193,988],{},[1008,2195,1658],{},[1008,2197,1055],{},[1008,2199,1025],{},[1015,2201,2202,2214,2226],{},[1005,2203,2204,2206,2208,2210,2212],{},[1020,2205,1537],{},[1020,2207,1737],{},[1020,2209,1737],{},[1020,2211,1737],{},[1020,2213,1737],{},[1005,2215,2216,2218,2220,2222,2224],{},[1020,2217,1531],{},[1020,2219,1737],{},[1020,2221,1737],{},[1020,2223,1737],{},[1020,2225,2047],{},[1005,2227,2228,2230,2232,2234,2236],{},[1020,2229,1534],{},[1020,2231,1737],{},[1020,2233,1737],{},[1020,2235,2178],{},[1020,2237,2238],{},"3500",[554,2240,2241],{},"Итак, мы получили ответ: максимальная стоимость товаров, которые поместятся в рюкзак, равна 3500₽ — для гитары и ноутбука.\nСтоимость каждой ячейки вычисляется по постоянной формуле, которая выглядит так:\nмаксимум из предыдущего элемента или стоимость текущего элемента плюс стоимость оставшегося пространства.\nТаким образом, в данной задаче объединяется решение двух подзадач для решения ещё одной большей задачи.",[1125,2243,2245],{"id":2244},"вопросы-по-задаче","Вопросы по задаче",[554,2247,2248],{},"Ответим на вопросы которую могут возникнуть.",[574,2250,2252],{"id":2251},"что-произойдет-при-добавлении-элемента","Что произойдет при добавлении элемента?",[554,2254,2255],{},"Представьте, что вы увидели четвертый предмет, который тоже можно засунуть в рюкзак!\nВместе со всем предыдущим добром можно также взять смартфон.\nПридется ли пересчитывать все заново с новым предметом? Нет.\nДинамическое программирование последовательно строит решение на основании вашей оценки.\nК настоящему моменту максимальные стоимости выглядят так:",[999,2257,2258,2272],{},[1002,2259,2260],{},[1005,2261,2262,2264,2266,2268,2270],{},[1008,2263,1653],{},[1008,2265,988],{},[1008,2267,1658],{},[1008,2269,1055],{},[1008,2271,1025],{},[1015,2273,2274,2286,2298],{},[1005,2275,2276,2278,2280,2282,2284],{},[1020,2277,1537],{},[1020,2279,1737],{},[1020,2281,1737],{},[1020,2283,1737],{},[1020,2285,1737],{},[1005,2287,2288,2290,2292,2294,2296],{},[1020,2289,1531],{},[1020,2291,1737],{},[1020,2293,1737],{},[1020,2295,1737],{},[1020,2297,2047],{},[1005,2299,2300,2302,2304,2306,2308],{},[1020,2301,1534],{},[1020,2303,1737],{},[1020,2305,1737],{},[1020,2307,2178],{},[1020,2309,2238],{},[554,2311,2312],{},"Это означает, что в рюкзак с емкостью 4 кг можно упаковать товары стоимостью до 3500₽.\nДобавим новую строку для смартфона.",[999,2314,2315,2329],{},[1002,2316,2317],{},[1005,2318,2319,2321,2323,2325,2327],{},[1008,2320,1653],{},[1008,2322,988],{},[1008,2324,1658],{},[1008,2326,1055],{},[1008,2328,1025],{},[1015,2330,2331,2343,2355,2367],{},[1005,2332,2333,2335,2337,2339,2341],{},[1020,2334,1537],{},[1020,2336,1737],{},[1020,2338,1737],{},[1020,2340,1737],{},[1020,2342,1737],{},[1005,2344,2345,2347,2349,2351,2353],{},[1020,2346,1531],{},[1020,2348,1737],{},[1020,2350,1737],{},[1020,2352,1737],{},[1020,2354,2047],{},[1005,2356,2357,2359,2361,2363,2365],{},[1020,2358,1534],{},[1020,2360,1737],{},[1020,2362,1737],{},[1020,2364,2178],{},[1020,2366,2238],{},[1005,2368,2369,2372,2374,2376,2378],{},[1020,2370,2371],{},"Смартфон",[1020,2373],{},[1020,2375],{},[1020,2377],{},[1020,2379,2380],{},"ответ",[554,2382,2383],{},"Оказывается, в таблице появляется новый максимум! Заполним последнюю строку.\nНачнем с первой ячейки. Смартфон сам по себе помещается в рюкзак с емкостью 1 кг.\nСтарый максимум был равен 1500₽, но Смартфон стоит 2000₽.\nЗначит, берем Смартфон.\nВ следующей далее можно разместить смартфон и гитару.",[999,2385,2386,2400],{},[1002,2387,2388],{},[1005,2389,2390,2392,2394,2396,2398],{},[1008,2391,1653],{},[1008,2393,988],{},[1008,2395,1658],{},[1008,2397,1055],{},[1008,2399,1025],{},[1015,2401,2402,2414,2426,2438],{},[1005,2403,2404,2406,2408,2410,2412],{},[1020,2405,1537],{},[1020,2407,1737],{},[1020,2409,1737],{},[1020,2411,1737],{},[1020,2413,1737],{},[1005,2415,2416,2418,2420,2422,2424],{},[1020,2417,1531],{},[1020,2419,1737],{},[1020,2421,1737],{},[1020,2423,1737],{},[1020,2425,2047],{},[1005,2427,2428,2430,2432,2434,2436],{},[1020,2429,1534],{},[1020,2431,1737],{},[1020,2433,1737],{},[1020,2435,2178],{},[1020,2437,2238],{},[1005,2439,2440,2442,2444,2446,2448],{},[1020,2441,2371],{},[1020,2443,2178],{},[1020,2445,2238],{},[1020,2447],{},[1020,2449],{},[554,2451,2452],{},"Для ячейки 3 ничего лучшего, чем снова взять смартфон вместе с гитарой, все равно не найдется.\nА вот в последней ячейке ситуация становится интересной. Текущий максимум до смартфона был равен 3500₽.\nСнова можно взять смартфон, и еще останется свободное место на 3 кг.\nНо эти 3 кг можно заполнить на 2000₽! 2000₽ от смартфона + 2000₽ из старой подзадачи: получается 4000₽. Новый максимум!\nВот как выглядит новая завершающая таблица:",[999,2454,2455,2469],{},[1002,2456,2457],{},[1005,2458,2459,2461,2463,2465,2467],{},[1008,2460,1653],{},[1008,2462,988],{},[1008,2464,1658],{},[1008,2466,1055],{},[1008,2468,1025],{},[1015,2470,2471,2483,2495,2507],{},[1005,2472,2473,2475,2477,2479,2481],{},[1020,2474,1537],{},[1020,2476,1737],{},[1020,2478,1737],{},[1020,2480,1737],{},[1020,2482,1737],{},[1005,2484,2485,2487,2489,2491,2493],{},[1020,2486,1531],{},[1020,2488,1737],{},[1020,2490,1737],{},[1020,2492,1737],{},[1020,2494,2047],{},[1005,2496,2497,2499,2501,2503,2505],{},[1020,2498,1534],{},[1020,2500,1737],{},[1020,2502,1737],{},[1020,2504,2178],{},[1020,2506,2238],{},[1005,2508,2509,2511,2513,2515,2517],{},[1020,2510,2371],{},[1020,2512,2178],{},[1020,2514,2238],{},[1020,2516,2238],{},[1020,2518,2519],{},"4000",[554,2521,2522],{},"Вопрос: может ли значение в столбце уменьшиться? Ответ: нет. При каждой итерации сохраняется текущая оценка максимума.\nЭта оценка ни при каких условиях не может быть меньше предыдущей!",[574,2524,2526],{"id":2525},"что-произойдет-при-изменении-порядка-строк","Что произойдет при изменении порядка строк?",[554,2528,2529],{},"Допустим, строки заполняются в другом порядке: магнитофон, ноутбук, гитара.\nКак будет выглядеть таблица? Изменится ли ответ? Заполните таблицу самостоятельно и убедитесь — ответ не изменился.\nОтвет не зависит от порядка строк.",[574,2531,2533],{"id":2532},"можно-ли-заполнять-таблицу-по-столбцам-а-не-по-строкам","Можно ли заполнять таблицу по столбцам, а не по строкам?",[554,2535,2536],{},"В данной задаче это ни на что не влияет, но в других задачах возможны изменения.",[574,2538,2540],{"id":2539},"что-произойдет-при-добавлении-меньшего-элемента","Что произойдет при добавлении меньшего элемента?",[554,2542,2543],{},"Допустим, вы можете выбрать ожерелье, которое весит 0,5 кг и стоит 1000₽.\nИзначально наша структура таблицы предполагает, что все веса являются целыми числами.\nТеперь вы решаете взять ожерелье. Остается еще 3,5 кг.\nКакую максимальную стоимость можно разместить в объеме 3,5 кг? Неизвестно!\nМы вычисляли стоимость только для рюкзаков с емкостью 1, 2, 3 и 4 кг.\nТеперь придется определять стоимость для рюкзака на 3,5 кг.\nИз-за ожерелья приходится повысить точность представления весов, поэтому таблица должна измениться.",[999,2545,2546,2572],{},[1002,2547,2548],{},[1005,2549,2550,2552,2555,2557,2560,2562,2565,2567,2570],{},[1008,2551,1653],{},[1008,2553,2554],{},"0.5",[1008,2556,988],{},[1008,2558,2559],{},"1.5",[1008,2561,1658],{},[1008,2563,2564],{},"2.5",[1008,2566,1055],{},[1008,2568,2569],{},"3.5",[1008,2571,1025],{},[1015,2573,2574,2594,2614,2634],{},[1005,2575,2576,2578,2580,2582,2584,2586,2588,2590,2592],{},[1020,2577,1537],{},[1020,2579],{},[1020,2581],{},[1020,2583],{},[1020,2585],{},[1020,2587],{},[1020,2589],{},[1020,2591],{},[1020,2593],{},[1005,2595,2596,2598,2600,2602,2604,2606,2608,2610,2612],{},[1020,2597,1531],{},[1020,2599],{},[1020,2601],{},[1020,2603],{},[1020,2605],{},[1020,2607],{},[1020,2609],{},[1020,2611],{},[1020,2613],{},[1005,2615,2616,2618,2620,2622,2624,2626,2628,2630,2632],{},[1020,2617,1534],{},[1020,2619],{},[1020,2621],{},[1020,2623],{},[1020,2625],{},[1020,2627],{},[1020,2629],{},[1020,2631],{},[1020,2633],{},[1005,2635,2636,2639,2641,2643,2645,2647,2649,2651,2653],{},[1020,2637,2638],{},"Ожерелье",[1020,2640],{},[1020,2642],{},[1020,2644],{},[1020,2646],{},[1020,2648],{},[1020,2650],{},[1020,2652],{},[1020,2654],{},[574,2656,2658],{"id":2657},"можно-ли-взять-часть-предмета","Можно ли взять часть предмета?",[554,2660,2661],{},"Допустим, вы наполняете рюкзак в продуктовом магазине. Вы можете взять мешки с чечевицей и рисом.\nЕсли весь мешок не помещается, его можно открыть и отсыпать столько, сколько унесете.\nВ этом случае вы уже не действуете по принципу «все или ничего» — можно взять только часть предмета.\nКак решить такую задачу методом динамического программирования?\nОтвет: никак. В решении, полученном методом динамического программирования, вы либо берете предмет, либо не берете.\nАлгоритм не предусматривает возможности взять половину предмета.\nОднако проблема легко решается с помощью жадного алгоритма!\nСначала вы берете самый ценный предмет — настолько бóльшую его часть, насколько возможно.\nКогда самый ценный предмет будет исчерпан, вы берете максимально возможную часть следующего по ценности предмета и т.д.",[566,2663,2665],{"id":2664},"оптимизация-туристического-маршрута","Оптимизация туристического маршрута",[554,2667,2668],{},"Представьте, что вы приехали в Лондон на выходные. У вас два дня, а мест, которые хочется посетить, слишком много.\nПобывать везде не получится, поэтому вы составляете список.\nДля каждой достопримечательности, которую вы захотите увидеть, вы указываете, сколько времени займет осмотр и насколько сильно вы хотите ее увидеть.\nСможете ли вы построить оптимальный туристический маршрут на основании этого списка?\nДа это все та же задача о рюкзаке! Вместо ограниченной емкости рюкзака — ограниченное время.\nВместо магнитофонов и ноутбуков — список мест, которые вы хотите посетить.",[999,2670,2671,2683],{},[1002,2672,2673],{},[1005,2674,2675,2678,2681],{},[1008,2676,2677],{},"Достопримечательность",[1008,2679,2680],{},"Время",[1008,2682,1013],{},[1015,2684,2685,2696,2707,2717,2727],{},[1005,2686,2687,2690,2693],{},[1020,2688,2689],{},"Вестминстерское аббатство",[1020,2691,2692],{},"1\u002F2 дня",[1020,2694,2695],{},"7",[1005,2697,2698,2701,2704],{},[1020,2699,2700],{},"Национальная галерея",[1020,2702,2703],{},"1 день",[1020,2705,2706],{},"9",[1005,2708,2709,2712,2714],{},[1020,2710,2711],{},"Театр",[1020,2713,2692],{},[1020,2715,2716],{},"6",[1005,2718,2719,2722,2725],{},[1020,2720,2721],{},"Музей",[1020,2723,2724],{},"2 дня",[1020,2726,2706],{},[1005,2728,2729,2732,2734],{},[1020,2730,2731],{},"Собор св. Павла",[1020,2733,2692],{},[1020,2735,2736],{},"8",[554,2738,2739],{},"Нарисуйте таблицу динамического программирования для списка, прежде чем двигаться дальше.\nВот как должна выглядеть эта таблица:",[999,2741,2742,2758],{},[1002,2743,2744],{},[1005,2745,2746,2748,2751,2753,2756],{},[1008,2747,1653],{},[1008,2749,2750],{},"1\u002F2",[1008,2752,988],{},[1008,2754,2755],{},"1 1\u002F2",[1008,2757,1658],{},[1015,2759,2760,2773,2785,2798,2810],{},[1005,2761,2762,2765,2767,2769,2771],{},[1020,2763,2764],{},"Вестминистер",[1020,2766],{},[1020,2768],{},[1020,2770],{},[1020,2772],{},[1005,2774,2775,2777,2779,2781,2783],{},[1020,2776,2711],{},[1020,2778],{},[1020,2780],{},[1020,2782],{},[1020,2784],{},[1005,2786,2787,2790,2792,2794,2796],{},[1020,2788,2789],{},"Галерея",[1020,2791],{},[1020,2793],{},[1020,2795],{},[1020,2797],{},[1005,2799,2800,2802,2804,2806,2808],{},[1020,2801,2721],{},[1020,2803],{},[1020,2805],{},[1020,2807],{},[1020,2809],{},[1005,2811,2812,2815,2817,2819,2821],{},[1020,2813,2814],{},"Собор",[1020,2816],{},[1020,2818],{},[1020,2820],{},[1020,2822],{},[554,2824,2825],{},"Вы изобразили ее правильно? Теперь заполните. Какие достопримечательности вы выберете? Ответ: аббатство, галерея, собор.",[999,2827,2828,2842],{},[1002,2829,2830],{},[1005,2831,2832,2834,2836,2838,2840],{},[1008,2833,1653],{},[1008,2835,2750],{},[1008,2837,988],{},[1008,2839,2755],{},[1008,2841,1658],{},[1015,2843,2844,2856,2869,2883,2895],{},[1005,2845,2846,2848,2850,2852,2854],{},[1020,2847,2764],{},[1020,2849,2695],{},[1020,2851,2695],{},[1020,2853,2695],{},[1020,2855,2695],{},[1005,2857,2858,2860,2862,2865,2867],{},[1020,2859,2711],{},[1020,2861,2695],{},[1020,2863,2864],{},"13",[1020,2866,2864],{},[1020,2868,2864],{},[1005,2870,2871,2873,2875,2877,2880],{},[1020,2872,2789],{},[1020,2874,2695],{},[1020,2876,2864],{},[1020,2878,2879],{},"16",[1020,2881,2882],{},"22",[1005,2884,2885,2887,2889,2891,2893],{},[1020,2886,2721],{},[1020,2888,2695],{},[1020,2890,2864],{},[1020,2892,2879],{},[1020,2894,2882],{},[1005,2896,2897,2899,2901,2904,2907],{},[1020,2898,2814],{},[1020,2900,2736],{},[1020,2902,2903],{},"15",[1020,2905,2906],{},"21",[1020,2908,2909],{},"24",[574,2911,2913],{"id":2912},"взаимозависимые-элементы","Взаимозависимые элементы",[554,2915,2916],{},"Предположим, вы хотите посетить Париж и добавили в свой список пару элементов.",[999,2918,2919,2929],{},[1002,2920,2921],{},[1005,2922,2923,2925,2927],{},[1008,2924,2677],{},[1008,2926,2680],{},[1008,2928,1013],{},[1015,2930,2931,2939,2947,2955,2963,2971,2981,2990],{},[1005,2932,2933,2935,2937],{},[1020,2934,2689],{},[1020,2936,2692],{},[1020,2938,2695],{},[1005,2940,2941,2943,2945],{},[1020,2942,2700],{},[1020,2944,2703],{},[1020,2946,2706],{},[1005,2948,2949,2951,2953],{},[1020,2950,2711],{},[1020,2952,2692],{},[1020,2954,2716],{},[1005,2956,2957,2959,2961],{},[1020,2958,2721],{},[1020,2960,2724],{},[1020,2962,2706],{},[1005,2964,2965,2967,2969],{},[1020,2966,2731],{},[1020,2968,2692],{},[1020,2970,2736],{},[1005,2972,2973,2976,2979],{},[1020,2974,2975],{},"Эйфелева башня",[1020,2977,2978],{},"1 1\u002F2 дня",[1020,2980,2736],{},[1005,2982,2983,2986,2988],{},[1020,2984,2985],{},"Лувр",[1020,2987,2978],{},[1020,2989,2706],{},[1005,2991,2992,2995,2997],{},[1020,2993,2994],{},"Нотр-дам",[1020,2996,2978],{},[1020,2998,2695],{},[554,3000,3001],{},"На их посещение потребуется много времени, потому что сначала придется приехать из Лондона в Париж.\nПереезд отнимает полдня. Если вы захотите посмотреть все 3 достопримечательности, осмотр займет 4,5 дня.\nНебольшая поправка: не обязательно приезжать в Париж ради каждой достопримечательности.\nПосле того как вы там окажетесь, каждый последующий элемент займет всего один день.\nСледовательно, потребуется 1 день на каждую достопримечательность + 1 день на переезды = 3,5 дня, а не 4,5.",[554,3003,3004],{},"Если вы положите Эйфелеву башню в свой «рюкзак», то Лувр станет «дешевле» — он займет всего 1 день вместо 1,5.\nКак смоделировать это обстоятельство в динамическом программировании? Ответ: никак.\nДинамическое программирование — мощный метод, способный решать подзадачи и использовать полученные ответы для решения большой задачи.\nДинамическое программирование работает только в том случае, если каждая подзадача автономна, то есть не зависит от других подзадач.\nИз этого следует, что учесть поездки в Париж в алгоритме динамического программирования не удастся.",[574,3006,3008],{"id":3007},"может-ли-оказаться-что-решение-требует-более-двух-подрюкзаков","Может ли оказаться, что решение требует более двух «подрюкзаков»?",[554,3010,3011],{},"Может оказаться, что в лучшем решении должны отбираться больше двух элементов.\nВ текущем варианте алгоритма объединяются не более двух «подрюкзаков» — больше двух их не бывает.\nОднако вполне возможно, что у этих «подрюкзаков» будут собственные «подрюкзаки».",[574,3013,3015],{"id":3014},"возможно-ли-что-при-лучшем-решении-в-рюкзаке-остается-пустое-место","Возможно ли, что при лучшем решении в рюкзаке остается пустое место?",[554,3017,3018],{},"Да. Представьте, что вы можете также положить в рюкзак бриллиант.\nБриллиант очень крупный: он весит целых 3,5 кг и стоит 1 миллиард долларов — намного больше, чем любые другие предметы.\nБезусловно, нужно брать именно его!\nНо в рюкзаке остается еще пустое место на 0,5 кг, и в нем ничего не поместится.",[566,3020,3022],{"id":3021},"выводы","Выводы",[554,3024,3025],{},"Мы рассмотрели одну задачу динамического программирования. Какие выводы из нее можно сделать?",[1060,3027,3028,3031],{},[1063,3029,3030],{},"Динамическое программирование применяется для оптимизации какой-либо характеристики при заданных ограничениях. В задаче о рюкзаке требуется максимизировать стоимость отобранных предметов с ограничениями по емкости рюкзака.",[1063,3032,3033],{},"Динамическое программирование работает только в ситуациях, в которых задача может быть разбита на автономные подзадачи, не зависящие друг от друга.",[554,3035,3036],{},"Построить решение на базе динамического программирования бывает непросто. Несколько общих рекомендаций:",[1060,3038,3039,3042,3045],{},[1063,3040,3041],{},"в каждом решении из области динамического программирования строится таблица;",[1063,3043,3044],{},"значения ячеек таблицы обычно соответствуют оптимизируемой характеристике. Для задачи о рюкзаке значения представляли общую стоимость товаров;",[1063,3046,3047],{},"каждая ячейка представляет подзадачу, поэтому вы должны подумать о том, как разбить задачу на подзадачи. Это поможет вам определиться с осями.",[566,3049,3051],{"id":3050},"ещё-пример-задачи","Ещё пример задачи",[554,3053,3054],{},"Допустим, вы открыли сайт dictionary.com. Пользователь вводит слово, а сайт возвращает определение.\nНо если пользователь ввел несуществующее слово, нужно предположить, какое слово имелось в виду.\nАлексей ищет определение «fish», но он случайно ввел «hish». Такого слова в словаре нет, но зато у вас есть список похожих слов.\nКакое слово он хотел ввести на самом деле: fish или например, vista?",[574,3056,3058],{"id":3057},"построение-таблицы","Построение таблицы",[554,3060,3061],{},"Как должна выглядеть таблица для этой задачи? Вы должны ответить на следующие вопросы.",[1060,3063,3064,3067,3070],{},[1063,3065,3066],{},"Какие значения должны содержаться в ячейках?",[1063,3068,3069],{},"Как разбить эту задачу на подзадачи?",[1063,3071,3072],{},"Каков смысл осей таблицы?",[554,3074,3075],{},"В динамическом программировании вы пытаетесь максимизировать некоторую характеристику.\nВ данном случае ищется самая длинная подстрока, общая в двух словах.\nКакую общую подстроку содержат hish и fish? А как насчет hish и vista? Именно это требуется вычислить.\nКак говорилось ранее, значения в ячейках обычно представляют ту характеристику, которую вы пытаетесь оптимизировать.\nВероятно, в данном случае этой характеристикой будет число: длина самой длинной подстроки, общей для двух строк.\nКак разделить эту задачу на подзадачи? Например, можно заняться сравнением подстрок.\nВместо того чтобы сравнивать hish и fish, можно сначала сравнить his и fis.\nКаждая ячейка будет содержать длину самой длинной подстроки, общей для двух подстрок.\nТакое решение также подсказывает, что строками и столбцами таблицы, вероятно, будут два слова.\nА значит, таблица будет выглядеть примерно так:",[999,3077,3078,3095],{},[1002,3079,3080],{},[1005,3081,3082,3084,3087,3090,3093],{},[1008,3083,1653],{},[1008,3085,3086],{},"H",[1008,3088,3089],{},"I",[1008,3091,3092],{},"S",[1008,3094,3086],{},[1015,3096,3097,3110,3122,3134],{},[1005,3098,3099,3102,3104,3106,3108],{},[1020,3100,3101],{},"F",[1020,3103],{},[1020,3105],{},[1020,3107],{},[1020,3109],{},[1005,3111,3112,3114,3116,3118,3120],{},[1020,3113,3089],{},[1020,3115],{},[1020,3117],{},[1020,3119],{},[1020,3121],{},[1005,3123,3124,3126,3128,3130,3132],{},[1020,3125,3092],{},[1020,3127],{},[1020,3129],{},[1020,3131],{},[1020,3133],{},[1005,3135,3136,3138,3140,3142,3144],{},[1020,3137,3086],{},[1020,3139],{},[1020,3141],{},[1020,3143],{},[1020,3145],{},[574,3147,3149],{"id":3148},"заполнение-таблицы","Заполнение таблицы",[554,3151,3152],{},"Сейчас вы уже достаточно хорошо представляете, как должна выглядеть таблица.\nПо какой формуле заполняются ячейки таблицы?\nМы можем немного упростить свою задачу, потому что уже знаем решение — у hish и fish имеется общая подстрока длины 3: ish.\nОднако этот факт ничего не говорит о том, какая формула должна использоваться.\nПо правде говоря, простого способа вычислить формулу для данного случая не существует.\nВам придется экспериментировать и искать работоспособное решение.\nИногда алгоритм предоставляет не точный рецепт, а основу, на которую вы наращиваете свою идею.\nПопробуйте предложить решение этой задачи самостоятельно. Часть таблицы выглядит так:",[999,3154,3155,3169],{},[1002,3156,3157],{},[1005,3158,3159,3161,3163,3165,3167],{},[1008,3160,1653],{},[1008,3162,3086],{},[1008,3164,3089],{},[1008,3166,3092],{},[1008,3168,3086],{},[1015,3170,3171,3183,3195,3207],{},[1005,3172,3173,3175,3177,3179,3181],{},[1020,3174,3101],{},[1020,3176,642],{},[1020,3178,642],{},[1020,3180],{},[1020,3182],{},[1005,3184,3185,3187,3189,3191,3193],{},[1020,3186,3089],{},[1020,3188],{},[1020,3190],{},[1020,3192],{},[1020,3194],{},[1005,3196,3197,3199,3201,3203,3205],{},[1020,3198,3092],{},[1020,3200],{},[1020,3202],{},[1020,3204,1658],{},[1020,3206,642],{},[1005,3208,3209,3211,3213,3215,3217],{},[1020,3210,3086],{},[1020,3212],{},[1020,3214],{},[1020,3216],{},[1020,3218,1055],{},[554,3220,3221],{},"Попытайтесь вывести формулу самостоятельно, прежде чем продолжить читать.",[574,3223,3225],{"id":3224},"решение","Решение",[554,3227,3228],{},"Итоговая версия таблицы выглядит так:",[999,3230,3231,3245],{},[1002,3232,3233],{},[1005,3234,3235,3237,3239,3241,3243],{},[1008,3236,1653],{},[1008,3238,3086],{},[1008,3240,3089],{},[1008,3242,3092],{},[1008,3244,3086],{},[1015,3246,3247,3259,3271,3283],{},[1005,3248,3249,3251,3253,3255,3257],{},[1020,3250,3101],{},[1020,3252,642],{},[1020,3254,642],{},[1020,3256,642],{},[1020,3258,642],{},[1005,3260,3261,3263,3265,3267,3269],{},[1020,3262,3089],{},[1020,3264,642],{},[1020,3266,988],{},[1020,3268,642],{},[1020,3270,642],{},[1005,3272,3273,3275,3277,3279,3281],{},[1020,3274,3092],{},[1020,3276,642],{},[1020,3278,642],{},[1020,3280,1658],{},[1020,3282,642],{},[1005,3284,3285,3287,3289,3291,3293],{},[1020,3286,3086],{},[1020,3288,988],{},[1020,3290,642],{},[1020,3292,642],{},[1020,3294,1055],{},[554,3296,3297],{},"Формула заполнения ячеек:",[1143,3299,3300,3303],{},[1063,3301,3302],{},"Если буквы не совпадают, значение равно 0;",[1063,3304,3305],{},"Если буквы совпадают, то значение равно значению ячейки наверху слева +1.",[554,3307,3308],{},"На Python эта формула реализуется так:",[3310,3311,3315],"pre",{"className":3312,"code":3313,"language":3314,"meta":982,"style":982},"language-python shiki shiki-themes github-light","dp_table_hish = [\"h\", \"i\", \"s\", \"h\"]\ndp_table_fish = [\"f\", \"i\", \"s\", \"h\"]\ndp_table = [[0 for i in range(len(dp_table_hish))] for i in range(len(dp_table_fish))]\nfor i in range(0, len(dp_table_fish)):\n    for j in range(0, len(dp_table_hish)):\n        if dp_table_hish[j] == dp_table_fish[i]:  # Буквы совпадают\n            dp_table[i][j] = dp_table[i-1][j-1] + 1\n        else:  # Буквы не совпали\n            dp_table[i][j] = 0\nfor i in dp_table:\n    print(i)\n","python",[3316,3317,3318,3356,3382,3432,3453,3476,3495,3526,3538,3548,3560],"code",{"__ignoreMap":982},[3319,3320,3323,3327,3331,3334,3338,3341,3344,3346,3349,3351,3353],"span",{"class":3321,"line":3322},"line",1,[3319,3324,3326],{"class":3325},"sgsFI","dp_table_hish ",[3319,3328,3330],{"class":3329},"sD7c4","=",[3319,3332,3333],{"class":3325}," [",[3319,3335,3337],{"class":3336},"sYBdl","\"h\"",[3319,3339,3340],{"class":3325},", ",[3319,3342,3343],{"class":3336},"\"i\"",[3319,3345,3340],{"class":3325},[3319,3347,3348],{"class":3336},"\"s\"",[3319,3350,3340],{"class":3325},[3319,3352,3337],{"class":3336},[3319,3354,3355],{"class":3325},"]\n",[3319,3357,3358,3361,3363,3365,3368,3370,3372,3374,3376,3378,3380],{"class":3321,"line":1443},[3319,3359,3360],{"class":3325},"dp_table_fish ",[3319,3362,3330],{"class":3329},[3319,3364,3333],{"class":3325},[3319,3366,3367],{"class":3336},"\"f\"",[3319,3369,3340],{"class":3325},[3319,3371,3343],{"class":3336},[3319,3373,3340],{"class":3325},[3319,3375,3348],{"class":3336},[3319,3377,3340],{"class":3325},[3319,3379,3337],{"class":3336},[3319,3381,3355],{"class":3325},[3319,3383,3384,3387,3389,3392,3395,3398,3401,3404,3407,3410,3413,3416,3419,3421,3423,3425,3427,3429],{"class":3321,"line":1458},[3319,3385,3386],{"class":3325},"dp_table ",[3319,3388,3330],{"class":3329},[3319,3390,3391],{"class":3325}," [[",[3319,3393,642],{"class":3394},"sYu0t",[3319,3396,3397],{"class":3329}," for",[3319,3399,3400],{"class":3325}," i ",[3319,3402,3403],{"class":3329},"in",[3319,3405,3406],{"class":3394}," range",[3319,3408,3409],{"class":3325},"(",[3319,3411,3412],{"class":3394},"len",[3319,3414,3415],{"class":3325},"(dp_table_hish))] ",[3319,3417,3418],{"class":3329},"for",[3319,3420,3400],{"class":3325},[3319,3422,3403],{"class":3329},[3319,3424,3406],{"class":3394},[3319,3426,3409],{"class":3325},[3319,3428,3412],{"class":3394},[3319,3430,3431],{"class":3325},"(dp_table_fish))]\n",[3319,3433,3434,3436,3438,3440,3442,3444,3446,3448,3450],{"class":3321,"line":1449},[3319,3435,3418],{"class":3329},[3319,3437,3400],{"class":3325},[3319,3439,3403],{"class":3329},[3319,3441,3406],{"class":3394},[3319,3443,3409],{"class":3325},[3319,3445,642],{"class":3394},[3319,3447,3340],{"class":3325},[3319,3449,3412],{"class":3394},[3319,3451,3452],{"class":3325},"(dp_table_fish)):\n",[3319,3454,3455,3458,3461,3463,3465,3467,3469,3471,3473],{"class":3321,"line":1444},[3319,3456,3457],{"class":3329},"    for",[3319,3459,3460],{"class":3325}," j ",[3319,3462,3403],{"class":3329},[3319,3464,3406],{"class":3394},[3319,3466,3409],{"class":3325},[3319,3468,642],{"class":3394},[3319,3470,3340],{"class":3325},[3319,3472,3412],{"class":3394},[3319,3474,3475],{"class":3325},"(dp_table_hish)):\n",[3319,3477,3479,3482,3485,3488,3491],{"class":3321,"line":3478},6,[3319,3480,3481],{"class":3329},"        if",[3319,3483,3484],{"class":3325}," dp_table_hish[j] ",[3319,3486,3487],{"class":3329},"==",[3319,3489,3490],{"class":3325}," dp_table_fish[i]:  ",[3319,3492,3494],{"class":3493},"sAwPA","# Буквы совпадают\n",[3319,3496,3498,3501,3503,3506,3508,3510,3513,3515,3517,3520,3523],{"class":3321,"line":3497},7,[3319,3499,3500],{"class":3325},"            dp_table[i][j] ",[3319,3502,3330],{"class":3329},[3319,3504,3505],{"class":3325}," dp_table[i",[3319,3507,1653],{"class":3329},[3319,3509,988],{"class":3394},[3319,3511,3512],{"class":3325},"][j",[3319,3514,1653],{"class":3329},[3319,3516,988],{"class":3394},[3319,3518,3519],{"class":3325},"] ",[3319,3521,3522],{"class":3329},"+",[3319,3524,3525],{"class":3394}," 1\n",[3319,3527,3529,3532,3535],{"class":3321,"line":3528},8,[3319,3530,3531],{"class":3329},"        else",[3319,3533,3534],{"class":3325},":  ",[3319,3536,3537],{"class":3493},"# Буквы не совпали\n",[3319,3539,3541,3543,3545],{"class":3321,"line":3540},9,[3319,3542,3500],{"class":3325},[3319,3544,3330],{"class":3329},[3319,3546,3547],{"class":3394}," 0\n",[3319,3549,3551,3553,3555,3557],{"class":3321,"line":3550},10,[3319,3552,3418],{"class":3329},[3319,3554,3400],{"class":3325},[3319,3556,3403],{"class":3329},[3319,3558,3559],{"class":3325}," dp_table:\n",[3319,3561,3563,3566],{"class":3321,"line":3562},11,[3319,3564,3565],{"class":3394},"    print",[3319,3567,3568],{"class":3325},"(i)\n",[554,3570,3571],{},"Аналогично для строк hish и vista:",[3310,3573,3575],{"className":3312,"code":3574,"language":3314,"meta":982,"style":982},"dp_table_hish = [\"h\", \"i\", \"s\", \"h\"]\ndp_table_vista = [\"v\", \"i\", \"s\", \"t\", \"a\"]\ndp_table = [[0 for i in range(len(dp_table_hish))] for i in range(len(dp_table_vista))]\nfor i in range(0, len(dp_table_vista)):\n    for j in range(0, len(dp_table_hish)):\n        if dp_table_hish[j] == dp_table_vista[i]:\n            dp_table[i][j] = dp_table[i-1][j-1] + 1\n        else:\n            dp_table[i][j] = 0\nfor i in dp_table:\n    print(i)\n",[3316,3576,3577,3601,3633,3672,3693,3713,3724,3748,3755,3763,3773],{"__ignoreMap":982},[3319,3578,3579,3581,3583,3585,3587,3589,3591,3593,3595,3597,3599],{"class":3321,"line":3322},[3319,3580,3326],{"class":3325},[3319,3582,3330],{"class":3329},[3319,3584,3333],{"class":3325},[3319,3586,3337],{"class":3336},[3319,3588,3340],{"class":3325},[3319,3590,3343],{"class":3336},[3319,3592,3340],{"class":3325},[3319,3594,3348],{"class":3336},[3319,3596,3340],{"class":3325},[3319,3598,3337],{"class":3336},[3319,3600,3355],{"class":3325},[3319,3602,3603,3606,3608,3610,3613,3615,3617,3619,3621,3623,3626,3628,3631],{"class":3321,"line":1443},[3319,3604,3605],{"class":3325},"dp_table_vista ",[3319,3607,3330],{"class":3329},[3319,3609,3333],{"class":3325},[3319,3611,3612],{"class":3336},"\"v\"",[3319,3614,3340],{"class":3325},[3319,3616,3343],{"class":3336},[3319,3618,3340],{"class":3325},[3319,3620,3348],{"class":3336},[3319,3622,3340],{"class":3325},[3319,3624,3625],{"class":3336},"\"t\"",[3319,3627,3340],{"class":3325},[3319,3629,3630],{"class":3336},"\"a\"",[3319,3632,3355],{"class":3325},[3319,3634,3635,3637,3639,3641,3643,3645,3647,3649,3651,3653,3655,3657,3659,3661,3663,3665,3667,3669],{"class":3321,"line":1458},[3319,3636,3386],{"class":3325},[3319,3638,3330],{"class":3329},[3319,3640,3391],{"class":3325},[3319,3642,642],{"class":3394},[3319,3644,3397],{"class":3329},[3319,3646,3400],{"class":3325},[3319,3648,3403],{"class":3329},[3319,3650,3406],{"class":3394},[3319,3652,3409],{"class":3325},[3319,3654,3412],{"class":3394},[3319,3656,3415],{"class":3325},[3319,3658,3418],{"class":3329},[3319,3660,3400],{"class":3325},[3319,3662,3403],{"class":3329},[3319,3664,3406],{"class":3394},[3319,3666,3409],{"class":3325},[3319,3668,3412],{"class":3394},[3319,3670,3671],{"class":3325},"(dp_table_vista))]\n",[3319,3673,3674,3676,3678,3680,3682,3684,3686,3688,3690],{"class":3321,"line":1449},[3319,3675,3418],{"class":3329},[3319,3677,3400],{"class":3325},[3319,3679,3403],{"class":3329},[3319,3681,3406],{"class":3394},[3319,3683,3409],{"class":3325},[3319,3685,642],{"class":3394},[3319,3687,3340],{"class":3325},[3319,3689,3412],{"class":3394},[3319,3691,3692],{"class":3325},"(dp_table_vista)):\n",[3319,3694,3695,3697,3699,3701,3703,3705,3707,3709,3711],{"class":3321,"line":1444},[3319,3696,3457],{"class":3329},[3319,3698,3460],{"class":3325},[3319,3700,3403],{"class":3329},[3319,3702,3406],{"class":3394},[3319,3704,3409],{"class":3325},[3319,3706,642],{"class":3394},[3319,3708,3340],{"class":3325},[3319,3710,3412],{"class":3394},[3319,3712,3475],{"class":3325},[3319,3714,3715,3717,3719,3721],{"class":3321,"line":3478},[3319,3716,3481],{"class":3329},[3319,3718,3484],{"class":3325},[3319,3720,3487],{"class":3329},[3319,3722,3723],{"class":3325}," dp_table_vista[i]:\n",[3319,3725,3726,3728,3730,3732,3734,3736,3738,3740,3742,3744,3746],{"class":3321,"line":3497},[3319,3727,3500],{"class":3325},[3319,3729,3330],{"class":3329},[3319,3731,3505],{"class":3325},[3319,3733,1653],{"class":3329},[3319,3735,988],{"class":3394},[3319,3737,3512],{"class":3325},[3319,3739,1653],{"class":3329},[3319,3741,988],{"class":3394},[3319,3743,3519],{"class":3325},[3319,3745,3522],{"class":3329},[3319,3747,3525],{"class":3394},[3319,3749,3750,3752],{"class":3321,"line":3528},[3319,3751,3531],{"class":3329},[3319,3753,3754],{"class":3325},":\n",[3319,3756,3757,3759,3761],{"class":3321,"line":3540},[3319,3758,3500],{"class":3325},[3319,3760,3330],{"class":3329},[3319,3762,3547],{"class":3394},[3319,3764,3765,3767,3769,3771],{"class":3321,"line":3550},[3319,3766,3418],{"class":3329},[3319,3768,3400],{"class":3325},[3319,3770,3403],{"class":3329},[3319,3772,3559],{"class":3325},[3319,3774,3775,3777],{"class":3321,"line":3562},[3319,3776,3565],{"class":3394},[3319,3778,3568],{"class":3325},[554,3780,3781],{},"Таблица:",[999,3783,3784,3798],{},[1002,3785,3786],{},[1005,3787,3788,3790,3792,3794,3796],{},[1008,3789,1653],{},[1008,3791,3086],{},[1008,3793,3089],{},[1008,3795,3092],{},[1008,3797,3086],{},[1015,3799,3800,3813,3825,3837,3850],{},[1005,3801,3802,3805,3807,3809,3811],{},[1020,3803,3804],{},"V",[1020,3806,642],{},[1020,3808,642],{},[1020,3810,642],{},[1020,3812,642],{},[1005,3814,3815,3817,3819,3821,3823],{},[1020,3816,3089],{},[1020,3818,642],{},[1020,3820,988],{},[1020,3822,642],{},[1020,3824,642],{},[1005,3826,3827,3829,3831,3833,3835],{},[1020,3828,3092],{},[1020,3830,642],{},[1020,3832,642],{},[1020,3834,1658],{},[1020,3836,642],{},[1005,3838,3839,3842,3844,3846,3848],{},[1020,3840,3841],{},"T",[1020,3843,642],{},[1020,3845,642],{},[1020,3847,642],{},[1020,3849,642],{},[1005,3851,3852,3855,3857,3859,3861],{},[1020,3853,3854],{},"A",[1020,3856,642],{},[1020,3858,642],{},[1020,3860,642],{},[1020,3862,642],{},[554,3864,3865],{},"Важный момент: в этой задаче окончательное решение далеко не всегда находится в последней ячейке!\nВ задаче о рюкзаке последняя ячейка всегда содержит окончательное решение.\nНо в задаче поиска самой длинной общей подстроки решение определяется самым большим числом в таблице — и это может быть не последняя, а какая-то другая ячейка.\nВернемся к исходному вопросу: какая строка ближе к hish? У строк hish и fish есть общая подстрока длиной в три буквы.\nУ hish и vista есть общая подстрока из двух букв. Скорее всего, Алексей хотел ввести строку fish.",[566,3867,3869],{"id":3868},"самая-длинная-общая-подпоследовательность","Самая длинная общая подпоследовательность",[554,3871,3872],{},"Предположим, Алексей ввел строку fosh. Какое слово он имел в виду: fish или fort?\nСравним строки, по способу выше, длину общей подстроки.\nОкажется, что длина подстрок одинакова: две буквы! Но fosh при этом ближе к fish.\nМы сравниваем самую длинную общую подстроку, а на самом деле нужно сравнивать самую длинную общую подпоследовательность: количество букв в последовательности, общих для двух слов.\nКак вычислить самую длинную общую подпоследовательность?\nНиже приведена частично заполненная таблица для fish и fosh:",[999,3874,3875,3890],{},[1002,3876,3877],{},[1005,3878,3879,3881,3883,3886,3888],{},[1008,3880,1653],{},[1008,3882,3101],{},[1008,3884,3885],{},"O",[1008,3887,3092],{},[1008,3889,3086],{},[1015,3891,3892,3904,3916,3928],{},[1005,3893,3894,3896,3898,3900,3902],{},[1020,3895,3101],{},[1020,3897,988],{},[1020,3899,988],{},[1020,3901],{},[1020,3903],{},[1005,3905,3906,3908,3910,3912,3914],{},[1020,3907,3089],{},[1020,3909,988],{},[1020,3911],{},[1020,3913],{},[1020,3915],{},[1005,3917,3918,3920,3922,3924,3926],{},[1020,3919,3092],{},[1020,3921],{},[1020,3923,988],{},[1020,3925,1658],{},[1020,3927,1658],{},[1005,3929,3930,3932,3934,3936,3938],{},[1020,3931,3086],{},[1020,3933],{},[1020,3935],{},[1020,3937],{},[1020,3939],{},[554,3941,3942],{},"Сможете ли вы определить формулу для этой таблицы?\nСамая длинная общая подпоследовательность имеет много общего с самой длинной общей подстрокой, и их формулы тоже очень похожи.\nПопробуйте решить задачу самостоятельно.",[574,3944,3946],{"id":3945},"решение-самая-длинная-общая-подпоследовательность","Решение: самая длинная общая подпоследовательность",[554,3948,3949],{},"Формула для заполнения каждой ячейки(для соседелй наверху слева):",[1143,3951,3952,3955],{},[1063,3953,3954],{},"Если буквы не совпадают, выбрать большее значение;",[1063,3956,3957],{},"Если буквы совпадают, значение равно значению ячейки наверху слева +1 (как и в случае с самой длинной общей подстрокой).",[554,3959,3960],{},"Окончательные версии таблиц:",[999,3962,3963,3977],{},[1002,3964,3965],{},[1005,3966,3967,3969,3971,3973,3975],{},[1008,3968,1653],{},[1008,3970,3101],{},[1008,3972,3885],{},[1008,3974,3092],{},[1008,3976,3086],{},[1015,3978,3979,3991,4003,4015],{},[1005,3980,3981,3983,3985,3987,3989],{},[1020,3982,3101],{},[1020,3984,988],{},[1020,3986,988],{},[1020,3988,988],{},[1020,3990,988],{},[1005,3992,3993,3995,3997,3999,4001],{},[1020,3994,3089],{},[1020,3996,988],{},[1020,3998,988],{},[1020,4000,988],{},[1020,4002,988],{},[1005,4004,4005,4007,4009,4011,4013],{},[1020,4006,3092],{},[1020,4008,988],{},[1020,4010,988],{},[1020,4012,1658],{},[1020,4014,1658],{},[1005,4016,4017,4019,4021,4023,4025],{},[1020,4018,3086],{},[1020,4020,988],{},[1020,4022,988],{},[1020,4024,1658],{},[1020,4026,1055],{},[999,4028,4029,4043],{},[1002,4030,4031],{},[1005,4032,4033,4035,4037,4039,4041],{},[1008,4034,1653],{},[1008,4036,3101],{},[1008,4038,3885],{},[1008,4040,3092],{},[1008,4042,3086],{},[1015,4044,4045,4057,4069,4082],{},[1005,4046,4047,4049,4051,4053,4055],{},[1020,4048,3101],{},[1020,4050,988],{},[1020,4052,988],{},[1020,4054,988],{},[1020,4056,988],{},[1005,4058,4059,4061,4063,4065,4067],{},[1020,4060,3885],{},[1020,4062,988],{},[1020,4064,1658],{},[1020,4066,1658],{},[1020,4068,1658],{},[1005,4070,4071,4074,4076,4078,4080],{},[1020,4072,4073],{},"R",[1020,4075,988],{},[1020,4077,1658],{},[1020,4079,1658],{},[1020,4081,1658],{},[1005,4083,4084,4086,4088,4090,4092],{},[1020,4085,3841],{},[1020,4087,988],{},[1020,4089,1658],{},[1020,4091,1658],{},[1020,4093,1658],{},[554,4095,4096],{},"На Python это решение выглядит так:",[3310,4098,4100],{"className":3312,"code":4099,"language":3314,"meta":982,"style":982},"dp_table_fosh = [\"f\", \"o\", \"s\", \"h\"]\ndp_table_fish = [\"f\", \"i\", \"s\", \"h\"]\ndp_table = [[0 for i in range(len(dp_table_fosh))] for i in range(len(dp_table_fish))]\nfor i in range(0, len(dp_table_fish)):\n    for j in range(0, len(dp_table_fosh)):\n        if dp_table_fosh[j] == dp_table_fish[i]:  # Буквы совпадают\n            dp_table[i][j] = dp_table[i-1][j-1] + 1\n        else:  # Буквы не совпали\n            dp_table[i][j] = max(dp_table[i-1][j], dp_table[i][j-1])\nfor i in dp_table:\n    print(i)\n",[3316,4101,4102,4128,4152,4191,4211,4232,4245,4269,4277,4303,4313],{"__ignoreMap":982},[3319,4103,4104,4107,4109,4111,4113,4115,4118,4120,4122,4124,4126],{"class":3321,"line":3322},[3319,4105,4106],{"class":3325},"dp_table_fosh ",[3319,4108,3330],{"class":3329},[3319,4110,3333],{"class":3325},[3319,4112,3367],{"class":3336},[3319,4114,3340],{"class":3325},[3319,4116,4117],{"class":3336},"\"o\"",[3319,4119,3340],{"class":3325},[3319,4121,3348],{"class":3336},[3319,4123,3340],{"class":3325},[3319,4125,3337],{"class":3336},[3319,4127,3355],{"class":3325},[3319,4129,4130,4132,4134,4136,4138,4140,4142,4144,4146,4148,4150],{"class":3321,"line":1443},[3319,4131,3360],{"class":3325},[3319,4133,3330],{"class":3329},[3319,4135,3333],{"class":3325},[3319,4137,3367],{"class":3336},[3319,4139,3340],{"class":3325},[3319,4141,3343],{"class":3336},[3319,4143,3340],{"class":3325},[3319,4145,3348],{"class":3336},[3319,4147,3340],{"class":3325},[3319,4149,3337],{"class":3336},[3319,4151,3355],{"class":3325},[3319,4153,4154,4156,4158,4160,4162,4164,4166,4168,4170,4172,4174,4177,4179,4181,4183,4185,4187,4189],{"class":3321,"line":1458},[3319,4155,3386],{"class":3325},[3319,4157,3330],{"class":3329},[3319,4159,3391],{"class":3325},[3319,4161,642],{"class":3394},[3319,4163,3397],{"class":3329},[3319,4165,3400],{"class":3325},[3319,4167,3403],{"class":3329},[3319,4169,3406],{"class":3394},[3319,4171,3409],{"class":3325},[3319,4173,3412],{"class":3394},[3319,4175,4176],{"class":3325},"(dp_table_fosh))] ",[3319,4178,3418],{"class":3329},[3319,4180,3400],{"class":3325},[3319,4182,3403],{"class":3329},[3319,4184,3406],{"class":3394},[3319,4186,3409],{"class":3325},[3319,4188,3412],{"class":3394},[3319,4190,3431],{"class":3325},[3319,4192,4193,4195,4197,4199,4201,4203,4205,4207,4209],{"class":3321,"line":1449},[3319,4194,3418],{"class":3329},[3319,4196,3400],{"class":3325},[3319,4198,3403],{"class":3329},[3319,4200,3406],{"class":3394},[3319,4202,3409],{"class":3325},[3319,4204,642],{"class":3394},[3319,4206,3340],{"class":3325},[3319,4208,3412],{"class":3394},[3319,4210,3452],{"class":3325},[3319,4212,4213,4215,4217,4219,4221,4223,4225,4227,4229],{"class":3321,"line":1444},[3319,4214,3457],{"class":3329},[3319,4216,3460],{"class":3325},[3319,4218,3403],{"class":3329},[3319,4220,3406],{"class":3394},[3319,4222,3409],{"class":3325},[3319,4224,642],{"class":3394},[3319,4226,3340],{"class":3325},[3319,4228,3412],{"class":3394},[3319,4230,4231],{"class":3325},"(dp_table_fosh)):\n",[3319,4233,4234,4236,4239,4241,4243],{"class":3321,"line":3478},[3319,4235,3481],{"class":3329},[3319,4237,4238],{"class":3325}," dp_table_fosh[j] ",[3319,4240,3487],{"class":3329},[3319,4242,3490],{"class":3325},[3319,4244,3494],{"class":3493},[3319,4246,4247,4249,4251,4253,4255,4257,4259,4261,4263,4265,4267],{"class":3321,"line":3497},[3319,4248,3500],{"class":3325},[3319,4250,3330],{"class":3329},[3319,4252,3505],{"class":3325},[3319,4254,1653],{"class":3329},[3319,4256,988],{"class":3394},[3319,4258,3512],{"class":3325},[3319,4260,1653],{"class":3329},[3319,4262,988],{"class":3394},[3319,4264,3519],{"class":3325},[3319,4266,3522],{"class":3329},[3319,4268,3525],{"class":3394},[3319,4270,4271,4273,4275],{"class":3321,"line":3528},[3319,4272,3531],{"class":3329},[3319,4274,3534],{"class":3325},[3319,4276,3537],{"class":3493},[3319,4278,4279,4281,4283,4286,4289,4291,4293,4296,4298,4300],{"class":3321,"line":3540},[3319,4280,3500],{"class":3325},[3319,4282,3330],{"class":3329},[3319,4284,4285],{"class":3394}," max",[3319,4287,4288],{"class":3325},"(dp_table[i",[3319,4290,1653],{"class":3329},[3319,4292,988],{"class":3394},[3319,4294,4295],{"class":3325},"][j], dp_table[i][j",[3319,4297,1653],{"class":3329},[3319,4299,988],{"class":3394},[3319,4301,4302],{"class":3325},"])\n",[3319,4304,4305,4307,4309,4311],{"class":3321,"line":3550},[3319,4306,3418],{"class":3329},[3319,4308,3400],{"class":3325},[3319,4310,3403],{"class":3329},[3319,4312,3559],{"class":3325},[3319,4314,4315,4317],{"class":3321,"line":3562},[3319,4316,3565],{"class":3394},[3319,4318,3568],{"class":3325},[3310,4320,4322],{"className":3312,"code":4321,"language":3314,"meta":982,"style":982},"dp_table_fosh = [\"f\", \"o\", \"s\", \"h\"]\ndp_table_fort = [\"f\", \"o\", \"r\", \"t\"]\ndp_table = [[0 for i in range(len(dp_table_fosh))] for i in range(len(dp_table_fort))]\nfor i in range(0, len(dp_table_fort)):\n    for j in range(0, len(dp_table_fosh)):\n        if dp_table_fosh[j] == dp_table_fort[i]:  # Буквы совпадают\n            dp_table[i][j] = dp_table[i-1][j-1] + 1\n        else:  # Буквы не совпали\n            dp_table[i][j] = max(dp_table[i-1][j], dp_table[i][j-1])\nfor i in dp_table:\n    print(i)\n",[3316,4323,4324,4348,4374,4413,4434,4454,4467,4491,4499,4521,4531],{"__ignoreMap":982},[3319,4325,4326,4328,4330,4332,4334,4336,4338,4340,4342,4344,4346],{"class":3321,"line":3322},[3319,4327,4106],{"class":3325},[3319,4329,3330],{"class":3329},[3319,4331,3333],{"class":3325},[3319,4333,3367],{"class":3336},[3319,4335,3340],{"class":3325},[3319,4337,4117],{"class":3336},[3319,4339,3340],{"class":3325},[3319,4341,3348],{"class":3336},[3319,4343,3340],{"class":3325},[3319,4345,3337],{"class":3336},[3319,4347,3355],{"class":3325},[3319,4349,4350,4353,4355,4357,4359,4361,4363,4365,4368,4370,4372],{"class":3321,"line":1443},[3319,4351,4352],{"class":3325},"dp_table_fort ",[3319,4354,3330],{"class":3329},[3319,4356,3333],{"class":3325},[3319,4358,3367],{"class":3336},[3319,4360,3340],{"class":3325},[3319,4362,4117],{"class":3336},[3319,4364,3340],{"class":3325},[3319,4366,4367],{"class":3336},"\"r\"",[3319,4369,3340],{"class":3325},[3319,4371,3625],{"class":3336},[3319,4373,3355],{"class":3325},[3319,4375,4376,4378,4380,4382,4384,4386,4388,4390,4392,4394,4396,4398,4400,4402,4404,4406,4408,4410],{"class":3321,"line":1458},[3319,4377,3386],{"class":3325},[3319,4379,3330],{"class":3329},[3319,4381,3391],{"class":3325},[3319,4383,642],{"class":3394},[3319,4385,3397],{"class":3329},[3319,4387,3400],{"class":3325},[3319,4389,3403],{"class":3329},[3319,4391,3406],{"class":3394},[3319,4393,3409],{"class":3325},[3319,4395,3412],{"class":3394},[3319,4397,4176],{"class":3325},[3319,4399,3418],{"class":3329},[3319,4401,3400],{"class":3325},[3319,4403,3403],{"class":3329},[3319,4405,3406],{"class":3394},[3319,4407,3409],{"class":3325},[3319,4409,3412],{"class":3394},[3319,4411,4412],{"class":3325},"(dp_table_fort))]\n",[3319,4414,4415,4417,4419,4421,4423,4425,4427,4429,4431],{"class":3321,"line":1449},[3319,4416,3418],{"class":3329},[3319,4418,3400],{"class":3325},[3319,4420,3403],{"class":3329},[3319,4422,3406],{"class":3394},[3319,4424,3409],{"class":3325},[3319,4426,642],{"class":3394},[3319,4428,3340],{"class":3325},[3319,4430,3412],{"class":3394},[3319,4432,4433],{"class":3325},"(dp_table_fort)):\n",[3319,4435,4436,4438,4440,4442,4444,4446,4448,4450,4452],{"class":3321,"line":1444},[3319,4437,3457],{"class":3329},[3319,4439,3460],{"class":3325},[3319,4441,3403],{"class":3329},[3319,4443,3406],{"class":3394},[3319,4445,3409],{"class":3325},[3319,4447,642],{"class":3394},[3319,4449,3340],{"class":3325},[3319,4451,3412],{"class":3394},[3319,4453,4231],{"class":3325},[3319,4455,4456,4458,4460,4462,4465],{"class":3321,"line":3478},[3319,4457,3481],{"class":3329},[3319,4459,4238],{"class":3325},[3319,4461,3487],{"class":3329},[3319,4463,4464],{"class":3325}," dp_table_fort[i]:  ",[3319,4466,3494],{"class":3493},[3319,4468,4469,4471,4473,4475,4477,4479,4481,4483,4485,4487,4489],{"class":3321,"line":3497},[3319,4470,3500],{"class":3325},[3319,4472,3330],{"class":3329},[3319,4474,3505],{"class":3325},[3319,4476,1653],{"class":3329},[3319,4478,988],{"class":3394},[3319,4480,3512],{"class":3325},[3319,4482,1653],{"class":3329},[3319,4484,988],{"class":3394},[3319,4486,3519],{"class":3325},[3319,4488,3522],{"class":3329},[3319,4490,3525],{"class":3394},[3319,4492,4493,4495,4497],{"class":3321,"line":3528},[3319,4494,3531],{"class":3329},[3319,4496,3534],{"class":3325},[3319,4498,3537],{"class":3493},[3319,4500,4501,4503,4505,4507,4509,4511,4513,4515,4517,4519],{"class":3321,"line":3540},[3319,4502,3500],{"class":3325},[3319,4504,3330],{"class":3329},[3319,4506,4285],{"class":3394},[3319,4508,4288],{"class":3325},[3319,4510,1653],{"class":3329},[3319,4512,988],{"class":3394},[3319,4514,4295],{"class":3325},[3319,4516,1653],{"class":3329},[3319,4518,988],{"class":3394},[3319,4520,4302],{"class":3325},[3319,4522,4523,4525,4527,4529],{"class":3321,"line":3550},[3319,4524,3418],{"class":3329},[3319,4526,3400],{"class":3325},[3319,4528,3403],{"class":3329},[3319,4530,3559],{"class":3325},[3319,4532,4533,4535],{"class":3321,"line":3562},[3319,4534,3565],{"class":3394},[3319,4536,3568],{"class":3325},[554,4538,4539],{},"Ещё примеры применения динамического программирования:",[1060,4541,4542,4545,4548],{},[1063,4543,4544],{},"Биологи используют самую длинную общую подпоследовательность для выявления сходства в цепях ДНК. По этой метрике можно судить о сходстве двух видов животных, двух заболеваний и т.д. Самая длинная общая подпоследовательность используется для поиска лекарства от рассеянного склероза.",[1063,4546,4547],{},"Вы когда-нибудь пользовались ключом diff (например, в команде git diff)? Этот ключ выводит информацию о различиях между двумя файлами, а для этого он использует динамическое программирование.",[1063,4549,4550],{},"Расстояние Левенштейна оценивает, насколько похожи две строки, а для его вычисления применяется динамическое программирование. Расстояние Левенштейна используется в самых разных областях, от проверки орфографии до выявления отправки пользователем данных, защищенных авторским правом.",[554,4552,4553],{},"Поздравляю — вы справились! Безусловно, это была одна из самых сложных тем в программировании.\nНиже посмотрите и выполните упражнения, чтобы закрепить свои знания по теме.",[551,4555,4556],{},[554,4557,4558,4559],{},"В следующей статье речь идёт про ",[558,4560,4561],{"href":303},"алгоритм k ближайших соседей.",[566,4563],{"id":982},[546,4565],{":isList":4566,"title":1208},"[\"Динамическое программирование применяется при оптимизации некоторой характеристики;\",\"Динамическое программирование работает только в ситуациях, в которых задача может быть разбита на автономные подзадачи;\",\"В каждом решении из области динамического программирования строится таблица;\",\"Значения ячеек таблицы обычно соответствуют оптимизируемой характеристике;\",\"Каждая ячейка представляет подзадачу, поэтому вы должны подумать о том, как разбить задачу на подзадачи;\",\"Не существует единой формулы для вычисления решений методом динамического программирования.\"]",[566,4568],{"id":1118},[984,4570],{":isAnswers":4571,":isList":4572,":startOl":988,"isText":989,"title":990},"[\"Да. Вы сможете положить в рюкзак клавиатуру, смартфон и гитару общей стоимостью 4500.\",\"Возьмите воду, еду и камеру.\",\"Строки таблицы clues(столбцы) и blue(строки): | 0 0 0 0 0 | 0 1 0 0 0 | 0 0 2 0 0 | 0 0 0 3 0 |.\"]","[\"Предположим, к предметам из примера первой задачи(гитара, магнитофон, ноутбук) добавился еще один: клавиатура. Она весит 1 кг и стоит 1000₽. Стоит ли ее брать?\",\"Предположим, что вы собираетесь в турпоход. Емкость вашего рюкзака составляет 6 фунтов, и вы можете взять предметы из следующего списка. У каждого предмета имеется стоимость; чем она выше, тем важнее предмет: вода, 3 кг, 10; книга, 1 кг, 3; еда, 2 кг, 9; куртка, 2 кг, 5; камера, 1 кг, 6. Как выглядит оптимальный набор предметов для похода?\",\"Нарисуйте и заполните таблицу для вычисления самой длинной общей подстроки между строками blue и clues.\"]",[554,4574,4575,4576,4580,4581,4584],{},"Попробуйте сами скопировать и запустить код в окне ниже с интерпретатором Python и повторите примеры из статьи чтобы самим увидеть и понять как всё это работает.\nДля этого в ячейке с кодом нажмите клавиши на клавиатуре ",[4577,4578,4579],"strong",{},"Shift+Enter"," или запустите код через ",[4577,4582,4583],{},"кнопку Run"," по значку ▶.",[4586,4587],"jypiter",{},[1439,4589,1441],{},[1439,4591,4592],{},"html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":982,"searchDepth":1443,"depth":1444,"links":4594},[4595],{"id":1498,"depth":1443,"text":298,"children":4596},[4597,4600,4605],{"id":1513,"depth":1458,"text":1514,"children":4598},[4599],{"id":1567,"depth":1449,"text":1568},{"id":1635,"depth":1458,"text":298,"children":4601},[4602,4603,4604],{"id":1706,"depth":1444,"text":1537},{"id":1887,"depth":1444,"text":1531},{"id":2065,"depth":1444,"text":1534},{"id":2244,"depth":1458,"text":2245,"children":4606},[4607,4608,4609,4610,4611,4612,4617,4618,4623,4626,4627],{"id":2251,"depth":1444,"text":2252},{"id":2525,"depth":1444,"text":2526},{"id":2532,"depth":1444,"text":2533},{"id":2539,"depth":1444,"text":2540},{"id":2657,"depth":1444,"text":2658},{"id":2664,"depth":1449,"text":2665,"children":4613},[4614,4615,4616],{"id":2912,"depth":1444,"text":2913},{"id":3007,"depth":1444,"text":3008},{"id":3014,"depth":1444,"text":3015},{"id":3021,"depth":1449,"text":3022},{"id":3050,"depth":1449,"text":3051,"children":4619},[4620,4621,4622],{"id":3057,"depth":1444,"text":3058},{"id":3148,"depth":1444,"text":3149},{"id":3224,"depth":1444,"text":3225},{"id":3868,"depth":1449,"text":3869,"children":4624},[4625],{"id":3945,"depth":1444,"text":3946},{"id":982,"depth":1449,"text":982},{"id":1118,"depth":1449,"text":982},"2026-05-07","Метод решения сложных задач, разбиваемых на подзадачи. Примеры задач.","images\u002Fblog\u002Fpython\u002Fst34\u002Fimg.png",{},40,34,{"title":298,"description":4629},"k6A73YsSaTmwC6biV5sBOqRPaSklEo44rd-RHN5UF4g",{"id":4637,"title":294,"author":4638,"body":4640,"date":6019,"description":6020,"extension":1484,"image":6021,"meta":6022,"minRead":5682,"navigation":513,"num":6023,"path":295,"seo":6024,"stem":296,"__hash__":6025},"blog\u002Fblog\u002Fpython\u002Fst33.md",{"name":516,"avatar":4639},{"src":536,"alt":537},{"type":539,"value":4641,"toc":6005},[4642,4645,4648,4657,4661,4664,4733,4736,4747,4750,4753,4755,4758,4769,4772,4775,4779,4782,4786,4789,4797,4808,4813,4817,4820,4828,4831,4897,4900,4904,4907,4975,4978,5121,5124,5141,5145,5151,5198,5205,5278,5282,5285,5296,5299,5307,5312,5316,5339,5348,5354,5369,5379,5746,5749,5976,5979,5987,5989,5992,5998,6000,6002],[542,4643,294],{"id":4644},"жадные-алгоритмы",[546,4646],{":isList":4647,"title":549},"[\"Узнаете о жадной стратегии при решении задач.\",\"Разберётесь как браться за невозможные задачи, не имеющие быстрого алгоритмического решения NP-трудные задачи.\",\"Познакомитесь с приближёнными алгоритмами, которые могут использоваться для быстрого нахождения приближённого решения NP-полных задач.\"]",[551,4649,4650],{},[554,4651,4652,4653,4656],{},"В предыдущей статье был рассмотрен: ",[558,4654,4655],{"href":291},"алгоритм Дейкстры",".\nЗдесь далее текст пойдёт о жадных алгоритмах.",[1125,4658,4660],{"id":4659},"задача-составления-расписания","Задача составления расписания",[554,4662,4663],{},"Предположим, имеется учебный класс, в котором нужно провести как можно больше уроков. У вас есть список уроков:",[999,4665,4666,4679],{},[1002,4667,4668],{},[1005,4669,4670,4673,4676],{},[1008,4671,4672],{},"Предмет",[1008,4674,4675],{},"С",[1008,4677,4678],{},"ДО",[1015,4680,4681,4692,4703,4713,4723],{},[1005,4682,4683,4686,4689],{},[1020,4684,4685],{},"ИЗО",[1020,4687,4688],{},"8:00",[1020,4690,4691],{},"9:00",[1005,4693,4694,4697,4700],{},[1020,4695,4696],{},"English",[1020,4698,4699],{},"8:30",[1020,4701,4702],{},"9:30",[1005,4704,4705,4708,4710],{},[1020,4706,4707],{},"Алгебра",[1020,4709,4691],{},[1020,4711,4712],{},"10:00",[1005,4714,4715,4718,4720],{},[1020,4716,4717],{},"Информатика",[1020,4719,4702],{},[1020,4721,4722],{},"10:30",[1005,4724,4725,4728,4730],{},[1020,4726,4727],{},"Физика",[1020,4729,4712],{},[1020,4731,4732],{},"11:00",[554,4734,4735],{},"Провести все уроки не получится, потому что они перекрывают друг друга по времени.\nТребуется провести в классе как можно больше уроков.\nКак отобрать уроки, чтобы полученный набор оказался самым большим из возможных?\nВот какой составить необходимо алгоритм:",[1143,4737,4738,4741,4744],{},[1063,4739,4740],{},"Выбрать урок, завершающийся раньше всех. Это первый урок, который будет проведён в классе.",[1063,4742,4743],{},"Затем выбирается урок, начинающийся после завершения первого урока. И снова следует выбирать урок, который завершается раньше всех остальных. Он становится вторым уроком в расписании класса.",[1063,4745,4746],{},"Продолжайте действовать по тому же принципу, чтобы получить ответ.",[554,4748,4749],{},"Попробуйте алгоритм на примере таблицы выше. ИЗО заканчивается раньше всех уроков, поэтому выбираем первым уроком.\nДалее нужно найти и выбрать следующий урок, который начинается после 9:00 и завершается раньше остальных.\nАнглийский отпадает, но алгебра подходит. Наконец, информатика пересекается по времени с алгеброй, но физика подходит.\nИтак, задача решена, эти три урока должны проводится в классе: ИЗО, алгебра, физика.",[554,4751,4752],{},"Можно подумать что этот алгоритм удивительно прост. Он слишком очевиден, но в этом и заключается суть жадных алгоритмов!\nОни просты! Жадный алгоритм: на каждом своём шаге выбирает всегда оптимальный вариант.\nВ техническом плане выбирается всегда локально-оптимальное решение.\nКонечно такие алгоритмы сработают не всегда, но с задачей из примера или подобной они справляются легко и интуитивно понятно реализуются!\nРассмотрим далее другой пример.",[1125,4754,1514],{"id":1513},[554,4756,4757],{},"Представьте, что вы богатый покупатель или транжира денежных средств.\nВы зашли в магазин или супермаркет с рюкзаком и перед вами множество товаров, которые вы обязательно хотите немедленно купить.\nОднако, ёмкость вашего рюкзака и ваша грузоподъёмность не бесконечна: примерно рюкзак и соответственно вы сможете понести, допустим, 50 кг(как мешок с цементом)!\nВы также хотите купить максимально дорогие вещи!\nМожно легко представить и противоположную ситуацию — у вас абсолютно нет денег и вы хотите всё украсть и также унести 😁.\nНо задача одна и состоит в том, чтобы подобрать товары максимальной стоимости, которые вы смогли бы унести в своём рюкзаке.\nКакой алгоритм использовать?\nПопробуйте жадный алгоритм:",[1143,4759,4760,4763,4766],{},[1063,4761,4762],{},"Выбрать самый дорогой предмет, который поместиться в рюкзаке.",[1063,4764,4765],{},"Выбрать следующий по стоимости предмет, который поместится в рюкзаке.",[1063,4767,4768],{},"И так далее продолжить до заполнения всего места в рюкзаке.",[554,4770,4771],{},"Вот только, как можно было догадаться, на этот раз такая стратегия не приводит к лучшему решению и соответственно она не работает!\nДопустим вы выбираете самый дорогой товар, например, это музыкальный центр. Вы складываете его в рюкзак и место больше ни для чего не остаётся.\nПусть он стоил 1000000 рублей и это был самый дорогой товар в магазине.\nНо допустим, были также ещё и два товара, стоимостью 750000 и 500000 рублей, которые вдвоём поместились бы в ваш рюкзак.\nНо согласно алгоритму описанному выше вы бы их уже не купили.",[554,4773,4774],{},"Очевидно, жадный алгоритм не всегда выдаёт оптимальное решение всей задачи.\nВпрочем, зачастую результат, даже ошибочный, будет не так уж далёк от истинного ответа.\nИ в некоторых задачах достаточно жадного алгоритма, способного решить задачу достаточно хорошо.\nВ таких областях жадные алгоритмы работают отлично, потому что они просто реализуются, а полученное решение обычно близко к оптимуму.",[984,4776],{":isAnswers":4777,":isList":4778,":startOl":988,"isText":989,"title":990},"[\"Выбираем достопримечательности с наибольшей стоимостью в баллах, которую вы успеете посетить в оставшееся время. Остановитесь, когда таких достопримечательностей не останется. Такая стратегия не будет оптимальной.\",\"Жадная стратегия заключается в том, чтобы выбрать самую большую коробку, помещающуюся в оставшемся пространстве, и повторять это до тех пор, пока ещё можно выбрать хотя бы одну коробку. Такое решение не будет оптимальным.\"]","[\"Вы едите заграницу и у вас есть семь дней на знакомство с достопримечательности. Вы присваиваете каждой достопримечательности стоимость в баллах(насколько вы хотите её увидеть) и оцениваете продолжительность посещения. Как увидеть всё самое важное из всей поездки? Предложите жадную стратегию решения данной задачи. Будет ли решение оптимальным?\",\"Вы работаете в фирме по производству мебели и поставляете её. Коробки с мебелью размещаются в грузовике. Все коробки имеют разный размер, и вы стараетесь наиболее эффективно использовать доступное пространство в коробках. Как выбрать коробки для того, чтобы загрузка имела максимальную эффективность? Предложите жадную стратегию для решения данной задачи. Будет ли полученное решение оптимальным?\"]",[554,4780,4781],{},"Рассмотрим ещё пример, в котором без жадных алгоритмов трудно обойтись.",[1125,4783,4785],{"id":4784},"задача-о-покрытии-множества","Задача о покрытии множества",[554,4787,4788],{},"Вы открываете собственную авторскую программу по радио.\nНужно только решить на каких радиостанциях должна транслироваться ваша программа.\nКаждая трансляция на радио стоит денег, поэтому количество станций нужно свести к минимуму с максимальным качеством вещаний.\nИмеется список станций.\nКаждая станция покрывает определённый набор областей для вещания, эти наборы перекрываются по областям.\nКак найти минимальный набор станций, который покрывал бы все 89 субъектов и областей?\nЗадача довольно сложна. Составим алгоритм:",[1143,4790,4791,4794],{},[1063,4792,4793],{},"Составить список всех возможных подмножеств станций – так называемое степенное множество. В нём содержатся 2^n возможных подмножеств.",[1063,4795,4796],{},"Из этого списка выбирается множество с наименьшим набором станций, покрывающих все 89 субъектов.",[554,4798,4799,4800,4803,4804,4807],{},"Проблема решения данной задачи состоит в том, что вычисление всех возможных подмножеств станций займёт слишком много времени.\nДля ",[1095,4801,4802],{},"n"," станций оно потребует времени ",[1095,4805,4806],{},"O(2^n)."," Если станций немного, скажем от 5 до 10, — это допустимо.\nНо подумайте, что произойдёт во всех рассмотренных примерах при большом количестве элементов.\nПредположим, вы можете вычислять по 10 подмножеств в секунду.",[554,4809,4810],{},[1095,4811,4812],{},"Не существует алгоритма, который будет вычислять подмножества с приемлемой скоростью! Что делать? На помощь приходят жадные алгоритмы.",[566,4814,4816],{"id":4815},"приближённые-алгоритмы-реализация","Приближённые алгоритмы: реализация",[554,4818,4819],{},"Вот как выглядит жадный алгоритм, который выдаёт результат, достаточно близкий к оптимальному решению:",[1143,4821,4822,4825],{},[1063,4823,4824],{},"Выбрать станцию, покрывающую наибольшее количество областей, ещё не входящих в покрытие. Если станция будет покрывать некоторые области, уже входящие в покрытие, это нормально.",[1063,4826,4827],{},"Повторять, пока останутся области, не входящие в покрытие.",[554,4829,4830],{},"Этот алгоритм является приближённым. Когда вычисление точного решения занимает слишком много времени, применяется приближённый алгоритм.\nЭффективность приближённого алгоритма оценивается по: быстроте, близости полученного решения к оптимальному.",[554,4832,4833,4834,4893,4894,4896],{},"Жадные алгоритмы хороши не только тем, что они обычно легко формулируются, но и тем, что простота обычно оборачивается скоростью выполнения.\nВ данном случае жадный алгоритм выполняется за время ",[582,4835,4837],{"className":4836,"jax":586},[585],[588,4838,4842,4858],{"style":1577,"xmlns":591,"width":4839,"height":4840,"role":594,"focusable":595,"viewBox":4841,"xmlnsXLink":597},"6.461ex","2.452ex","0 -833.9 2855.6 1083.9",[599,4843,4844,4846,4848,4850,4852,4854],{},[602,4845],{"id":1585,"d":1586},[602,4847],{"id":608,"d":609},[602,4849],{"id":1593,"d":829},[602,4851],{"id":624,"d":625},[602,4853],{"id":628,"d":629},[602,4855],{"id":4856,"d":4857},"MJX-1-TEX-N-2C","M78 35T78 60T94 103T137 121Q165 121 187 96T210 8Q210 -27 201 -60T180 -117T154 -158T130 -185T117 -194Q113 -194 104 -185T95 -172Q95 -168 106 -156T131 -126T157 -76T173 -3V9L172 8Q170 7 167 6T161 3T152 1T140 0Q113 0 96 17Z",[639,4859,4860],{"stroke":641,"fill":641,"stroke-width":642,"transform":643},[639,4861,4862,4866,4870,4881,4886],{"dataMmlNode":646},[639,4863,4864],{"dataMmlNode":674},[664,4865],{"dataC":1604,"xLinkHref":1605},[639,4867,4868],{"dataMmlNode":662,"transform":1608},[664,4869],{"dataC":666,"xLinkHref":667},[639,4871,4872,4876],{"dataMmlNode":655,"transform":1613},[639,4873,4874],{"dataMmlNode":674},[664,4875],{"dataC":927,"xLinkHref":1623},[639,4877,4879],{"dataMmlNode":681,"transform":4878},"translate(633,363) scale(0.707)",[664,4880],{"dataC":705,"xLinkHref":706},[639,4882,4884],{"dataMmlNode":662,"transform":4883},"translate(2188.6,0)",[664,4885],{"dataC":712,"xLinkHref":713},[639,4887,4889],{"dataMmlNode":662,"transform":4888},"translate(2577.6,0)",[664,4890],{"dataC":4891,"xLinkHref":4892},"2C","#MJX-1-TEX-N-2C"," где ",[1095,4895,4802],{}," – количество радиостанций.",[554,4898,4899],{},"Теперь разберёмся как задача будет выглядеть в программном коде на Python.",[566,4901,4903],{"id":4902},"подготовительный-код","Подготовительный код",[554,4905,4906],{},"В этом примере для простоты будет использоваться небольшое подмножество областей и станций.\nСначала составим список областей:",[3310,4908,4910],{"className":3312,"code":4909,"language":3314,"meta":982,"style":982},"# Для обозначения субъектов РФ используются коды\n# Переданный массив преобразуется в множество\nstates_needed = set([\"28\", \"29\", \"30\", \"31\", \"32\", \"33\", \"34\", \"35\"])  \n",[3316,4911,4912,4917,4922],{"__ignoreMap":982},[3319,4913,4914],{"class":3321,"line":3322},[3319,4915,4916],{"class":3493},"# Для обозначения субъектов РФ используются коды\n",[3319,4918,4919],{"class":3321,"line":1443},[3319,4920,4921],{"class":3493},"# Переданный массив преобразуется в множество\n",[3319,4923,4924,4927,4929,4932,4935,4938,4940,4943,4945,4948,4950,4953,4955,4958,4960,4963,4965,4968,4970,4973],{"class":3321,"line":1458},[3319,4925,4926],{"class":3325},"states_needed ",[3319,4928,3330],{"class":3329},[3319,4930,4931],{"class":3394}," set",[3319,4933,4934],{"class":3325},"([",[3319,4936,4937],{"class":3336},"\"28\"",[3319,4939,3340],{"class":3325},[3319,4941,4942],{"class":3336},"\"29\"",[3319,4944,3340],{"class":3325},[3319,4946,4947],{"class":3336},"\"30\"",[3319,4949,3340],{"class":3325},[3319,4951,4952],{"class":3336},"\"31\"",[3319,4954,3340],{"class":3325},[3319,4956,4957],{"class":3336},"\"32\"",[3319,4959,3340],{"class":3325},[3319,4961,4962],{"class":3336},"\"33\"",[3319,4964,3340],{"class":3325},[3319,4966,4967],{"class":3336},"\"34\"",[3319,4969,3340],{"class":3325},[3319,4971,4972],{"class":3336},"\"35\"",[3319,4974,4302],{"class":3325},[554,4976,4977],{},"В этой реализации используем множество.\nЭта структура данных похожа на список, но каждый элемент может встречаться во множестве не более одного раза.\nМножества не содержат дубликатов. Также понадобится список станций, из которого будет выбираться покрытие.\nВоспользуемся словарём:",[3310,4979,4981],{"className":3312,"code":4980,"language":3314,"meta":982,"style":982},"stations = {}\nstations[\"one\"] = set([\"31\", \"32\", \"33\"])\nstations[\"two\"] = set([\"29\", \"31\", \"28\"])\nstations[\"three\"] = set([\"30\", \"32\", \"34\"])\nstations[\"four\"] = set([\"32\", \"33\"])\nstations[\"five\"] = set([\"34\", \"35\"])\n",[3316,4982,4983,4993,5021,5048,5075,5098],{"__ignoreMap":982},[3319,4984,4985,4988,4990],{"class":3321,"line":3322},[3319,4986,4987],{"class":3325},"stations ",[3319,4989,3330],{"class":3329},[3319,4991,4992],{"class":3325}," {}\n",[3319,4994,4995,4998,5001,5003,5005,5007,5009,5011,5013,5015,5017,5019],{"class":3321,"line":1443},[3319,4996,4997],{"class":3325},"stations[",[3319,4999,5000],{"class":3336},"\"one\"",[3319,5002,3519],{"class":3325},[3319,5004,3330],{"class":3329},[3319,5006,4931],{"class":3394},[3319,5008,4934],{"class":3325},[3319,5010,4952],{"class":3336},[3319,5012,3340],{"class":3325},[3319,5014,4957],{"class":3336},[3319,5016,3340],{"class":3325},[3319,5018,4962],{"class":3336},[3319,5020,4302],{"class":3325},[3319,5022,5023,5025,5028,5030,5032,5034,5036,5038,5040,5042,5044,5046],{"class":3321,"line":1458},[3319,5024,4997],{"class":3325},[3319,5026,5027],{"class":3336},"\"two\"",[3319,5029,3519],{"class":3325},[3319,5031,3330],{"class":3329},[3319,5033,4931],{"class":3394},[3319,5035,4934],{"class":3325},[3319,5037,4942],{"class":3336},[3319,5039,3340],{"class":3325},[3319,5041,4952],{"class":3336},[3319,5043,3340],{"class":3325},[3319,5045,4937],{"class":3336},[3319,5047,4302],{"class":3325},[3319,5049,5050,5052,5055,5057,5059,5061,5063,5065,5067,5069,5071,5073],{"class":3321,"line":1449},[3319,5051,4997],{"class":3325},[3319,5053,5054],{"class":3336},"\"three\"",[3319,5056,3519],{"class":3325},[3319,5058,3330],{"class":3329},[3319,5060,4931],{"class":3394},[3319,5062,4934],{"class":3325},[3319,5064,4947],{"class":3336},[3319,5066,3340],{"class":3325},[3319,5068,4957],{"class":3336},[3319,5070,3340],{"class":3325},[3319,5072,4967],{"class":3336},[3319,5074,4302],{"class":3325},[3319,5076,5077,5079,5082,5084,5086,5088,5090,5092,5094,5096],{"class":3321,"line":1444},[3319,5078,4997],{"class":3325},[3319,5080,5081],{"class":3336},"\"four\"",[3319,5083,3519],{"class":3325},[3319,5085,3330],{"class":3329},[3319,5087,4931],{"class":3394},[3319,5089,4934],{"class":3325},[3319,5091,4957],{"class":3336},[3319,5093,3340],{"class":3325},[3319,5095,4962],{"class":3336},[3319,5097,4302],{"class":3325},[3319,5099,5100,5102,5105,5107,5109,5111,5113,5115,5117,5119],{"class":3321,"line":3478},[3319,5101,4997],{"class":3325},[3319,5103,5104],{"class":3336},"\"five\"",[3319,5106,3519],{"class":3325},[3319,5108,3330],{"class":3329},[3319,5110,4931],{"class":3394},[3319,5112,4934],{"class":3325},[3319,5114,4967],{"class":3336},[3319,5116,3340],{"class":3325},[3319,5118,4972],{"class":3336},[3319,5120,4302],{"class":3325},[554,5122,5123],{},"Ключи — названия станций, а значения — сокращенные обозначения областей, входящих в зону охвата.\nТаким образом, в данном примере станция one вещает в субъектах с кодами 31, 32, 33(Белгородская, Брянская и Владимирская области).\nВсе значения являются множествами. Хранение данных во множествах упрощает работу.\nНаконец, нам понадобится структура данных для хранения итогового набора станций:",[3310,5125,5127],{"className":3312,"code":5126,"language":3314,"meta":982,"style":982},"final_stations = set()\n",[3316,5128,5129],{"__ignoreMap":982},[3319,5130,5131,5134,5136,5138],{"class":3321,"line":3322},[3319,5132,5133],{"class":3325},"final_stations ",[3319,5135,3330],{"class":3329},[3319,5137,4931],{"class":3394},[3319,5139,5140],{"class":3325},"()\n",[566,5142,5144],{"id":5143},"вычисление-ответа","Вычисление ответа",[554,5146,5147,5148,1397],{},"Теперь необходимо вычислить набор используемых станций. Правильных решений может быть несколько.\nНеобходимо перебрать все станции и выбрать ту, которая обслуживает больше всего субъектов-областей, не входящих в текущее покрытие.\nБудем называть её ",[3316,5149,5150],{},"best_station",[3310,5152,5154],{"className":3312,"code":5153,"language":3314,"meta":982,"style":982},"while states_needed:\n  best_station = None\n  states_covered = set()\n  for station, states_for_station in stations.items():\n",[3316,5155,5156,5164,5174,5185],{"__ignoreMap":982},[3319,5157,5158,5161],{"class":3321,"line":3322},[3319,5159,5160],{"class":3329},"while",[3319,5162,5163],{"class":3325}," states_needed:\n",[3319,5165,5166,5169,5171],{"class":3321,"line":1443},[3319,5167,5168],{"class":3325},"  best_station ",[3319,5170,3330],{"class":3329},[3319,5172,5173],{"class":3394}," None\n",[3319,5175,5176,5179,5181,5183],{"class":3321,"line":1458},[3319,5177,5178],{"class":3325},"  states_covered ",[3319,5180,3330],{"class":3329},[3319,5182,4931],{"class":3394},[3319,5184,5140],{"class":3325},[3319,5186,5187,5190,5193,5195],{"class":3321,"line":1449},[3319,5188,5189],{"class":3329},"  for",[3319,5191,5192],{"class":3325}," station, states_for_station ",[3319,5194,3403],{"class":3329},[3319,5196,5197],{"class":3325}," stations.items():\n",[554,5199,5200,5201,5204],{},"Множество ",[3316,5202,5203],{},"states_covered содержит"," все области, обслуживаемые этой станцией, которые ещё не входят в текущее покрытие.\nПомните, мы ищем станцию, которая будет обслуживать большинство ещё не охваченных областей.\nЦикл for перебирает все станции и находит среди них наилучшую.\nРассмотрим тело цикла for:",[3310,5206,5208],{"className":3312,"code":5207,"language":3314,"meta":982,"style":982},"for station, states_for_station in stations.items():\n  covered = states_needed & states_for_station # Пересечение множеств\n  if len(covered) > len(states_covered):\n    best_station = station\n    states_covered = covered\n",[3316,5209,5210,5220,5239,5258,5268],{"__ignoreMap":982},[3319,5211,5212,5214,5216,5218],{"class":3321,"line":3322},[3319,5213,3418],{"class":3329},[3319,5215,5192],{"class":3325},[3319,5217,3403],{"class":3329},[3319,5219,5197],{"class":3325},[3319,5221,5222,5225,5227,5230,5233,5236],{"class":3321,"line":1443},[3319,5223,5224],{"class":3325},"  covered ",[3319,5226,3330],{"class":3329},[3319,5228,5229],{"class":3325}," states_needed ",[3319,5231,5232],{"class":3329},"&",[3319,5234,5235],{"class":3325}," states_for_station ",[3319,5237,5238],{"class":3493},"# Пересечение множеств\n",[3319,5240,5241,5244,5247,5250,5253,5255],{"class":3321,"line":1458},[3319,5242,5243],{"class":3329},"  if",[3319,5245,5246],{"class":3394}," len",[3319,5248,5249],{"class":3325},"(covered) ",[3319,5251,5252],{"class":3329},">",[3319,5254,5246],{"class":3394},[3319,5256,5257],{"class":3325},"(states_covered):\n",[3319,5259,5260,5263,5265],{"class":3321,"line":1449},[3319,5261,5262],{"class":3325},"    best_station ",[3319,5264,3330],{"class":3329},[3319,5266,5267],{"class":3325}," station\n",[3319,5269,5270,5273,5275],{"class":3321,"line":1444},[3319,5271,5272],{"class":3325},"    states_covered ",[3319,5274,3330],{"class":3329},[3319,5276,5277],{"class":3325}," covered\n",[566,5279,5281],{"id":5280},"про-множества","Про множества",[554,5283,5284],{},"С двумя множествами можно выполнить ряд операций:",[1060,5286,5287,5290,5293],{},[1063,5288,5289],{},"объединение множеств означает слияние элементов обоих множеств;",[1063,5291,5292],{},"под операцией пересечения множеств понимается поиск элементов, входящих в оба множества;",[1063,5294,5295],{},"под разностью множеств понимается исключение из одного множества элементов, присутствующих в другом множестве.",[554,5297,5298],{},"Основные особенности множеств:",[1060,5300,5301,5304],{},[1063,5302,5303],{},"множества похожи на списки, но не содержат дубликатов;",[1063,5305,5306],{},"с множествами можно выполнять различные операции — объединение пересечение и разность.",[554,5308,5309],{},[558,5310,5311],{"href":231},"Подробнее про множества",[566,5313,5315],{"id":5314},"допишем-код","Допишем код",[554,5317,5200,5318,5321,5322,5325,5326,5329,5330,5332,5333,5335,5336,5338],{},[3316,5319,5320],{},"covered"," содержит области, присутствующие как ",[3316,5323,5324],{},"states_needed",", так и в ",[3316,5327,5328],{},"states_for_station",".\nТаким образом, ",[3316,5331,5320],{}," — множество областей, не входящих в покрытие, которые покрываются текущей станцией!\nЗатем мы проверяем, покрывает ли эта станция больше областей, чем текущая станция ",[3316,5334,5150],{},".\nЕсли условие выполняется, то станция сохраняется в ",[3316,5337,5150],{},".\nНаконец, после завершения цикла best_station добавляется в итоговый список станции:",[3310,5340,5342],{"className":3312,"code":5341,"language":3314,"meta":982,"style":982},"final_station.add(best_station)\n",[3316,5343,5344],{"__ignoreMap":982},[3319,5345,5346],{"class":3321,"line":3322},[3319,5347,5341],{"class":3325},[554,5349,5350,5351,5353],{},"Также необходимо обновить содержимое ",[3316,5352,5324],{},".\nТе области(субъекты), которые входят в зону покрытия станций, больше не нужны:",[3310,5355,5357],{"className":3312,"code":5356,"language":3314,"meta":982,"style":982},"states_needed -= states_covered\n",[3316,5358,5359],{"__ignoreMap":982},[3319,5360,5361,5363,5366],{"class":3321,"line":3322},[3319,5362,4926],{"class":3325},[3319,5364,5365],{"class":3329},"-=",[3319,5367,5368],{"class":3325}," states_covered\n",[554,5370,5371,5372,5374,5375,5378],{},"Цикл продолжается, пока множество ",[3316,5373,5324],{}," не станет пустым. В конце остаюётся только вывести ",[3316,5376,5377],{},"final_stations",".\nПолный код выглядит так:",[3310,5380,5382],{"className":3312,"code":5381,"language":3314,"meta":982,"style":982},"# Для обозначения субъектов РФ используются коды\n# Переданный массив преобразуется в множество\nstates_needed = set([\"28\", \"29\", \"30\", \"31\", \"32\", \"33\", \"34\", \"35\"]) \n\nstations = {}\nstations[\"one\"] = set([\"31\", \"32\", \"33\"])\nstations[\"two\"] = set([\"29\", \"31\", \"28\"])\nstations[\"three\"] = set([\"30\", \"32\", \"34\"])\nstations[\"four\"] = set([\"32\", \"33\"])\nstations[\"five\"] = set([\"34\", \"35\"])\n\nfinal_stations = set()\nwhile states_needed:\n  best_station = None\n  states_covered = set()\n  for station, states_for_station in stations.items():\n    covered = states_needed & states_for_station\n    if len(covered) > len(states_covered) and station not in final_stations:\n      best_station = station\n      states_covered = covered\n  if best_station is not None:\n    states_needed -= states_covered\n    final_stations.add(best_station)\n    stations.pop(best_station)\n    \nprint(final_stations)\n",[3316,5383,5384,5388,5392,5435,5440,5448,5474,5500,5526,5548,5570,5574,5585,5592,5601,5612,5623,5638,5670,5680,5690,5709,5719,5725,5731,5737],{"__ignoreMap":982},[3319,5385,5386],{"class":3321,"line":3322},[3319,5387,4916],{"class":3493},[3319,5389,5390],{"class":3321,"line":1443},[3319,5391,4921],{"class":3493},[3319,5393,5394,5396,5398,5400,5402,5404,5406,5408,5410,5412,5414,5416,5418,5420,5422,5424,5426,5428,5430,5432],{"class":3321,"line":1458},[3319,5395,4926],{"class":3325},[3319,5397,3330],{"class":3329},[3319,5399,4931],{"class":3394},[3319,5401,4934],{"class":3325},[3319,5403,4937],{"class":3336},[3319,5405,3340],{"class":3325},[3319,5407,4942],{"class":3336},[3319,5409,3340],{"class":3325},[3319,5411,4947],{"class":3336},[3319,5413,3340],{"class":3325},[3319,5415,4952],{"class":3336},[3319,5417,3340],{"class":3325},[3319,5419,4957],{"class":3336},[3319,5421,3340],{"class":3325},[3319,5423,4962],{"class":3336},[3319,5425,3340],{"class":3325},[3319,5427,4967],{"class":3336},[3319,5429,3340],{"class":3325},[3319,5431,4972],{"class":3336},[3319,5433,5434],{"class":3325},"]) \n",[3319,5436,5437],{"class":3321,"line":1449},[3319,5438,5439],{"emptyLinePlaceholder":513},"\n",[3319,5441,5442,5444,5446],{"class":3321,"line":1444},[3319,5443,4987],{"class":3325},[3319,5445,3330],{"class":3329},[3319,5447,4992],{"class":3325},[3319,5449,5450,5452,5454,5456,5458,5460,5462,5464,5466,5468,5470,5472],{"class":3321,"line":3478},[3319,5451,4997],{"class":3325},[3319,5453,5000],{"class":3336},[3319,5455,3519],{"class":3325},[3319,5457,3330],{"class":3329},[3319,5459,4931],{"class":3394},[3319,5461,4934],{"class":3325},[3319,5463,4952],{"class":3336},[3319,5465,3340],{"class":3325},[3319,5467,4957],{"class":3336},[3319,5469,3340],{"class":3325},[3319,5471,4962],{"class":3336},[3319,5473,4302],{"class":3325},[3319,5475,5476,5478,5480,5482,5484,5486,5488,5490,5492,5494,5496,5498],{"class":3321,"line":3497},[3319,5477,4997],{"class":3325},[3319,5479,5027],{"class":3336},[3319,5481,3519],{"class":3325},[3319,5483,3330],{"class":3329},[3319,5485,4931],{"class":3394},[3319,5487,4934],{"class":3325},[3319,5489,4942],{"class":3336},[3319,5491,3340],{"class":3325},[3319,5493,4952],{"class":3336},[3319,5495,3340],{"class":3325},[3319,5497,4937],{"class":3336},[3319,5499,4302],{"class":3325},[3319,5501,5502,5504,5506,5508,5510,5512,5514,5516,5518,5520,5522,5524],{"class":3321,"line":3528},[3319,5503,4997],{"class":3325},[3319,5505,5054],{"class":3336},[3319,5507,3519],{"class":3325},[3319,5509,3330],{"class":3329},[3319,5511,4931],{"class":3394},[3319,5513,4934],{"class":3325},[3319,5515,4947],{"class":3336},[3319,5517,3340],{"class":3325},[3319,5519,4957],{"class":3336},[3319,5521,3340],{"class":3325},[3319,5523,4967],{"class":3336},[3319,5525,4302],{"class":3325},[3319,5527,5528,5530,5532,5534,5536,5538,5540,5542,5544,5546],{"class":3321,"line":3540},[3319,5529,4997],{"class":3325},[3319,5531,5081],{"class":3336},[3319,5533,3519],{"class":3325},[3319,5535,3330],{"class":3329},[3319,5537,4931],{"class":3394},[3319,5539,4934],{"class":3325},[3319,5541,4957],{"class":3336},[3319,5543,3340],{"class":3325},[3319,5545,4962],{"class":3336},[3319,5547,4302],{"class":3325},[3319,5549,5550,5552,5554,5556,5558,5560,5562,5564,5566,5568],{"class":3321,"line":3550},[3319,5551,4997],{"class":3325},[3319,5553,5104],{"class":3336},[3319,5555,3519],{"class":3325},[3319,5557,3330],{"class":3329},[3319,5559,4931],{"class":3394},[3319,5561,4934],{"class":3325},[3319,5563,4967],{"class":3336},[3319,5565,3340],{"class":3325},[3319,5567,4972],{"class":3336},[3319,5569,4302],{"class":3325},[3319,5571,5572],{"class":3321,"line":3562},[3319,5573,5439],{"emptyLinePlaceholder":513},[3319,5575,5577,5579,5581,5583],{"class":3321,"line":5576},12,[3319,5578,5133],{"class":3325},[3319,5580,3330],{"class":3329},[3319,5582,4931],{"class":3394},[3319,5584,5140],{"class":3325},[3319,5586,5588,5590],{"class":3321,"line":5587},13,[3319,5589,5160],{"class":3329},[3319,5591,5163],{"class":3325},[3319,5593,5595,5597,5599],{"class":3321,"line":5594},14,[3319,5596,5168],{"class":3325},[3319,5598,3330],{"class":3329},[3319,5600,5173],{"class":3394},[3319,5602,5604,5606,5608,5610],{"class":3321,"line":5603},15,[3319,5605,5178],{"class":3325},[3319,5607,3330],{"class":3329},[3319,5609,4931],{"class":3394},[3319,5611,5140],{"class":3325},[3319,5613,5615,5617,5619,5621],{"class":3321,"line":5614},16,[3319,5616,5189],{"class":3329},[3319,5618,5192],{"class":3325},[3319,5620,3403],{"class":3329},[3319,5622,5197],{"class":3325},[3319,5624,5626,5629,5631,5633,5635],{"class":3321,"line":5625},17,[3319,5627,5628],{"class":3325},"    covered ",[3319,5630,3330],{"class":3329},[3319,5632,5229],{"class":3325},[3319,5634,5232],{"class":3329},[3319,5636,5637],{"class":3325}," states_for_station\n",[3319,5639,5641,5644,5646,5648,5650,5652,5655,5658,5661,5664,5667],{"class":3321,"line":5640},18,[3319,5642,5643],{"class":3329},"    if",[3319,5645,5246],{"class":3394},[3319,5647,5249],{"class":3325},[3319,5649,5252],{"class":3329},[3319,5651,5246],{"class":3394},[3319,5653,5654],{"class":3325},"(states_covered) ",[3319,5656,5657],{"class":3329},"and",[3319,5659,5660],{"class":3325}," station ",[3319,5662,5663],{"class":3329},"not",[3319,5665,5666],{"class":3329}," in",[3319,5668,5669],{"class":3325}," final_stations:\n",[3319,5671,5673,5676,5678],{"class":3321,"line":5672},19,[3319,5674,5675],{"class":3325},"      best_station ",[3319,5677,3330],{"class":3329},[3319,5679,5267],{"class":3325},[3319,5681,5683,5686,5688],{"class":3321,"line":5682},20,[3319,5684,5685],{"class":3325},"      states_covered ",[3319,5687,3330],{"class":3329},[3319,5689,5277],{"class":3325},[3319,5691,5693,5695,5698,5701,5704,5707],{"class":3321,"line":5692},21,[3319,5694,5243],{"class":3329},[3319,5696,5697],{"class":3325}," best_station ",[3319,5699,5700],{"class":3329},"is",[3319,5702,5703],{"class":3329}," not",[3319,5705,5706],{"class":3394}," None",[3319,5708,3754],{"class":3325},[3319,5710,5712,5715,5717],{"class":3321,"line":5711},22,[3319,5713,5714],{"class":3325},"    states_needed ",[3319,5716,5365],{"class":3329},[3319,5718,5368],{"class":3325},[3319,5720,5722],{"class":3321,"line":5721},23,[3319,5723,5724],{"class":3325},"    final_stations.add(best_station)\n",[3319,5726,5728],{"class":3321,"line":5727},24,[3319,5729,5730],{"class":3325},"    stations.pop(best_station)\n",[3319,5732,5734],{"class":3321,"line":5733},25,[3319,5735,5736],{"class":3325},"    \n",[3319,5738,5740,5743],{"class":3321,"line":5739},26,[3319,5741,5742],{"class":3394},"print",[3319,5744,5745],{"class":3325},"(final_stations)\n",[554,5747,5748],{},"Вместо станций 1,2,3,5 можно было выбрать станции 2,3,4, и 5.\nНиже сравним время выполнения алгоритма:",[999,5750,5751,5864],{},[1002,5752,5753],{},[1005,5754,5755,5758,5806],{},[1008,5756,5757],{},"Кол-во станций",[1008,5759,5760,5761],{},"Точный алгоритм ",[582,5762,5764],{"className":5763,"jax":586},[585],[588,5765,5766,5779],{"style":1577,"xmlns":591,"width":1578,"height":1579,"role":594,"focusable":595,"viewBox":1580,"xmlnsXLink":597},[599,5767,5768,5771,5773,5775,5777],{},[602,5769],{"id":5770,"d":1586},"MJX-2-TEX-I-1D442",[602,5772],{"id":803,"d":609},[602,5774],{"id":815,"d":625},[602,5776],{"id":828,"d":829},[602,5778],{"id":818,"d":629},[639,5780,5781],{"stroke":641,"fill":641,"stroke-width":642,"transform":643},[639,5782,5783,5788,5792,5802],{"dataMmlNode":646},[639,5784,5785],{"dataMmlNode":674},[664,5786],{"dataC":1604,"xLinkHref":5787},"#MJX-2-TEX-I-1D442",[639,5789,5790],{"dataMmlNode":662,"transform":1608},[664,5791],{"dataC":666,"xLinkHref":846},[639,5793,5794,5798],{"dataMmlNode":655,"transform":1613},[639,5795,5796],{"dataMmlNode":681},[664,5797],{"dataC":705,"xLinkHref":874},[639,5799,5800],{"dataMmlNode":674,"transform":1620},[664,5801],{"dataC":927,"xLinkHref":928},[639,5803,5804],{"dataMmlNode":662,"transform":1626},[664,5805],{"dataC":712,"xLinkHref":879},[1008,5807,5808,5809],{},"Жадный алгоритм ",[582,5810,5812],{"className":5811,"jax":586},[585],[588,5813,5816,5833],{"style":1577,"xmlns":591,"width":5814,"height":4840,"role":594,"focusable":595,"viewBox":5815,"xmlnsXLink":597},"5.832ex","0 -833.9 2577.6 1083.9",[599,5817,5818,5821,5824,5827,5830],{},[602,5819],{"id":5820,"d":1586},"MJX-3-TEX-I-1D442",[602,5822],{"id":5823,"d":609},"MJX-3-TEX-N-28",[602,5825],{"id":5826,"d":829},"MJX-3-TEX-I-1D45B",[602,5828],{"id":5829,"d":625},"MJX-3-TEX-N-32",[602,5831],{"id":5832,"d":629},"MJX-3-TEX-N-29",[639,5834,5835],{"stroke":641,"fill":641,"stroke-width":642,"transform":643},[639,5836,5837,5842,5847,5859],{"dataMmlNode":646},[639,5838,5839],{"dataMmlNode":674},[664,5840],{"dataC":1604,"xLinkHref":5841},"#MJX-3-TEX-I-1D442",[639,5843,5844],{"dataMmlNode":662,"transform":1608},[664,5845],{"dataC":666,"xLinkHref":5846},"#MJX-3-TEX-N-28",[639,5848,5849,5854],{"dataMmlNode":655,"transform":1613},[639,5850,5851],{"dataMmlNode":674},[664,5852],{"dataC":927,"xLinkHref":5853},"#MJX-3-TEX-I-1D45B",[639,5855,5856],{"dataMmlNode":681,"transform":4878},[664,5857],{"dataC":705,"xLinkHref":5858},"#MJX-3-TEX-N-32",[639,5860,5861],{"dataMmlNode":662,"transform":4883},[664,5862],{"dataC":712,"xLinkHref":5863},"#MJX-3-TEX-N-29",[1015,5865,5866,5876,5887,5896],{},[1005,5867,5868,5870,5873],{},[1020,5869,1033],{},[1020,5871,5872],{},"3.3 сек",[1020,5874,5875],{},"2.5 сек",[1005,5877,5878,5881,5884],{},[1020,5879,5880],{},"10",[1020,5882,5883],{},"102.5 сек",[1020,5885,5886],{},"10 сек",[1005,5888,5889,5891,5894],{},[1020,5890,705],{},[1020,5892,5893],{},"13.6 лет",[1020,5895,5883],{},[1005,5897,5898,5901,5973],{},[1020,5899,5900],{},"100",[1020,5902,5903,5972],{},[582,5904,5906],{"className":5905,"jax":586},[585],[588,5907,5912,5932],{"style":5908,"xmlns":591,"width":5909,"height":5910,"role":594,"focusable":595,"viewBox":5911,"xmlnsXLink":597},"vertical-align: -0.05ex;","7.318ex","2.005ex","0 -864 3234.6 886",[599,5913,5914,5918,5922,5925,5929],{},[602,5915],{"id":5916,"d":5917},"MJX-4-TEX-N-34","M462 0Q444 3 333 3Q217 3 199 0H190V46H221Q241 46 248 46T265 48T279 53T286 61Q287 63 287 115V165H28V211L179 442Q332 674 334 675Q336 677 355 677H373L379 671V211H471V165H379V114Q379 73 379 66T385 54Q393 47 442 46H471V0H462ZM293 211V545L74 212L183 211H293Z",[602,5919],{"id":5920,"d":5921},"MJX-4-TEX-N-2217","M229 286Q216 420 216 436Q216 454 240 464Q241 464 245 464T251 465Q263 464 273 456T283 436Q283 419 277 356T270 286L328 328Q384 369 389 372T399 375Q412 375 423 365T435 338Q435 325 425 315Q420 312 357 282T289 250L355 219L425 184Q434 175 434 161Q434 146 425 136T401 125Q393 125 383 131T328 171L270 213Q283 79 283 63Q283 53 276 44T250 35Q231 35 224 44T216 63Q216 80 222 143T229 213L171 171Q115 130 110 127Q106 124 100 124Q87 124 76 134T64 161Q64 166 64 169T67 175T72 181T81 188T94 195T113 204T138 215T170 230T210 250L74 315Q65 324 65 338Q65 353 74 363T98 374Q106 374 116 368T171 328L229 286Z",[602,5923],{"id":5924,"d":617},"MJX-4-TEX-N-31",[602,5926],{"id":5927,"d":5928},"MJX-4-TEX-N-30","M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z",[602,5930],{"id":5931,"d":625},"MJX-4-TEX-N-32",[639,5933,5934],{"stroke":641,"fill":641,"stroke-width":642,"transform":643},[639,5935,5936,5942,5949],{"dataMmlNode":646},[639,5937,5938],{"dataMmlNode":681},[664,5939],{"dataC":5940,"xLinkHref":5941},"34","#MJX-4-TEX-N-34",[639,5943,5945],{"dataMmlNode":662,"transform":5944},"translate(722.2,0)",[664,5946],{"dataC":5947,"xLinkHref":5948},"2217","#MJX-4-TEX-N-2217",[639,5950,5952,5962],{"dataMmlNode":655,"transform":5951},"translate(1444.4,0)",[639,5953,5954,5957],{"dataMmlNode":681},[664,5955],{"dataC":685,"xLinkHref":5956},"#MJX-4-TEX-N-31",[664,5958],{"dataC":5959,"xLinkHref":5960,"transform":5961},"30","#MJX-4-TEX-N-30","translate(500,0)",[639,5963,5965],{"dataMmlNode":658,"transform":5964,"dataMjxTexclass":659},"translate(1033,393.1) scale(0.707)",[639,5966,5967,5970],{"dataMmlNode":681},[664,5968],{"dataC":705,"xLinkHref":5969},"#MJX-4-TEX-N-32",[664,5971],{"dataC":685,"xLinkHref":5956,"transform":5961}," лет",[1020,5974,5975],{},"16.68 мин",[554,5977,5978],{},"Жадные алгоритмы не всегда дают точный ответ, но они очень быстрые.\nЗадача о покрытии множеств относится к NP-трудным задачам.\nНемного позже в статьях я приведу больше примеров об NP-трудных задачах.\nА на этом знакомство с жадными алгоритмами можно считать успешным.",[551,5980,5981],{},[554,5982,5983,5984,5986],{},"В следующей статье речь пойдёт про ",[558,5985,560],{"href":299},".",[566,5988],{"id":982},[546,5990],{":isList":5991,"title":1208},"[\"Жадные алгоритмы стремятся к локальной оптимизации в расчёте на то, что в итоге будет достигнут глобальный оптимум;\",\"Если у вас имеется NP-трудная задача, лучше всего воспользоваться приближённым алгоритмом;\",\"Жадные алгоритмы легко реализовать и быстро выполнить, поэтому из них получаются хорошие приближённые алгоритмы.\"]",[554,5993,4575,5994,4580,5996,4584],{},[4577,5995,4579],{},[4577,5997,4583],{},[4586,5999],{},[1439,6001,1441],{},[1439,6003,6004],{},"html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":982,"searchDepth":1443,"depth":1444,"links":6006},[6007],{"id":4644,"depth":1443,"text":294,"children":6008},[6009,6010,6011],{"id":4659,"depth":1458,"text":4660},{"id":1513,"depth":1458,"text":1514},{"id":4784,"depth":1458,"text":4785,"children":6012},[6013,6014,6015,6016,6017,6018],{"id":4815,"depth":1449,"text":4816},{"id":4902,"depth":1449,"text":4903},{"id":5143,"depth":1449,"text":5144},{"id":5280,"depth":1449,"text":5281},{"id":5314,"depth":1449,"text":5315},{"id":982,"depth":1449,"text":982},"2026-04-28","Жадная стратегия при решении задач. NP-трудные задачи. Приближенное решение NP-полных задач.","images\u002Fblog\u002Fpython\u002Fst33\u002Fimg.png",{},33,{"title":294,"description":6020},"D4InitWt1v6iVnXaEcZvfWlmvWdgfLKLkICUhcARB_0",{"data":6027,"body":6028},{},{"type":6029,"children":6030},"root",[6031],{"type":6032,"tag":554,"props":6033,"children":6034},"element",{},[6035],{"type":6036,"value":6037},"text","Мой процесс является совместным и итеративным и обычно включает в себя такие этапы, как поиск и исследование, формирование идей, прототипирование, разработка, проверка и тестирование, визуальный контакт и тесное сотрудничество. Я адаптирую процесс в соответствии с потребностями и всегда уделяя особое внимание решениям, ориентированным на конечного пользователя моих услуг.",{"data":6039,"body":6040},{},{"type":6029,"children":6041},[6042],{"type":6032,"tag":554,"props":6043,"children":6044},{},[6045],{"type":6036,"value":6046},"Я специализируюсь на обучении информатики\u002Fпрограммирования на Python и fullstack разработке. Это включает в себя обучение учащихся для сдачи единого государственного экзамена ОГЭ\u002FЕГЭ по информатике. В области разработки это \"скрапинг и парсинг\" данных, интерактивное прототипирование, создание интуитивно понятных пользовательских интерфейсов, создание адаптивных приложений, веб-сайтов и веб-приложений. Моя цель – успешное обучение учащихся для сдачи экзаменов и создание цифровых продуктов от разработки концепции до внедрения.",{"data":6048,"body":6049},{},{"type":6029,"children":6050},[6051],{"type":6032,"tag":554,"props":6052,"children":6053},{},[6054],{"type":6036,"value":6055},"Конечно! Мне нравится работать с начинающими, помогая им формировать знания в области программирования и учить создавать решения с нуля. Я могу адаптировать свой процесс к быстро меняющейся среде обучения.",1780737497619]