fangpy hace 1 año
padre
commit
9d82a6ed48

+ 22 - 2
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/ApsBalancingApplication.java

@@ -14,9 +14,11 @@ import org.optaplanner.core.api.solver.SolverFactory;
 import org.optaplanner.core.config.solver.SolverConfig;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.Duration;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
+import java.time.temporal.TemporalAdjusters;
 import java.util.*;
 
 @Slf4j
@@ -115,10 +117,28 @@ public class ApsBalancingApplication {
         /*ProductionProcesses a = new ProductionProcesses();
         a.setId("11111");
         System.out.println(ObjectUtil.cloneByStream(a).getId());*/
-        String[] split = "1050^_^10500态热轧卷冷轧 厚6*宽1600mm 1吨^_^1600.00^_^6.0000^_^6.0000".split("\\^_\\^");
+        /*String[] split = "1050^_^10500态热轧卷冷轧 厚6*宽1600mm 1吨^_^1600.00^_^6.0000^_^6.0000".split("\\^_\\^");
         BigDecimal i1 = new BigDecimal("1600");
         int cores = Runtime.getRuntime().availableProcessors();
-        System.out.println(cores);
+        System.out.println(cores);*/
+        /*BigDecimal thickness = new BigDecimal("1.2");
+        System.out.println(thickness.setScale(0, RoundingMode.CEILING).intValue());
+        Integer a = 1;Integer b = 1;
+        System.out.println(a+b);*/
+
+        LocalDateTime now = LocalDateTime.now();
+        LocalDateTime nearestTenMinutes = now.minusSeconds(now.getSecond()) // 减去当前秒数
+                .minusNanos(now.getNano()) // 减去当前纳秒数
+                .plusMinutes(-now.getMinute() % 10) // 减去当前分钟数的余数,向下调整到最近的10的倍数
+                .plusMinutes(10); // 加上调整后的分钟数的余数
+
+        System.out.println(nearestTenMinutes);
+    }
+
+    public static void constraintTest(){
+        // 构建约束校验器,入参:约束供应者实例,规划方案类,规划实体类
+        /*ConstraintVerifier<ApsConstraintProvider, TimeTable> constraintVerifier = ConstraintVerifier.build(
+                new ApsConstraintProvider(), TimeTable.class, Lesson.class);*/
     }
 
     public static void consTest(){

+ 5 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/domain/ApsOverallConfig.java

@@ -3,6 +3,7 @@ package com.rongwei.rwapsserver.aps.domain;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Map;
@@ -39,5 +40,9 @@ public class ApsOverallConfig implements Serializable {
      * 立板时间(小时)
      */
     private Integer standingtime;
+    /**
+     * 松散度
+     */
+    private BigDecimal looseness;
 
 }

+ 12 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/domain/EquipmentRunTime.java

@@ -34,6 +34,13 @@ public class EquipmentRunTime implements Serializable {
      * 工序
      */
     private String processType;
+    /**
+     * 合金
+     */
+    private String volumeMetal;
+
+    // 合金状态
+    private String volumeMetalstate;
 
     /**
      * 上机准备时间(单位:分钟)
@@ -54,6 +61,11 @@ public class EquipmentRunTime implements Serializable {
      */
     private BigDecimal totalSinglerollweight;
 
+    /**
+     * 厚度
+     */
+    private BigDecimal totalThickness;
+
     /**
      * 是否锁定标识,排程中的是false
      */

+ 24 - 3
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/domain/ProductionProcesses.java

@@ -225,6 +225,8 @@ public class ProductionProcesses implements Serializable {
      * 单卷宽度
      */
     private BigDecimal volumeWidth;
+    // 单卷厚度
+    private BigDecimal volumeThickness;
 
     /**
      * 单卷重
@@ -236,6 +238,9 @@ public class ProductionProcesses implements Serializable {
      */
     private String volumeMetal;
 
+    // 合金状态
+    private String volumeMetalstate;
+
     /**
      * 输入物料
      */
@@ -331,11 +336,11 @@ public class ProductionProcesses implements Serializable {
         }*/
         Integer maxDelay = 1;
         if(this.processType.equals("成退") || this.processType.equals("中退")){
-            maxDelay = 500;
+            maxDelay = 5000;
         }else if(this.processType.equals("冷轧") || this.processType.equals("铸轧")){
-            maxDelay = 100;
+            maxDelay = 1000;
         }else{
-            maxDelay = 100;
+            maxDelay = 1000;
         }
         return ValueRangeFactory.createIntValueRange(0, maxDelay);
     }
@@ -717,6 +722,22 @@ public class ProductionProcesses implements Serializable {
         this.uniqueBsProcessesId = uniqueBsProcessesId;
     }
 
+    public String getVolumeMetalstate() {
+        return volumeMetalstate;
+    }
+
+    public void setVolumeMetalstate(String volumeMetalstate) {
+        this.volumeMetalstate = volumeMetalstate;
+    }
+
+    public BigDecimal getVolumeThickness() {
+        return volumeThickness;
+    }
+
+    public void setVolumeThickness(BigDecimal volumeThickness) {
+        this.volumeThickness = volumeThickness;
+    }
+
     public String getSeriSort(){
         String sortStr = this.getId();
         if(this.getStartTime() != null){

+ 21 - 3
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/listener/TaskStartTimeListener.java

@@ -12,6 +12,7 @@ import org.optaplanner.core.api.domain.variable.VariableListener;
 import org.optaplanner.core.api.score.director.ScoreDirector;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
@@ -94,11 +95,12 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
             LocalDateTime startDateTime = startTimeNewSet(process,scoreDirector);
 
             // 随机延时时间处理
-            if(process.getProcessType().equals("成退") || process.getProcessType().equals("中退")
-                    || process.getProcessType().equals("铸轧")){
+            if(process.getProcessType().equals("成退") || process.getProcessType().equals("中退")){
+                startDateTime = startDateTime.plusMinutes(process.getDelay() * 10);
+            } else if (process.getProcessType().equals("铸轧")) {
                 startDateTime = startDateTime.plusMinutes(process.getDelay() * 10);
             } else if (process.getProcessType().equals("冷轧")) {
-                startDateTime = startDateTime.plusMinutes(process.getDelay() * 30);
+                startDateTime = startDateTime.plusMinutes(process.getDelay() * 10);
             } else{
                 startDateTime = startDateTime.plusMinutes(process.getDelay() * 10);
             }
@@ -475,6 +477,9 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
     }
 
     private LocalDateTime startTimeNewSet(ProductionProcesses process,ScoreDirector<ApsSolution> scoreDirector){
+        /*if(process.getBsProcessesId().get(0).equals("ae76af901d0e4811b1b0025ae1fdea00")){
+            System.out.println(process);
+        }*/
         // 获取所有规划实体对象数据
         ApsSolution workingSolution = scoreDirector.getWorkingSolution();
         // 时间设定
@@ -497,6 +502,12 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
                 }else{
                     lzTimes = process.getApsOverallConfig().getRoamTime().get("WORKSHOP_CROSS");
                 }
+                // 松散度
+                if(preProcess.getApsOverallConfig().getLooseness() != null){
+                    BigDecimal lostime = preProcess.getApsOverallConfig().getLooseness().multiply(new BigDecimal(preProcess.getProduceTime())).divide(new BigDecimal("100"));
+                    Integer losinttime = lostime.setScale(0, RoundingMode.CEILING).intValue();
+                    lzTimes = lzTimes + losinttime;
+                }
                 // 最小等待时间对比流转时间
                 if(preProcess.getMinWaitTime() != null && lzTimes<preProcess.getMinWaitTime()){
                     lzTimes = preProcess.getMinWaitTime();
@@ -505,6 +516,13 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
 
             // 当前工序最小开始时间、结束时间
             LocalDateTime proStartTime = endTime.plusMinutes(lzTimes);
+            if(process.getProcessType().equals("成退") || process.getProcessType().equals("中退")){
+                proStartTime = proStartTime.minusSeconds(proStartTime.getSecond()) // 减去当前秒数
+                        .minusNanos(proStartTime.getNano()) // 减去当前纳秒数
+                        .plusMinutes(-proStartTime.getMinute() % 10) // 减去当前分钟数的余数,向下调整到最近的10的倍数
+                        .plusMinutes(10);
+            }
+
             LocalDateTime proEndTime = proStartTime.plusMinutes(process.getProduceTime());
             // 当前工序最大开始时间、结束时间
             LocalDateTime proMaxStartTime = null;

+ 121 - 10
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/score/ApsConstraintProvider.java

@@ -855,11 +855,16 @@ public class ApsConstraintProvider implements ConstraintProvider {
             for (EquipmentRunTime equipmentRunTime : equipment.getEquipmentRunTimes()) {
                 ProductionProcesses pp = new ProductionProcesses();
                 pp.setStartTime(equipmentRunTime.getStartRunTime());
+                pp.setEquipment(equipment);
+                pp.setEndTime(equipmentRunTime.getEndRunTime());
                 pp.setSeriesProduceMark(equipmentRunTime.getSeriesProduceMark());
                 pp.setProcessType(equipmentRunTime.getProcessType());
+                pp.setVolumeMetal(equipmentRunTime.getVolumeMetal());
+                pp.setVolumeMetalstate(equipmentRunTime.getVolumeMetalstate());
                 pp.setBsProcessesId(Arrays.asList(new String[]{"haspcprocess"}));
                 pp.setVolumeWidth(equipmentRunTime.getTotalVolumeWidth());
                 pp.setSinglerollweight(equipmentRunTime.getTotalSinglerollweight());
+                pp.setVolumeThickness(equipmentRunTime.getTotalThickness());
                 pp.setConflictRoptions(new HashMap<>());
                 if(equipmentRunTime.getOccupyType().equals("process")){
                     pp.setTaskType("processes");
@@ -905,7 +910,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                     }
                 }
             }else{
-                if(prePro.getEndTime().compareTo(nextPro.getStartTime()) == 1){
+                if(prePro.getEndTime().compareTo(nextPro.getStartTime()) > 0){
                     if("2".equals(type)){
 //                        System.out.println("1:作业加工时间有交叉");
                         conflictRoptions1.put("hard-eqTimeCrossTuihuo","作业加工时间有交叉");
@@ -920,10 +925,106 @@ public class ApsConstraintProvider implements ConstraintProvider {
             List<ProductionProcesses> v = entry.getValue();
             BigDecimal totalWidth = new BigDecimal("0");
             BigDecimal totalWeight = new BigDecimal("0");
+            Set<String> metalSet = new HashSet<>();
+            Set<String> processTypeSet = new HashSet<>();
+            Set<String> metalstateSet = new HashSet<>();
+            // 最大、最小宽度
+            BigDecimal maxVolumeWidth = null;
+            BigDecimal minVolumeWidth = null;
+            // 最大、最小厚度
+            BigDecimal maxVolumeThickness = null;
+            BigDecimal minVolumeThickness = null;
+            // 最大、最小重量
+            BigDecimal maxSinglerollweight = null;
+            BigDecimal minSinglerollweight = null;
+
             for (ProductionProcesses productionProcesses : v) {
                 totalWidth = totalWidth.add(productionProcesses.getVolumeWidth()).add(productionProcesses.getEquipment().getEquipmentParameter().getFurnace());
                 totalWeight = totalWeight.add(productionProcesses.getSinglerollweight());
+                metalSet.add(productionProcesses.getVolumeMetal());
+                processTypeSet.add(productionProcesses.getProcessType());
+                metalstateSet.add(productionProcesses.getVolumeMetalstate());
+                // 宽度
+                if(maxVolumeWidth == null){
+                    maxVolumeWidth = productionProcesses.getVolumeWidth();
+                }else{
+                    if(productionProcesses.getVolumeWidth().compareTo(maxVolumeWidth)>0){
+                        maxVolumeWidth = productionProcesses.getVolumeWidth();
+                    }
+                }
+                if(minVolumeWidth == null){
+                    minVolumeWidth = productionProcesses.getVolumeWidth();
+                }else{
+                    if(productionProcesses.getVolumeWidth().compareTo(minVolumeWidth)<0){
+                        minVolumeWidth = productionProcesses.getVolumeWidth();
+                    }
+                }
+                // 厚度
+                if(maxVolumeThickness == null){
+                    maxVolumeThickness = productionProcesses.getVolumeThickness();
+                }else{
+                    if(productionProcesses.getVolumeThickness().compareTo(maxVolumeThickness)>0){
+                        maxVolumeThickness = productionProcesses.getVolumeThickness();
+                    }
+                }
+                if(minVolumeThickness == null){
+                    minVolumeThickness = productionProcesses.getVolumeThickness();
+                }else{
+                    if(productionProcesses.getVolumeThickness().compareTo(minVolumeThickness)<0){
+                        minVolumeThickness = productionProcesses.getVolumeThickness();
+                    }
+                }
+                // 重量
+                if(maxSinglerollweight == null){
+                    maxSinglerollweight = productionProcesses.getSinglerollweight();
+                }else{
+                    if(productionProcesses.getSinglerollweight().compareTo(maxSinglerollweight)>0){
+                        maxSinglerollweight = productionProcesses.getSinglerollweight();
+                    }
+                }
+                if(minSinglerollweight == null){
+                    minSinglerollweight = productionProcesses.getSinglerollweight();
+                }else{
+                    if(productionProcesses.getSinglerollweight().compareTo(minSinglerollweight)<0){
+                        minSinglerollweight = productionProcesses.getSinglerollweight();
+                    }
+                }
             }
+            // 工序类型、合金、合金状态要一致
+            if(metalSet.size()>1 || processTypeSet.size()>1 || metalstateSet.size()>1){
+                if("2".equals(type)){
+                    for (ProductionProcesses productionProcesses : v) {
+                        productionProcesses.getConflictRoptions().put("hard-eqTimeCrossTuihuo","不满足退火合并规则");
+                    }
+                }
+                b++;
+            }
+            // 重量、宽度、厚度要满足一定规则
+            else{
+                String processType = v.get(0).getProcessType();
+                BigDecimal btVolumeWidth = null;
+                BigDecimal btVolumeThickness = null;
+                BigDecimal btSinglerollweight = null;
+                if("成退".equals(processType)){
+                    btVolumeWidth = new BigDecimal("50");
+                    btVolumeThickness = new BigDecimal("0.05");
+                    btSinglerollweight = new BigDecimal("1");
+                }else if ("中退".equals(processType)){
+                    btVolumeWidth = new BigDecimal("100");
+                    btVolumeThickness = new BigDecimal("0.08");
+                    btSinglerollweight = new BigDecimal("1");
+                }
+                if(maxVolumeWidth.subtract(minVolumeWidth).compareTo(btVolumeWidth)>0 || maxVolumeThickness.subtract(minVolumeThickness).compareTo(btVolumeThickness)>0
+                        || maxSinglerollweight.subtract(minSinglerollweight).compareTo(btSinglerollweight)>0){
+                    if("2".equals(type)){
+                        for (ProductionProcesses productionProcesses : v) {
+                            productionProcesses.getConflictRoptions().put("hard-eqTimeCrossTuihuo","不满足退火合并规则");
+                        }
+                    }
+                    b++;
+                }
+            }
+
             if(totalWidth.compareTo(v.get(0).getEquipment().getEquipmentParameter().getEquipmentWidth())>0
                     || totalWeight.compareTo(v.get(0).getEquipment().getEquipmentParameter().getEquipmentBearing())>0){
                 if("2".equals(type)){
@@ -1128,6 +1229,8 @@ public class ApsConstraintProvider implements ConstraintProvider {
             pp.setBsProcessesId(Arrays.asList(new String[]{"lastprocess"}));
             pp.setConflictRoptions(new HashMap<>());
             hasStartTimeProcess.add(0,pp);
+        }else{
+            b = b+2;
         }
         for(int i=0;i<hasStartTimeProcess.size()-1;i++){
             if(hasStartTimeProcess.get(i).getSeriesProduceMark() != null && hasStartTimeProcess.get(i+1).getSeriesProduceMark() != null){
@@ -1145,7 +1248,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                     if(serspre.length == 5 && sersafter.length == 5){
                         // 合金不同或者产品类型不同则需要换辊和立板
                         if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
-                            b = b+2;
+                            b = b+4;
                             conflictRoptions1.put("soft-seriesProduceZz","和后一道工序违反换辊和立板的连续约束");
                             conflictRoptions2.put("soft-seriesProduceZz","和前一道工序违反换辊和立板的连续约束");
                         }else{
@@ -1158,11 +1261,11 @@ public class ApsConstraintProvider implements ConstraintProvider {
                                 BigDecimal i1 = new BigDecimal(s1);
                                 BigDecimal i2 = new BigDecimal(s2);
                                 if(i1.compareTo(i2)<0){
-                                    b = b+2;
+                                    b = b+4;
                                     conflictRoptions1.put("soft-seriesProduceZz","和后一道工序违反换辊和立板的连续约束");
                                     conflictRoptions2.put("soft-seriesProduceZz","和前一道工序违反换辊和立板的连续约束");
                                 }else if(i1.compareTo(i2)>0){
-                                    b++;
+                                    b = b+3;
                                     conflictRoptions1.put("soft-seriesProduceZz","和后一道工序违反立板的连续约束");
                                     conflictRoptions2.put("soft-seriesProduceZz","和前一道工序违反立板的连续约束");
                                 }
@@ -1172,6 +1275,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
                         }
                     }
                 } else if ("冷轧".equals(hasStartTimeProcess.get(i).getProcessType())) {
+                    /*if(hasStartTimeProcess.size() == 2){
+                        System.out.println(hasStartTimeProcess);
+                    }*/
                     if(conflictRoptions1.containsKey("soft-seriesProduceLz")){
                         conflictRoptions1.remove("soft-seriesProduceLz");
                     }
@@ -1202,29 +1308,29 @@ public class ApsConstraintProvider implements ConstraintProvider {
                                 BigDecimal i2 = new BigDecimal(s2);
                                 // 后端工序大于前道工序,并且大于30mm
                                 if((i1.add(new BigDecimal("30"))).compareTo(i2)<0){
-                                    b = b+6;
+                                    b = b+7;
                                     conflictRoptions1.put("soft-seriesProduceLz","和后一道工序违反换辊的连续约束");
                                     conflictRoptions2.put("soft-seriesProduceLz","和前一道工序违反换辊的连续约束");
                                 }
                                 // 后端工序大于前道工序,并且小于30mm
                                 else if(i1.compareTo(i2)<0 && (i1.add(new BigDecimal("30"))).compareTo(i2)>=0){
-                                    b = b+5;
+                                    b = b+6;
                                     conflictRoptions1.put("soft-seriesProduceLz","和后一道工序违反换辊的连续约束");
                                     conflictRoptions2.put("soft-seriesProduceLz","和前一道工序违反换辊的连续约束");
                                 }
                                 // 后端工序小于前道工序
                                 else if(i1.compareTo(i2)>0){
-                                    b = b+4;
+                                    b = b+5;
                                 }
                                 // 宽度相等的情况下
                                 else{
                                     // 输入厚度不同
                                     if(t1.compareTo(t2) != 0){
-                                        b = b+3;
+                                        b = b+4;
                                     }else{
                                         // 输出厚度不同
                                         if(to1.compareTo(to2) != 0){
-                                            b = b+2;
+                                            b = b+3;
                                         }else{
                                             // 不属于同一作业
                                             if(!processId1.equals(processId2)){
@@ -1497,7 +1603,12 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 .groupBy(ProductionProcesses::getUniqueBsProcessesId,ConstraintCollectors.toList())
                 .filter((equipmentEquassociated,processes) -> {
                     if(processes != null && processes.size()>0){
-                        return true;
+                        Map<String, List<ProductionProcesses>> listMap = processes.stream().collect(Collectors.groupingBy(ProductionProcesses::getEquipmentId));
+                        if(listMap != null && listMap.size()>1){
+                            return true;
+                        }else{
+                            return false;
+                        }
                     }else{
                         return false;
                     }

+ 1 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/service/impl/ProductionScheduleServiceImpl.java

@@ -257,6 +257,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         apsOverallConfig.setWashingtime(productionScheduleVo.getWashingtime());
         apsOverallConfig.setStandingtime(productionScheduleVo.getStandingtime());
         apsOverallConfig.setClosealloynames(productionScheduleVo.getClosealloynames());
+        apsOverallConfig.setLooseness(productionScheduleVo.getLooseness());
         unsolvedCloudBalance.setStartTime(startTime);
 
         // 根据前道、后道工序ID,转换为前道、后道工序对象

+ 6 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/vo/ProductionScheduleVo.java

@@ -5,6 +5,8 @@ import com.rongwei.rwapsserver.aps.domain.Equipment;
 import com.rongwei.rwapsserver.aps.domain.ProductionProcesses;
 import com.rongwei.rwapsserver.aps.domain.WashingMetal;
 import lombok.Data;
+
+import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -57,5 +59,9 @@ public class ProductionScheduleVo {
      * 立板时间(小时)
      */
     private Integer standingtime;
+    /**
+     * 松散度
+     */
+    private BigDecimal looseness;
 
 }