-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: Dynamic Constraint Weight in constraint factory #1172
Comments
The approach you propose here is effectively turning a constraint weight into a match weight. A constraint weight is a configurable yet static number - a match weight depends on the specific impact you want the particular constraint match to make. Since you already have a fully dynamic match weight, I really do not see the point of a dynamic constraint weight as well. Set your constraint weight to 1 (which is the default), and use match weight to penalize by an arbitrary amount - that is how the system is designed to function. What do you intend to accomplish by making both the constraint and the match weights dynamic? |
The level (HARD/SOFT/...) can only be set on the constraint weight. The penalize/reward method only offer penalizeInt/Long/BigDecimal, you can't "penalizeScore". EDIT: |
I see your point now, thanks for clarifying. Not the first time we're seeing such request. The goal for Conceptually, allowing to do this on the match level IMO doesn't make sense - I don't see which single constraint can be both hard and soft, based on what it matched. Would overtime hours suddenly be less serious, because it's Bob and not Ann? Can Ed be in two places at once, but nobody else can? Would fuel costs suddenly break the solution, if the driver is Peter and not Paul? Instead, this requirement seems to me like a side effect of some other problem you're attempting to solve. Perhaps having two constraints would bring performance costs, and therefore you're trying to get it done with just one constraint? |
Here is an example: I have a planning with configurable tasks. I have a task limit rule (constraint). Sometime a task is mandatory (hard) sometime it is not (soft). But in both cases they are a limit constraint. The user create the tasks and choose what tasks are mandatory (hard or soft level) and the weight of the constraint. I could probably use the constraint override but I don't like to have to use "constraint name" to associate a dynamic weight to a constraint. Especially when the name of the constraint itself is dynamic. ( I think it would be easier to just set the weight from the constraintFactory by keeping the weight in some planningvalue. Yes having two constraints could be a solution, but they would be the same, they would have the same flow (forEach/join/map/groupBy/penalize etc.) the only difference is one penalizing hard and the other is penalizing soft. |
Thanks for the explanation. I would indeed go with two constraints here. A constraint called "Mandatory tasks must be assigned" is different in my mind to a constraint called "Reward optional task assignments" - even though their implementation may be virtually the same. Consider score analysis, another feature of the solver - if you see matches from the same constraint being hard once, and soft another time, you have to start drilling down into justifications to figure out what exactly happened. Having two constraints for this saves you from that work, it makes score analysis self-explanatory. The fact that two constraints take more performance is often not really a problem, because many constraints are cheap. For expensive constraints, the Enterprise Edition of Timefold Solver has a "node sharing" feature which can (under the hood) merge those executions is they are indeed the same. |
Constraint Weight can be configured at runtime/dynamically using ConstraintWeightOverrides but it's a bit tedious to configure.
Could it be possible to configure them dynamically/lazily using the constraintFactory ? Example:
The text was updated successfully, but these errors were encountered: