|
@@ -30,6 +30,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
eqTimeCross(constraintFactory),
|
|
|
deliveryDate(constraintFactory),
|
|
|
seriesProduce(constraintFactory),
|
|
|
+ seriesProduceTimeWait(constraintFactory),
|
|
|
lzTimeLessMaxWait(constraintFactory),
|
|
|
equipmentRunTime(constraintFactory),
|
|
|
balancedEqUse(constraintFactory),
|
|
@@ -493,6 +494,174 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
.asConstraint("lzTimeLessMaxWait");
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 连续生产换辊时间考虑
|
|
|
+ * @param constraintFactory
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Constraint seriesProduceTimeWait(ConstraintFactory constraintFactory) {
|
|
|
+ return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
+ .groupBy(ProductionProcesses::getEquipmentId, ConstraintCollectors.toList())
|
|
|
+ .filter((equipmentId,processes) -> {
|
|
|
+ Equipment equipment = null;
|
|
|
+ if(processes != null && processes.size()>0){
|
|
|
+ equipment = processes.get(0).getEquipment();
|
|
|
+ }
|
|
|
+ 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());
|
|
|
+ pp.setCutfinishmin(equipmentRunTime.getCutfinishmin());
|
|
|
+ hasStartTimeProcess.add(pp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(hasStartTimeProcess != null && hasStartTimeProcess.size()>1){
|
|
|
+ // 安装开始时间排序
|
|
|
+ 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());
|
|
|
+ pp.setEndTime(equipment.getLastProcessEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
|
|
|
+ hasStartTimeProcess.add(0,pp);
|
|
|
+ }
|
|
|
+ // 临时标记
|
|
|
+ Boolean a = false;
|
|
|
+ for(int i=0;i<hasStartTimeProcess.size()-1;i++){
|
|
|
+ if(hasStartTimeProcess.get(i).getSeriesProduceMark() != null && hasStartTimeProcess.get(i+1).getSeriesProduceMark() != null){
|
|
|
+ if("铸轧".equals(hasStartTimeProcess.get(i).getProcessType()) && "铸轧".equals(hasStartTimeProcess.get(i+1).getProcessType())){
|
|
|
+ if(!hasStartTimeProcess.get(i).getSeriesProduceMark().equals(hasStartTimeProcess.get(i+1).getSeriesProduceMark())){
|
|
|
+ if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
|
|
|
+ .plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
+ a = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if ("冷轧".equals(hasStartTimeProcess.get(i).getProcessType()) && "冷轧".equals(hasStartTimeProcess.get(i+1).getProcessType())) {
|
|
|
+ String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("^_^");
|
|
|
+ String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("^_^");
|
|
|
+ if(serspre.length == 3 && sersafter.length == 3){
|
|
|
+ if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
|
|
|
+ if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
|
|
|
+ .plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
+ a = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ String s1 = serspre[2];
|
|
|
+ String s2 = sersafter[2];
|
|
|
+ try{
|
|
|
+ Integer i1 = Integer.parseInt(s1);
|
|
|
+ Integer i2 = Integer.parseInt(s2);
|
|
|
+ if(i1<i2 || (i1-i2)>30){
|
|
|
+ if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
|
|
|
+ .plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
+ a = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }catch (Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return a;
|
|
|
+ }else{
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .penalize(HardSoftScore.ONE_HARD,(equipmentId,processes)->{
|
|
|
+ int b = 0;
|
|
|
+ Equipment equipment = null;
|
|
|
+ if(processes != null && processes.size()>0){
|
|
|
+ equipment = processes.get(0).getEquipment();
|
|
|
+ }
|
|
|
+ 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());
|
|
|
+ pp.setCutfinishmin(equipmentRunTime.getCutfinishmin());
|
|
|
+ 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());
|
|
|
+ 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).getSeriesProduceMark() != null && hasStartTimeProcess.get(i+1).getSeriesProduceMark() != null){
|
|
|
+ if("铸轧".equals(hasStartTimeProcess.get(i).getProcessType())){
|
|
|
+ if(!hasStartTimeProcess.get(i).getSeriesProduceMark().equals(hasStartTimeProcess.get(i+1).getSeriesProduceMark())){
|
|
|
+ if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
|
|
|
+ .plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
+ b++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if ("冷轧".equals(hasStartTimeProcess.get(i).getProcessType())) {
|
|
|
+ String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("^_^");
|
|
|
+ String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("^_^");
|
|
|
+ if(serspre.length == 3 && sersafter.length == 3){
|
|
|
+ if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
|
|
|
+ if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
|
|
|
+ .plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
+ b++;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ String s1 = serspre[2];
|
|
|
+ String s2 = sersafter[2];
|
|
|
+ try{
|
|
|
+ Integer i1 = Integer.parseInt(s1);
|
|
|
+ Integer i2 = Integer.parseInt(s2);
|
|
|
+ if(i1<i2 || (i1-i2)>30){
|
|
|
+ if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
|
|
|
+ .plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
+ b++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }catch (Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /*if("0001be252874536843730b100020".equals(equipmentId)){
|
|
|
+ System.out.println("******得分:"+b);
|
|
|
+ }*/
|
|
|
+ if(b>0){
|
|
|
+ return b*10;
|
|
|
+ }
|
|
|
+ return 10;
|
|
|
+ })
|
|
|
+ .asConstraint("seriesProduceTimeWait");
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 硬约束:同一个设备的不同的工步运行时间不能有交叉
|
|
|
* @param constraintFactory
|
|
@@ -610,7 +779,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
Equipment equipment = null;
|
|
|
if(processes != null && processes.size()>0){
|
|
|
equipment = processes.get(0).getEquipment();
|
|
|
- List<ProductionProcesses> plist = new ArrayList<>();
|
|
|
+ /*List<ProductionProcesses> plist = new ArrayList<>();
|
|
|
for (ProductionProcesses process : processes) {
|
|
|
ProductionProcesses pro = new ProductionProcesses();
|
|
|
pro.setId(process.getId());
|
|
@@ -620,7 +789,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
pro.setEndTime(process.getEndTime());
|
|
|
plist.add(pro);
|
|
|
}
|
|
|
- equipment.setProcessesList(plist);
|
|
|
+ equipment.setProcessesList(plist);*/
|
|
|
}
|
|
|
List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
|
|
|
// 设备占用时间参与连续生产排程
|