我最近一直在熟悉Optaplanner - 更具体地说,就是护士排班的例子 - 而且一直试图增加一个新的硬约束,但到目前为止,还没有取得多大成功。
我正在努力添加DayUnavailableRequest约束(即员工无法在特定日期工作)。我使用DayOffRequest作为模板。两个约束之间的唯一区别是DayUnavailableRequest约束将是" hard"。
为此,我在请求文件夹中添加了一个新文件 - 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;
}
}
然后我将以下内容添加到nurseRosteringScoreRules.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`
在nurseRoster.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>
返回一个很长的&#34;未捕获的异常&#34;错误。
<DayUnavailableRequest>
<DayUnavailable>
<EmployeeID>4</EmployeeID>
<Date>2014-10-24</Date>
</DayUnavailable>
</DayUnavailableRequest>
不会返回错误,但也不会应用于该应用程序。
非常感谢任何帮助。此外,如果有更有效的方式来添加员工可用性,请分享。
感谢。
答案 0 :(得分:0)
您在NurseRosteringImporter.java中添加了
第115行:
readShiftOnRequestList(nurseRoster, schedulingPeriodElement.getChild("ShiftOnRequests"));
你必须添加它,而不是:
readDayUnavailableRequestList(nurseRoster, schedulingPeriodElement.getChild("DayUnavailableRequest"));
答案 1 :(得分:-1)
777
的在线NurseRosteringImporter.java
,您需要添加与行776
,775
,773
等相同的行,但是DayUnavailableRequest
1}}。
你也需要做上面提到的那个人。
这些变化对我有用。