That being said, MIPs are not the only kind of solvers. There are also "local search" based constraint solvers, which does not have the restriction that each constraint must be modelled as a relation or equation of integer variables. In local search solvers, the constraints are mostly treated as a black box that tells how good a particular solution is. As a consequent, local search solvers are typically unable to find the optimal solution (since it would require testing all possible solutions because the constraint is treated as a black box), but rather finds a "near-optimal" solution in reasonable time.
One local search based solver is Timefold Solver. In it, users annotate their domain so the solver knows what are the variables and possible values. This means instead of your constraints dealing with `int`, it would deal with `Shift` and `Employee`, and can access any of their methods.
Disclosure: I work on Timefold Solver
For example, to do the "Some employees are qualified to do either role, but others can only be a cashier, or a restocker." constraint in the article, it would be written like this:
def required_skill(constraint_factory: ConstraintFactory):
return (constraint_factory.for_each(Shift)
.filter(lambda shift: shift.required_skill not in shift.employee.skills)
.penalize(HardSoftScore.ONE_HARD)
.as_constraint("Missing required skill")
)
Some examples taken from Timefold quickstarts:- Employee scheduling (https://github.com/TimefoldAI/timefold-quickstarts/tree/stab...)
- Vehicle routing (https://github.com/TimefoldAI/timefold-quickstarts/tree/stab...)
- School timetabling (https://github.com/TimefoldAI/timefold-quickstarts/tree/stab...)
The Python examples seem to have a very strong Java smell. That might just be my prefer for functional styles over OOP styles though.
We aim to treat Python as a first-class citizen (while keeping it maintainable). For instance, many of the Java methods are mapped to properties on the Python classes with more Pythonic names (see `ScoreExplanation` for an example).
I suspect what gives the Java smell is probably the `SolverFactory`/`SolverConfig`, which is a lot of boilerplate code. A lot of the code can be generated, although we would need to design an API for that.
The fluent (method chaining) API might also be giving the Java smell; I don't see many fluent API being used in Python. In particular, needing to either end lines with `\` or surround the statement with brackets make long fluent chains annoying to use. This is harder to change, since there is no Pythonic alternative that I know of for method chaining.
constraint_factory.create_from_chain(
ForEach(Shift)
| Filter(lambda shift: shift.required_skill not in shift.employee.skills)
| Penalize(HardSoftScore.ONE_HARD)
| AsConstraint("Missing required skill")
)
Feel more Pythonic than (
constraint_factory.for_each(Shift)
.filter(lambda shift: shift.required_skill not in shift.employee.skills)
.penalize(HardSoftScore.ONE_HARD)
.as_constraint("Missing required skill")
)
?Many problems in business and manufacturing fit this bill. Optimal product mix, optimal routing, choosing the best spot for a warehouse, scheduling employees, constructing an investment protfolio, coming up with a diet that fits certain criteria, etc.
I even remember a practice problem from uni where we had to optimally distribute songs on two sides of a tape album (it was an old professor), satisfying constraints such as “each side should have a ballad” and “each side has at most x minutes of running time”.
You can do this with regular coding too, but if you can easily construct a certain kind of mathematical model of your problem, you can easily solve it with linear programming.
I have about 5 years of experience in MiniZinc solving scheduling problems but sadly all that code is locked behind closed doors never to be open sourced. I would love put together some fully worked constraint programming examples complete with containerisation / visualisation/ modeling etc but the barrier to doing so is finding problems that are actually worth solving and have open source data to work on.
As for the "mathematical equations" referred to by a parent, we're talking linear algebraic equations with perhaps a 2nd order term thrown in for quadratic models. I think these should be within the grasp of someone who wants to delve into the topic, and if not perhaps it's a good place to start dig deeper.
edited to be less of a prick.
I’d definitely be interested in that.
Exactly. I was looking at using a sat solver for a rules engine and couldn't make heads or tails how to use it. After alot of deduction, got a basic POC working, but couldn't extend it to what was actually needed. But the gulf between toy implementations and anything more substantial was very large.