|
@@ -26,6 +26,13 @@ import org.optaplanner.core.api.solver.Solver;
|
|
import org.optaplanner.core.api.solver.SolverFactory;
|
|
import org.optaplanner.core.api.solver.SolverFactory;
|
|
import org.optaplanner.core.api.solver.event.BestSolutionChangedEvent;
|
|
import org.optaplanner.core.api.solver.event.BestSolutionChangedEvent;
|
|
import org.optaplanner.core.api.solver.event.SolverEventListener;
|
|
import org.optaplanner.core.api.solver.event.SolverEventListener;
|
|
|
|
+import org.optaplanner.core.config.constructionheuristic.ConstructionHeuristicPhaseConfig;
|
|
|
|
+import org.optaplanner.core.config.constructionheuristic.ConstructionHeuristicType;
|
|
|
|
+import org.optaplanner.core.config.heuristic.selector.common.SelectionOrder;
|
|
|
|
+import org.optaplanner.core.config.heuristic.selector.move.generic.ChangeMoveSelectorConfig;
|
|
|
|
+import org.optaplanner.core.config.heuristic.selector.move.generic.SwapMoveSelectorConfig;
|
|
|
|
+import org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig;
|
|
|
|
+import org.optaplanner.core.config.localsearch.decider.acceptor.LocalSearchAcceptorConfig;
|
|
import org.optaplanner.core.config.solver.EnvironmentMode;
|
|
import org.optaplanner.core.config.solver.EnvironmentMode;
|
|
import org.optaplanner.core.config.solver.SolverConfig;
|
|
import org.optaplanner.core.config.solver.SolverConfig;
|
|
import org.optaplanner.core.config.solver.termination.TerminationConfig;
|
|
import org.optaplanner.core.config.solver.termination.TerminationConfig;
|
|
@@ -56,13 +63,18 @@ public class ProductionScheduleTaServiceImpl implements ProductionScheduleTaServ
|
|
public ProductionScheduleRetTaVo productionSchedule(ProductionScheduleTaVo productionScheduleVo) throws Exception{
|
|
public ProductionScheduleRetTaVo productionSchedule(ProductionScheduleTaVo productionScheduleVo) throws Exception{
|
|
log.info("*************** 排程开始(productionLxSchedule):"+productionScheduleVo.getProductionScheduleId()+" *******************");
|
|
log.info("*************** 排程开始(productionLxSchedule):"+productionScheduleVo.getProductionScheduleId()+" *******************");
|
|
|
|
|
|
|
|
+ String orderIds = "2e6681bb8a3140b7acf56d25dedf5ae0,2cfd9764b7d341f4ab0797e6fffbef4b,094f1cfdb59b4181982c47068317ba40," +
|
|
|
|
+ "fdf23365c4fb41ed8d25b135f3a850bd,0f766bf9aaac4b80a18d5849de3ba8ba,43c996ef6966455789b455225ed1c26c,66ef0e569e144f6189b39a72f2c2666a" +
|
|
|
|
+ "aadcd8d4f96d43349cb0cce66e79a51d,7ab8bce8e12541e69d3bb68fd3950200,224561482e60461dba6da471c872e60a," +
|
|
|
|
+ "5494eff9337c4d58bad240c32a6d9a1e,e7910a7d2acd4195ba20e66d58dfc8b6,698afa4133b34948ae7b6fc5683ce478";
|
|
List<String> orderidStrs = new ArrayList<>();
|
|
List<String> orderidStrs = new ArrayList<>();
|
|
- orderidStrs.add("fdf23365c4fb41ed8d25b135f3a850bd");
|
|
|
|
-// orderidStrs.add("0c1394851a64456e9f2749720be27c41");
|
|
|
|
|
|
+ orderidStrs.add("4c0dcd0e147a4fd29742088bac692aee");
|
|
|
|
+ orderidStrs.add("e2f95da1b00f475395e06b99e90f5bbe");
|
|
// orderidStrs.add("5494eff9337c4d58bad240c32a6d9a1e");
|
|
// orderidStrs.add("5494eff9337c4d58bad240c32a6d9a1e");
|
|
// orderidStrs.add("6f8da7c629f54b5a810ed6ce13dbee17");
|
|
// orderidStrs.add("6f8da7c629f54b5a810ed6ce13dbee17");
|
|
|
|
+
|
|
/*List<ProductionProcessesTa> pdps = productionScheduleVo.getProcesses().stream().filter(v ->
|
|
/*List<ProductionProcessesTa> pdps = productionScheduleVo.getProcesses().stream().filter(v ->
|
|
- orderidStrs.contains(v.getProduceOrder().get(0).getId())
|
|
|
|
|
|
+ !orderidStrs.contains(v.getProduceOrder().get(0).getId())
|
|
).collect(Collectors.toList());
|
|
).collect(Collectors.toList());
|
|
productionScheduleVo.setProcesses(pdps);*/
|
|
productionScheduleVo.setProcesses(pdps);*/
|
|
// 排程结果对象
|
|
// 排程结果对象
|
|
@@ -107,6 +119,9 @@ public class ProductionScheduleTaServiceImpl implements ProductionScheduleTaServ
|
|
// 排程作业排序
|
|
// 排程作业排序
|
|
sortProcess(apsSolution.getProcessesList(),1);
|
|
sortProcess(apsSolution.getProcessesList(),1);
|
|
|
|
|
|
|
|
+ /*if(1 == 1){
|
|
|
|
+ return new ProductionScheduleRetTaVo();
|
|
|
|
+ }*/
|
|
// 去掉锁定工序
|
|
// 去掉锁定工序
|
|
List<ProductionProcessesTa> notLocks = new ArrayList<>();
|
|
List<ProductionProcessesTa> notLocks = new ArrayList<>();
|
|
List<ProductionProcessesTa> hasLocks = new ArrayList<>();
|
|
List<ProductionProcessesTa> hasLocks = new ArrayList<>();
|
|
@@ -129,10 +144,17 @@ public class ProductionScheduleTaServiceImpl implements ProductionScheduleTaServ
|
|
.withSolutionClass(ApsSolutionTa.class)
|
|
.withSolutionClass(ApsSolutionTa.class)
|
|
.withEntityClasses(ProductionProcessesTa.class, EquipmentTa.class)
|
|
.withEntityClasses(ProductionProcessesTa.class, EquipmentTa.class)
|
|
.withConstraintProviderClass(ApsConstraintListProvider.class)
|
|
.withConstraintProviderClass(ApsConstraintListProvider.class)
|
|
- .withTerminationConfig(new TerminationConfig().withUnimprovedSecondsSpentLimit(120L))
|
|
|
|
|
|
+ .withTerminationConfig(new TerminationConfig().withUnimprovedSecondsSpentLimit(60L))
|
|
// .withTerminationSpentLimit(Duration.ofSeconds(180))
|
|
// .withTerminationSpentLimit(Duration.ofSeconds(180))
|
|
.withMoveThreadCount(cores)
|
|
.withMoveThreadCount(cores)
|
|
);
|
|
);
|
|
|
|
+ /*SolverConfig solverConfig = SolverConfig.createFromXmlResource("apsSchedulingSolverConfig.xml");
|
|
|
|
+ solverConfig.withEnvironmentMode(EnvironmentMode.REPRODUCIBLE)
|
|
|
|
+ .withTerminationConfig(new TerminationConfig().withUnimprovedSecondsSpentLimit(60L))
|
|
|
|
+ .withMoveThreadCount(cores);
|
|
|
|
+ SolverFactory<ApsSolutionTa> solverFactory = SolverFactory.create(solverConfig);*/
|
|
|
|
+
|
|
|
|
+
|
|
Solver<ApsSolutionTa> solver = solverFactory.buildSolver();
|
|
Solver<ApsSolutionTa> solver = solverFactory.buildSolver();
|
|
solver.addEventListener(new SolverEventListener<ApsSolutionTa>() {
|
|
solver.addEventListener(new SolverEventListener<ApsSolutionTa>() {
|
|
public void bestSolutionChanged(BestSolutionChangedEvent<ApsSolutionTa> event) {
|
|
public void bestSolutionChanged(BestSolutionChangedEvent<ApsSolutionTa> event) {
|
|
@@ -241,10 +263,67 @@ public class ProductionScheduleTaServiceImpl implements ProductionScheduleTaServ
|
|
equipments.add(optionalProviderEquipment);
|
|
equipments.add(optionalProviderEquipment);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+ // 排序按照宽度从大到小排序
|
|
|
|
+ List<ProductionProcessesTa> toApsPros = vv;
|
|
|
|
+ Collections.sort(toApsPros,(p1,p2)->{
|
|
|
|
+ return p2.getVolumeWidth().compareTo(p1.getVolumeWidth());
|
|
|
|
+ });
|
|
|
|
+ List<ProductionProcessesTa> minTimeAfterPros = toApsPros.stream().filter(v->{
|
|
|
|
+ boolean minTimePros = false;
|
|
|
|
+ List<ProductionProcessesTa> previousProcesses = v.getPreviousProcesses();
|
|
|
|
+ // 获取前道工序结束时间加上最小等待时间
|
|
|
|
+ if (previousProcesses != null && previousProcesses.size() > 0) {
|
|
|
|
+ LocalDateTime lastEndTime = null;
|
|
|
|
+ for (ProductionProcessesTa previousProcess : previousProcesses) {
|
|
|
|
+ LocalDateTime endTime = previousProcess.getEndTime();
|
|
|
|
+ if (endTime != null) {
|
|
|
|
+ if(lastEndTime == null){
|
|
|
|
+ lastEndTime = endTime;
|
|
|
|
+ }else {
|
|
|
|
+ if(endTime.isAfter(lastEndTime)){
|
|
|
|
+ lastEndTime = endTime;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 前道工序加上最小等待时间大于排程开始时间加上5小时则放到最后排程
|
|
|
|
+ if(lastEndTime != null){
|
|
|
|
+ if(v.getMinWaitTime() != null){
|
|
|
|
+ lastEndTime = lastEndTime.plusMinutes(v.getMinWaitTime());
|
|
|
|
+ if(v.getApsOverallConfig().getStartTime().plusHours(5).isBefore(lastEndTime)){
|
|
|
|
+ minTimePros = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return minTimePros;
|
|
|
|
+ }).collect(Collectors.toList());
|
|
|
|
|
|
|
|
+ List<ProductionProcessesTa> toApsLastPros = new ArrayList<>();
|
|
|
|
+ if(minTimeAfterPros != null && minTimeAfterPros.size()>0){
|
|
|
|
+ for (ProductionProcessesTa toApsPro : toApsPros) {
|
|
|
|
+ List<ProductionProcessesTa> l1 = minTimeAfterPros.stream().filter(v -> v.getId().equals(toApsPro.getId())).collect(Collectors.toList());
|
|
|
|
+ if(l1 == null || l1.size() == 0){
|
|
|
|
+ toApsLastPros.add(toApsPro);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ toApsLastPros.addAll(toApsPros);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ toApsLastPros.addAll(minTimeAfterPros);
|
|
|
|
+
|
|
apsSolution1.setEquipmentList(equipments);
|
|
apsSolution1.setEquipmentList(equipments);
|
|
- apsSolution1.setProcessesList(vv);
|
|
|
|
|
|
+ apsSolution1.setProcessesList(toApsLastPros);
|
|
|
|
+
|
|
|
|
+ /*List<EquipmentTa> equipmentTaList1 = apsSolution1.getEquipmentList().stream().filter(v -> v.getId().equals("0001be252874536843730b100153")).collect(Collectors.toList());
|
|
|
|
+ if(equipmentTaList1 != null && equipmentTaList1.size() > 0){
|
|
|
|
+ int a1 = 0;
|
|
|
|
+ }else{
|
|
|
|
+ return;
|
|
|
|
+ }*/
|
|
|
|
|
|
ApsSolutionTa solvedBalance1 = solver.solve(apsSolution1);
|
|
ApsSolutionTa solvedBalance1 = solver.solve(apsSolution1);
|
|
for (ProductionProcessesTa productionProcesses : solvedBalance1.getProcessesList()) {
|
|
for (ProductionProcessesTa productionProcesses : solvedBalance1.getProcessesList()) {
|
|
@@ -253,14 +332,7 @@ public class ProductionScheduleTaServiceImpl implements ProductionScheduleTaServ
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- List<EquipmentTa> equipmentTaList1 = solvedBalance1.getEquipmentList().stream().filter(v -> v.getId().equals("0001be252874536843730b100152")).collect(Collectors.toList());
|
|
|
|
- if(equipmentTaList1 != null && equipmentTaList1.size() > 0){
|
|
|
|
- int a1 = 0;
|
|
|
|
- }
|
|
|
|
- List<EquipmentTa> equipmentTaList2 = solvedBalance1.getEquipmentList().stream().filter(v -> v.getId().equals("0001be252874536843730b100151")).collect(Collectors.toList());
|
|
|
|
- if(equipmentTaList2 != null && equipmentTaList2.size() > 0){
|
|
|
|
- int a1 = 0;
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
log.info("**************排程评分分析***************");
|
|
log.info("**************排程评分分析***************");
|
|
SolutionManager<ApsSolutionTa, HardSoftScore> scoreManager = SolutionManager.create(solverFactory);
|
|
SolutionManager<ApsSolutionTa, HardSoftScore> scoreManager = SolutionManager.create(solverFactory);
|
|
ScoreExplanation<ApsSolutionTa, HardSoftScore> explain = scoreManager.explain(solvedBalance1);
|
|
ScoreExplanation<ApsSolutionTa, HardSoftScore> explain = scoreManager.explain(solvedBalance1);
|