Here is my problem to solve using optapy.
@problem_fact
class Room:
id: int
name: str
def __init__(self, id, name):
self.id = id
self.name = name
@planning_id
def get_id(self):
return self.id
def __str__(self):
return f"Room(id={self.id}, name={self.name})"
@problem_fact
class Timeslot:
id: int
day_of_week: str
start_time: datetime.time
end_time: datetime.time
def __init__(self, id, day_of_week, start_time, end_time):
self.id = id
self.day_of_week = day_of_week
self.start_time = start_time
self.end_time = end_time
@planning_id
def get_id(self):
return self.id
def set_value(self, id):
self.id = id
def __str__(self):
return (
f"Timeslot("
f"id={self.id}, "
f"day_of_week={self.day_of_week}, "
f"start_time={self.start_time}, "
f"end_time={self.end_time})"
)
@problem_fact
class Base:
pass
@planning_entity
class Slot(Base):
def __init__(self, timeslot=None):
self.timeslot = timeslot
# self.timeslot1 = timeslot1
@optapy.planning_variable(Base, value_range_provider_refs=['timeslotRangeLSEntity', 'timeslotRangeLBEntity'],
graph_type=PlanningVariableGraphType.CHAINED)
def get_timeslot(self):
return self.timeslot
def set_timeslot(self, new_timeslot):
self.timeslot = new_timeslot
@planning_entity
class Lesson(Slot):
id: int
subject: str
teacher: str
student_group: str
timeslot: Timeslot
room: Room
def __init__(self, id, subject, teacher, student_group,timeslot=None, room=None):
self.id = id
self.subject = subject
self.teacher = teacher
self.student_group = student_group
self.timeslot = timeslot
self.room = room
@planning_id
def get_id(self):
return self.id
@planning_variable(Room, ["roomRange"])
def get_room(self):
return self.room
def set_room(self, new_room):
self.room = new_room
def __str__(self):
return (
f"Lesson("
f"id={self.id}, "
f"timeslot={self.timeslot}, "
f"room={self.room}, "
f"teacher={self.teacher}, "
f"subject={self.subject}, "
f"student_group={self.student_group}"
f")"
)
@planning_entity
class Lab(Slot):
id: int
subject: str
teacher: str
student_group: str
timeslot: Timeslot
room: Room
def __init__(self, id, subject, teacher, student_group,timeslot=None, room=None):
self.id = id
self.subject = subject
self.teacher = teacher
self.student_group = student_group
self.timeslot = timeslot
self.room = room
@planning_id
def get_id(self):
return self.id
@planning_variable(Room, ["roomRange"])
def get_room(self):
return self.room
def set_room(self, new_room):
self.room = new_room
def __str__(self):
return (
f"Lab("
f"id={self.id}, "
f"timeslot={self.timeslot}, "
f"room={self.room}, "
f"teacher={self.teacher}, "
f"subject={self.subject}, "
f"student_group={self.student_group}"
f")"
)
def format_list(a_list):
return ',\n'.join(map(str, a_list))
@planning_solution
class TimeTable:
timeslot_list: list[Timeslot]
# timeslot_list1: list[Timeslot]
room_list: list[Room]
lesson_list: list[Lesson]
lab_list: list[Lab]
score: HardSoftScore
def __init__(self, timeslot_list, room_list, lesson_list,lab_list, score=None):
self.timeslot_list = timeslot_list
# self.timeslot_list1 = timeslot_list1
self.room_list = room_list
self.lesson_list = lesson_list
self.lab_list = lab_list
self.score = score
@problem_fact_collection_property(Room)
@value_range_provider("roomRange")
def get_room_list(self):
return self.room_list
@planning_entity_collection_property(Slot)
@value_range_provider("timeslotRangeLSEntity")
def get_lesson_list(self):
return self.lesson_list
@planning_entity_collection_property(Slot)
@value_range_provider("timeslotRangeLBEntity")
def get_lab_list(self):
return self.lab_list
@planning_score(HardSoftScore)
def get_score(self):
return self.score
def set_score(self, score):
self.score = score
def __str__(self):
return (
f"TimeTable("
f"timeslot_list={format_list(self.timeslot_list)},\n"
# f"timeslot_list1={format_list(self.timeslot_list1)},\n"
f"room_list={format_list(self.room_list)},\n"
f"lesson_list={format_list(self.lesson_list)},\n"
f"lab_list={format_list(self.lab_list)},\n"
f"score={str(self.score.toString()) if self.score is not None else 'None'}"
f")"
)
def generate_problem():
timeslot_list = [
Timeslot(1, "MONDAY", time(hour=8, minute=30), time(hour=9, minute=30)),
Timeslot(2, "MONDAY", time(hour=9, minute=30), time(hour=10, minute=30)),
Timeslot(3, "MONDAY", time(hour=10, minute=30), time(hour=11, minute=30)),
Timeslot(4, "MONDAY", time(hour=13, minute=30), time(hour=14, minute=30)),
Timeslot(5, "MONDAY", time(hour=14, minute=30), time(hour=15, minute=30)),
Timeslot(6, "TUESDAY", time(hour=10, minute=30), time(hour=11, minute=30)),
Timeslot(7, "TUESDAY", time(hour=13, minute=30), time(hour=14, minute=30)),
Timeslot(8, "TUESDAY", time(hour=14, minute=30), time(hour=15, minute=30)),
Timeslot(9, "TUESDAY", time(hour=15, minute=30), time(hour=16, minute=30)),
Timeslot(10, "TUESDAY", time(hour=16, minute=30), time(hour=17, minute=30)),
Timeslot(11, "MONDAY", time(hour=15, minute=30), time(hour=17, minute=30)),
Timeslot(12, "TUESDAY", time(hour=8, minute=30), time(hour=10, minute=30))
]
# timeslot_list1 = [
# ]
room_list = [
Room(1, "Room A"),
Room(2, "Room B"),
Room(3, "Room C"),
Room(4, "Room D")
]
lesson_list = [
Lesson(1, "Math", "A. Turing", "9th grade"),
Lesson(2, "Math", "A. Turing", "9th grade"),
Lesson(3, "Physics", "M. Curie", "9th grade"),
Lesson(4, "Chemistry", "M. Curie", "9th grade"),
Lesson(5, "Biology", "C. Darwin", "9th grade"),
Lesson(6, "History", "I. Jones", "9th grade"),
Lesson(7, "English", "I. Jones", "9th grade"),
Lesson(8, "English", "I. Jones", "9th grade"),
Lesson(9, "Spanish", "P. Cruz", "9th grade"),
Lesson(10, "Spanish", "P. Cruz", "9th grade"),
Lesson(11, "Math", "A. Turing", "10th grade"),
Lesson(12, "Math", "A. Turing", "10th grade"),
Lesson(13, "Math", "A. Turing", "10th grade"),
Lesson(14, "Physics", "M. Curie", "10th grade"),
Lesson(15, "Chemistry", "M. Curie", "10th grade"),
Lesson(16, "French", "M. Curie", "10th grade"),
Lesson(17, "Geography", "C. Darwin", "10th grade"),
Lesson(18, "History", "I. Jones", "10th grade"),
Lesson(19, "English", "P. Cruz", "10th grade"),
Lesson(20, "Spanish", "P. Cruz", "10th grade")
]
lab_list = [
Lab(21, "LAB", "Selva", "9th grade"),
Lab(22, "LAB", "Selva", "10th grade")
]
lesson = lesson_list[0]
lesson.set_timeslot(timeslot_list[0])
lesson.set_room(room_list[0])
lab = lab_list[0]
lab.set_timeslot(timeslot_list[10])
lab.set_room(room_list[3])
return TimeTable(timeslot_list, room_list, lesson_list,lab_list)
Here I used Base class(@problem_fact) and extended the abstract class as Slot(@planning_entity). Here I declared the timeslot as a common for two @planning_entity(one is Lab another one is Lesson). I am passing 2 different timeslot range for those two @planning_entity.
When i used to solve this problem i am getting below error!
java.lang.IllegalStateException: Error occurred when wrapping object (Lab(id=21, timeslot=Timeslot(id=11, day_of_week=MONDAY, start_time=15:30:00, end_time=17:30:00), room=Room(id=4, name=Room D), teacher=Selva, subject=LAB, student_group=9th grade)).
Kindly help me to solve this! Thanks
Your model is incorrect: you have a chained
@planning_variableinSlotwithout an anchor value range ('timeslotRangeLSEntity' and 'timeslotRangeLBEntity' correspond to Lesson and Lab respectively, which are both planning entities that extend Slot, which cannot be used as an anchor). I am guessing you want TimeSlot to be your anchor. However, currently, it does not extend Base, so you need to modify TimeSlot to extend Base.However, you are also hitting an OptaPlanner bug: having multiple planning entity classes in a chained model will throw a class cast exception (https://issues.redhat.com/browse/PLANNER-2798). Until the bug is fixed, you need to workaround it. What this mean in your scenario is that Lab and Lesson need to be merged into one class, and in order to distinguish them, you need to use a field on the class. This modified domain should work: