This media is not supported in your browser
VIEW IN TELEGRAM
С наступающим 🎄❄️☃️ Сбычи мечт и много хорошего кода в новом 2025 году 🎁👩💻🧑💻
Подпишись 👉🏻 @KodduuPython 🤖
Подпишись 👉🏻 @KodduuPython 🤖
👍8❤2🔥2
Не успели купить 🎁, подарите знания (любой курс можно подарить):
1️⃣ Python: самый быстрый курс
2️⃣ Python Data Science: самый быстрый курс
👉 Junior Python Data Scientist (программа из курсов 1️⃣ и 2️⃣)
3️⃣ Python в нескучных примерах (50)
👉 Junior Python Developer and Data Scientist (программа из курсов 1️⃣, 2️⃣ и 3️⃣)
4️⃣ Топ 100 вопросов с реальных собеседований по Python (шпаргалка) 👉 бесплатный курс
5️⃣ Язык программирования BrainFuck или ВыносМозга! 👉 бесплатный курс
Подпишись 👉🏻 @KodduuPython 🤖
1️⃣ Python: самый быстрый курс
2️⃣ Python Data Science: самый быстрый курс
👉 Junior Python Data Scientist (программа из курсов 1️⃣ и 2️⃣)
3️⃣ Python в нескучных примерах (50)
👉 Junior Python Developer and Data Scientist (программа из курсов 1️⃣, 2️⃣ и 3️⃣)
4️⃣ Топ 100 вопросов с реальных собеседований по Python (шпаргалка) 👉 бесплатный курс
5️⃣ Язык программирования BrainFuck или ВыносМозга! 👉 бесплатный курс
Подпишись 👉🏻 @KodduuPython 🤖
👍4❤1
Ниже пример простого скрипта на Python, который собирает новогоднее поздравление из случайно выбранных слов и фраз. Его можно расширять, добавлять дополнительные списки или логику по своему вкусу.
### Как это работает:
1. Списки со словами и фразами: Для разных частей поздравления (`starts`,
2. Модуль `random`: При помощи
3. Сборка текста: Формируем итоговую строку (`greeting`), используя f-строки с подстановками.
4. Вывод результата: Вызов
При желании можно:
- Добавить больше слов в списки.
- Формировать более сложные конструкции предложений.
- Сохранять поздравление в файл или отправлять его по электронной почте.
Подпишись 👉🏻 @KodduuPython 🤖
import random
def generate_new_year_greeting():
"""
Генерирует новогоднее поздравление, выбирая слова из списков случайным образом.
"""
# Приветствия/начальные фразы
starts = [
"Поздравляю",
"Сердечно поздравляю",
"От всей души приветствую",
"С огромной радостью поздравляю"
]
# Прилагательные/эпитеты
adjectives = [
"счастливого",
"волшебного",
"радостного",
"прекрасного",
"блестящего"
]
# Основные пожелания
wishes = [
"здоровья",
"удачи",
"радости",
"любви",
"тепла",
"творческих успехов",
"исполнения всех желаний"
]
# Дополнительные фразы
extras = [
"чтобы каждый день был наполнен чудесами",
"пусть все мечты сбываются",
"желаю верить в себя и покорять любые вершины",
"пусть в сердце живёт только добро",
"и пусть этот год принесёт много ярких событий"
]
# Заключительные фразы/пожелания
endings = [
"С Новым годом!",
"Пусть в этом году будет всё на высоте!",
"Пусть в новом году будет только лучше!",
"С праздником!",
"Свершений и новых побед!"
]
# Собираем предложение
greeting = (
f"{random.choice(starts)} с наступившим {random.choice(adjectives)} Новым годом!\n\n"
f"Желаю {random.choice(wishes)}, {random.choice(wishes)}, а также {random.choice(wishes)}.\n"
f"И, конечно, {random.choice(extras)}.\n\n"
f"{random.choice(endings)}"
)
return greeting
def main():
# Генерируем и выводим поздравление
print(generate_new_year_greeting())
if __name__ == "__main__":
main()
### Как это работает:
1. Списки со словами и фразами: Для разных частей поздравления (`starts`,
adjectives, wishes, extras, `endings`) заведены отдельные списки. 2. Модуль `random`: При помощи
random.choice выбирается по одной фразе/слову из каждого списка. 3. Сборка текста: Формируем итоговую строку (`greeting`), используя f-строки с подстановками.
4. Вывод результата: Вызов
print(generate_new_year_greeting()) выдаёт нам случайное поздравление на каждом запуске. При желании можно:
- Добавить больше слов в списки.
- Формировать более сложные конструкции предложений.
- Сохранять поздравление в файл или отправлять его по электронной почте.
Подпишись 👉🏻 @KodduuPython 🤖
👍8❤4
Ниже приведён шуточный пример кода на Python, который «оценивает», сколько салата «Оливье» было съедено во всём мире на Новый год. Все расчёты, конечно, условны и сделаны для иллюстрации, а не на основе реальной статистики.
### Как работает код
1. Параметры «мировой» статистики
-
-
-
2. Средняя порция
В примере для простоты взято \(300\) граммов на человека. Кто-то съедает больше, кто-то меньше — но пусть будет так.
3. Вычисление
- Находим общее число людей, которые (гипотетически) ели Оливье.
- Умножаем на 300 г.
- Переводим всё это в килограммы.
4. Случайный разброс
В коде мы добавляем ±10% (переменная `fluctuation_percent`), чтобы сделать оценку ещё менее «точной» и более шутливой.
5. Вывод
В
---
Это, конечно, не настоящее научное исследование, а лишь пример того, как можно реализовать в Python «виртуальный счётчик» чего угодно — например, салата Оливье в новогоднюю ночь.
Подпишись 👉🏻 @KodduuPython 🤖
import random
def estimate_olivier_eaten():
"""
Возвращает приблизительное (и шуточное) количество килограммов Оливье,
которые были съедены на планете в новогоднюю ночь.
"""
# (1) Численность населения (приблизительно, в миллиардах)
world_population = 8.05 # млрд (примерно к 2024 году)
# (2) Процент людей, отмечающих Новый год
# Условно предположим, что его празднуют 80% населения
celebrating_people_percent = 0.8
# (3) Процент любителей Оливье среди тех, кто празднует
# Пусть из празднующих минимум 50% едят Оливье
olivier_lovers_percent = 0.5
# (4) Средняя порция Оливье на человека (в граммах)
# Предположим 300 г на душу – кто-то съест больше, кто-то меньше
avg_portion_per_person_grams = 300
# (5) Считаем
# Сколько людей ест Оливье
number_of_olivier_eaters = world_population * 1_000_000_000 \
* celebrating_people_percent \
* olivier_lovers_percent
# Сколько всего граммов Оливье пришлось на этих людей
total_grams_olivier = number_of_olivier_eaters * avg_portion_per_person_grams
# Переводим в килограммы
total_kilos_olivier = total_grams_olivier / 1000
return total_kilos_olivier
def main():
# Получим оценку
kilos_olivier = estimate_olivier_eaten()
# Для «дополнительной реалистичности» внесём случайный разброс ±10%
# Ведь точное число никто не знает 🙂
fluctuation_percent = random.uniform(-0.1, 0.1)
kilos_olivier *= (1 + fluctuation_percent)
# Красиво форматируем число (например, с разделением разрядов)
result_str = f"{kilos_olivier:,.0f}" # округлим до целых
print(f"По приблизительным (шуточным) оценкам, в новогоднюю ночь "
f"на планете было съедено около {result_str} кг Оливье!")
if __name__ == "__main__":
main()
### Как работает код
1. Параметры «мировой» статистики
-
world_population — приблизительная численность населения Земли в миллиардах. -
celebrating_people_percent — доля тех, кто отмечает Новый год. -
olivier_lovers_percent — доля тех, кто в праздничную ночь ест Оливье (из тех, кто вообще празднует).2. Средняя порция
В примере для простоты взято \(300\) граммов на человека. Кто-то съедает больше, кто-то меньше — но пусть будет так.
3. Вычисление
- Находим общее число людей, которые (гипотетически) ели Оливье.
- Умножаем на 300 г.
- Переводим всё это в килограммы.
4. Случайный разброс
В коде мы добавляем ±10% (переменная `fluctuation_percent`), чтобы сделать оценку ещё менее «точной» и более шутливой.
5. Вывод
В
main() печатаем итоговое «псевдо-число» в красиво отформатированном виде.---
Это, конечно, не настоящее научное исследование, а лишь пример того, как можно реализовать в Python «виртуальный счётчик» чего угодно — например, салата Оливье в новогоднюю ночь.
Подпишись 👉🏻 @KodduuPython 🤖
⚡5❤1
Ниже приведён упрощённый пример на Python, демонстрирующий базовые идеи, которые могли использоваться для плановых расчётов в экономике (как, например, в СССР). Он не претендует на историческую точность и полноту, но иллюстрирует общий подход к задачам планирования с применением математической оптимизации.
---
Краткое введение в задачу
Предположим, что у нас есть несколько типов ресурсов (например, металл, дерево, электроэнергия и т.д.), и мы хотим произвести несколько видов товаров (станки, мебель, автомобили и т.д.). У каждого товара есть:
1. План по выпуску (то есть минимальное количество, которое нужно произвести по указу «сверху»).
2. Потребление ресурсов на единицу выпуска (например, один автомобиль требует 1 тонну металла, 10 кВт⋅ч электроэнергии и т.п.).
3. Ограниченное количество ресурсов, доступных в нашей «народно-хозяйственной» системе.
Основная задача: найти, сколько каждого вида товара нужно произвести, чтобы:
- Выполнить (или превысить) плановые задания (заказ государства).
- Не превысить доступные объёмы ресурсов.
- Максимизировать (или минимизировать) некую целевую функцию — например, суммарную “пользу” (удовлетворение потребностей народа / вклад в экономику).
В реальном СССР и других плановых экономиках задач было в разы больше и сложнее: расчёты производились по десяткам тысяч наименований продукции, учитывалась логистика, взаимозаменяемость ресурсов, отраслевые приоритеты и т.д. В 70–80-х годах это было крайне затруднительно из-за недостатка вычислительной техники и несовершенства методов планирования, что приводило к неточностям, дефицитам и дисбалансам.
Сегодня же, используя современные вычислительные мощности и продвинутые алгоритмы (линейное и нелинейное программирование, машинное обучение, системы принятия решений в реальном времени и т.п.), можно в теории гораздо эффективнее решать плановые задачи. Хотя, конечно, сама концепция плановой экономики поднимает множество вопросов и проблем, выходящих за рамки чисто вычислительной стороны дела.
Сложность плановых расчётов в 70–80-х
Недостаток вычислительной техники. ЭВМ в СССР (например, «Минск», «Урал», ЕС ЭВМ) имели на порядки меньшую производительность по сравнению с современными ПК. В 70–80-е годы такие машины могли обрабатывать относительно простые и не слишком большие задачи. Полноценный учёт сотен тысяч наименований товаров и ресурсов представлял колоссальную computational-проблему.
Ручной труд экономистов и плановиков. Многие расчёты производились вручную, с помощью арифмометров, перфокарт. Часть плановых заданий корректировалась “на местах”, что приводило к искажению общей картины.
Ограничения математических моделей. Методологии линейного программирования, многокритериальной оптимизации и т. п. тогда не были развиты так широко, как сейчас. Вдобавок многие экономические и социальные факторы трудно формализовать линейной моделью.
В результате получался грубый (и часто запаздывающий) план, который вёл к дефициту одних товаров и избытку других, очередям, бартерным схемам и так далее.
Подпишись 👉🏻 @KodduuPython 🤖
---
Краткое введение в задачу
Предположим, что у нас есть несколько типов ресурсов (например, металл, дерево, электроэнергия и т.д.), и мы хотим произвести несколько видов товаров (станки, мебель, автомобили и т.д.). У каждого товара есть:
1. План по выпуску (то есть минимальное количество, которое нужно произвести по указу «сверху»).
2. Потребление ресурсов на единицу выпуска (например, один автомобиль требует 1 тонну металла, 10 кВт⋅ч электроэнергии и т.п.).
3. Ограниченное количество ресурсов, доступных в нашей «народно-хозяйственной» системе.
Основная задача: найти, сколько каждого вида товара нужно произвести, чтобы:
- Выполнить (или превысить) плановые задания (заказ государства).
- Не превысить доступные объёмы ресурсов.
- Максимизировать (или минимизировать) некую целевую функцию — например, суммарную “пользу” (удовлетворение потребностей народа / вклад в экономику).
В реальном СССР и других плановых экономиках задач было в разы больше и сложнее: расчёты производились по десяткам тысяч наименований продукции, учитывалась логистика, взаимозаменяемость ресурсов, отраслевые приоритеты и т.д. В 70–80-х годах это было крайне затруднительно из-за недостатка вычислительной техники и несовершенства методов планирования, что приводило к неточностям, дефицитам и дисбалансам.
Сегодня же, используя современные вычислительные мощности и продвинутые алгоритмы (линейное и нелинейное программирование, машинное обучение, системы принятия решений в реальном времени и т.п.), можно в теории гораздо эффективнее решать плановые задачи. Хотя, конечно, сама концепция плановой экономики поднимает множество вопросов и проблем, выходящих за рамки чисто вычислительной стороны дела.
Сложность плановых расчётов в 70–80-х
Недостаток вычислительной техники. ЭВМ в СССР (например, «Минск», «Урал», ЕС ЭВМ) имели на порядки меньшую производительность по сравнению с современными ПК. В 70–80-е годы такие машины могли обрабатывать относительно простые и не слишком большие задачи. Полноценный учёт сотен тысяч наименований товаров и ресурсов представлял колоссальную computational-проблему.
Ручной труд экономистов и плановиков. Многие расчёты производились вручную, с помощью арифмометров, перфокарт. Часть плановых заданий корректировалась “на местах”, что приводило к искажению общей картины.
Ограничения математических моделей. Методологии линейного программирования, многокритериальной оптимизации и т. п. тогда не были развиты так широко, как сейчас. Вдобавок многие экономические и социальные факторы трудно формализовать линейной моделью.
В результате получался грубый (и часто запаздывающий) план, который вёл к дефициту одних товаров и избытку других, очередям, бартерным схемам и так далее.
Подпишись 👉🏻 @KodduuPython 🤖
## Пример кода на Python
Для решения подобных задач часто применяют библиотеки для линейного программирования (Linear Programming). Одна из популярных библиотек в Python —
Ниже приведён пример задачи, где мы хотим произвести три вида продукции: A, B и C.
- Каждый вид продукции требует определённое количество ресурсов (R1 и R2).
- Есть плановый минимум по каждому товару.
- Есть ограничения на объём ресурсов.
- Мы хотим максимизировать так называемую “общественную пользу” (условный показатель важности каждого товара).
### Код
### Интерпретация результатов
1. Статус решения может показать, что задача решена оптимально (`Optimal`) или что оптимального решения нет (если, например, требования слишком высоки и ресурсы не позволяют их удовлетворить).
2. Количество продукции (xA, xB, xC) — сколько штук каждого товара в итоге планируется выпускать.
3. Максимальная польза (value(problem.objective)) показывает значение целевой функции.
Подпишись 👉🏻 @KodduuPython 🤖
Для решения подобных задач часто применяют библиотеки для линейного программирования (Linear Programming). Одна из популярных библиотек в Python —
PuLP. Если её нет, установите командой:
pip install pulp
Ниже приведён пример задачи, где мы хотим произвести три вида продукции: A, B и C.
- Каждый вид продукции требует определённое количество ресурсов (R1 и R2).
- Есть плановый минимум по каждому товару.
- Есть ограничения на объём ресурсов.
- Мы хотим максимизировать так называемую “общественную пользу” (условный показатель важности каждого товара).
### Код
# Пример кода, иллюстрирующего подход к задаче планирования
from pulp import LpProblem, LpMaximize, LpVariable, LpInteger, lpSum, LpStatus, value
# Создаём задачу линейного программирования (ЛП)
problem = LpProblem("SovietPlan", LpMaximize)
# Объявим переменные:
# xA, xB, xC — количество единиц продукции A, B и C, которое мы собираемся произвести.
# для наглядности используем целочисленное программирование (LpInteger),
# хотя в реальности могут быть и вещественные переменные.
xA = LpVariable('xA', lowBound=0, cat=LpInteger)
xB = LpVariable('xB', lowBound=0, cat=LpInteger)
xC = LpVariable('xC', lowBound=0, cat=LpInteger)
# Плановые задания (минимальное количество, которое нужно произвести)
planA = 10
planB = 20
planC = 5
# Коэффициенты потребления ресурсов на единицу каждого товара.
# Пусть ресурс R1 (например, металл) и ресурс R2 (например, электроэнергия).
# Допустим, на производство 1 единицы A нужно 3 ед. R1 и 1 ед. R2,
# на производство 1 единицы B — 2 ед. R1 и 2 ед. R2,
# на производство 1 единицы C — 4 ед. R1 и 3 ед. R2
r1_for_A = 3
r2_for_A = 1
r1_for_B = 2
r2_for_B = 2
r1_for_C = 4
r2_for_C = 3
# Доступное количество ресурсов
R1_available = 100 # например, 100 тонн металла
R2_available = 90 # например, 90 кВт⋅ч условной электроэнергии
# "Польза" (или приоритет) от каждой единицы товара
# В реальном случае это могло бы учитывать потребности населения,
# важность для военной промышленности, экспортный потенциал и т.п.
benefitA = 5
benefitB = 4
benefitC = 6
# Целевая функция: максимизируем суммарную "пользу"
problem += (benefitA * xA + benefitB * xB + benefitC * xC), "Total_Benefit"
# Добавим ограничения
# 1. Выполнение плановых заданий
problem += xA >= planA, "Min_A"
problem += xB >= planB, "Min_B"
problem += xC >= planC, "Min_C"
# 2. Ограничение по ресурсам
problem += (r1_for_A * xA + r1_for_B * xB + r1_for_C * xC) <= R1_available, "Res_R1"
problem += (r2_for_A * xA + r2_for_B * xB + r2_for_C * xC) <= R2_available, "Res_R2"
# Решаем задачу
problem.solve()
# Вывод результатов
print(f"Статус решения: {LpStatus[problem.status]}")
print(f"Оптимальное количество продукции A (xA): {xA.varValue}")
print(f"Оптимальное количество продукции B (xB): {xB.varValue}")
print(f"Оптимальное количество продукции C (xC): {xC.varValue}")
print(f"Максимальная польза: {value(problem.objective)}")
### Интерпретация результатов
1. Статус решения может показать, что задача решена оптимально (`Optimal`) или что оптимального решения нет (если, например, требования слишком высоки и ресурсы не позволяют их удовлетворить).
2. Количество продукции (xA, xB, xC) — сколько штук каждого товара в итоге планируется выпускать.
3. Максимальная польза (value(problem.objective)) показывает значение целевой функции.
Подпишись 👉🏻 @KodduuPython 🤖
Ниже приведу пример задачи из современной практики, которая по своей структуре напоминает упрощённую модель плановой экономики, но уже в контексте цепочек поставок (Supply Chain). Это одна из наиболее распространённых и сложных задач в современной логистике и экономике. В реальных условиях такие задачи включают сотни (а то и тысячи) складов, фабрик, пунктов потребления, видов транспорта и видов продукции.
Пример:
- Есть два завода (Factory1, Factory2), на которых производятся два вида товаров (Product A и Product B).
- Есть два распределительных центра (склада) (DC1, DC2).
- Есть два региона с конечным спросом (Market1, Market2).
- Мы знаем спрос в каждом регионе по каждому товару, ограничения по мощности заводов (сколько каждого товара они могут произвести) и ёмкость складов (сколько там можно держать товаров).
- Мы хотим минимизировать совокупные затраты (произвести товар, перевезти с завода на склад, затем со склада — к конечному потребителю).
Подобная постановка задачи — задача оптимизации в цепочке поставок (supply chain optimization), которая, как и плановая задача, может вырасти до огромных масштабов и требовать значительных вычислительных ресурсов.
---
## Иллюстративный пример на Python (используем библиотеку PuLP)
> Для решения потребуется библиотека PuLP. Установить её можно командой:
>
Пример:
- Есть два завода (Factory1, Factory2), на которых производятся два вида товаров (Product A и Product B).
- Есть два распределительных центра (склада) (DC1, DC2).
- Есть два региона с конечным спросом (Market1, Market2).
- Мы знаем спрос в каждом регионе по каждому товару, ограничения по мощности заводов (сколько каждого товара они могут произвести) и ёмкость складов (сколько там можно держать товаров).
- Мы хотим минимизировать совокупные затраты (произвести товар, перевезти с завода на склад, затем со склада — к конечному потребителю).
Подобная постановка задачи — задача оптимизации в цепочке поставок (supply chain optimization), которая, как и плановая задача, может вырасти до огромных масштабов и требовать значительных вычислительных ресурсов.
---
## Иллюстративный пример на Python (используем библиотеку PuLP)
> Для решения потребуется библиотека PuLP. Установить её можно командой:
>
> pip install pulp
>
from pulp import (
LpProblem, LpMinimize, LpVariable, LpStatus, lpSum, LpInteger, value
)
# ---------------------------
# 1. ДАННЫЕ ЗАДАЧИ
# ---------------------------
# Заводы (factories), Склады (distribution centers), Рынки/регионы (markets)
factories = ["Factory1", "Factory2"]
distribution_centers = ["DC1", "DC2"]
markets = ["Market1", "Market2"]
products = ["ProductA", "ProductB"]
# Производственные мощности (максимальное кол-во единиц товара,
# которое может быть выпущено на каждом заводе)
# form: capacity[завод][продукт]
capacity = {
"Factory1": {"ProductA": 100, "ProductB": 80},
"Factory2": {"ProductA": 120, "ProductB": 100}
}
# Ёмкость складов (сколько всего единиц любых товаров может храниться на складе)
# form: dc_capacity[склад]
dc_capacity = {
"DC1": 150,
"DC2": 150
}
# Спрос в регионах (сколько единиц каждого товара нужно в каждом рынке)
# form: demand[рынок][продукт]
demand = {
"Market1": {"ProductA": 60, "ProductB": 40},
"Market2": {"ProductA": 80, "ProductB": 70}
}
# Себестоимость производства (cost of production) на каждом заводе
# form: production_cost[завод][продукт]
production_cost = {
"Factory1": {"ProductA": 2.0, "ProductB": 3.0},
"Factory2": {"ProductA": 2.5, "ProductB": 2.8}
}
# Стоимость транспортировки с завода до склада (за 1 единицу товара)
# form: transport_cost_factory_dc[(завод, склад)]
transport_cost_factory_dc = {
("Factory1", "DC1"): 0.5,
("Factory1", "DC2"): 0.6,
("Factory2", "DC1"): 0.7,
("Factory2", "DC2"): 0.4
}
# Стоимость транспортировки со склада к рынку (за 1 единицу товара)
# form: transport_cost_dc_market[(склад, рынок)]
transport_cost_dc_market = {
("DC1", "Market1"): 0.3,
("DC1", "Market2"): 0.8,
("DC2", "Market1"): 0.6,
("DC2", "Market2"): 0.5
}
# ---------------------------
# 2. ПОСТАНОВКА ЗАДАЧИ
# ---------------------------
# Создадим задачу линейного программирования: минимизация общих затрат
problem = LpProblem("SupplyChainOptimization", LpMinimize)
# ---------------------------
# 3. ПЕРЕМЕННЫЕ
# ---------------------------
# Пусть:
# x_fdc[p, f, dc] = количество товара p, производимого на заводе f,
# и отправляемого на склад dc
#
# y_dcm[p, dc, m] = количество товара p, отгружаемого со склада dc на рынок m
# Объявим переменные как неотрицательные целые (или неотрицательные непрерывные — зависит от контекста)
x_fdc = {}
for p in products:
for f in factories:
for dc in distribution_centers:
x_fdc[(p, f, dc)] = LpVariable(
f"x_{p}_{f}_{dc}",
lowBound=0,
cat='Continuous'
)
y_dcm = {}
for p in products:
for dc in distribution_centers:
for m in markets:
y_dcm[(p, dc, m)] = LpVariable(
f"y_{p}_{dc}_{m}",
lowBound=0,
cat='Continuous'
)
# ---------------------------
# 4. ЦЕЛЕВАЯ ФУНКЦИЯ
# ---------------------------
# Общие затраты = затраты на производство + затраты на перевозку от завода к складу + от склада к рынку
problem += lpSum(
production_cost[f][p] * x_fdc[(p, f, dc)]
+ transport_cost_factory_dc[(f, dc)] * x_fdc[(p, f, dc)]
for p in products
for f in factories
for dc in distribution_centers
) + lpSum(
transport_cost_dc_market[(dc, m)] * y_dcm[(p, dc, m)]
for p in products
for dc in distribution_centers
for m in markets
), "Total_Cost"
# ---------------------------
# 5. ОГРАНИЧЕНИЯ
# ---------------------------
# (A) Ограничения по производственным мощностям заводов:
# сумма отправленного товара p с завода f на все склады dc <= capacity[f][p]
for f in factories:
for p in products:
problem += lpSum(x_fdc[(p, f, dc)] for dc in distribution_centers) <= capacity[f][p], \
f"ProdCapacity_{f}_{p}"
# (B) Ограничения по ёмкости складов:
# на складе dc общее кол-во хранимых товаров (прибывших от всех заводов)
# не должно превышать dc_capacity[dc],
# но! нужно учесть, что то, что пришло на склад, может сразу уехать на рынок.
# Если мы считаем, что склад одновременно может хранить всё, что приходит,
# и лимит — это некая "пропускная способность", то упростим до:
# Σ(продуктов, заводов) x_fdc <= capacity_dc
# В реальности часто вводят дополнительные переменные для учёта запасов.
# Сделаем упрощённо.
for dc in distribution_centers:
problem += lpSum(x_fdc[(p, f, dc)] for p in products for f in factories) <= dc_capacity[dc], \
f"StorageCapacity_{dc}"
# (C) Баланс на складе (поток товаров через склад):
# кол-во товара p, пришедшее на склад dc, должно быть равно
# кол-ву, которое отгружается дальше в рынки (если мы предполагаем 0 складских запасов в конце).
# Σ(factories) x_fdc = Σ(markets) y_dcm
for dc in distribution_centers:
for p in products:
problem += lpSum(x_fdc[(p, f, dc)] for f in factories) == lpSum(y_dcm[(p, dc, m)] for m in markets), \
f"FlowBalance_{dc}_{p}"
# (D) Удовлетворение спроса в каждом рынке:
# Σ(dc) y_dcm >= demand[m][p]
for m in markets:
for p in products:
problem += lpSum(y_dcm[(p, dc, m)] for dc in distribution_centers) >= demand[m][p], \
f"Demand_{m}_{p}"
# ---------------------------
# 6. РЕШЕНИЕ ЗАДАЧИ
# ---------------------------
problem.solve()
# ---------------------------
# 7. ВЫВОД РЕЗУЛЬТАТОВ
# ---------------------------
print(f"Статус решения: {LpStatus[problem.status]}")
print(f"Минимальные совокупные затраты: {value(problem.objective):.2f}\n")
for (p, f, dc) in x_fdc:
qty = x_fdc[(p, f, dc)].varValue
if qty > 0:
print(f"Производство {p} на {f}, отправка на {dc}: {qty}")
for (p, dc, m) in y_dcm:
qty = y_dcm[(p, dc, m)].varValue
if qty > 0:
print(f"Отгрузка {p} со склада {dc} в {m}: {qty}")
В реальной задаче, особенно если нужно учитывать наличие запасов на складах и временные интервалы, логистические (транспортные) ограничения (наличие вагонов, машин, графики перевозок), затраты на хранение, несколько периодов планирования и прочее, модель становится значительно более сложной и крупной.
Подпишись 👉🏻 @KodduuPython 🤖
⚡6
Ниже приведён пример кода на Python, иллюстрирующего «задачу о маршрутах Деда Мороза» (упрощённая версия задачи коммивояжёра). В ней мы хотим найти оптимальный маршрут Деда Мороза, чтобы он мог доставить подарки в несколько домов (точек на карте), начиная и заканчивая в условном «Лапландском логистическом центре» (или просто в «домике Деда Мороза»).
Здесь мы используем библиотеку OR-Tools от Google (а не `pulp`). Если библиотеки нет, установите её:
## Пример кода
Здесь мы используем библиотеку OR-Tools от Google (а не `pulp`). Если библиотеки нет, установите её:
pip install ortools
## Пример кода
from ortools.constraint_solver import routing_enums
from ortools.constraint_solver import pywrapcp
def create_data_model():
"""
Создаём структуру с входными данными.
distance_matrix: матрица расстояний между всеми точками (0-я точка — «Лапландия»).
num_vehicles: количество "транспортных средств" (один Дед Мороз).
depot: индекс начальной/конечной точки (тоже «Лапландия»).
"""
data = {}
# Пример: у нас есть 6 домов + 1 "домик Деда Мороза" (всего 7 точек).
# Матрицу расстояний можно задать произвольно или сгенерировать.
# Ниже — условный пример (симметричная матрица).
data['distance_matrix'] = [
# От каждой точки до каждой (0-я строка — расстояния из «Лапландии»).
[0, 10, 15, 20, 25, 30, 12], # Lapland (0) -> ...
[10, 0, 18, 13, 28, 15, 22], # House1 (1) -> ...
[15, 18, 0, 17, 16, 22, 15], # House2 (2)
[20, 13, 17, 0, 14, 19, 23], # House3 (3)
[25, 28, 16, 14, 0, 25, 20], # House4 (4)
[30, 15, 22, 19, 25, 0, 18], # House5 (5)
[12, 22, 15, 23, 20, 18, 0 ], # House6 (6)
]
data['num_vehicles'] = 1 # Дед Мороз «один»
data['depot'] = 0 # Начальная (и конечная) точка — 0, то есть «Лапландия»
return data
def main():
# Создаём данные
data = create_data_model()
distance_matrix = data['distance_matrix']
num_locations = len(distance_matrix) # Всего точек (включая «Лапландию»)
num_vehicles = data['num_vehicles']
depot = data['depot']
# Создаём менеджер маршрутов и модель
manager = pywrapcp.RoutingIndexManager(
num_locations, # кол-во локаций (вершин)
num_vehicles, # кол-во «трансп. средств»
depot # индекс депо (старт/финиш)
)
routing = pywrapcp.RoutingModel(manager)
# Функция-«коллбек», возвращающая расстояние между двумя точками
def distance_callback(from_index, to_index):
# Преобразуем внутренние индексы маршрутизатора в индексы из матрицы
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return distance_matrix[from_node][to_node]
# Регистрируем функцию коллбека и присваиваем ей ID
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# Зададим параметры поиска (например, стратегию поиска маршрута)
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums.FirstSolutionStrategy.PATH_CHEAPEST_ARC
)
# По желанию — включим какую-нибудь эвристику локального поиска
# search_parameters.local_search_metaheuristic = (
# routing_enums.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
# )
# search_parameters.time_limit.seconds = 5 # ограничение по времени
# Запускаем решение
solution = routing.SolveWithParameters(search_parameters)
if solution:
# Выводим итоговый маршрут
print("Оптимальный маршрут Деда Мороза (минимальное суммарное расстояние):")
index = routing.Start(0) # начинаем с депо (Лапландия)
plan_output = "Лапландия -> "
route_distance = 0
while not routing.IsEnd(index):
next_index = solution.Value(routing.NextVar(index))
route_distance += routing.GetArcCostForVehicle(index, next_index, 0)
plan_output += f"House{manager.IndexToNode(next_index)} -> "
index = next_index
plan_output += "Лапландия (конец)"
print(plan_output)
print(f"Общее расстояние: {route_distance}")
else:
print("Решение не найдено!")
if __name__ == '__main__':
main()
### Пояснения
1. OR-Tools — это мощная библиотека от Google для решения задач оптимизации (в том числе маршрутизации, линейного и целочисленного программирования, расписаний и т. д.).
2. Ключевые моменты:
- distance_matrix: матрица расстояний между всеми точками (включая точку «Лапландии», где начинается и заканчивается маршрут).
- RoutingIndexManager и RoutingModel: объекты, которые отвечают за «оптимизационную модель».
- distance_callback: функция, которая для каждой пары «откуда–куда» возвращает расстояние.
- В конце мы получаем итоговый маршрут (последовательность посещения домов), чтобы суммарное расстояние было минимальным.
3. Мы предположили, что Дед Мороз должен объехать все дома (узлы) один раз и вернуться в исходную точку (в классической постановке — задача коммивояжёра). В результате мы ищем маршрут, минимизирующий общее расстояние путешествия.
4. В реальном мире можно добавлять множество дополнительных условий:
- Временные окна (должен доставить подарок до определённого времени).
- Ограничения по весу и объёму подарков (если у Деда Мороза несколько волшебных саней).
- Разные скорости движения или разные стоимости поездки (например, снежные заносы).
Но даже в таком упрощённом виде пример показывает, как другая библиотека (OR-Tools), а не
PuLP, применяется для решения оптимизационной задачи на тему «доставки подарков Дедом Морозом».Подпишись 👉🏻 @KodduuPython 🤖
🔥5
NetworkX — это удобная и мощная библиотека для работы с графами на Python. С её помощью можно:
- Создавать графы (ориентированные и неориентированные)
- Добавлять вершины и рёбра
- Находить кратчайшие пути (алгоритмы Дейкстры, Беллмана — Форда и др.)
- Искать связные компоненты, вычислять центральности, кластеризации и многое другое
Ниже — короткий пример, где мы создаём простой граф, добавляем рёбра и ищем кратчайший путь между двумя узлами:
NetworkX хорошо подходит для исследований в области сетевых структур, социальных графов, логистики, оптимизации и просто для обучения графовым алгоритмам.
Подпишись 👉🏻 @KodduuPython 🤖
- Создавать графы (ориентированные и неориентированные)
- Добавлять вершины и рёбра
- Находить кратчайшие пути (алгоритмы Дейкстры, Беллмана — Форда и др.)
- Искать связные компоненты, вычислять центральности, кластеризации и многое другое
Ниже — короткий пример, где мы создаём простой граф, добавляем рёбра и ищем кратчайший путь между двумя узлами:
import networkx as nx
# Создадим неориентированный граф
G = nx.Graph()
# Добавим вершины (можно неявно при добавлении рёбер)
G.add_nodes_from(["A", "B", "C", "D", "E"])
# Добавим рёбра с весами
G.add_edge("A", "B", weight=2)
G.add_edge("A", "C", weight=5)
G.add_edge("B", "D", weight=3)
G.add_edge("C", "D", weight=1)
G.add_edge("D", "E", weight=4)
# Ищем кратчайший путь (по весам) из A в E
path = nx.dijkstra_path(G, source="A", target="E", weight="weight")
distance = nx.dijkstra_path_length(G, source="A", target="E", weight="weight")
print("Кратчайший путь A -> E:", path)
print(f"Общая длина пути: {distance}")
NetworkX хорошо подходит для исследований в области сетевых структур, социальных графов, логистики, оптимизации и просто для обучения графовым алгоритмам.
Подпишись 👉🏻 @KodduuPython 🤖
🔥2👍1
Вышла новая статья на pikabu "Как стать АйТишником в 2025 году (пошаговый план)". Суммировал опыт многих, кто пришел в ИТ из других сфер.
Подпишись 👉🏻 @KodduuPython 🤖
Подпишись 👉🏻 @KodduuPython 🤖
Пикабу
Как стать АйТишником в 2025 году (пошаговый план)
Автор: 8088
🔥5👍2❤1
Ниже приведён прикладной пример использования библиотеки NetworkX для решения простой задачи на графах: представим, что у нас есть небольшая сеть дорог в городе, и мы хотим найти самый быстрый маршрут от склада до магазина с учётом скоростей на участках дорог.
- Узлы графа (nodes) — это перекрёстки.
- Рёбра графа (edges) — это дороги между перекрёстками.
- У каждого ребра есть:
- длина дороги (в километрах),
- скорость (км/ч), с которой можно проехать этот участок.
Целевая метрика: время в пути (в часах). Мы хотим найти кратчайший (по времени) путь, а не по географическому расстоянию.
## Пример кода
### Что происходит в коде?
1. build_city_graph() — создаёт ориентированный граф (DiGraph). Каждая дорога (ребро) имеет:
-
-
2. compute_travel_time() — функция для расчёта времени в пути (в часах) = \(\text{distance} / \text{speed}\).
3. Мы в цикле по всем рёбрам графа (G.edges(data=True)) создаём новый атрибут
4. nx.dijkstra_path и nx.dijkstra_path_length — стандартные методы NetworkX для нахождения кратчайшего пути и его «стоимости» (суммы весов) в взвешенном графе:
-
5. На выходе — маршрут (список перекрёстков) и итоговое время.
NetworkX даёт удобный способ моделировать любые сетевые структуры (дорожные сети, социальные графы, электрические сети и т. д.), используя множество готовых алгоритмов (поиск кратчайшего пути, анализ центральности, минимальное остовное дерево, поиск компонент связности и многое другое).
Подпишись 👉🏻 @KodduuPython 🤖
- Узлы графа (nodes) — это перекрёстки.
- Рёбра графа (edges) — это дороги между перекрёстками.
- У каждого ребра есть:
- длина дороги (в километрах),
- скорость (км/ч), с которой можно проехать этот участок.
Целевая метрика: время в пути (в часах). Мы хотим найти кратчайший (по времени) путь, а не по географическому расстоянию.
## Пример кода
import networkx as nx
def build_city_graph():
"""
Создаёт и возвращает ориентированный граф (DiGraph) с атрибутами:
- distance (км)
- speed (км/ч)
"""
G = nx.DiGraph()
# Добавим несколько перекрёстков (можно просто добавлять рёбра,
# тогда вершины создадутся автоматически)
intersections = ["Warehouse", "A", "B", "C", "Store"]
G.add_nodes_from(intersections)
# Добавим дороги (рёбра) с атрибутами:
# G.add_edge(откуда, куда, distance=..., speed=...)
G.add_edge("Warehouse", "A", distance=3.0, speed=30.0)
G.add_edge("Warehouse", "B", distance=5.0, speed=40.0)
G.add_edge("A", "C", distance=2.0, speed=20.0)
G.add_edge("B", "C", distance=2.5, speed=35.0)
G.add_edge("C", "Store", distance=4.0, speed=40.0)
G.add_edge("A", "Store", distance=8.0, speed=60.0)
# Можно добавить и обратные направления, если дороги двусторонние
G.add_edge("A", "Warehouse", distance=3.0, speed=30.0)
G.add_edge("B", "Warehouse", distance=5.0, speed=40.0)
# И так далее...
return G
def compute_travel_time(u, v, data):
"""
Вычисляем время (часы) проезда по участку (u->v) на основе атрибутов distance и speed.
data — словарь атрибутов ребра.
"""
dist = data.get("distance", 1.0)
spd = data.get("speed", 1.0)
return dist / spd # время = расстояние/скорость
def main():
# 1. Строим граф
G = build_city_graph()
# 2. Считаем «вес» каждого ребра как время
# Для поиска кратчайшего пути по времени используем атрибуты distance и speed.
# NetworkX позволяет указать коллбэк (функцию), которая вычисляет вес «на лету»,
# но здесь, для наглядности, прямо создадим новый атрибут "time".
for u, v, data in G.edges(data=True):
data["time"] = compute_travel_time(u, v, data)
# 3. Ищем кратчайший маршрут по атрибуту "time"
start = "Warehouse"
end = "Store"
# Используем алгоритм Дейкстры (dijkstra_path) или любой другой
path = nx.dijkstra_path(G, source=start, target=end, weight="time")
total_time = nx.dijkstra_path_length(G, source=start, target=end, weight="time")
print("Самый быстрый маршрут:", " -> ".join(path))
print(f"Общее время в пути (часы): {total_time:.2f}")
if __name__ == "__main__":
main()
### Что происходит в коде?
1. build_city_graph() — создаёт ориентированный граф (DiGraph). Каждая дорога (ребро) имеет:
-
distance: длина участка (км), -
speed: доступная скорость движения (км/ч). 2. compute_travel_time() — функция для расчёта времени в пути (в часах) = \(\text{distance} / \text{speed}\).
3. Мы в цикле по всем рёбрам графа (G.edges(data=True)) создаём новый атрибут
time, который потом используется в алгоритме Дейкстры.4. nx.dijkstra_path и nx.dijkstra_path_length — стандартные методы NetworkX для нахождения кратчайшего пути и его «стоимости» (суммы весов) в взвешенном графе:
-
source=start, target=end, weight="time" указывает, что в качестве веса ребра следует использовать именно атрибут time.5. На выходе — маршрут (список перекрёстков) и итоговое время.
NetworkX даёт удобный способ моделировать любые сетевые структуры (дорожные сети, социальные графы, электрические сети и т. д.), используя множество готовых алгоритмов (поиск кратчайшего пути, анализ центральности, минимальное остовное дерево, поиск компонент связности и многое другое).
Подпишись 👉🏻 @KodduuPython 🤖
👍7❤1
До 12 января действует скидка на программу Junior Python Developer и Data Scientist +интервью тесты 🔥🔥🔥
Программа включает в себя курс по Python, по Python Data Sceince, CookBook для практики Python и "Топ 100 вопросов с реальных собеседований по Python (+тесты)" 🔥🔥🔥
Подпишись 👉🏻 @KodduuPython 🤖
Программа включает в себя курс по Python, по Python Data Sceince, CookBook для практики Python и "Топ 100 вопросов с реальных собеседований по Python (+тесты)" 🔥🔥🔥
Подпишись 👉🏻 @KodduuPython 🤖