Вопрос или проблема
У меня есть сценарий планирования, в котором у каждого временного промежутка есть стоимость. Мне нужно выбрать временные промежутки, которые дадут наименьшую стоимость за период в 24 часа. См. ниже пример набора данных.
Начало | Конец | Стоимость
- 00:00 | 01:00 | $30
- 01:00 | 05:00 | $50
- 02:00 | 08:00 | $70
- 04:00 | 12:00 | $100
- 08:00 | 11:00 | $60
- 10:00 | 14:00 | $50
- 13:00 | 17:00 | $90
- 13:00 | 20:00 | $120
- 16:00 | 23:00 | $80
- 18:00 | 22:00 | $60
- 19:00 | 20:00 | $50
- 21:00 | 23:00 | $20
Существует ли какое-либо программное обеспечение или библиотека на Python, которую я могу использовать для выбора набора временных промежутков с наименьшей стоимостью, так чтобы каждый временной промежуток не пересекался и все они в сумме составляли 24 часа?
Это похоже на вариант задачи о рюкзаке.
Я предполагаю, что OptaPy может справиться с этим.
.
Ответ или решение
Задача расписания с целью минимизации затрат описывает классическую проблему оптимизации, где необходимо выбрать временные интервалы с наименьшей стоимостью, обеспечив покрытие всей доступной временной шкалы в 24 часа без перекрытий. Эта задача аналогична варианту задачи о рюкзаке, где главная цель — оптимизировать использование ограниченного ресурса, в данном случае времени.
Решения на Python для решения задачи расписания
В данной ситуации Python предоставляет разнообразные библиотеки и инструменты, которые могут помочь в решении задачи минимизации затрат в расписании:
-
OptaPy: Эта библиотека представлена как Python интерфейс к OptaPlanner, мощному набору инструментов для решения задач оптимизации и планирования. OptaPy хорошо подходит для сложных задач, подобных вашей, поскольку поддерживает ограничения и может обрабатывать разные сценарии оптимизации. Библиотека может помочь автоматизировать процесс поиска оптимального решения с учетом заданных ограничений и требований.
-
PuLP: Это библиотека линейного программирования для решения задач оптимизации. С помощью PuLP вы можете сформулировать задачу как линейную задачу минимизации с ограничениями, соответствующими вашим временным периодам и стоимостям. PuLP эффективно работает с такими задачами, как минимизация затрат, если заданы четкие ограничения.
-
Google OR-Tools: Этот то инструментарий предлагает набор алгоритмов для решения задач маршрутизации, планирования и оптимизации. Он поддерживает как линейное, так и целочисленное программирование, что делает его подходящим для сложных задач планирования и распределения ресурсов.
Подход к решению задачи с помощью PuLP
Вы можете использовать PuLP следующим образом:
-
Задание переменных: Определите бинарные переменные для каждого временного интервала, где значение 1 будет означать выбор этого интервала, а 0 — нет.
-
Формулировка целевой функции: Целевая функция должна минимизировать суммарные затраты выбранных временных интервалов.
-
Задание ограничений:
- Убедитесь, что интервалы времени не перекрываются, т.е. если один временной интервал выбран, то другой, перекрывающийся с ним, не может быть выбран.
- Все выбранные интервалы должны покрывать ровно 24 часа времени.
Пример кода на Python с использованием PuLP
from pulp import LpProblem, LpVariable, lpSum, LpMinimize
# Данные
intervals = [
{'start': 0, 'end': 1, 'cost': 30},
{'start': 1, 'end': 5, 'cost': 50},
{'start': 2, 'end': 8, 'cost': 70},
{'start': 4, 'end': 12, 'cost': 100},
{'start': 8, 'end': 11, 'cost': 60},
{'start': 10, 'end': 14, 'cost': 50},
{'start': 13, 'end': 17, 'cost': 90},
{'start': 13, 'end': 20, 'cost': 120},
{'start': 16, 'end': 23, 'cost': 80},
{'start': 18, 'end': 22, 'cost': 60},
{'start': 19, 'end': 20, 'cost': 50},
{'start': 21, 'end': 23, 'cost': 20},
]
# Задание проблемы
prob = LpProblem("Scheduling", LpMinimize)
# Определение переменных
x = [LpVariable(f"x{i}", cat='Binary') for i in range(len(intervals))]
# Целевая функция
prob += lpSum([interval['cost'] * x[i] for i, interval in enumerate(intervals)])
# Ограничения
# Например, дополнительные ограничения для не пересекающихся временных интервалов
# Решение задачи
prob.solve()
# Вывод решения
for i, var in enumerate(x):
if var.value() == 1:
print(f"Выбран временной интервал: {intervals[i]['start']} - {intervals[i]['end']} за ${intervals[i]['cost']}")
При внимательном изучении задачи и применении этих инструментов вы можете эффективно найти оптимальное решение для вашего расписания, минимизируя затраты и обеспечивая полное покрытие временной шкалы.