Optaplanner ScoreDirector连续计划DayOff请求

问题描述 投票:1回答:3

我正在尝试启用持续计划和请求。我试图按照doco中提供的计算机示例。代码如下。我可以看到调试期间更新的值。代码如下。我究竟做错了什么

public void addEmployeeDayOff(final Employee employee,final DayOffRequest dayOffRequest) {
        logger.info("Scheduling employee dayoff ({}).", dayOffRequest);
        doProblemFactChange(scoreDirector -> {
            NurseRoster nurseRoster = scoreDirector.getWorkingSolution();
            Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);
            DayOffRequest dayoffRequest = scoreDirector.lookUpWorkingObject(dayOffRequest);
            scoreDirector.beforeProblemPropertyChanged(workingEmployee);
            if (workingEmployee == null) {

                return;
            }

            ArrayList<DayOffRequest> requestoffList = new ArrayList<>(nurseRoster.getDayOffRequestList());
            nurseRoster.setDayOffRequestList(requestoffList);
            scoreDirector.beforeProblemFactAdded(dayoffRequest);
            workingEmployee.getDayOffRequestMap().put(dayoffRequest.getShiftDate(), dayoffRequest);
            scoreDirector.afterProblemPropertyChanged(workingEmployee);
            nurseRoster.getDayOffRequestList().add(dayoffRequest);
            scoreDirector.afterProblemPropertyChanged(dayoffRequest);

            scoreDirector.triggerVariableListeners();

        });

The above is called from here:
            List<DayOffRequest> dayOffRequestList;
            //updating from database .. not sure if this is the issue
            List<DayOffData> dayOffElementList = (List<DayOffData>) rosterService.listDayOffData();
            dayOffRequestList = new ArrayList<>(dayOffElementList.size());
            long nextdayoffId =0L;
            for (DayOffData element : dayOffElementList) {
                if (nextdayoffId <= element.getId()) {
                    nextdayoffId = element.getId() + 1L;
                }

                DayOffRequest dayOffRequest = new DayOffRequest();
                String empID = element.getEmployee().getName();
                int weight = element.getWeight();
                LocalDate shiftDate = element.getShiftDate();
                ShiftDate date1 = shiftDateMap.get(shiftDate);
                Employee employee = employeeMap.get(empID);

                dayOffRequest.setId(nextdayoffId);
                dayOffRequest.setWeight(weight);
                dayOffRequest.setEmployee(employee);
                dayOffRequest.setShiftDate(date1);
                dayOffRequestList.add(dayOffRequest);
                //If this is not enabled the values don't pass to the addEmployeeDayOff method is this correct??
                scoreDirector.afterProblemFactAdded(dayOffRequest);
                scoreDirector.afterProblemFactAdded(employee);
                addEmployeeDayOff(employee,dayOffRequest);
            }
optaplanner
3个回答
0
投票

我发现这有效,但不确定这是否是解决问题的正确方法。

public void addEmployeeDayOff(final Employee employee, final DayOffRequest dayOffRequest) {
        logger.info("Scheduling employee dayoff ({}).", dayOffRequest);
        doProblemFactChange(scoreDirector -> {
            NurseRoster nurseRoster = (NurseRoster) scoreDirector.getWorkingSolution();

            Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);

            DayOffRequest dayoffRequest = (DayOffRequest) scoreDirector.lookUpWorkingObject(dayOffRequest);
            scoreDirector.beforeProblemPropertyChanged(workingEmployee);
            if (workingEmployee == null) {

                return;
            }

            ArrayList<DayOffRequest> requestoffList = new ArrayList<>(nurseRoster.getDayOffRequestList());
            nurseRoster.setDayOffRequestList(requestoffList);
            scoreDirector.afterProblemFactAdded(requestoffList);
            scoreDirector.afterProblemPropertyChanged(requestoffList);

            ArrayList<Employee> beforeempList = new ArrayList<>(nurseRoster.getEmployeeList());
            nurseRoster.setEmployeeList(beforeempList);
            nurseRoster.getEmployeeList().remove(workingEmployee);
            scoreDirector.beforeProblemFactRemoved(workingEmployee);
            scoreDirector.afterProblemFactRemoved(workingEmployee);

            ArrayList<Employee> empList = new ArrayList<>(nurseRoster.getEmployeeList());
            nurseRoster.setEmployeeList(empList);
            workingEmployee.getDayOffRequestMap().put(dayOffRequest.getShiftDate(), dayOffRequest);
            nurseRoster.getEmployeeList().add(workingEmployee);
            scoreDirector.beforeProblemFactAdded(workingEmployee);
            scoreDirector.afterProblemFactAdded(workingEmployee);
            scoreDirector.triggerVariableListeners();
        });

0
投票

我已经在这里上传了xml和Java文件https://github.com/rod182211/Optaplanner,希望有人可以告诉我为什么当我提前14天不是所有规则继续适用。我假设得分者只需要知道变化。


0
投票

提前14天通过以下方式考虑请求。

doProblemFactChange(scoreDirector -> {
        NurseRoster nurseRoster = scoreDirector.getWorkingSolution();
        NurseRosterParametrization nurseRosterParametrization = nurseRoster
                .getNurseRosterParametrization();

        List<ShiftDate> shiftDateList = nurseRoster.getShiftDateList();

        Shift oldLastShift = nurseRoster.getShiftList()
                .get(nurseRoster.getShiftList().size() - 1);
        long shiftId = oldLastShift.getId() + 1L;
        int shiftIndex = oldLastShift.getIndex() + 1;
        ShiftDate oldLastShiftDate = shiftDateList
                .get(shiftDateList.size() - 1);
        long shiftDateId = (oldLastShiftDate.getId() + 1L);
        int shiftDayIndex = (oldLastShiftDate.getDayIndex() + 1);
        // long parmId = nurseRoster.getNurseRosterParametrization().getId()
        // + 1L;

        scoreDirector
                .beforeProblemPropertyChanged(nurseRosterParametrization);

        // Update to get the first day along with adding 14 days to the run
        LocalDate startDate = (oldLastShiftDate.getDate().plusDays(1));
        LocalDate endDate = (oldLastShiftDate.getDate().plusDays(14));
        int maxDayIndex = Math.toIntExact(DAYS.between(startDate, endDate));
        int shiftDateSize = maxDayIndex + 1;
        List<ShiftDate> shiftDateList1 = new ArrayList<>(shiftDateSize);
        shiftDateMap = new HashMap<>(shiftDateSize);
        LocalDate date = startDate;
        for (int i = 0; i < shiftDateSize; i++) {
            ShiftDate shiftDate = new ShiftDate();
            shiftDate.setId(shiftDateId);
            shiftDate.setDayIndex(shiftDayIndex);
            shiftDate.setDate(date);
            shiftDate.setShiftList(new ArrayList<>());
            shiftDateMap.put(date, shiftDate);
            shiftDateId++;
            shiftDayIndex++;
            date = date.plusDays(1);
            nurseRoster.getShiftDateList().add(shiftDate);
            shiftDateList1.add(shiftDate);
            scoreDirector.afterProblemFactAdded(shiftDate);

        }

        List<Skill> skillList;

        List<Skill> skillElementList = (List<Skill>) nurseRoster
                .getSkillList();
        skillList = new ArrayList<>(skillElementList.size());
        skillMap = new HashMap<>(skillElementList.size());
        long id = 0L;
        for (Skill element : skillElementList) {
            Skill skill = new Skill();
            skill.setId(id);
            skill.setCode(element.getCode());
            skillList.add(skill);
            if (skillMap.containsKey(skill.getCode())) {
                throw new IllegalArgumentException(
                        "There are 2 skills with the same code ("
                                + skill.getCode() + ").");
            }
            skillMap.put(skill.getCode(), skill);
            id++;
        }



        List<Contract> contractElementList = (List<Contract>) nurseRoster
                .getContractList();

        List<Contract> contractList = new ArrayList<>(
                contractElementList.size());

        contractMap = new HashMap<>(contractElementList.size());

        for (Contract element : contractElementList) {
            Contract contract = new Contract();
            long Id = element.getId();
            contract.setId(Id);
            contract.setCode(element.getCode());
            contract.setDescription(element.getDescription());
            WeekendDefinition weekend = element.getWeekendDefinition();
            contract.setWeekendDefinition(weekend);
            contract.setContractLineList(new ArrayList<ContractLine>());
            contractMap.put(contract.getCode(), contract);
            contractList.add(contract);
        }

        List<ShiftTypeSkillRequirement> coverRequirementElementList = (List<ShiftTypeSkillRequirement>) nurseRoster
                .getShiftTypeSkillRequirementList();
        List<ShiftType> shiftTypeElementList = (List<ShiftType>) rosterService
                .listShiftType();
        List<ShiftType> shiftTypeList = new ArrayList<>(
                shiftTypeElementList.size());
        shiftTypeMap = new HashMap<>(shiftTypeElementList.size());
        long Id = 0L;
        int index = 0;
        long shiftTypeSkillRequirementId = 0L;
        List<ShiftTypeSkillRequirement> shiftTypeSkillRequirementList = new ArrayList<>(
                shiftTypeElementList.size() * 2);

        for (ShiftType element : shiftTypeElementList) {

            ShiftType shiftType = new ShiftType();
            shiftType.setId(Id);
            shiftType.setCode(element.getCode());
            shiftType.setIndex(index);
            String startTimeString = element.getStartTimeString();
            shiftType.setStartTimeString(startTimeString);
            String endTimeString = element.getEndTimeString();
            shiftType.setEndTimeString(endTimeString);
            shiftType
                    .setNight(startTimeString.compareTo(endTimeString) > 0);
            shiftType.setDescription(element.getDescription());

            for (ShiftTypeSkillRequirement skillElement : coverRequirementElementList) {
                ShiftTypeSkillRequirement shiftTypeSkillRequirement = new ShiftTypeSkillRequirement();
                shiftTypeSkillRequirement
                        .setId(shiftTypeSkillRequirementId);
                shiftTypeSkillRequirement.setShiftType(shiftType);
                Skill skill = skillMap
                        .get(skillElement.getSkill().getCode());
                if (skill == null) {
                    throw new IllegalArgumentException("The skill ("
                            + skillElement.getSkill().getCode()
                            + ") of shiftType (" + shiftType.getCode()
                            + ") does not exist.");
                }
                shiftTypeSkillRequirement.setSkill(skill);
                shiftTypeSkillRequirementList
                        .add(shiftTypeSkillRequirement);
                shiftTypeSkillRequirementId++;
            }

            shiftTypeList.add(shiftType);
            if (shiftTypeMap.containsKey(shiftType.getCode())) {
                throw new IllegalArgumentException(
                        "There are 2 shiftTypes with the same code ("
                                + shiftType.getCode() + ").");
            }
            shiftTypeMap.put(shiftType.getCode(), shiftType);
            Id++;
            index++;
        }
        nurseRoster.setShiftTypeList(shiftTypeList);
        nurseRoster.setShiftTypeSkillRequirementList(
                shiftTypeSkillRequirementList);

        int shiftListSize = shiftDateMap.size() * shiftTypeList.size();

        List<Shift> shiftList1 = new ArrayList<>(shiftListSize);
        dateAndShiftTypeToShiftMap = new HashMap<>(shiftListSize);
        dayOfWeekAndShiftTypeToShiftListMap = new HashMap<>(
                7 * shiftTypeList.size());

        for (ShiftDate shiftDate : shiftDateList1) {
            for (ShiftType shiftType : shiftTypeList) {
                Shift shift = new Shift();
                shift.setId(shiftId);
                shift.setShiftDate(shiftDate);
                shiftDate.getShiftList().add(shift);
                shift.setShiftType(shiftType);
                shift.setIndex(shiftIndex);
                shift.setRequiredEmployeeSize(0); // Filled in later
                shiftList1.add(shift);
                dateAndShiftTypeToShiftMap.put(
                        Pair.of(shiftDate.getDate(), shiftType.getCode()),
                        shift);
                addShiftToDayOfWeekAndShiftTypeToShiftListMap(shiftDate,
                        shiftType, shift);
                shiftId++;
                shiftIndex++;
                nurseRoster.getShiftList().add(shift);
                scoreDirector.afterProblemFactAdded(shift);
            }

        }
        List<DayOffRequest> dayOffRequestList;
        List<DayOffRequest> requestList = (List<DayOffRequest>) nurseRoster.getDayOffRequestList();
        DayOffRequest oldLastDayOff = requestList.get(requestList.size() - 1);
        long DayOffId = (oldLastDayOff.getId() + 1l);


        List<DayOffDate> dayOffElementList = rosterService.listDayOffDate();

        dayOffRequestList = new ArrayList<>(dayOffElementList.size());

        for (DayOffDate element : dayOffElementList) {
            DayOffRequest dayOffRequest = new DayOffRequest();

            int weight = element.getWeight();
            LocalDate shiftDate = element.getDate();

            ShiftDate date1 = shiftDateMap.get(shiftDate);
            Employee employee = element.getEmployee();
            Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);
            dayOffRequest.setId(DayOffId);
            DayOffId++;
            dayOffRequest.setWeight(weight);
            dayOffRequest.setEmployee(workingEmployee);
            dayOffRequest.setShiftDate(date1);
            workingEmployee.getDayOffRequestMap().put(date1, dayOffRequest);
            nurseRoster.getDayOffRequestList().add(dayOffRequest);


        }

        List<DayOnRequest> dayOnRequestList;

        List<DayOnDate> dayOnElementList1 = rosterService.listDayOnDate();

        dayOnRequestList = new ArrayList<>(dayOnElementList1.size());
        for (DayOnDate element : dayOnElementList1) {

            DayOnRequest dayOnRequest = new DayOnRequest();
            long DayOnId = element.getId();
            int weight = element.getWeight();       
            LocalDate localshiftDate = element.getDate();

            ShiftDate dateon = shiftDateMap.get(localshiftDate);
            Employee employee = element.getEmployee();

            Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);

            dayOnRequest.setId(DayOnId);

            dayOnRequest.setWeight(weight);
            dayOnRequest.setEmployee(workingEmployee);
            dayOnRequest.setShiftDate(dateon);
            dayOnRequestList.add(dayOnRequest);
            workingEmployee.getDayOnRequestMap().put(dateon, dayOnRequest);
            nurseRoster.getDayOnRequestList().add(dayOnRequest);

        }


        List<ShiftOffRequest> shiftOffRequestList;

        List<ShiftOffDate> shiftOffElementList = (List<ShiftOffDate>) rosterService.listShiftOffDate();
        shiftOffRequestList = new ArrayList<>(shiftOffElementList.size());
        for (ShiftOffDate element : shiftOffElementList) {

            ShiftOffRequest shiftOffRequest = new ShiftOffRequest();

            long ShiftonId = element.getId();
            int weight = element.getWeight();                 
            Employee employee = element.getEmployee();
            Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);
            LocalDate  date1 = element.getDate();
            String shiftcode = element.getShiftType().getCode();
            Shift shift = dateAndShiftTypeToShiftMap.get(Pair.of(date1, shiftcode));

            shiftOffRequest.setId(ShiftonId);
            shiftOffRequest.setEmployee(workingEmployee);
            shiftOffRequest.setShift(shift);
            shiftOffRequest.setWeight(weight);
            shiftOffRequestList.add(shiftOffRequest);
            workingEmployee.getShiftOffRequestMap().put(shift, shiftOffRequest);
            nurseRoster.setShiftOffRequestList(shiftOffRequestList);

        }


        List<ShiftOnRequest> shiftOnRequestList;

        List<ShiftOnDate> shiftOnElementList = (List<ShiftOnDate>) rosterService.listShiftOnDate();
        shiftOnRequestList = new ArrayList<>(shiftOnElementList.size());
        for (ShiftOnDate element : shiftOnElementList) {

            ShiftOnRequest shiftOnRequest = new ShiftOnRequest();

            long ShiftonId = element.getId();
            int weight = element.getWeight();                 
            Employee employee = element.getEmployee();
            Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);
            LocalDate  date1 = element.getDate();
            String shiftcode = element.getShiftType().getCode();
            Shift shift = dateAndShiftTypeToShiftMap.get(Pair.of(date1, shiftcode));

            shiftOnRequest.setId(ShiftonId);
            shiftOnRequest.setEmployee(workingEmployee);
            shiftOnRequest.setShift(shift);
            shiftOnRequest.setWeight(weight);
            shiftOnRequestList.add(shiftOnRequest);
            workingEmployee.getShiftOnRequestMap().put(shift, shiftOnRequest);
            nurseRoster.setShiftOnRequestList(shiftOnRequestList);

        }

        List<CoverRequirements> coverRequirementElementList1 = (List<CoverRequirements>) rosterService
                .listCoverRequirements();
        for (CoverRequirements element : coverRequirementElementList1) {
            String type = element.getShiftType().getCode();
            DayOfWeek day = element.getDayOfWeek();
            int req = element.getRequiredEmployeesize();
            ShiftType shiftType = shiftTypeMap.get(type);
            Pair<DayOfWeek, ShiftType> key = Pair.of(day, shiftType);

            List<Shift> shiftList = dayOfWeekAndShiftTypeToShiftListMap
                    .get(key);

            for (Shift shift : shiftList) {
                shift.setRequiredEmployeeSize(
                        shift.getRequiredEmployeeSize() + req);

            }
        }
        List<ShiftAssignment> shiftAssignmentList = new ArrayList<>(
                shiftList1.size());
        long shiftAssignmentId = nurseRoster.getShiftAssignmentList()
                .get(nurseRoster.getShiftAssignmentList().size() - 1)
                .getId() + 1L;
        for (Shift shift : shiftList1) {
            for (int i = 0; i < shift.getRequiredEmployeeSize(); i++) {
                ShiftAssignment newShiftAssignment = new ShiftAssignment();
                newShiftAssignment.setId(shiftAssignmentId);
                shiftAssignmentId++;
                newShiftAssignment.setShift(shift);
                newShiftAssignment.setIndexInShift(i);
                shiftAssignmentList.add(newShiftAssignment);
                nurseRoster.getShiftAssignmentList()
                        .add(newShiftAssignment);
                scoreDirector.afterEntityAdded(newShiftAssignment);

            }

        }

//这应该移动计划窗口

        nurseRosterParametrization.setFirstShiftDate(shiftDateList1.get(0));
        nurseRosterParametrization.setLastShiftDate(shiftDateList1.get(shiftDateList1.size() - 1));
        nurseRosterParametrization.setPlanningWindowStart(shiftDateList1.get(0));
        nurseRoster.setNurseRosterParametrization(nurseRosterParametrization);
        scoreDirector.afterProblemPropertyChanged(nurseRosterParametrization);
        scoreDirector.triggerVariableListeners();

    }, true);
}
© www.soinside.com 2019 - 2024. All rights reserved.