Есть ли необходимость в файле конфигурации xml или drools drl при использовании SoltaManager от Optaplanner? - PullRequest
1 голос
/ 21 апреля 2020

Я использую стартер начальной загрузки optaplanner для решения проблемы с списком сотрудников. У меня есть 2 класса, Сотрудник и Планирование лица Shift. В настоящее время я назначаю смены сотрудникам на основе их уровня квалификации, используя поставщика ограничений, как показано ниже.

public class ConstraintProvider implements 

    org.optaplanner.core.api.score.stream.ConstraintProvider {
        @Override
        public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
            return new Constraint[]{
                    requiredSkillLevelOfEmployeesForShifts(constraintFactory)
            };
        }

        private Constraint requiredSkillLevelOfEmployeesForShifts(ConstraintFactory constraintFactory) {
            return constraintFactory.from(Shift.class)
                    .groupBy(Shift::getEmployee, sum(Shift::getRequiredSkillLevel))
                    .filter((employee, requiredSkillLevel) -> requiredSkillLevel > employee.getSkillLevel())
                    .penalize("requiredSkillLevelForShifts",
                    HardSoftScore.ONE_HARD,
                    (employee, requiredSkillLevel) -> requiredSkillLevel - employee.getSkillLevel());
        }


    }

Я передаю список смен и сотрудников через JSON контроллеру, который затем решает и возвращает лучшее решение.


    @RestController
    @RequestMapping("/api")
    public class RostersController {

        @Autowired
        private SolverManager<Roster, UUID> solverManager;

        @PostMapping("/solve")
        public Roster solve(@RequestBody Roster problem) {
            UUID problemId = UUID.randomUUID();
            // Submit the problem to start solving
            SolverJob<Roster, UUID> solverJob = solverManager.solve(problemId, problem);
            Roster solution;
            try {
                // Wait until the solving ends
                solution = solverJob.getFinalBestSolution();
            } catch (InterruptedException | ExecutionException e) {
                throw new IllegalStateException("Solving failed.", e);
            }
            return solution;
        }

    }

Я хочу добавить еще одно ограничение, в котором я ограничиваю количество смен, которые сотрудник может выполнять за неделю, а также то, что сотрудник не может выполнять более одной смены в день. Можно ли сделать это, добавив другое ограничение, или мне нужен какой-то файл config. xml вместе с файлом drools .drl, чтобы добавить больше специфических c ограничений?

1 Ответ

2 голосов
/ 22 апреля 2020

DRL (scoreRules.drl) и ConstraintProvider являются взаимоисключающими. Вы начали реализовывать свои ограничения с ConstraintProvider, поэтому давайте придерживаться этого и добавим любые новые ограничения, которые могут вам понадобиться. ConstraintProvider является частью нового API Constraint Streams, который позволяет вам определять ограничения в Java, и его легко протестировать с помощью ConstraintVerifier.

Если и только если вы не используете optaplanner-spring-boot-starter или quarkus-optaplanner, в вашем примере отсутствует фрагмент, который говорит SolverManager имя класса вашей реализации ConstraintProvider. Вы можете сделать это с помощью solverConfig.xml. С optaplanner-spring-boot-starter или quarkus-optaplanner этот файл выводится автоматически:

<?xml version="1.0" encoding="UTF-8"?>
<solver>
  <solutionClass>com.your.domain.Roster</solutionClass>
  <entityClass>com.your.domain.Shift</entityClass>

  <scoreDirectorFactory>
    <constraintProviderClass>com.your.domain.ConstraintProvider</constraintProviderClass>
  </scoreDirectorFactory>
</solver>

...