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 { private Set 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 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; } }