Почему при составлении списка сотрудников Opta Planner не назначают сотрудников на смену, даже если они доступны? - PullRequest
0 голосов
/ 09 июля 2020

В настоящее время у меня есть список из 30 смен и 25 сотрудников, которые есть в наличии. У этих 25 сотрудников время начала и окончания смены соответствует доступности сотрудников. Тем не менее, Opta назначает только 19 смен и оставляет все другие смены пустыми и не назначает оставшихся 6 сотрудников. Я что-то здесь пропустил или мне следует обратить внимание на какой-либо другой аспект?

Ниже мой файл правил Opta, я удалил все другие правила, так как они не требовались в моем случае.

Opta версия списка сотрудников, в настоящее время использующая список 7.28.0-SNAPSHOT для решения 240 секунд.

// ############################################################################
// Hard constraints
// ############################################################################

rule "Unavailable time slot for an employee"
    when
        EmployeeAvailability(
                $e : employee,
                $employeeName : employee.getName(),
                $startDateTime : startDateTime,
                $endDateTime : endDateTime)
        Shift(
                employee == $e,
                !DateTimeUtils.doTimeslotsMatch($startDateTime,$endDateTime, startDateTime, endDateTime, $employeeName))
    then
        scoreHolder.addHardConstraintMatch(kcontext, -100);
end

rule "No overlapping shifts for an employee"
    when
        $s : Shift( employee != null,
                    $e : employee,
                    $employeeName : employee.getName(),
                    $firstStartDateTime: startDateTime,
                    $firstEndDateTime : endDateTime)
        $s2: Shift( employee == $e,
                    this != $s,
                    DateTimeUtils.doTimeslotsMatch($firstStartDateTime,$firstEndDateTime, startDateTime, endDateTime, $employeeName))
    then
        scoreHolder.addHardConstraintMatch(kcontext, -100);
end

// ############################################################################
// Medium constraints
// ############################################################################

rule "Assign every possible shift"
    when
        Shift(employee == null)
    then
        scoreHolder.addMediumConstraintMatch(kcontext, -100);
end

// ############################################################################
// Soft constraints
// ############################################################################

rule "available time slot for an employee"
    when
        $rosterParametrization : RosterParametrization(desiredTimeSlotWeight != 0)
        EmployeeAvailability(
                $e : employee,
                $employeeName : employee.getName(),
                $startDateTime : startDateTime,
                $endDateTime : endDateTime)
        Shift(
                employee == $e,
                DateTimeUtils.doTimeslotsMatch($startDateTime,$endDateTime, startDateTime, endDateTime, $employeeName))
    then
        scoreHolder.addSoftConstraintMatch(kcontext, 100);
end

rule "Skill set preference"
    when
        Shift(employee != null, matchedPreferencedDisciplineCount > 0,$matchedPreferencedDisciplineCount : matchedPreferencedDisciplineCount)
    then
        scoreHolder.addSoftConstraintMatch(kcontext, + $matchedPreferencedDisciplineCount);
end

Вот мой обновленный файл конфигурации решателя.

<?xml version="1.0" encoding="UTF-8"?>
<solver>
  <!--<environmentMode>FAST_ASSERT</environmentMode>-->
  <solutionClass>org.optaweb.employeerostering.domain.roster.Roster</solutionClass>
  <entityClass>org.optaweb.employeerostering.domain.shift.Shift</entityClass>

  <scoreDirectorFactory>
    <scoreDrl>org/optaweb/employeerostering/service/solver/employeeRosteringScoreRules.drl</scoreDrl>
  </scoreDirectorFactory>

  <termination>
    <secondsSpentLimit>240</secondsSpentLimit>
  </termination>

  <localSearch>
    <unionMoveSelector>
      <pillarChangeMoveSelector>
        <subPillarType>SEQUENCE</subPillarType>
      </pillarChangeMoveSelector>
      <pillarSwapMoveSelector>
        <subPillarType>SEQUENCE</subPillarType>
      </pillarSwapMoveSelector>
    </unionMoveSelector>
    <acceptor>
      <entityTabuSize>7</entityTabuSize>
    </acceptor>
    <forager>
      <acceptedCountLimit>800</acceptedCountLimit>
    </forager>
  </localSearch>

</solver>

Также он заставляет меня внедрять Comparable при смене объекта планирования

public class Shift extends AbstractPersistable implements Comparable<Shift> {

    private static final Comparator<Shift> PILLAR_SEQUENCE_COMPARATOR = Comparator
            .comparing((Shift a) -> a.getStartDateTime())
            .thenComparing(a -> a.getEndDateTime());

Решит ли это мою проблему решателя, который не назначает сотрудников, хотя они доступны, и удалит себя из локальных оптимумов .

1 Ответ

0 голосов
/ 13 июля 2020

Используйте селекторы перемещения на основе Pilar для более эффективного выхода из локальных оптимумов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...