@@ -764,6 +764,93 @@ The current `SolverManager` implementation runs on a single computer node,
764764but future work aims to distribute solver loads across a cloud.
765765
766766
767+ [#solverManagerBuilder]
768+ == The `SolverManager` Builder
769+
770+ The `SolverManager` also enables the creation of a builder to customize and submit a planning problem for solving.
771+
772+ [tabs]
773+ ====
774+ Java::
775+ +
776+ [source,java,options="nowrap"]
777+ ----
778+ public interface SolverManager<Solution_> {
779+
780+ SolverJobBuilder<Solution_, ProblemId_> solveBuilder();
781+
782+ ...
783+ }
784+ ----
785+
786+ Python::
787+ +
788+ [source,python,options="nowrap"]
789+ ----
790+ class SolverManager(Generic[Solution_, ProblemId_]):
791+ ...
792+ def solve_builder(self) -> SolverJobBuilder[Solution_, ProblemId_]:
793+ ...
794+ ----
795+ ====
796+
797+
798+ A `SolverJobBuilder` includes various settings, as shown in the following code snippet:
799+
800+ [tabs]
801+ ====
802+ Java::
803+ +
804+ [source,java,options="nowrap"]
805+ ----
806+ solverManager.solveBuilder()
807+ .withProblemId(problemId)
808+ .withProblem(problem)
809+ .withFirstInitializedSolutionConsumer(firstInitializedSolutionConsumer)
810+ .withBestSolutionConsumer(bestSolutionConsumer)
811+ .withFinalBestSolutionConsumer(finalBestSolutionConsumer)
812+ .withExceptionHandler(exceptionHandler)
813+ .withConfigOverride(configOverride)
814+ ...
815+ ----
816+
817+ Python::
818+ +
819+ [source,python,options="nowrap"]
820+ ----
821+ solver_manager.solve_builder()
822+ .with_problem_id(problemId)
823+ .with_problem(problem)
824+ .with_first_initialized_solution_consumer(on_firs_solution_changed)
825+ .with_best_solution_consumer(on_best_solution_changed)
826+ .with_final_best_solution_consumer(on_final_solution_changed)
827+ .with_exception_handler(on_exception_handler)
828+ .with_config_override(config_override)
829+ ...
830+ ----
831+ ====
832+
833+ The job's unique ID is specified using `withProblemId(problemId)`,
834+ while the problem is defined with `withProblem(problem)`.
835+ A consumer for the first initialized solution can be configured with `withFirstInitializedSolutionConsumer(...)`.
836+ The solution is returned by the last phase that immediately precedes the first local search phase.
837+ Whenever a new best solution is generated by the solver,
838+ it can be consumed by configuring it with `withBestSolutionConsumer(...)`.
839+ The final best solution consumer,
840+ which is called at the end of the solving process,
841+ can be set using `withFinalBestSolutionConsumer(...)`.
842+ To handle errors that may arise during the solving process,
843+ set up the handling logic by defining `withExceptionHandler(...)`.
844+ Finally, some solver settings, such as the termination configuration, can be overridden using `withConfigOverride(...)`.
845+
846+ [WARNING]
847+ ====
848+ The solutions returned by the events in `withFirstInitializedSolutionConsumer(...)`
849+ and `withBestSolutionConsumer(...)` can be reused during the solving process.
850+ Therefore, do not apply any changes to the solution instance while the solver is running,
851+ as any modifications may lead to solver corruption.
852+ ====
853+
767854[#solverManagerSolveBatch]
768855=== Solve batch problems
769856
0 commit comments