2014-10-22 9 views
0

저는 최근에 Optaplanner에 대해 자세히 알아 보았습니다. - 더 구체적으로 말하자면, 간호사가 수위를 올리는 사례를 통해 - 새로운 제약 조건을 추가하려고 시도했지만 지금까지는 성공.Optaplanner : 새로운 제약 조건 추가하기 (하드)

DayUnavailableRequest 제약 조건을 추가하기 위해 노력하고 있습니다 (예 : 특정 일에 직원을 고용 할 수 없음). DayOffRequest를 템플릿으로 사용하고 있습니다. 두 조건 사이의 유일한 차이점은 DayUnavailableRequest 제약 조건은 "어렵습니다"라는 것입니다.

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에 다음과 같은 추가 : nurseRoster에서

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` 

- DayUnavailableRequest.Java - 요청 폴더에

는이를 위해, 나는 새 파일을 추가했습니다. 자바, 나는 추가 :

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

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

뿐만 아니라 :

를 ...

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

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

private Map<ShiftDate, DayUnavailableRequest> dayUnavailableRequestMap; 

및 마지막 NurseRosteringImporter.java에 포함 I :

facts.addAll(dayUnavailableRequestList); 

는 Employee.java에서 I 첨가 라인 (115)에

:

readShiftOnRequestList(nurseRoster, schedulingPeriodElement.getChild("ShiftOnRequests")); 
라인 (131)에 63,210

:

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> 

오류를 반환하지는 않지만 응용 프로그램에도 적용되지 않습니다.

도움을 주시면 감사하겠습니다. 또한 직원의 가용성을 높일 수있는보다 효율적인 방법이 있다면 공유하십시오.

감사합니다.

+0

readDayUnavailableRequestList()가 호출되고 있습니까? –

+0

getProblemFacts()에 breakpoint를 두어 NurseRoster의 dayUnavailableRequest 목록과 Employee의 dayUnavailableRequest 맵이 제대로 채워 졌는지 확인하십시오. –

+0

이 작업을 수행 했습니까? –

답변

0

NurseRosteringImporter에 추가했습니다.자바 :

라인 (115)에

:

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

그리고 당신이해야하는 대신, 이것을 추가 :

이 라인 777
readDayUnavailableRequestList(nurseRoster, schedulingPeriodElement.getChild("DayUnavailableRequest")); 
-1

NurseRosteringImporter.java 당신이 라인과 동일 라인을 추가 할 필요가 776, 775, 773 등이지만, DayUnavailableRequest 인 경우.

위의 사람도해야 할 일을해야합니다.

이 변경 사항은 저에게 효과적이었습니다.