|
@@ -26,7 +26,7 @@ public class ApsConstraintListProvider implements ConstraintProvider {
|
|
|
return new Constraint[]{
|
|
|
// HARD
|
|
|
hasOnePreGbAfterNowNew(constraintFactory),
|
|
|
-// nextLockProNew(constraintFactory),
|
|
|
+ nextLockProNew(constraintFactory),
|
|
|
eqTimeCross(constraintFactory),
|
|
|
seriesProduceTimeWait(constraintFactory),
|
|
|
seriesProduceWashTimeWait(constraintFactory),
|
|
@@ -54,62 +54,6 @@ public class ApsConstraintListProvider implements ConstraintProvider {
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 硬约束:合并生产工序设备、开始时间、结束时间都一样
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint mergeSame(ConstraintFactory constraintFactory) {
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .groupBy(ProductionProcesses::getMergeProcessMark, ConstraintCollectors.toList())
|
|
|
- .filter((mergeProcessMark,processes) -> {
|
|
|
- if(processes != null && processes.size()>1){
|
|
|
- boolean a = false;
|
|
|
- // 合并生产的设备、开始时间、结束时间要一致
|
|
|
- Equipment ep = null;
|
|
|
- LocalDateTime startTime = null;
|
|
|
- LocalDateTime endTime = null;
|
|
|
- for (ProductionProcesses process : processes) {
|
|
|
- if(process.getEquipment() != null){
|
|
|
- if(ep == null){
|
|
|
- ep = process.getEquipment();
|
|
|
- }else{
|
|
|
- if(!ep.getId().equals(process.getEquipment().getId())){
|
|
|
- a = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if(process.getStartTime() != null){
|
|
|
- if(startTime == null){
|
|
|
- startTime = process.getStartTime();
|
|
|
- }else{
|
|
|
- if(startTime.compareTo(process.getStartTime()) != 0){
|
|
|
- a = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if(process.getEndTime() != null){
|
|
|
- if(endTime == null){
|
|
|
- endTime = process.getEndTime();
|
|
|
- }else{
|
|
|
- if(endTime.compareTo(process.getEndTime()) != 0){
|
|
|
- a = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return a;
|
|
|
- }else{
|
|
|
- return false;
|
|
|
- }
|
|
|
- })
|
|
|
- .penalize(HardSoftScore.ONE_HARD,(mergeProcessMark, processes) -> 100)
|
|
|
- .asConstraint("mergeSame");
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 不能超过最大开始时间
|
|
|
* @param constraintFactory
|
|
@@ -174,53 +118,6 @@ public class ApsConstraintListProvider implements ConstraintProvider {
|
|
|
.asConstraint("hasOnePreGbAfterNow");
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 下道工序如果是锁定工序则判断是否下道工序时间在当前工序之后
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint nextLockPro(ConstraintFactory constraintFactory) {
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter(productionProcesses -> {
|
|
|
- boolean bln = false;
|
|
|
- List<ProductionProcesses> nextProcesses = productionProcesses.getNextProcesses();
|
|
|
- if(nextProcesses != null && nextProcesses.size()>0){
|
|
|
- if(nextProcesses.get(0).getIfLock()){
|
|
|
- // 当前工序结束时间
|
|
|
- LocalDateTime preEndTime = productionProcesses.getEndTime();
|
|
|
- // 获取下道工序最早开始时间
|
|
|
- LocalDateTime earlyStartTime = null;
|
|
|
- for (ProductionProcesses nextProcess : nextProcesses) {
|
|
|
- // 下道工序开始时间
|
|
|
- LocalDateTime startTime = nextProcess.getStartTime();
|
|
|
- // 流转时间(最小等待时间)
|
|
|
- Integer lzTimes = 0;
|
|
|
- if(productionProcesses.getEquipment().getWorkshopid() != null && productionProcesses.getEquipment().getWorkshopid().equals(nextProcess.getEquipment().getWorkshopid())){
|
|
|
- lzTimes = productionProcesses.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
|
|
|
- }else{
|
|
|
- lzTimes = productionProcesses.getApsOverallConfig().getRoamTime().get("WORKSHOP_CROSS");
|
|
|
- }
|
|
|
- // 最小等待时间对比流转时间
|
|
|
- if(productionProcesses.getMinWaitTime() != null && lzTimes<productionProcesses.getMinWaitTime()){
|
|
|
- lzTimes = productionProcesses.getMinWaitTime();
|
|
|
- }
|
|
|
- if(preEndTime.plusMinutes(lzTimes).compareTo(startTime)>0){
|
|
|
- bln = true;
|
|
|
- }
|
|
|
- // 最大等待时间
|
|
|
- Integer maxWaitTime = productionProcesses.getMaxWaitTime();
|
|
|
- if(maxWaitTime != null && maxWaitTime>0 && preEndTime.plusMinutes(maxWaitTime).compareTo(startTime)<0){
|
|
|
- bln = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return bln;
|
|
|
- })
|
|
|
- .penalize(HardMediumSoftScore.ONE_HARD,(productionProcesses) -> 30)
|
|
|
- .asConstraint("nextLockPro");
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 下道工序如果是锁定工序则判断是否下道工序时间在当前工序之后(新的等待时间调整)
|
|
|
* @param constraintFactory
|
|
@@ -321,45 +218,6 @@ public class ApsConstraintListProvider implements ConstraintProvider {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 所有下道工序最大等待时间考虑
|
|
|
- * @param productionProcesses
|
|
|
- * @param nextStartTimes
|
|
|
- * @param totalMinWaitTime
|
|
|
- */
|
|
|
- private void getAllNextLockMaxWaitTime(ProductionProcesses productionProcesses,List<LocalDateTime> nextStartTimes,Integer totalMinWaitTime){
|
|
|
- List<ProductionProcesses> nextProcesses = productionProcesses.getNextProcesses();
|
|
|
- if(nextProcesses != null && nextProcesses.size()>0){
|
|
|
- Integer nowTotalMinWaitTime = totalMinWaitTime;
|
|
|
- for (ProductionProcesses nextProcess : nextProcesses) {
|
|
|
- LocalDateTime startTime = nextProcess.getStartTime();
|
|
|
- if(nextProcess.getMaxWaitTime() != null && nextProcess.getMaxWaitTime()>0){
|
|
|
- nowTotalMinWaitTime = totalMinWaitTime + nextProcess.getMaxWaitTime();
|
|
|
- if(nextProcess.getIfLock()){
|
|
|
- startTime = startTime.minusMinutes(nowTotalMinWaitTime);
|
|
|
- nextStartTimes.add(startTime);
|
|
|
- }else{
|
|
|
- getAllNextLockMaxWaitTime(nextProcess,nextStartTimes,nowTotalMinWaitTime);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 汇总所有下道工序的加工时间
|
|
|
- * @param nextProcess
|
|
|
- * @param map
|
|
|
- */
|
|
|
- private void allNextProduceTime(ProductionProcesses nextProcess, Map<String,Integer> map, String proId){
|
|
|
- map.put(proId,map.get(proId)+nextProcess.getProduceTime());
|
|
|
- if(nextProcess.getNextProcesses() != null && nextProcess.getNextProcesses().size()>0){
|
|
|
- for (ProductionProcesses process : nextProcess.getNextProcesses()) {
|
|
|
- allNextProduceTime(process,map,proId);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 设备运行时间段,不可再排产
|
|
|
* @param constraintFactory
|
|
@@ -407,65 +265,6 @@ public class ApsConstraintListProvider implements ConstraintProvider {
|
|
|
.asConstraint("equipmentRunTime");
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- /**
|
|
|
- * 前后工序如果一样则连续生产中间不能有其它作业
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint sameSeriesProcess(ConstraintFactory constraintFactory){
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter(pro->{
|
|
|
- return !pro.getProcessType().equals("成退") && !pro.getProcessType().equals("中退")
|
|
|
- && !pro.getProcessType().equals("小卷成退") && !pro.getProcessType().equals("铸轧");
|
|
|
- })
|
|
|
- .filter(productionProcesses -> {
|
|
|
- boolean bol = false;
|
|
|
-
|
|
|
- return bol;
|
|
|
- })
|
|
|
- .penalize(HardMediumSoftScore.ONE_HARD,(proc1)->15)
|
|
|
- .asConstraint("sameSeriesProcess");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 最大等待时间,不能小于流转时间
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint lzTimeLessMaxWait(ConstraintFactory constraintFactory) {
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter(productionProcesses -> {
|
|
|
- // 对比前后工序设备所属工厂、获取最大流转时间
|
|
|
- boolean bol = false;
|
|
|
- if(productionProcesses.getPreviousProcesses() != null && productionProcesses.getPreviousProcesses().size()>0){
|
|
|
- for (ProductionProcesses previousProcess : productionProcesses.getPreviousProcesses()) {
|
|
|
- Integer lzTimes = 0;
|
|
|
- if(previousProcess.getEquipment() == null){
|
|
|
- System.out.println("previousProcess.getEquipment() == null");
|
|
|
- System.out.println(previousProcess.getBsProcessesId());
|
|
|
- System.out.println(previousProcess.getId());
|
|
|
- }
|
|
|
- if(productionProcesses.getEquipment() == null){
|
|
|
- System.out.println("productionProcesses.getEquipment() == null");
|
|
|
- }
|
|
|
- if(previousProcess.getEquipment().getWorkshopid() != null && previousProcess.getEquipment().getWorkshopid().equals(productionProcesses.getEquipment().getWorkshopid())){
|
|
|
- lzTimes = productionProcesses.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
|
|
|
- }else{
|
|
|
- lzTimes = productionProcesses.getApsOverallConfig().getRoamTime().get("WORKSHOP_CROSS");
|
|
|
- }
|
|
|
- if(previousProcess.getMaxWaitTime() != null && previousProcess.getMaxWaitTime()>0 && previousProcess.getMaxWaitTime()<lzTimes){
|
|
|
- bol = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return bol;
|
|
|
- })
|
|
|
- .penalize(HardMediumSoftScore.ONE_HARD,(proc1)->90)
|
|
|
- .asConstraint("lzTimeLessMaxWait");
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 连续生产洗炉时间约束
|
|
|
* @param constraintFactory
|
|
@@ -829,55 +628,6 @@ public class ApsConstraintListProvider implements ConstraintProvider {
|
|
|
return b;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 退火前一道工序尽量靠近
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint beforeThClose(ConstraintFactory constraintFactory) {
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter((processe) -> {
|
|
|
- boolean a = false;
|
|
|
- if(processe.getStartTime() != null){
|
|
|
- List<ProductionProcesses> nextProcesses = processe.getNextProcesses();
|
|
|
- if(nextProcesses != null && nextProcesses.size()>0){
|
|
|
- for (ProductionProcesses nextProcess : nextProcesses) {
|
|
|
- if("成退".equals(nextProcess.getProcessType()) || "中退".equals(nextProcess.getProcessType()) || "小卷成退".equals(nextProcess.getProcessType())){
|
|
|
- a = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return a;
|
|
|
- })
|
|
|
- .groupBy(ProductionProcesses::getUniqueBsProcessesId, ConstraintCollectors.toList())
|
|
|
- .filter((bsProcessesId,processes) -> {
|
|
|
- if(processes != null && processes.size()>1){
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
- })
|
|
|
- .penalize(HardMediumSoftScore.ONE_MEDIUM,(bsProcessesId,processes)->{
|
|
|
- long counNum = 0;
|
|
|
- List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
|
|
|
- // 按照开始时间排序
|
|
|
- Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
|
|
|
- if(hasStartTimeProcess.size()>1){
|
|
|
- for (int i = 0; i < hasStartTimeProcess.size()-1; i++) {
|
|
|
- ProductionProcesses processes1 = hasStartTimeProcess.get(i);
|
|
|
- ProductionProcesses processes2 = hasStartTimeProcess.get(i+1);
|
|
|
- long minutesDiff = ChronoUnit.MINUTES.between(processes1.getStartTime(), processes2.getStartTime());
|
|
|
- if(minutesDiff<0){
|
|
|
- int a = 1;
|
|
|
- }
|
|
|
- counNum = counNum + minutesDiff;
|
|
|
- }
|
|
|
- }
|
|
|
- return (int)counNum;
|
|
|
- })
|
|
|
- .asConstraint("beforeThClose");
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 换辊和立板时间约束
|
|
|
* @param processes
|
|
@@ -1891,85 +1641,6 @@ public class ApsConstraintListProvider implements ConstraintProvider {
|
|
|
return daysBetween-deliveryMinDate;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 均衡排产的软约束,任务尽量分配到不同设备上
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint balancedEqUse(ConstraintFactory constraintFactory){
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter((tc) -> {
|
|
|
- return true;
|
|
|
- })
|
|
|
- .groupBy(ProductionProcesses::getTaskType,ConstraintCollectors.toList())
|
|
|
- .filter((taskType, processess) ->{
|
|
|
- boolean isbalance = false;
|
|
|
- Integer balanceNum = balanceCount(processess);
|
|
|
- if(balanceNum>0){
|
|
|
- isbalance = true;
|
|
|
- }
|
|
|
- return isbalance;
|
|
|
- })
|
|
|
- .penalize(HardMediumSoftScore.ONE_SOFT,(taskType, processess) -> {
|
|
|
- Integer balanceNum = balanceCount(processess);
|
|
|
- return balanceNum;
|
|
|
- })
|
|
|
- .asConstraint("balancedEqUse");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 均衡排产分数计算
|
|
|
- * @param processess
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Integer balanceCount(List<ProductionProcesses> processess){
|
|
|
- Integer balanceNum = 0;
|
|
|
- if(processess != null && processess.size()>0){
|
|
|
- /**
|
|
|
- * 缓存所有设备计划均衡排产时间和实际排产时间
|
|
|
- * map的value是List<Integer>类型长度为2,第一个为计划均衡排产时间,第二个为实际排产时间
|
|
|
- */
|
|
|
- Map<String,List<Integer>> equipmentPlanActualTime = new HashMap<>();
|
|
|
- for (ProductionProcesses productionProcesses : processess) {
|
|
|
- if(productionProcesses.getEquipmentId() == null){
|
|
|
- continue;
|
|
|
- }
|
|
|
- // 排产作业的加工时间除以可选设备个数即为均衡排产时间
|
|
|
- int balanceTime = (productionProcesses.getProduceTime() / productionProcesses.getOptionalEquipments().size())+1;
|
|
|
- for (String optionalEquipment : productionProcesses.getOptionalEquipments()) {
|
|
|
- // 缓存里有当前设备时,累计计划和实际时间
|
|
|
- if(equipmentPlanActualTime.containsKey(optionalEquipment)){
|
|
|
- List<Integer> planActualTimeList = equipmentPlanActualTime.get(optionalEquipment);
|
|
|
- Integer planTime = planActualTimeList.get(0)+balanceTime;
|
|
|
- Integer actualTime = planActualTimeList.get(1);
|
|
|
- if(productionProcesses.getEquipmentId().equals(optionalEquipment)){
|
|
|
- actualTime = actualTime + productionProcesses.getProduceTime();
|
|
|
- }
|
|
|
- planActualTimeList.set(0,planTime);
|
|
|
- planActualTimeList.set(1,actualTime);
|
|
|
- }
|
|
|
- // 缓存里没有当前设备时初始化并赋值
|
|
|
- else{
|
|
|
- List<Integer> planActualTimeList = new ArrayList<>();
|
|
|
- planActualTimeList.add(balanceTime);
|
|
|
- if(productionProcesses.getEquipmentId().equals(optionalEquipment)){
|
|
|
- planActualTimeList.add(productionProcesses.getProduceTime());
|
|
|
- }else {
|
|
|
- planActualTimeList.add(0);
|
|
|
- }
|
|
|
- equipmentPlanActualTime.put(optionalEquipment,planActualTimeList);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- // 计算所有设备的计划时间和实际时间之差的绝对值之和
|
|
|
- for(String eqid : equipmentPlanActualTime.keySet()){
|
|
|
- List<Integer> integers = equipmentPlanActualTime.get(eqid);
|
|
|
- balanceNum = balanceNum + (Math.abs(integers.get(1)-integers.get(0)));
|
|
|
- }
|
|
|
- }
|
|
|
- return balanceNum;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 连续生产约束条件,同一设备的连续生产标识一样的工序、尽量排在一起
|
|
|
* 铸轧考虑换辊和立板
|
|
@@ -2503,42 +2174,6 @@ public class ApsConstraintListProvider implements ConstraintProvider {
|
|
|
return notSeriesNum;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 相同作业连续生产约束
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint sameProcessSeries(ConstraintFactory constraintFactory){
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter((process)->{
|
|
|
- return StrUtil.isNotBlank(process.getEquipmentId()) && StrUtil.isNotBlank(process.getProcessType())
|
|
|
- && !"成退".equals(process.getProcessType()) && !"中退".equals(process.getProcessType());
|
|
|
- })
|
|
|
- .groupBy(ProductionProcesses::getUniqueBsProcessesId,ConstraintCollectors.toList())
|
|
|
- .penalize(HardMediumSoftScore.ONE_SOFT,(bsProcessesId, processess) -> {
|
|
|
- long a = 0;
|
|
|
- if(processess != null && processess.size()>0){
|
|
|
- Map<String, List<ProductionProcesses>> orderProcess = processess.stream().collect(Collectors.groupingBy(ProductionProcesses::getEquipmentId));
|
|
|
- if(orderProcess != null && orderProcess.size()>0){
|
|
|
- for(String key : orderProcess.keySet()) {
|
|
|
- List<ProductionProcesses> pss = orderProcess.get(key);
|
|
|
- if(pss != null && pss.size()>1){
|
|
|
- Collections.sort(pss, Comparator.comparing(ProductionProcesses::getStartTime));
|
|
|
- for (int i = 0;i<pss.size()-1;i++) {
|
|
|
- ProductionProcesses p1 = pss.get(i);
|
|
|
- ProductionProcesses p2 = pss.get(i+1);
|
|
|
- long minutes = ChronoUnit.MINUTES.between(p1.getStartTime(), p2.getStartTime());
|
|
|
- a = a + minutes*10;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return (int) a;
|
|
|
- })
|
|
|
- .asConstraint("sameProcessSeries");
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 排程时间尽量靠前
|
|
|
* @param constraintFactory
|
|
@@ -2572,121 +2207,6 @@ public class ApsConstraintListProvider implements ConstraintProvider {
|
|
|
.asConstraint("processNear");
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 排程时间尽量靠前
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint processBtNear(ConstraintFactory constraintFactory){
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter((process)->{
|
|
|
- return "冷轧".equals(process.getProcessType()) || "铸轧".equals(process.getProcessType());
|
|
|
- })
|
|
|
- .groupBy(ProductionProcesses::getEquipmentId,ConstraintCollectors.toList())
|
|
|
- .filter((equipmentId,processs)->{
|
|
|
- if(processs != null && processs.size()>0){
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
- })
|
|
|
- .penalize(HardMediumSoftScore.ONE_MEDIUM,(equipmentId,processs) -> {
|
|
|
- int b = 0;
|
|
|
- Equipment equipment = null;
|
|
|
- if(processs != null && processs.size()>0){
|
|
|
- equipment = processs.get(0).getEquipment();
|
|
|
- }
|
|
|
- List<ProductionProcesses> hasStartTimeProcess = processs.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
|
|
|
- // 设备占用时间参与连续生产排程
|
|
|
- if(equipment != null && equipment.getEquipmentRunTimes() != null && equipment.getEquipmentRunTimes().size()>0){
|
|
|
- for (EquipmentRunTime equipmentRunTime : equipment.getEquipmentRunTimes()) {
|
|
|
- if(equipmentRunTime.getOccupyType().equals("process")){
|
|
|
- ProductionProcesses pp = new ProductionProcesses();
|
|
|
- pp.setStartTime(equipmentRunTime.getStartRunTime());
|
|
|
- pp.setEndTime(equipmentRunTime.getEndRunTime());
|
|
|
- pp.setSeriesProduceMark(equipmentRunTime.getSeriesProduceMark());
|
|
|
- pp.setProcessType(equipmentRunTime.getProcessType());
|
|
|
- pp.setBsProcessesId(Arrays.asList(new String[]{"haspcprocess"}));
|
|
|
- pp.setConflictRoptions(new HashMap<>());
|
|
|
- hasStartTimeProcess.add(pp);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- // 按照开始时间排序
|
|
|
- Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
|
|
|
- // 获取设备已排程好的最后一个作业,计算连续加工
|
|
|
- if(equipment.getLastProcessType() != null && equipment.getLastSeriesProduceMark() != null){
|
|
|
- ProductionProcesses pp = new ProductionProcesses();
|
|
|
- pp.setSeriesProduceMark(equipment.getLastSeriesProduceMark());
|
|
|
- pp.setProcessType(equipment.getLastProcessType());
|
|
|
- pp.setBsProcessesId(Arrays.asList(new String[]{"lastprocess"}));
|
|
|
- pp.setConflictRoptions(new HashMap<>());
|
|
|
- pp.setEndTime(equipment.getLastProcessEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
|
|
|
- hasStartTimeProcess.add(0,pp);
|
|
|
- }
|
|
|
- for(int i=0;i<hasStartTimeProcess.size()-1;i++){
|
|
|
- if(hasStartTimeProcess.get(i).getId() == null && hasStartTimeProcess.get(i+1).getId() == null){
|
|
|
- continue;
|
|
|
- }
|
|
|
- if("铸轧".equals(hasStartTimeProcess.get(i).getProcessType())){
|
|
|
- if(hasStartTimeProcess.get(i+1).getStartTime().compareTo(hasStartTimeProcess.get(i).getEndTime().plusHours(10))>0){
|
|
|
- b++;
|
|
|
- }
|
|
|
- } else if ("冷轧".equals(hasStartTimeProcess.get(i).getProcessType())) {
|
|
|
- if(hasStartTimeProcess.get(i+1).getStartTime().compareTo(hasStartTimeProcess.get(i).getEndTime().plusHours(10))>0){
|
|
|
- b++;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return b*300;
|
|
|
- })
|
|
|
- .asConstraint("processBtNear");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 排程时间尽量靠前
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint processLzNear(ConstraintFactory constraintFactory){
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter((process)->{
|
|
|
- return "冷轧".equals(process.getProcessType()) || "铸轧".equals(process.getProcessType());
|
|
|
- })
|
|
|
- .filter((process)->{
|
|
|
- if(process.getPreviousProcesses() == null || process.getPreviousProcesses().size() == 0){
|
|
|
- if(process.getStartTime().compareTo(process.getApsOverallConfig().getStartTime())>0){
|
|
|
- return true;
|
|
|
- }else{
|
|
|
- return false;
|
|
|
- }
|
|
|
- }else{
|
|
|
- ProductionProcesses preProcess = process.getPreviousProcesses().get(0);
|
|
|
- // 流转时间
|
|
|
- Integer lzTimes = 0;
|
|
|
- if(preProcess != null && preProcess.getEquipment() != null){
|
|
|
- if(preProcess.getEquipment().getWorkshopid() != null && preProcess.getEquipment().getWorkshopid().equals(process.getEquipment().getWorkshopid())){
|
|
|
- lzTimes = process.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
|
|
|
- }else{
|
|
|
- lzTimes = process.getApsOverallConfig().getRoamTime().get("WORKSHOP_CROSS");
|
|
|
- }
|
|
|
- // 最小等待时间对比流转时间
|
|
|
- if(preProcess.getMinWaitTime() != null && lzTimes<preProcess.getMinWaitTime()){
|
|
|
- lzTimes = preProcess.getMinWaitTime();
|
|
|
- }
|
|
|
- LocalDateTime minStartTime = preProcess.getEndTime().plusMinutes(lzTimes);
|
|
|
- if(process.getStartTime().compareTo(minStartTime.plusHours(48))>0){
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
- })
|
|
|
- .penalize(HardMediumSoftScore.ONE_MEDIUM,(process) -> {
|
|
|
- return 300;
|
|
|
- })
|
|
|
- .asConstraint("processLzNear");
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 退火工序组炉规则
|
|
|
* @param constraintFactory
|
|
@@ -2913,52 +2433,7 @@ public class ApsConstraintListProvider implements ConstraintProvider {
|
|
|
})
|
|
|
.asConstraint("sameEquipment");
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * 冷轧尽量靠近
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint sameBsLzClose(ConstraintFactory constraintFactory){
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter((processes) -> "冷轧".equals(processes.getProcessType()))
|
|
|
- .groupBy(ProductionProcesses::getUniqueBsProcessesId, ConstraintCollectors.toList())
|
|
|
- .filter((uniqueBsProcessesId,processes) -> {
|
|
|
- if(processes != null && processes.size()>1){
|
|
|
- return true;
|
|
|
- }else{
|
|
|
- return false;
|
|
|
- }
|
|
|
- })
|
|
|
- .penalize(HardMediumSoftScore.ONE_SOFT,(uniqueBsProcessesId,processes)->{
|
|
|
- int countNum = 0;
|
|
|
- LocalDateTime maxTime = null;
|
|
|
- LocalDateTime minTime = null;
|
|
|
- for (ProductionProcesses process : processes) {
|
|
|
- LocalDateTime startTime = process.getStartTime();
|
|
|
- if(maxTime == null){
|
|
|
- maxTime = startTime;
|
|
|
- }else{
|
|
|
- if(startTime.compareTo(maxTime)>0){
|
|
|
- maxTime = startTime;
|
|
|
- }
|
|
|
- }
|
|
|
- if(minTime == null){
|
|
|
- minTime = startTime;
|
|
|
- }else{
|
|
|
- if(startTime.compareTo(minTime)<0){
|
|
|
- minTime = startTime;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if(minTime != null && maxTime != null){
|
|
|
- countNum = (int)ChronoUnit.MINUTES.between(minTime, maxTime);
|
|
|
- }
|
|
|
- return countNum*100;
|
|
|
- })
|
|
|
- .asConstraint("sameBsLzClose");
|
|
|
-
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* 硬约束:小卷成退合并约束
|