Java Optaplanner:添加新约束(硬)
最近,我一直在熟悉Optaplanner——更具体地说,是它的护士排班示例——并试图添加一个新的硬约束,但到目前为止,还没有取得多大成功 我正在努力添加DayUnavailableRequest约束(即员工在特定日期无法工作)。我使用dayoff请求作为模板。这两个约束之间的唯一区别是DayUnavailableRequest约束将是“硬的” 为此,我在请求文件夹中添加了一个新文件DayUnavailableRequest.Java:Java Optaplanner:添加新约束(硬),java,scheduling,project-planning,optaplanner,rostering,Java,Scheduling,Project Planning,Optaplanner,Rostering,最近,我一直在熟悉Optaplanner——更具体地说,是它的护士排班示例——并试图添加一个新的硬约束,但到目前为止,还没有取得多大成功 我正在努力添加DayUnavailableRequest约束(即员工在特定日期无法工作)。我使用dayoff请求作为模板。这两个约束之间的唯一区别是DayUnavailableRequest约束将是“硬的” 为此,我在请求文件夹中添加了一个新文件DayUnavailableRequest.Java: package org.optaplanner.exampl
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;
}
}
然后,我将以下内容添加到NurseServeringScoreRules.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`
在nurservester.java中,我添加了:
public List<DayUnavailableRequest> getDayUnavailableRequestList() {
return dayUnavailableRequestList;
}
public void setDayUnavailableRequestList(List<DayUnavailableRequest> dayUnavailableRequestList) {
this.dayUnavailableRequestList = dayUnavailableRequestList;
}
private Map<ShiftDate, DayUnavailableRequest> dayUnavailableRequestMap;
在Employee.java中,我添加了:
public List<DayUnavailableRequest> getDayUnavailableRequestList() {
return dayUnavailableRequestList;
}
public void setDayUnavailableRequestList(List<DayUnavailableRequest> dayUnavailableRequestList) {
this.dayUnavailableRequestList = dayUnavailableRequestList;
}
private Map<ShiftDate, DayUnavailableRequest> dayUnavailableRequestMap;
第131行:
nurseRoster.getDayUnavailableRequestList().size(),
而且
public Map<ShiftDate, DayUnavailableRequest> getDayUnavailableRequestMap() {
return dayUnavailableRequestMap;
}
public void setDayUnavailableRequestMap(Map<ShiftDate, DayUnavailableRequest> dayUnavailableRequestMap) {
this.dayUnavailableRequestMap = dayUnavailableRequestMap;
}
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);
}
private void readDayUnavailableRequestList(NurseSter NurseSter,元素dayUnavailableRequestsElement)抛出JDOMException{
列表日期不可用请求列表;
if(dayUnavailableRequestsElement==null){
dayUnavailableRequestList=Collections.emptyList();
}否则{
List dayUnavailableElementList=(List)dayUnavailableRequestsElement.getChildren();
dayUnavailableRequestList=新的ArrayList(dayUnavailableElementList.size());
长id=0L;
for(元素:dayUnavailableElementList){
assertElementName(元素“DayUnavailable”);
DayUnavailableRequest DayUnavailableRequest=新的DayUnavailableRequest();
dayUnavailableRequest.setId(id);
Element employeeElement=Element.getChild(“EmployeeID”);
Employee=employeeMap.get(employeeElement.getText());
if(employee==null){
抛出新的IllegalArgumentException(“shiftDate(“+employeeElement.getText())
+dayUnavailableRequest的(“+dayUnavailableRequest+”)不存在。”);
}
dayUnavailableRequest.setEmployee(员工);
元素dateElement=Element.getChild(“日期”);
ShiftDate ShiftDate=shiftDateMap.get(dateElement.getText());
if(shiftDate==null){
抛出新的IllegalArgumentException(“日期(“+dateElement.getText())
+dayUnavailableRequest的(“+dayUnavailableRequest+”)不存在。”);
}
dayUnavailableRequest.SetShift日期(shiftDate);
dayUnavailableRequestList.add(dayUnavailableRequest);
employee.getDayUnavailableRequestMap().put(shiftDate,dayUnavailableRequest);
id++;
}
}
NurseServer.setDayUnavailableRequestList(dayUnavailableRequestList);
}
我使用sprint01_1week.xml进行测试。当我添加约束数据时,我要么收到一个错误,要么应用程序工作,但可用性约束本身不起作用
例如:
<DaysUnavailable>
<DayUnavailable>
<EmployeeID>4</EmployeeID>
<Date>2014-10-24</Date>
</DayUnavailable>
</DaysUnavailable>
4.
2014-10-24
返回一个长的“未捕获异常”错误
4.
2014-10-24
不会返回错误,但也不会应用于应用程序
任何帮助都将不胜感激。此外,如果有更有效的方法增加员工可用性,请与我们分享
谢谢。您在NurseServeringImporter.java中添加了: 第115行:
readShiftOnRequestList(nurseRoster, schedulingPeriodElement.getChild("ShiftOnRequests"));
readShiftOnRequestList(nurseRoster, schedulingPeriodElement.getChild("ShiftOnRequests"));
您必须添加以下内容:
readDayUnavailableRequestList(nurseRoster, schedulingPeriodElement.getChild("DayUnavailableRequest"));
在
nursserosteringimporter.java的777
行上,您需要添加与行776
、775
、773
等相同的行,但对于DayUnavailableRequest
你也需要照上面那个人说的去做
这些更改对我起到了作用。您确定正在调用readDayUnavailableRequestList()吗?在getProblemFacts()中放置一个断点,以确保NurseSter上的dayUnavailableRequest列表和Employee上的dayUnavailableRequest映射都已正确填写。您完成了吗?