0

我最近一直在熟悉 Optaplanner——更具体地说,是它的护士排班示例——并且一直在尝试添加一个新的硬约束,但到目前为止,还没有取得太大的成功。

我正在努力添加 DayUnavailableRequest 约束(即员工在特定日期无法工作)。我使用 DayOffRequest 作为模板。这两个约束之间的唯一区别是 DayUnavailableRequest 约束会“硬”。

为此,我在请求文件夹中添加了一个新文件 - DayUnavailableRequest.Java:

package org.optaplanner.examples.nurserostering.domain.request;
import com.thoughtworks.xstream.annotations.XStreamAlias;

import org.optaplanner.examples.common.domain.AbstractPersistable;
import org.optaplanner.examples.nurserostering.domain.Employee;
import org.optaplanner.examples.nurserostering.domain.ShiftDate;

@XStreamAlias("DayUnavailableRequest")
public class DayUnavailableRequest extends AbstractPersistable {

private Employee employee;
private ShiftDate shiftDate;

public Employee getEmployee() {
    return employee;
}

public void setEmployee(Employee employee) {
    this.employee = employee;
}

public ShiftDate getShiftDate() {
    return shiftDate;
}

public void setShiftDate(ShiftDate shiftDate) {
    this.shiftDate = shiftDate;
}

@Override
public String toString() {
    return shiftDate + "_OFF_" + employee;
}

}

然后我将以下内容添加到nurserRosteringScoreRules.drl:

Availability day on/off
rule "dayUnavailableRequest"
when
    $dayUnavailableRequest : DayUnavailableRequest($employee : employee, $shiftDate :  shiftDate)
    $assignment : ShiftAssignment(employee == $employee, shiftDate == $shiftDate)
then
    scoreHolder.addHardConstraintMatch(kcontext, - 1);
end`

在nurserRoster.java 中,我添加了:

public List<DayUnavailableRequest> getDayUnavailableRequestList() {
return dayUnavailableRequestList;
}

public void setDayUnavailableRequestList(List<DayUnavailableRequest> dayUnavailableRequestList) {
    this.dayUnavailableRequestList = dayUnavailableRequestList;
}    

也:

facts.addAll(dayUnavailableRequestList);

在 Employee.java 中,我添加了:

private Map<ShiftDate, DayUnavailableRequest> dayUnavailableRequestMap;

和...

public Map<ShiftDate, DayUnavailableRequest> getDayUnavailableRequestMap() {
    return dayUnavailableRequestMap;
}

public void setDayUnavailableRequestMap(Map<ShiftDate, DayUnavailableRequest> dayUnavailableRequestMap) {
    this.dayUnavailableRequestMap = dayUnavailableRequestMap;
}

最后,在 NurseRosteringImporter.java 中,我包括:

在第 115 行:

readShiftOnRequestList(nurseRoster, schedulingPeriodElement.getChild("ShiftOnRequests"));

在第 131 行:

nurseRoster.getDayUnavailableRequestList().size(),

和...

private void readDayUnavailableRequestList(NurseRoster nurseRoster, Element dayUnavailableRequestsElement) throws JDOMException {
        List<DayUnavailableRequest> dayUnavailableRequestList;
        if (dayUnavailableRequestsElement == null) {
            dayUnavailableRequestList = Collections.emptyList();
        } else {
            List<Element> dayUnavailableElementList = (List<Element>) dayUnavailableRequestsElement.getChildren();
            dayUnavailableRequestList = new ArrayList<DayUnavailableRequest>(dayUnavailableElementList.size());
            long id = 0L;
            for (Element element : dayUnavailableElementList) {
                assertElementName(element, "DayUnavailable");
                DayUnavailableRequest dayUnavailableRequest = new DayUnavailableRequest();
                dayUnavailableRequest.setId(id);

                Element employeeElement = element.getChild("EmployeeID");
                Employee employee = employeeMap.get(employeeElement.getText());
                if (employee == null) {
                    throw new IllegalArgumentException("The shiftDate (" + employeeElement.getText()
                            + ") of dayUnavailableRequest (" + dayUnavailableRequest + ") does not exist.");
                }
                dayUnavailableRequest.setEmployee(employee);

                Element dateElement = element.getChild("Date");
                ShiftDate shiftDate = shiftDateMap.get(dateElement.getText());
                if (shiftDate == null) {
                    throw new IllegalArgumentException("The date (" + dateElement.getText()
                            + ") of dayUnavailableRequest (" + dayUnavailableRequest + ") does not exist.");
                }
                dayUnavailableRequest.setShiftDate(shiftDate);

                dayUnavailableRequestList.add(dayUnavailableRequest);
                employee.getDayUnavailableRequestMap().put(shiftDate, dayUnavailableRequest);
                id++;
            }
        }
        nurseRoster.setDayUnavailableRequestList(dayUnavailableRequestList);
    }

我正在使用 sprint01_1week.xml 进行测试。当我添加约束数据时,我要么收到错误,要么应用程序工作但可用性约束本身不生效。

例如:

<DaysUnavailable>   
 <DayUnavailable>
  <EmployeeID>4</EmployeeID>
  <Date>2014-10-24</Date>
 </DayUnavailable>
</DaysUnavailable>

返回一个长的“未捕获的异常”错误。

<DayUnavailableRequest>
 <DayUnavailable>
  <EmployeeID>4</EmployeeID>
  <Date>2014-10-24</Date>
 </DayUnavailable>
</DayUnavailableRequest>  

不会返回错误,但也不会应用于应用程序。

任何帮助将不胜感激。另外,如果有更有效的方法来增加员工的可用性,请分享。

谢谢。

4

2 回答 2

0

您在 NurseRosteringImporter.java 中添加了:

在第 115 行:

readShiftOnRequestList(nurseRoster, schedulingPeriodElement.getChild("ShiftOnRequests"));

你必须添加这个,而不是:

readDayUnavailableRequestList(nurseRoster, schedulingPeriodElement.getChild("DayUnavailableRequest"));
于 2015-12-10T10:41:12.780 回答
-1

在 Line 777ofNurseRosteringImporter.java你需要添加与 line 相同的行776,等775773但对于DayUnavailableRequest.

你也需要按照上面那个人说的去做。

这些变化对我有用。

于 2017-01-21T04:06:11.693 回答