В зависимости от того, как далеко вы планируете взять # 6, и насколько велик набор данных, он может быть нетривиальным; это, конечно, попахивает глобальной оптимизацией NP-hard ...
Тем не менее, если вы говорите о десятках (а не сотнях) узлов, довольно тупой алгоритм должен дать достаточно хорошую производительность.
Итак, у вас есть два ограничения:
- Общее упорядочение по классам по баллам;
это гибко
- Классовые столкновения; это не гибкий.
Что я имею в виду под «гибкостью», так это то, что вы можете посещать более разнесенные классы (с более низкими баллами), но вы не можете посещать два класса одновременно. Интересно, что между оценкой и столкновениями может быть положительная корреляция; классы с более высоким баллом чаще сталкиваются.
Мой первый проход по алгоритму:
selected_classes = []
classes = sorted(classes, key=lambda c: c.score)
for clas in classes:
if not clas.clashes_with(selected_classes):
selected_classes.append(clas)
Разработка столкновений может быть неловкой, если классы имеют разную длину, начинаются в странное время и так далее. Отображение времени начала и окончания в упрощенное представление «блоков» времени (каждые 15 минут / 30 минут или все, что вам нужно) облегчит поиск совпадений между началом и концом различных классов.