package com.chinaztt.mes.aps.core.solver;
|
|
import com.chinaztt.mes.aps.core.domain.Task;
|
import org.optaplanner.core.impl.domain.variable.listener.VariableListener;
|
import org.optaplanner.core.impl.score.director.ScoreDirector;
|
|
import java.time.LocalDateTime;
|
import java.util.*;
|
|
/**
|
* @Author: zhangxy
|
* @Date: 2020-10-19 20:36
|
*/
|
public class StartTimeUpdatingVariableListener implements VariableListener<Task> {
|
private Set<Long> idSet = new HashSet<>();
|
|
@Override
|
public void beforeEntityAdded(ScoreDirector scoreDirector, Task task) {
|
|
}
|
|
@Override
|
public void afterEntityAdded(ScoreDirector scoreDirector, Task task) {
|
updatePlanStartTime(scoreDirector, task);
|
}
|
|
@Override
|
public void beforeVariableChanged(ScoreDirector scoreDirector, Task task) {
|
|
}
|
|
@Override
|
public void afterVariableChanged(ScoreDirector scoreDirector, Task task) {
|
this.updatePlanStartTime(scoreDirector, task);
|
}
|
|
@Override
|
public void beforeEntityRemoved(ScoreDirector scoreDirector, Task task) {
|
|
}
|
|
@Override
|
public void afterEntityRemoved(ScoreDirector scoreDirector, Task task) {
|
|
}
|
|
|
protected void updatePlanStartTime(ScoreDirector scoreDirector, Task sourceTask) {
|
idSet.clear();
|
Queue<Task> uncheckedSuccessorQueue = new ArrayDeque<>();
|
uncheckedSuccessorQueue.add(sourceTask);
|
while (!uncheckedSuccessorQueue.isEmpty()) {
|
Task task = uncheckedSuccessorQueue.remove();
|
if (idSet.contains(task.getId())) {
|
continue;
|
}
|
boolean updated = doUpdate(scoreDirector, task);
|
if (updated) {
|
idSet.add(task.getId());
|
if (task.getNextTask() != null) {
|
uncheckedSuccessorQueue.add(task.getNextTask());
|
}
|
if (task.getSuccessorOfRouting() != null) {
|
uncheckedSuccessorQueue.add(task.getSuccessorOfRouting());
|
}
|
}
|
}
|
}
|
|
|
protected boolean doUpdate(ScoreDirector scoreDirector, Task task) {
|
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime time1 = task.getPreviousTaskOrResource() == null ? now : task.getPreviousTaskOrResource().getPlanEndTime();
|
LocalDateTime time2 = task.getPredecessorOfRouting() == null ? now : task.getPredecessorOfRouting().getPlanEndTime();
|
|
LocalDateTime maxTime = time1.compareTo(time2) >= 0 ? time1 : time2;
|
if (Objects.equals(maxTime, task.getPlanStartTime())) {
|
return false;
|
}
|
scoreDirector.beforeVariableChanged(task, "planStartTime");
|
task.setPlanStartTime(maxTime);
|
scoreDirector.afterVariableChanged(task, "planStartTime");
|
return true;
|
}
|
|
|
}
|