|
@@ -46,7 +46,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
tuihuoSp(constraintFactory),
|
|
|
sameEquipment(constraintFactory),
|
|
|
seriesZzLb(constraintFactory),
|
|
|
-
|
|
|
+ seriesLzHg(constraintFactory),
|
|
|
preNextProcessSameWorkShop(constraintFactory),
|
|
|
// SOFT
|
|
|
processNear(constraintFactory),
|
|
@@ -611,6 +611,186 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
.asConstraint("seriesProduceTimeWait");
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 冷轧换辊预留周期
|
|
|
+ * @param constraintFactory
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Constraint seriesLzHg(ConstraintFactory constraintFactory){
|
|
|
+ return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
+ .filter((processe) -> {
|
|
|
+ return "冷轧".equals(processe.getProcessType()) || "箔轧".equals(processe.getProcessType());
|
|
|
+ })
|
|
|
+ .groupBy(ProductionProcesses::getEquipmentId, ConstraintCollectors.toList())
|
|
|
+ .filter((equipmentId,processes) -> {
|
|
|
+ if(processes != null && processes.size()>0){
|
|
|
+ for (ProductionProcesses process : processes) {
|
|
|
+ if(process.getConflictRoptions().containsKey("soft-seriesZzLb")){
|
|
|
+ process.getConflictRoptions().remove("soft-seriesZzLb");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ })
|
|
|
+ .penalize(HardMediumSoftScore.ONE_MEDIUM,(equipmentId,processes)->{
|
|
|
+ int counNum = seriesLzHgCount(processes);
|
|
|
+ return counNum*30;
|
|
|
+ })
|
|
|
+ .asConstraint("seriesLzHg");
|
|
|
+ }
|
|
|
+
|
|
|
+ private int seriesLzHgCount(List<ProductionProcesses> processes){
|
|
|
+ int b = 0;
|
|
|
+ Equipment equipment = null;
|
|
|
+ if(processes != null && processes.size()>0){
|
|
|
+ equipment = processes.get(0).getEquipment();
|
|
|
+ }else{
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+ List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
|
|
|
+ // 设备占用时间参与连续生产排程
|
|
|
+ if(equipment != null && equipment.getEquipmentRunTimes() != null && equipment.getEquipmentRunTimes().size()>0){
|
|
|
+ for (EquipmentRunTime equipmentRunTime : equipment.getEquipmentRunTimes()) {
|
|
|
+ ProductionProcesses pp = new ProductionProcesses();
|
|
|
+ pp.setStartTime(equipmentRunTime.getStartRunTime());
|
|
|
+ pp.setEndTime(equipmentRunTime.getEndRunTime());
|
|
|
+ pp.setSeriesProduceMark(equipmentRunTime.getSeriesProduceMark());
|
|
|
+ pp.setProcessType(equipmentRunTime.getProcessType());
|
|
|
+ pp.setPrepressworkmin(equipmentRunTime.getPrepressworkmin() == null ? 0 : equipmentRunTime.getPrepressworkmin());
|
|
|
+ pp.setCutfinishmin(equipmentRunTime.getCutfinishmin() == null ? 0 : equipmentRunTime.getCutfinishmin());
|
|
|
+ pp.setApsOverallConfig(hasStartTimeProcess.get(0).getApsOverallConfig());
|
|
|
+ pp.setConflictRoptions(new HashMap<>());
|
|
|
+ pp.setProduceTime(equipmentRunTime.getOnceprocessmin());
|
|
|
+ pp.setSinglerollweight(equipmentRunTime.getTotalSinglerollweight());
|
|
|
+ pp.setLastSerialLbWeight(equipmentRunTime.getLastSerialLbWeight());
|
|
|
+ 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.setCutfinishmin(equipment.getLastProcessCutfinishmin() == null ? 0 : equipment.getLastProcessCutfinishmin());
|
|
|
+ pp.setEndTime(equipment.getLastProcessEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
|
|
|
+ pp.setApsOverallConfig(hasStartTimeProcess.get(0).getApsOverallConfig());
|
|
|
+ pp.setProduceTime(equipment.getOnceprocessmin());
|
|
|
+ pp.setConflictRoptions(new HashMap<>());
|
|
|
+ pp.setSinglerollweight(equipment.getLastSinglerollweight());
|
|
|
+ pp.setLastSerialLbWeight(equipment.getLastSerialLbWeight());
|
|
|
+ hasStartTimeProcess.add(0,pp);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 周期立板已连续生产吨数
|
|
|
+ LocalDateTime lzlxstarttime = null;
|
|
|
+ if(equipment.getLxzTime() != null){
|
|
|
+ lzlxstarttime = equipment.getLxzTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
|
|
+ }else{
|
|
|
+ lzlxstarttime = hasStartTimeProcess.get(0).getStartTime();
|
|
|
+ }
|
|
|
+ int huzq = 60*8;
|
|
|
+ for(int i=0;i<hasStartTimeProcess.size()-1;i++){
|
|
|
+ ProductionProcesses prePro = hasStartTimeProcess.get(i);
|
|
|
+ ProductionProcesses nextPro = hasStartTimeProcess.get(i+1);
|
|
|
+ Map<String, String> conflictRoptions1 = prePro.getConflictRoptions();
|
|
|
+ Map<String, String> conflictRoptions2 = nextPro.getConflictRoptions();
|
|
|
+
|
|
|
+ ProductionProcesses prepro = hasStartTimeProcess.get(i);
|
|
|
+ ProductionProcesses nextpro = hasStartTimeProcess.get(i+1);
|
|
|
+ String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("\\^_\\^");
|
|
|
+ String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("\\^_\\^");
|
|
|
+ // 前道工序宽度、输入物料厚度、输出物料厚度
|
|
|
+ String s1 = serspre[2];
|
|
|
+ // 后道工序宽度、输入物料厚度、输出物料厚度
|
|
|
+ String s2 = sersafter[2];
|
|
|
+ BigDecimal i1 = new BigDecimal(s1);
|
|
|
+ BigDecimal i2 = new BigDecimal(s2);
|
|
|
+ // 判断原有前后两道历史工序是否连续
|
|
|
+ /*boolean ispreafterLx = false;
|
|
|
+ if(prepro.getId() == null && nextpro.getId() != null && hasStartTimeProcess.size()>i+2
|
|
|
+ && hasStartTimeProcess.get(i+2).getId() == null){
|
|
|
+ ProductionProcesses nextnextpro = hasStartTimeProcess.get(i + 2);
|
|
|
+ if(StrUtil.isNotBlank(prepro.getProZg()) && StrUtil.isNotBlank(nextnextpro.getProZg())){
|
|
|
+ if(prepro.getProZg().equals(nextnextpro.getProZg())){
|
|
|
+ String[] sersafterafter = nextnextpro.getSeriesProduceMark().split("\\^_\\^");
|
|
|
+ BigDecimal i3 = new BigDecimal(sersafterafter[2]);
|
|
|
+ if(i1.compareTo(i3)>=0){
|
|
|
+ ispreafterLx = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (prepro.getId() != null && nextpro.getId() == null && i>0
|
|
|
+ && hasStartTimeProcess.get(i-1).getId() == null) {
|
|
|
+ ProductionProcesses preprepro = hasStartTimeProcess.get(i-1);
|
|
|
+ if(StrUtil.isNotBlank(preprepro.getProZg()) && StrUtil.isNotBlank(nextpro.getProZg())){
|
|
|
+ if(preprepro.getProZg().equals(nextpro.getProZg())){
|
|
|
+ String[] sersprepre = preprepro.getSeriesProduceMark().split("\\^_\\^");
|
|
|
+ BigDecimal i0 = new BigDecimal(sersprepre[2]);
|
|
|
+ if(i0.compareTo(i2)>=0){
|
|
|
+ ispreafterLx = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+
|
|
|
+ if(StrUtil.isNotBlank(prepro.getProZg()) && StrUtil.isNotBlank(nextpro.getProZg())){
|
|
|
+ String preZg = prepro.getProZg();
|
|
|
+ String nextZg = nextpro.getProZg();
|
|
|
+ if(!preZg.equals(nextZg)){
|
|
|
+ if(lzlxstarttime.plusMinutes(huzq).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
+ // 只有存在当前排程的作业才会记录扣分数
|
|
|
+ if(nextPro.getId() != null){
|
|
|
+ b = b+8;
|
|
|
+ conflictRoptions2.put("soft-seriesZzLb","和上道工序没有预留足够的周期换辊时间");
|
|
|
+ }else{
|
|
|
+ if(prePro.getId() != null){
|
|
|
+ b = b+8;
|
|
|
+ conflictRoptions1.put("soft-seriesZzLb","和下道工序没有预留足够的周期换辊时间");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lzlxstarttime = hasStartTimeProcess.get(i+1).getStartTime();
|
|
|
+ }else{
|
|
|
+ if((i1.add(new BigDecimal("30"))).compareTo(i2)<0){
|
|
|
+ if(lzlxstarttime.plusMinutes(huzq).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
+ // 只有存在当前排程的作业才会记录扣分数
|
|
|
+ if(nextPro.getId() != null){
|
|
|
+ b = b+8;
|
|
|
+ conflictRoptions2.put("soft-seriesZzLb","和上道工序没有预留足够的周期换辊时间");
|
|
|
+ }else{
|
|
|
+ if(prePro.getId() != null){
|
|
|
+ b = b+8;
|
|
|
+ conflictRoptions1.put("soft-seriesZzLb","和下道工序没有预留足够的周期换辊时间");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lzlxstarttime = hasStartTimeProcess.get(i+1).getStartTime();
|
|
|
+ }else if(i1.compareTo(i2)>0){
|
|
|
+ int ii = ((i1.subtract(i2)).divideToIntegralValue(new BigDecimal("100"))).intValue();
|
|
|
+ int it = ii*60;
|
|
|
+ if(it>huzq){
|
|
|
+ it = huzq;
|
|
|
+ }
|
|
|
+ if(lzlxstarttime.plusMinutes(it).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
+ // 只有存在当前排程的作业才会记录扣分数
|
|
|
+ if(nextPro.getId() != null){
|
|
|
+ b = b+1;
|
|
|
+ }else{
|
|
|
+ if(prePro.getId() != null){
|
|
|
+ b = b+1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 铸轧预留连续排产时间
|
|
|
* @param constraintFactory
|