From b7e4691efbbd79228f4da984bce29c82390aa795 Mon Sep 17 00:00:00 2001 From: "ki.sagidullin" Date: Sat, 4 Apr 2026 16:41:25 +0500 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D0=B0=D1=8F=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=87=D0=B0=D1=8F=20=D0=B2=D0=B5=D1=80=D1=81?= =?UTF-8?q?=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 38 ++++++++++++++++++++ main.py | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 README.md create mode 100644 main.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..8a98230 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# ИИ Промпт +Нужно назначить операторов на смены + +Условия: +* апрель 2026 года. Месяц начинается со среды +* график нужен на каждый день этого месяца +* Операторов всего 6 +* в каждой смене - должен быть один оператор +* У каждого оператора должно быть 10 выходных +* оператор не должен работать больше 5 дней подряд +* в день оператор может работать только одну смену + +Смены(4 на каждый день): +с 06:00 до 14:30 +с 08:00 до 16:30 +с 11:30 до 20:00 +с 12:30 до 21:00 + +Список операторов и их пожелания: +1. Оператор Иванов: Хочет отдыхать 10 апреля и 13 апреля +2. Оператор Алексеев: Хочет работать по понедельникам в смену с 06:00 до 14:30 +3. Оператор Сидоров: Хочет отдыхать 25 апреля и 26 апреля +4. Оператор Козобородов: предпочитает смену 11:30–20:00, но может работать в любую, если иначе график не составить. +5. Оператор Трудяшкина: Хочет отдыхать 4 апреля +6. Оператор Петрова: Хочет отдыхать 29 и 14 апреля + +Задача: +Составь конкретный ежедневный график (таблицей: день недели → смена → оператор), соблюдая: +- условия задачи +- на каждую смену должен быть назначен оператор +- выходные - это дни когда оператор вообще не работает +- пожелания обязательны к исполнению, если это не делает график невозможным +- дни отдыха входят в 10 выходных + +Перед отправкой мне решения - проверь что все условия отрабатывают. +Если у тебя есть какой-то вопрос или что-то непонятно - задай, я отвечу +Ответ выдай в csv, в котором столбцы - день;1 смена;2 смена;3 смена;4 смена +Если возможности подобрать такой график работ нет - то так и ответь \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..0d19fcb --- /dev/null +++ b/main.py @@ -0,0 +1,101 @@ +from ortools.sat.python import cp_model + +import csv + +# Определяем даты апреля 2026 года +days = [ + "2026-04-{:02d}".format(i) for i in range(1, 31) +] + +# Смены +shifts = [ + (6, 14.5), # с 06:00 до 14:30 + (8, 16.5), # с 08:00 до 16:30 + (11.5, 20), # с 11:30 до 20:00 + (12.5, 21) # с 12:30 до 21:00 +] + +# Операторы и их пожелания +operators = [ + "Иванов", + "Алексеев", + "Сидоров", + "Козобородов", + "Трудяшкина", + "Петрова" +] + +operator_preferences = { + "Иванов": ["2026-04-10", "2026-04-13"], + "Алексеев": [(i, 0) for i in days if (int(i[-2:]) - 1) % 7 == 0], # Понедельники + "Сидоров": ["2026-04-25", "2026-04-26"], + "Козобородов": [(i, 2) for i in days], # Предпочитает смену 11:30–20:00 + "Трудяшкина": ["2026-04-04"], + "Петрова": ["2026-04-08", "2026-04-29"] +} + +# Создаем модель +model = cp_model.CpModel() + +# Переменные: определяем, работает ли оператор на смене в день +works = {} +for day in days: + for shift_idx in range(len(shifts)): + for op in operators: + works[(day, shift_idx, op)] = model.NewBoolVar(f"{op}_{day}_shift_{shift_idx}") + +# # Пожелания операторов +for op, prefs in operator_preferences.items(): + if isinstance(prefs, list): + for pref in prefs: + if isinstance(pref, tuple): + day, shift = pref + model.AddHint(works[day, shift, op], 1) + else: + day = pref + model.Add(sum(works[day, shift_idx, op] for shift_idx in range(len(shifts))) == 0) + +# Условие 1: На каждую смену должен быть назначен оператор +for day in days: + for shift_idx in range(len(shifts)): + model.Add(sum(works[day, shift_idx, op] for op in operators) == 1) + +# Условие 2: У каждого оператора должно быть 8 выходных +for op in operators: + model.Add(sum(works[day, shift_idx, op] for day in days for shift_idx in range(len(shifts))) == 20 ) + +# Условие 3: Оператор не должен работать больше 5 дней подряд +for op in operators: + for day_idx in range(len(days) - 4): + model.Add(sum(works[days[day_idx + i], shift_idx, op] for i in range(5) for shift_idx in range(len(shifts))) <= 4) + +# Условие 4: В день оператор может работать только одну смену +for day in days: + for op in operators: + model.Add(sum(works[day, shift_idx, op] for shift_idx in range(len(shifts))) <= 1) + +# Решаем модель +solver = cp_model.CpSolver() +status = solver.Solve(model) + +if status != cp_model.OPTIMAL and status != cp_model.FEASIBLE: + print("Невозможно составить график") +else: + # Создаем CSV файл с результатами + with open('shift_schedule.csv', 'w', newline='', encoding='utf-8') as file: + writer = csv.writer(file) + writer.writerow(['Day'] + [f'{i+1} shift' for i in range(len(shifts))]) + + for day in days: + row = [day] + for shift_idx in range(len(shifts)): + op = None + for op_name in operators: + if solver.Value(works[day, shift_idx, op_name]) == 1: + op = op_name + break + row.append(op) + writer.writerow(row) + + print("График успешно составлен и сохранен в 'shift_schedule.csv'") + \ No newline at end of file