|
@@ -26,41 +26,28 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
return new Constraint[]{
|
|
|
// eqTypeSame(constraintFactory),
|
|
|
// noPreGbAfterNow(constraintFactory),
|
|
|
+// lzTimeLessMaxWait(constraintFactory),
|
|
|
+
|
|
|
hasOnePreGbAfterNow(constraintFactory),
|
|
|
eqTimeCross(constraintFactory),
|
|
|
seriesProduceTimeWait(constraintFactory),
|
|
|
seriesProduceWashTimeWait(constraintFactory),
|
|
|
- lzTimeLessMaxWait(constraintFactory),
|
|
|
equipmentRunTime(constraintFactory),
|
|
|
eqTimeCrossTuihuo(constraintFactory),
|
|
|
|
|
|
deliveryDate(constraintFactory),
|
|
|
seriesProduce(constraintFactory),
|
|
|
seriesProduceWashingFurnace(constraintFactory),
|
|
|
-// mergeTuihuo(constraintFactory),
|
|
|
+ mergeTuihuo(constraintFactory),
|
|
|
sameEquipment(constraintFactory),
|
|
|
|
|
|
- sameProcessSeries(constraintFactory),
|
|
|
+// sameProcessSeries(constraintFactory),
|
|
|
processNear(constraintFactory),
|
|
|
|
|
|
// balancedEqUse(constraintFactory),
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 硬约束:工步所需的设备必须在工序的可选设备之内
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint eqTypeSame(ConstraintFactory constraintFactory) {
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter(productionProcesses -> {
|
|
|
- return !productionProcesses.getOptionalEquipments().contains(productionProcesses.getEquipment().getId());
|
|
|
- })
|
|
|
- .penalize(HardSoftScore.ONE_HARD,(productionProcesses) -> 300)
|
|
|
- .asConstraint("eqTypeSame");
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 硬约束:合并生产工序设备、开始时间、结束时间都一样
|
|
|
* @param constraintFactory
|
|
@@ -118,202 +105,23 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 硬约束:没有上一步工步的开始时间小于当前时间
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint noPreGbAfterNow(ConstraintFactory constraintFactory) {
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter(productionProcesses -> {
|
|
|
- if(productionProcesses.getApsOverallConfig().getStartTimeLong() != null && productionProcesses.getApsOverallConfig().getStartTimeLong()>0){
|
|
|
- return productionProcesses.getPreviousProcesses() == null && productionProcesses.getStartTime().atZone(zoneId).toInstant().toEpochMilli() < productionProcesses.getApsOverallConfig().getStartTimeLong();
|
|
|
- }else{
|
|
|
- return productionProcesses.getPreviousProcesses() == null && productionProcesses.getStartTime().atZone(zoneId).toInstant().toEpochMilli() < DateUtil.date().getTime();
|
|
|
- }
|
|
|
- })
|
|
|
- .penalize(HardSoftScore.ONE_HARD,(productionProcesses) -> 80)
|
|
|
- .asConstraint("noPreGbAfterNow");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 硬约束:有上一步工步的开始时间要大于上一步工步最早结束时间,小于最晚结束时间
|
|
|
- * 根据上一步的最小等待时间和最大等待时间来判断
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint hasPreGbAfterNow(ConstraintFactory constraintFactory) {
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter(productionProcesses -> {
|
|
|
- // 获取上一步最晚结束时间
|
|
|
- LocalDateTime preLastMinTime = null;
|
|
|
- LocalDateTime preLastMaxTime = null;
|
|
|
- // 最大单批次生产时间
|
|
|
- Integer maxUnitProduceTime = 0;
|
|
|
- if(productionProcesses.getPreviousProcesses() != null){
|
|
|
- for (ProductionProcesses previousProcess : productionProcesses.getPreviousProcesses()) {
|
|
|
- // 流转时间
|
|
|
- Integer lzTimes = 0;
|
|
|
- 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.getUnitProduceTime() != null && maxUnitProduceTime<previousProcess.getUnitProduceTime()){
|
|
|
- maxUnitProduceTime = previousProcess.getUnitProduceTime();
|
|
|
- }
|
|
|
-
|
|
|
- // 计算最小、最大等待时间
|
|
|
- LocalDateTime thisMinEndTime = previousProcess.getEndTime();
|
|
|
- LocalDateTime thisMaxEndTime = null;
|
|
|
- if(previousProcess.getMinWaitTime() != null){
|
|
|
- /**
|
|
|
- * 根据前后工序单批次生产时间比较来排序
|
|
|
- * 1、前道工序单批次生产时间小于后道工序单批次生产时间,则最小开始时间等于单批次生产时间
|
|
|
- * 2、前道工序单批次生产时间小于后道工序单批次生产时间,则从最后倒排时间
|
|
|
- */
|
|
|
-
|
|
|
-
|
|
|
- // 最小等待时间对比流转时间
|
|
|
- if(lzTimes>previousProcess.getMinWaitTime()){
|
|
|
- thisMinEndTime = thisMinEndTime.plusMinutes(lzTimes);
|
|
|
- }else{
|
|
|
- thisMinEndTime = thisMinEndTime.plusMinutes(previousProcess.getMinWaitTime());
|
|
|
- }
|
|
|
- }
|
|
|
- if(previousProcess.getMaxWaitTime() != null){
|
|
|
- thisMaxEndTime = thisMaxEndTime.plusMinutes(previousProcess.getMaxWaitTime());
|
|
|
- }
|
|
|
- // 最小结束时间
|
|
|
- if(preLastMinTime == null){
|
|
|
- preLastMinTime = thisMinEndTime;
|
|
|
- }else{
|
|
|
- if(preLastMinTime.compareTo(thisMinEndTime)<0){
|
|
|
- preLastMinTime = thisMinEndTime;
|
|
|
- }
|
|
|
- }
|
|
|
- // 最大结束时间
|
|
|
- if(thisMaxEndTime != null){
|
|
|
- if(preLastMaxTime == null){
|
|
|
- preLastMaxTime = thisMaxEndTime;
|
|
|
- }else{
|
|
|
- if(preLastMaxTime.compareTo(thisMinEndTime)>0){
|
|
|
- preLastMaxTime = thisMaxEndTime;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- boolean bln = productionProcesses.getStartTime().atZone(zoneId).toInstant().toEpochMilli() < preLastMinTime.atZone(zoneId).toInstant().toEpochMilli();
|
|
|
- if(preLastMaxTime != null){
|
|
|
- System.out.println("preLastMaxTime != null");
|
|
|
- bln = bln || productionProcesses.getStartTime().atZone(zoneId).toInstant().toEpochMilli() > preLastMaxTime.atZone(zoneId).toInstant().toEpochMilli();
|
|
|
- }
|
|
|
- return bln;
|
|
|
- }else{
|
|
|
- return false;
|
|
|
- }
|
|
|
- })
|
|
|
- .penalize(HardSoftScore.ONE_HARD,(productionProcesses) -> 80)
|
|
|
- .asConstraint("hasPreGbAfterNow");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 前提条件:前道工序只有一个
|
|
|
- * 硬约束:有上一步工步的开始时间要大于上一步工步最早结束时间,小于最晚结束时间
|
|
|
- * 根据上一步的最小等待时间和最大等待时间来判断
|
|
|
+ * 单卷模式下前后道工序时间约束
|
|
|
* @param constraintFactory
|
|
|
* @return
|
|
|
*/
|
|
|
- private Constraint hasOnePreGbAfterNowOld(ConstraintFactory constraintFactory) {
|
|
|
+ private Constraint hasOnePreGbAfterNow(ConstraintFactory constraintFactory) {
|
|
|
return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
.filter(productionProcesses -> {
|
|
|
+ /*if(productionProcesses.getId().equals("2a231077b58844548c4a9d9e8f90f628")){
|
|
|
+ int a = 1;
|
|
|
+ }*/
|
|
|
boolean bln = false;
|
|
|
- // 最大单批次生产时间
|
|
|
- Integer maxUnitProduceTime = 0;
|
|
|
- // 最大流转时间
|
|
|
- Integer lzMaxTimes = 0;
|
|
|
- // 前道工序最小首批加工最大等待时间
|
|
|
- LocalDateTime lastFirstMaxWaitTime = null;
|
|
|
if(productionProcesses.getPreviousProcesses() != null && productionProcesses.getPreviousProcesses().size()>0){
|
|
|
- // 瓶颈工序,简化为等待前道工序全部完成才加工后道工序
|
|
|
- if((productionProcesses.getBottleneck() != null && productionProcesses.getBottleneck())
|
|
|
- || (productionProcesses.getPreviousProcesses().get(0).getBottleneck() != null && productionProcesses.getPreviousProcesses().get(0).getBottleneck())){
|
|
|
- LocalDateTime lastMaxStartTime = null;
|
|
|
- LocalDateTime lastMinMaxWaitTime = null;
|
|
|
- for (ProductionProcesses previousProcess : productionProcesses.getPreviousProcesses()) {
|
|
|
- // 流转时间
|
|
|
- Integer lzTimes = 0;
|
|
|
- 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(lzMaxTimes<lzTimes){
|
|
|
- lzMaxTimes = lzTimes;
|
|
|
- }
|
|
|
- // 最小等待时间
|
|
|
- Integer minWaitTime = previousProcess.getMinWaitTime() == null ? 0 : previousProcess.getMinWaitTime();
|
|
|
- if(lzTimes>minWaitTime){
|
|
|
- minWaitTime = lzTimes;
|
|
|
- }
|
|
|
- if(lastMaxStartTime == null){
|
|
|
- lastMaxStartTime = previousProcess.getEndTime().plusMinutes(minWaitTime);
|
|
|
- }else {
|
|
|
- if(lastMaxStartTime.compareTo(previousProcess.getEndTime().plusMinutes(minWaitTime))<0){
|
|
|
- lastMaxStartTime = previousProcess.getEndTime().plusMinutes(minWaitTime);
|
|
|
- }
|
|
|
- }
|
|
|
- // 如有最大等待时间,计算首批次加工等待时间不能超过最大等待时间
|
|
|
- if(previousProcess.getMaxWaitTime() != null){
|
|
|
- if(lastMinMaxWaitTime == null){
|
|
|
- lastMinMaxWaitTime = previousProcess.getEndTime().plusMinutes(previousProcess.getMaxWaitTime());
|
|
|
- }else{
|
|
|
- if(previousProcess.getEndTime().plusMinutes(previousProcess.getMaxWaitTime()).compareTo(lastMinMaxWaitTime)<0){
|
|
|
- lastMinMaxWaitTime = previousProcess.getEndTime().plusMinutes(previousProcess.getMaxWaitTime());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- // 开始时间不小于最大的最小等待时间、不大于最小的最大等待时间
|
|
|
- if(lastMaxStartTime != null && productionProcesses.getStartTime().compareTo(lastMaxStartTime)<0){
|
|
|
- bln = true;
|
|
|
- }else if(lastMinMaxWaitTime != null && productionProcesses.getStartTime().compareTo(lastMinMaxWaitTime)>0){
|
|
|
- bln = true;
|
|
|
- }
|
|
|
- }
|
|
|
- // 非瓶颈工序,非瓶颈工序,默认前道工序只有一个
|
|
|
- else{
|
|
|
- // 此种情况简化为前道工序只有一个
|
|
|
- ProductionProcesses preProcess = productionProcesses.getPreviousProcesses().get(0);
|
|
|
- maxUnitProduceTime = preProcess.getUnitProduceTime();
|
|
|
- // 前道工序的所有下道工序
|
|
|
- List<ProductionProcesses> nextProcesses = preProcess.getNextProcesses();
|
|
|
- Map<String,Integer> map = new HashMap<>();
|
|
|
- for (ProductionProcesses nextProcess : nextProcesses) {
|
|
|
- map.put(nextProcess.getId(),0);
|
|
|
- allNextProduceTime(nextProcess,map,nextProcess.getId());
|
|
|
- nextProcess.setNextAllProduceTime(map.get(nextProcess.getId()));
|
|
|
- }
|
|
|
- nextProcesses.sort((o1, o2) -> o1.getNextAllProduceTime().compareTo(o2.getNextAllProduceTime()));
|
|
|
- // 前道工序
|
|
|
- LocalDateTime startTime = preProcess.getStartTime();
|
|
|
- if(startTime == null){
|
|
|
- System.out.println("preProcess.getId():"+preProcess.getId());
|
|
|
- System.out.println("productionProcesses.getId():"+productionProcesses.getId());
|
|
|
- }
|
|
|
- LocalDateTime endTime = preProcess.getStartTime();
|
|
|
- for (ProductionProcesses nextProcess : nextProcesses) {
|
|
|
- int i = preProcess.getUnitProduceTime() * nextProcess.getProducePcNum();
|
|
|
- if(!nextProcess.getId().equals(productionProcesses.getId())){
|
|
|
- startTime = startTime.plusMinutes(i);
|
|
|
- }else{
|
|
|
- endTime = startTime.plusMinutes(i);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 流转时间
|
|
|
- Integer lzTimes = 0;
|
|
|
+ // 此种情况简化为前道工序只有一个
|
|
|
+ ProductionProcesses preProcess = productionProcesses.getPreviousProcesses().get(0);
|
|
|
+ // 流转时间(最小等待时间)
|
|
|
+ Integer lzTimes = 0;
|
|
|
+ if(preProcess.getEquipment() != null){
|
|
|
if(preProcess.getEquipment().getWorkshopid() != null && preProcess.getEquipment().getWorkshopid().equals(productionProcesses.getEquipment().getWorkshopid())){
|
|
|
lzTimes = productionProcesses.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
|
|
|
}else{
|
|
@@ -323,98 +131,20 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
if(preProcess.getMinWaitTime() != null && lzTimes<preProcess.getMinWaitTime()){
|
|
|
lzTimes = preProcess.getMinWaitTime();
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * 后道工序批次生产时间大于等于前道工序批次生产时间
|
|
|
- * 从第一批次开始往后排程
|
|
|
- */
|
|
|
-
|
|
|
- if(preProcess.getMaxWaitTime() != null){
|
|
|
- lastFirstMaxWaitTime = startTime.plusMinutes(preProcess.getUnitProduceTime()).plusMinutes(preProcess.getMaxWaitTime());
|
|
|
- }
|
|
|
- if(productionProcesses.getUnitProduceTime()>=maxUnitProduceTime){
|
|
|
- if(productionProcesses.getStartTime().compareTo(startTime.plusMinutes(preProcess.getUnitProduceTime()).plusMinutes(lzTimes))<0){
|
|
|
- bln = true;
|
|
|
- }else{
|
|
|
- if(lastFirstMaxWaitTime != null){
|
|
|
- if(productionProcesses.getStartTime().compareTo(lastFirstMaxWaitTime)>0){
|
|
|
- bln = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ // 最大等待时间
|
|
|
+ Integer maxWaitTime = preProcess.getMaxWaitTime();
|
|
|
+ if(productionProcesses.getStartTime().compareTo(preProcess.getEndTime().plusMinutes(lzTimes))<0){
|
|
|
+ bln = true;
|
|
|
}
|
|
|
- /**
|
|
|
- * 后道工序批次生产时间小于前道工序批次生产时间
|
|
|
- * 从最后批次开始往前排程
|
|
|
- */
|
|
|
- else{
|
|
|
- // 开始时间:最后一批次结束时间加流转时间,再往前倒排批次数减一乘以单批次生产时间
|
|
|
- LocalDateTime startTime1 = endTime.plusMinutes(lzTimes).minusMinutes(productionProcesses.getUnitProduceTime() * (productionProcesses.getProducePcNum() - 1));
|
|
|
- // 结束时间重新赋值
|
|
|
-// productionProcesses.setEndTime(endTime.plusMinutes(lzTimes).plusMinutes(productionProcesses.getUnitProduceTime()));
|
|
|
- if(productionProcesses.getStartTime().compareTo(startTime1)<0){
|
|
|
+ if(maxWaitTime != null && maxWaitTime>0){
|
|
|
+ if(productionProcesses.getStartTime().compareTo(preProcess.getEndTime().plusMinutes(maxWaitTime))>0){
|
|
|
bln = true;
|
|
|
}
|
|
|
- // 存在最大等待时间时
|
|
|
- if(preProcess.getMaxWaitTime() != null){
|
|
|
- // 超过最大等待时间
|
|
|
- if(productionProcesses.getStartTime().compareTo(startTime1.plusMinutes(preProcess.getMaxWaitTime()))>0){
|
|
|
- bln = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(bln){
|
|
|
-// System.out.println("log-开始时间:"+productionProcesses.getStartTime());
|
|
|
-// System.out.println("log-正确的开始时间:"+startTime.plusMinutes(preProcess.getUnitProduceTime()).plusMinutes(lzTimes));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- return bln;
|
|
|
- })
|
|
|
- .penalize(HardSoftScore.ONE_HARD,(productionProcesses) -> 40)
|
|
|
- .asConstraint("hasOnePreGbAfterNow");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 单卷模式下前后道工序时间约束
|
|
|
- * @param constraintFactory
|
|
|
- * @return
|
|
|
- */
|
|
|
- private Constraint hasOnePreGbAfterNow(ConstraintFactory constraintFactory) {
|
|
|
- return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
- .filter(productionProcesses -> {
|
|
|
- /*if(productionProcesses.getId().equals("2a231077b58844548c4a9d9e8f90f628")){
|
|
|
- int a = 1;
|
|
|
- }*/
|
|
|
- boolean bln = false;
|
|
|
- if(productionProcesses.getPreviousProcesses() != null && productionProcesses.getPreviousProcesses().size()>0){
|
|
|
- // 此种情况简化为前道工序只有一个
|
|
|
- ProductionProcesses preProcess = productionProcesses.getPreviousProcesses().get(0);
|
|
|
- // 流转时间(最小等待时间)
|
|
|
- Integer lzTimes = 0;
|
|
|
- if(preProcess.getEquipment().getWorkshopid() != null && preProcess.getEquipment().getWorkshopid().equals(productionProcesses.getEquipment().getWorkshopid())){
|
|
|
- lzTimes = productionProcesses.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
|
|
|
- }else{
|
|
|
- lzTimes = productionProcesses.getApsOverallConfig().getRoamTime().get("WORKSHOP_CROSS");
|
|
|
- }
|
|
|
- // 最小等待时间对比流转时间
|
|
|
- if(preProcess.getMinWaitTime() != null && lzTimes<preProcess.getMinWaitTime()){
|
|
|
- lzTimes = preProcess.getMinWaitTime();
|
|
|
- }
|
|
|
- // 最大等待时间
|
|
|
- Integer maxWaitTime = preProcess.getMaxWaitTime();
|
|
|
- if(productionProcesses.getStartTime().compareTo(preProcess.getEndTime().plusMinutes(lzTimes))<0){
|
|
|
- bln = true;
|
|
|
- }
|
|
|
- if(maxWaitTime != null && maxWaitTime>0){
|
|
|
- if(productionProcesses.getStartTime().compareTo(preProcess.getEndTime().plusMinutes(maxWaitTime))>0){
|
|
|
- bln = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- /*if(productionProcesses.getMaxWaitTime() != null && productionProcesses.getMaxWaitTime()>0){
|
|
|
+ if(productionProcesses.getMaxWaitTime() != null && productionProcesses.getMaxWaitTime()>0
|
|
|
+ || (productionProcesses.getNextProcesses() != null && productionProcesses.getNextProcesses().size()>0 && "成退,中退,小卷成退".contains(productionProcesses.getNextProcesses().get(0).getProcessType()))){
|
|
|
if(productionProcesses.getNextProcesses() != null && productionProcesses.getNextProcesses().size()>0){
|
|
|
for (ProductionProcesses nextProcess : productionProcesses.getNextProcesses()) {
|
|
|
if(nextProcess.getEquipment() != null && nextProcess.getStartTime() != null){
|
|
@@ -442,7 +172,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- }*/
|
|
|
+ }
|
|
|
return bln;
|
|
|
})
|
|
|
.penalize(HardMediumSoftScore.ONE_HARD,(productionProcesses) -> 40)
|
|
@@ -470,6 +200,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
*/
|
|
|
private Constraint equipmentRunTime(ConstraintFactory constraintFactory) {
|
|
|
return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
+ .filter(pro->{
|
|
|
+ return !pro.getProcessType().equals("成退") && !pro.getProcessType().equals("中退");
|
|
|
+ })
|
|
|
.filter(productionProcesses -> {
|
|
|
boolean bol = false;
|
|
|
// 瓶颈工序合并生产规则,总宽度和总承重不超过最大值即可
|
|
@@ -925,20 +658,30 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
}
|
|
|
b++;
|
|
|
}else{
|
|
|
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
- String startTimeKey = prePro.getStartTime().format(formatter);
|
|
|
- if(!ppMap.containsKey(startTimeKey)){
|
|
|
- List<ProductionProcesses> pps = new ArrayList<>();
|
|
|
- ppMap.put(startTimeKey,pps);
|
|
|
- }
|
|
|
- List<ProductionProcesses> processesList = ppMap.get(startTimeKey);
|
|
|
- List<ProductionProcesses> preHas = processesList.stream().filter(v -> v.getId().equals(prePro.getId())).collect(Collectors.toList());
|
|
|
- List<ProductionProcesses> nextHas = processesList.stream().filter(v -> v.getId().equals(nextPro.getId())).collect(Collectors.toList());
|
|
|
- if(preHas == null || preHas.size() == 0){
|
|
|
- processesList.add(prePro);
|
|
|
- }
|
|
|
- if(nextHas == null || nextHas.size() == 0){
|
|
|
- processesList.add(nextPro);
|
|
|
+ List<ProduceOrder> produceOrder1 = prePro.getProduceOrder();
|
|
|
+ List<ProduceOrder> produceOrder2 = nextPro.getProduceOrder();
|
|
|
+ if(produceOrder1 != null && produceOrder1.size()>0 && produceOrder2 != null && produceOrder2.size()>0
|
|
|
+ && produceOrder1.get(0).getId().equals(produceOrder2.get(0).getId())
|
|
|
+ && !prePro.getUniqueBsProcessesId().equals(nextPro.getUniqueBsProcessesId())){
|
|
|
+ conflictRoptions1.put("hard-eqTimeCrossTuihuo","同一坯料计划不同工序退火不能排一起");
|
|
|
+ conflictRoptions2.put("hard-eqTimeCrossTuihuo","同一坯料计划不同工序退火不能排一起");
|
|
|
+ b++;
|
|
|
+ }else{
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+ String startTimeKey = prePro.getStartTime().format(formatter);
|
|
|
+ if(!ppMap.containsKey(startTimeKey)){
|
|
|
+ List<ProductionProcesses> pps = new ArrayList<>();
|
|
|
+ ppMap.put(startTimeKey,pps);
|
|
|
+ }
|
|
|
+ List<ProductionProcesses> processesList = ppMap.get(startTimeKey);
|
|
|
+ List<ProductionProcesses> preHas = processesList.stream().filter(v -> v.getId().equals(prePro.getId())).collect(Collectors.toList());
|
|
|
+ List<ProductionProcesses> nextHas = processesList.stream().filter(v -> v.getId().equals(nextPro.getId())).collect(Collectors.toList());
|
|
|
+ if(preHas == null || preHas.size() == 0){
|
|
|
+ processesList.add(prePro);
|
|
|
+ }
|
|
|
+ if(nextHas == null || nextHas.size() == 0){
|
|
|
+ processesList.add(nextPro);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}else{
|
|
@@ -1098,6 +841,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ if(deliveryMinDate == null){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
Boolean bol = productionProcesses.getNextProcesses() == null &&
|
|
|
productionProcesses.getEndTime().atZone(zoneId).toInstant().toEpochMilli()>deliveryMinDate.getTime();
|
|
|
return bol;
|
|
@@ -1433,7 +1179,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
})
|
|
|
.penalize(HardMediumSoftScore.ONE_MEDIUM,(equipmentEquassociated, processess) -> {
|
|
|
int washingFurnaceCount = seriesProduceWashingFurnaceCount(processess);
|
|
|
- return washingFurnaceCount*10;
|
|
|
+ return washingFurnaceCount*300;
|
|
|
})
|
|
|
.asConstraint("seriesProduceWashingFurnace");
|
|
|
}
|
|
@@ -1521,21 +1267,27 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
return StrUtil.isNotBlank(process.getEquipmentId()) && StrUtil.isNotBlank(process.getProcessType())
|
|
|
&& !"成退".equals(process.getProcessType()) && !"中退".equals(process.getProcessType());
|
|
|
})
|
|
|
- .groupBy(ProductionProcesses::getEquipmentId,ConstraintCollectors.toList())
|
|
|
- .penalize(HardMediumSoftScore.ONE_SOFT,(equipmentId, processess) -> {
|
|
|
- int notSeriesNum = 0;
|
|
|
- List<ProductionProcesses> hasStartTimeProcess = processess.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
|
|
|
- // 根据开始时间排序
|
|
|
- Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
|
|
|
- // 评分计算
|
|
|
- for(int i=0;i<hasStartTimeProcess.size()-1;i++){
|
|
|
- ProductionProcesses pre = hasStartTimeProcess.get(i);
|
|
|
- ProductionProcesses next = hasStartTimeProcess.get(i+1);
|
|
|
- if(!pre.getBsProcessesId().get(0).equals(next.getBsProcessesId().get(0))){
|
|
|
- notSeriesNum++;
|
|
|
+ .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 notSeriesNum;
|
|
|
+ return (int) a;
|
|
|
})
|
|
|
.asConstraint("sameProcessSeries");
|
|
|
}
|
|
@@ -1558,7 +1310,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
ProductionProcesses preProcess = process.getPreviousProcesses().get(0);
|
|
|
// 流转时间
|
|
|
Integer lzTimes = 0;
|
|
|
- if(preProcess != null){
|
|
|
+ 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{
|
|
@@ -1568,10 +1320,10 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
if(preProcess.getMinWaitTime() != null && lzTimes<preProcess.getMinWaitTime()){
|
|
|
lzTimes = preProcess.getMinWaitTime();
|
|
|
}
|
|
|
- }
|
|
|
- LocalDateTime minStartTime = preProcess.getEndTime().plusMinutes(lzTimes);
|
|
|
- if(process.getStartTime().compareTo(minStartTime)>0){
|
|
|
- return true;
|
|
|
+ LocalDateTime minStartTime = preProcess.getEndTime().plusMinutes(lzTimes);
|
|
|
+ if(process.getStartTime().compareTo(minStartTime)>0){
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
@@ -1604,7 +1356,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 退火工序优先合并
|
|
|
+ * 退火工序组炉规则
|
|
|
* @param constraintFactory
|
|
|
* @return
|
|
|
*/
|
|
@@ -1622,31 +1374,30 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
}
|
|
|
})
|
|
|
.penalize(HardMediumSoftScore.ONE_MEDIUM,(equipmentId,processes)->{
|
|
|
+ // 同一工序的优先组炉
|
|
|
+ List<ProductionProcesses> ths = new ArrayList<>();
|
|
|
+ processes.forEach(v->{
|
|
|
+ ths.add(v);
|
|
|
+ });
|
|
|
// 退火合并工序
|
|
|
Map<String,List<ProductionProcesses>> ppMap = new HashMap<>();
|
|
|
- for(int i=0;i<processes.size()-1;i++){
|
|
|
- ProductionProcesses prePro = processes.get(i);
|
|
|
- ProductionProcesses nextPro = processes.get(i+1);
|
|
|
- // 开始时间相等为合并工序
|
|
|
- if (prePro.getStartTime().compareTo(nextPro.getStartTime()) == 0){
|
|
|
+ if(ths.size()>0){
|
|
|
+ if(ths.size() == 2){
|
|
|
+ int a = 0;
|
|
|
+ }
|
|
|
+ for(int i=0;i<ths.size();i++){
|
|
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
- String startTimeKey = prePro.getStartTime().format(formatter);
|
|
|
- if(!ppMap.containsKey(startTimeKey)){
|
|
|
- List<ProductionProcesses> pps = new ArrayList<>();
|
|
|
- ppMap.put(startTimeKey,pps);
|
|
|
- }
|
|
|
- List<ProductionProcesses> processesList = ppMap.get(startTimeKey);
|
|
|
- List<ProductionProcesses> preHas = processesList.stream().filter(v -> v.getId().equals(prePro.getId())).collect(Collectors.toList());
|
|
|
- List<ProductionProcesses> nextHas = processesList.stream().filter(v -> v.getId().equals(nextPro.getId())).collect(Collectors.toList());
|
|
|
- if(preHas == null || preHas.size() == 0){
|
|
|
- processesList.add(prePro);
|
|
|
- }
|
|
|
- if(nextHas == null || nextHas.size() == 0){
|
|
|
- processesList.add(nextPro);
|
|
|
+ String startTimeKey = ths.get(i).getStartTime().format(formatter)+ths.get(i).getEquipmentId();
|
|
|
+ if(ppMap.containsKey(startTimeKey)){
|
|
|
+ ppMap.get(startTimeKey).add(ths.get(i));
|
|
|
+ }else{
|
|
|
+ List<ProductionProcesses> ps = new ArrayList<>();
|
|
|
+ ps.add(ths.get(i));
|
|
|
+ ppMap.put(startTimeKey,ps);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- return ppMap.size()*10000;
|
|
|
+ return ppMap.size()*100;
|
|
|
})
|
|
|
.asConstraint("mergeTuihuo");
|
|
|
}
|
|
@@ -1658,6 +1409,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
*/
|
|
|
private Constraint sameEquipment(ConstraintFactory constraintFactory){
|
|
|
return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
+ .filter(pro->{
|
|
|
+ return pro.getProcessType().equals("铸轧") || pro.getProcessType().equals("冷轧");
|
|
|
+ })
|
|
|
.groupBy(ProductionProcesses::getUniqueBsProcessesId,ConstraintCollectors.toList())
|
|
|
.filter((equipmentEquassociated,processes) -> {
|
|
|
if(processes != null && processes.size()>0){
|