Let's assume that we have a fullstack application that has a page in the frontend side where we can select the constraints that we should apply to a specific problem. The list of those constraints will be sent to the backend side when we run the Timefold Solver for that specific problem.
How can I make sure that the Timefold Solver will apply just the constraints I chose from the frontend side? How can I modify the TimetableConstraintProvider (for example) to achieve the mentioned functionality.
public class TimetableConstraintProvider implements ConstraintProvider {
@Override
public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
return new Constraint[] {
// Hard constraints
roomConflict(constraintFactory),
teacherConflict(constraintFactory),
studentGroupConflict(constraintFactory),
// Soft constraints
teacherRoomStability(constraintFactory),
teacherTimeEfficiency(constraintFactory),
studentGroupSubjectVariety(constraintFactory)
};
}
//implementation of the constraints
}
I assume that, first, we should have an POST/GET endpoints for the selected constraints. After that what are the next steps? Any help is welcomed. Thank you!
Based on the documentation about Constraint Configuration (https://timefold.ai/docs/timefold-solver/latest/constraints-and-score/constraint-configuration#constraintWeight) I managed to build dynamic constraints by extending the timetable project (https://github.com/TimefoldAI/timefold-quickstarts/tree/stable/technology/java-spring-boot). Please note that the solution is not using Spring Data JPA for the simplicity:
So, first, you need a Constraint Configuration Bean where you input all the constraints' weights (ZERO means that the certain constraint will not be taken into account by the Solver):
Add the Constraint Configuration into your @PlanningSolution Bean:
Rewrite every constraint in the ConstraintProvider Bean using penalizeConfigurable() or rewardConfigurable() methods:
In this case, this constraint will search in the ConstraintConfiguration Bean for a constraint with the value "roomConflict" to apply the score penalty.
Then, in the DemoDataController Bean add a list of constraints to be taken into account by the Timefold Solver:
and return the Timetable with the timetableConstraintConfiguration included:
And that's it. It should work. Please let me know if it worked.
PS: if you want to use Spring Data JPA, you would want to create a CRUD application where you can post and get all the data needed for the Timetable (there is in the Timefold documentation how you use Spring JPA with Timefold Solver). So, before you initialize the Timetable object that you want to be solved, make sure that you use the Repository to get all the data from your domain (Room, Timeslot, Lesson, Constraints) and let Timefold do the dirty work for you. In short, to make an application that also uses JPA practically you just need to adapt the code from GitHub to a CRUD environment.
PPS: Thank you Timefold team for your support!