Problem solving¶
Solving a scheduling problem involves the SchedulingSolver
class.
Solver definition¶
A SchedulingSolver
instance takes a SchedulingProblem
instance:
It takes the following optional arguments:
-
debug
: False by default, if set to True will output many useful information. -
max_time
: in seconds, the maximal time allowed to find a solution. Default is 10s. -
parallel
: boolean False by default, if True force the solver to be executed in multithreaded mode. It might be quicker. Or not. -
random_values
: a boolean, default toFalse
. If set toTrue
, enable a builtin generator to set random initial values. By setting this attribute toTrue
, one expects the solver to give a different solution each time it is called. -
logics
: a string, None by default. Can be set to any of the supported z3 logics, "QF_IDL", "QF_LIA", etc. see https://smtlib.cs.uiowa.edu/logics.shtml. By default (logics set to None), the solver tries to find the best logics, but there can be significant improvements by setting a specific logics ("QF_IDL" or "QF_UFIDL" seems to give the best performances). -
verbosity
: an integer, 0 by default. 1 or 2 increases the solver verbosity. TO be used in a debugging or inspection purpose. -
optimizer
: a string, "incremental" by default, can be also set to "optimize". 1 or 2 increases the solver verbosity. TO be used in a debugging or inspection purpose. -
optimize_priority
: a string among "pareto", "lex", "box", "weight".
Solve¶
Just call the solve
method. This method returns a Solution
instance.
Running the solve
method returns can either fail or succeed, according to the 4 following cases:
- The problem cannot be solved because some constraints are contradictory. It is called "Unsatisfiable". The
solve
method returns False. For example:
It is obvious that these constraints cannot be both satisfied.
-
The problem cannot be solved for an unknown reason (the satisfiability of the set of constraints cannot be computed). The
solve
method returns False. -
The solver takes too long to complete and exceeds the allowed
max_time
. Thesolve
method returns False. -
The solver successes in finding a schedule that satisfies all the constraints. The
solve
method returns the solution, which can be rendered as a Gantt chart or a JSON string.
Note
If the solver fails to give a solution, increase the max_time
(case 2) or remove some constraints (case 1).
Find another solution¶
The solver may schedule:
-
one solution among many, in the case where there is no optimization,
-
the best possible schedule in case of an optimization issue.
In both cases, you may need to check a different schedule that fits all the constraints. Use the find_another_solution
method and pass the variable you would want the solver to look for another solution.
Note
Before requesting another solution, the solve
method has first to be executed, i.e. there should already be a current solution.
You can pass any variable to the find_another_solution
method: a task start, a task end, a task duration, a resource productivity etc.
For example, there are 5 different ways to schedule a FixedDurationTask with a duration=2 in an horizon of 6. The default solution returned by the solver is:
problem = ps.SchedulingProblem(name='FindAnotherSolution', horizon=6)
task_1 = ps.FixedDurationTask(name='task1', duration=2)
problem.add_task(task_1)
solver = ps.SchedulingSolver(problem=problem)
solution = solver.solve()
print("Solution for task_1.start:", solution.tasks['task1'])
Then, we can request for another solution:
solution = solver.find_another_solution(task_1.start)
if solution is not None:
print("New solution for task_1.start:", solution.tasks['task1'])
You can recursively call find_another_solution
to find all possible solutions, until the solver fails to return a new one.
Run in debug mode¶
If the debug
attribute is set to True, the z3 solver is run with the unsat_core option. This will result in a much longer computation time, but this will help identifying the constraints that conflict. Because of this higher consumption of resources, the debug
flag should be used only if the solver fails to find a solution.
Optimization¶
Please refer to the Objectives page for further details.
Gantt chart¶
Please refer to the Gantt chart page for further details.
Logics¶
logics | computing_time(s) | flowtime | priority | obj value |
---|---|---|---|---|
QF_LRA | 2.84 | 147 | 289 | 436 |
QF_LIA | 4.25 | 165 | 320 | 485 |
QF_RDL | 0.48 | None | None | None |
QF_IDL | 3.45 | 174 | 339 | 513 |
QF_AUFLIA | 6.01 | 129 | 270 | 399 |
QF_ALIA | 3.69 | 139 | 280 | 419 |
QF_AUFLIRA | 4.30 | 145 | 266 | 411 |
QF_AUFNIA | 4.41 | 159 | 337 | 496 |
QF_AUFNIRA | 5.35 | 168 | 310 | 478 |
QF_ANIA | 6.12 | 168 | 320 | 488 |
QF_LIRA | 5.41 | 151 | 302 | 453 |
QF_UFLIA | 6.18 | 143 | 296 | 439 |
QF_UFLRA | 9.19 | 143 | 305 | 448 |
QF_UFIDL | 4.98 | 132 | 263 | 395 |
QF_UFRDL | 5.69 | 171 | 352 | 523 |
QF_NIRA | 6.72 | 142 | 268 | 410 |
QF_UFNRA | 8.51 | 160 | 300 | 460 |
QF_UFNIA | 18.89 | 130 | 261 | 391 |
QF_UFNIRA | 6.36 | 171 | 320 | 491 |
QF_S | 5.28 | 152 | 289 | 441 |
QF_SLIA | 4.33 | 174 | 361 | 535 |
UFIDL | 6.70 | 126 | 246 | 372 |
HORN | 0.49 | None | None | None |
QF_FPLRA | 6.21 | 129 | 253 | 382 |