Commit 25c58c5b authored by Tong Li's avatar Tong Li

算法优化

parent 9d08cc4f
...@@ -465,7 +465,7 @@ public class ResourceGanttController { ...@@ -465,7 +465,7 @@ public class ResourceGanttController {
ParamValidator.validateSceneExists(sceneService, sceneId); ParamValidator.validateSceneExists(sceneService, sceneId);
planResultService.InsertOrderAuto(sceneId, newOrderData); // planResultService.InsertOrderAuto(sceneId, newOrderData);
return R.ok("自动插单成功"); return R.ok("自动插单成功");
} }
......
...@@ -17,7 +17,7 @@ public class ScheduleParams { ...@@ -17,7 +17,7 @@ public class ScheduleParams {
private static final int MIN_POPULATION_SIZE = 10; private static final int MIN_POPULATION_SIZE = 10;
private static final int MAX_POPULATION_SIZE = 50; private static final int MAX_POPULATION_SIZE = 50;
private static final int MIN_MAX_ITERATIONS = 50; private static final int MIN_MAX_ITERATIONS = 50;
private static final int MAX_MAX_ITERATIONS = 250; private static final int MAX_MAX_ITERATIONS = 100;
private static final float MIN_CROSSOVER_PROB = 0.6f; private static final float MIN_CROSSOVER_PROB = 0.6f;
private static final float MAX_CROSSOVER_PROB = 0.9f; private static final float MAX_CROSSOVER_PROB = 0.9f;
private static final float MIN_MUTATION_PROB = 0.2f; private static final float MIN_MUTATION_PROB = 0.2f;
......
...@@ -417,13 +417,13 @@ public class GeneticAlgorithm { ...@@ -417,13 +417,13 @@ public class GeneticAlgorithm {
} }
// 加载锁定工单到ResultOld // 加载锁定工单到ResultOld
List<GAScheduleResult> lockedOrders = GlobalCacheUtil.get("locked_orders_" + sceneId); // List<GAScheduleResult> lockedOrders = GlobalCacheUtil.get("locked_orders_" + sceneId);
if (lockedOrders != null && !lockedOrders.isEmpty()) { // if (lockedOrders != null && !lockedOrders.isEmpty()) {
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(lockedOrders, GAScheduleResult.class)); // chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(lockedOrders, GAScheduleResult.class));
FileHelper.writeLogFile("将 " + lockedOrders.size() + " 个锁定工单加载到初始种群中"); // FileHelper.writeLogFile("将 " + lockedOrders.size() + " 个锁定工单加载到初始种群中");
} else { // } else {
chromosome.setResultOld(new CopyOnWriteArrayList<>()); // chromosome.setResultOld(new CopyOnWriteArrayList<>());
} // }
decoder.decodeChromosomeWithCache(chromosome); decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) { if (chromosome.getFitness() == 0) {
......
...@@ -471,10 +471,14 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -471,10 +471,14 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 步骤2:按OperationSequencing顺序调度工序 // 步骤2:按OperationSequencing顺序调度工序
Map<Integer, Integer> orderProcessCounter = new HashMap<>(); Map<Integer, Integer> orderProcessCounter = new HashMap<>();
Map<Integer, Integer> orderLastEndTime = new HashMap<>(); Map<Integer, Integer> orderLastEndTime = new HashMap<>();
Map<Integer, Entry> entryIndexById = new HashMap<>();
Map<Integer, List<Entry>> entrysBygroupId = new HashMap<>();
for (Entry op : allOperations) { for (Entry op : allOperations) {
int groupId = op.getGroupId(); int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0); orderProcessCounter.putIfAbsent(groupId, 0);
orderLastEndTime.putIfAbsent(groupId, 0); orderLastEndTime.putIfAbsent(groupId, 0);
entryIndexById.put(op.getId(),op);
entrysBygroupId.computeIfAbsent(groupId, k -> new ArrayList<>()).add(op);
} }
// Map<Long, String> machineState = chromosome.getMachines().stream() // Map<Long, String> machineState = chromosome.getMachines().stream()
...@@ -483,10 +487,12 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -483,10 +487,12 @@ if(finishedOrder==null||finishedOrder.size()==0)
// List<Entry> allScheduledOps = new ArrayList<>(); // List<Entry> allScheduledOps = new ArrayList<>();
// 缓存机器任务 // 缓存机器任务
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache = new HashMap<>(); Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache = new HashMap<>();
for (Entry op : allOperations) {
}
for (int groupId : chromosome.getOperationSequencing()) { for (int groupId : chromosome.getOperationSequencing()) {
int scheduledCount = orderProcessCounter.get(groupId); int scheduledCount = orderProcessCounter.get(groupId);
List<Entry> orderOps = allOperations.stream() List<Entry> orderOps = entrysBygroupId.get(groupId).stream()
.filter(t -> t.getGroupId() == groupId)
.sorted(Comparator.comparing(Entry::getSequence)) .sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList()); .collect(Collectors.toList());
...@@ -1243,12 +1249,12 @@ return actualEndTime; ...@@ -1243,12 +1249,12 @@ return actualEndTime;
} }
machineTasks =chromosome.getResult().stream() // machineTasks =chromosome.getResult().stream()
.filter(t -> t.getMachineId() == machine.getId()) // .filter(t -> t.getMachineId() == machine.getId())
.sorted(Comparator.comparingInt(GAScheduleResult::getStartTime)) // .sorted(Comparator.comparingInt(GAScheduleResult::getStartTime))
.collect(Collectors.toCollection(CopyOnWriteArrayList::new)); // .collect(Collectors.toCollection(CopyOnWriteArrayList::new));
//
machineTasksCache.put(machine.getId(), machineTasks); // machineTasksCache.put(machine.getId(), machineTasks);
if(machineTasks!=null&&machineTasks.size()>0&&_globalParam.is_smoothChangeOver()) if(machineTasks!=null&&machineTasks.size()>0&&_globalParam.is_smoothChangeOver())
{ {
...@@ -1385,7 +1391,9 @@ return actualEndTime; ...@@ -1385,7 +1391,9 @@ return actualEndTime;
// FileHelper.writeLogFile(" 结束 "+ConvertTime(startTime)+"--"+ConvertTime(endTime)+" "+operation.getGroupId()+" : "+operation.getId()+",处理时间: " + processingTime + ", 后处理: " + teardownTime + // FileHelper.writeLogFile(" 结束 "+ConvertTime(startTime)+"--"+ConvertTime(endTime)+" "+operation.getGroupId()+" : "+operation.getId()+",处理时间: " + processingTime + ", 后处理: " + teardownTime +
// ", 前处理: " + preTime + ", 换型: " + setupTime+ ", 数量: " + operation.getQuantity()+ ", 设备: "+machine.getId()+ ", 是否可中断: "+operation.getIsInterrupt()); // ", 前处理: " + preTime + ", 换型: " + setupTime+ ", 数量: " + operation.getQuantity()+ ", 设备: "+machine.getId()+ ", 是否可中断: "+operation.getIsInterrupt());
machineTasksCache.remove(machine.getId()); if (machineTasks != null) {
machineTasks.add(result);
}
return endTime; return endTime;
} }
...@@ -2399,24 +2407,21 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2399,24 +2407,21 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
private void calculateScheduleResult(Chromosome chromosome) { private void calculateScheduleResult(Chromosome chromosome) {
double[] Objectives=new double[_globalParam.getObjectiveWeights().size()]; double[] Objectives = new double[_globalParam.getObjectiveWeights().size()];
int i=0; int i = 0;
for (ObjectiveConfig config : _globalParam.getObjectiveConfigs()) { for (ObjectiveConfig config : _globalParam.getObjectiveConfigs()) {
if( config.isEnabled()) if (config.isEnabled()) {
{ if (config.getName() == GlobalParam.OBJECTIVE_MAKESPAN) {
if(config.getName()==GlobalParam.OBJECTIVE_MAKESPAN)
{
// 1. 最早完工时间(最小化) // 1. 最早完工时间(最小化)
double makespan = chromosome.getResult().stream() double makespan = chromosome.getResult().stream()
.mapToInt(GAScheduleResult::getEndTime) .mapToInt(GAScheduleResult::getEndTime)
.max() .max()
.orElse(0); .orElse(0);
Objectives[i]=makespan; Objectives[i] = makespan;
chromosome.setMakespan(makespan); chromosome.setMakespan(makespan);
} }
if(config.getName()==GlobalParam.OBJECTIVE_TARDINESS) if (config.getName() == GlobalParam.OBJECTIVE_TARDINESS) {
{
// 2. 交付期满足情况(最小化延迟) // 2. 交付期满足情况(最小化延迟)
double tardiness = 0; double tardiness = 0;
...@@ -2435,60 +2440,57 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2435,60 +2440,57 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
.sorted() .sorted()
.collect(Collectors.toList()); .collect(Collectors.toList());
Order order = chromosome.getOrders().stream() Order order = chromosome.getOrders().stream()
.filter(t->orderIds.contains(t.getOrderId())) .filter(t -> orderIds.contains(t.getOrderId()))
.max(Comparator.comparing(Order::getDueDate)) .max(Comparator.comparing(Order::getDueDate))
.orElse(null); .orElse(null);
if(order.isNewCreate()) if (order.isNewCreate()) {
{continue;} continue;
LocalDateTime dueDateTime=order.getDueDate(); }
LocalDateTime dueDateTime = order.getDueDate();
LocalDateTime completionTime =baseTime.plusSeconds(orderCompletion); LocalDateTime completionTime = baseTime.plusSeconds(orderCompletion);
if (completionTime.isAfter(dueDateTime)) { if (completionTime.isAfter(dueDateTime)) {
// 计算延迟小时数(修复时间计算) // 计算延迟小时数(修复时间计算)
long hours = ChronoUnit.HOURS.between(dueDateTime, completionTime); long hours = ChronoUnit.HOURS.between(dueDateTime, completionTime);
long minutes = ChronoUnit.MINUTES.between(dueDateTime, completionTime) % 60; long minutes = ChronoUnit.MINUTES.between(dueDateTime, completionTime) % 60;
tardiness += hours*60 + (double) minutes ; tardiness += hours * 60 + (double) minutes;
} }
} }
Objectives[i]=tardiness; Objectives[i] = tardiness;
chromosome.setDelayTime(tardiness); chromosome.setDelayTime(tardiness);
} }
if(config.getName()==GlobalParam.OBJECTIVE_SETUP_TIME) if (config.getName() == GlobalParam.OBJECTIVE_SETUP_TIME) {
{
// 3. 最小总换型时间 // 3. 最小总换型时间
double totalSetupTime = calculateTotalSetupTime(chromosome); double totalSetupTime = calculateTotalSetupTime(chromosome);
chromosome.setTotalChangeoverTime(totalSetupTime); chromosome.setTotalChangeoverTime(totalSetupTime);
Objectives[i]=totalSetupTime; Objectives[i] = totalSetupTime;
} }
if(config.getName()==GlobalParam.OBJECTIVE_FLOW_TIME) if (config.getName() == GlobalParam.OBJECTIVE_FLOW_TIME) {
{
// 4. 最小化总流程时间 所有工序加工时间的总和 // 4. 最小化总流程时间 所有工序加工时间的总和
double totalFlowTime = calculateTotalFlowTime(chromosome); double totalFlowTime = calculateTotalFlowTime(chromosome);
chromosome.setTotalFlowTime(totalFlowTime); chromosome.setTotalFlowTime(totalFlowTime);
Objectives[i]=totalFlowTime; Objectives[i] = totalFlowTime;
} }
if(config.getName()==GlobalParam.OBJECTIVE_MACHINE_LOAD) if (config.getName() == GlobalParam.OBJECTIVE_MACHINE_LOAD) {
{
// 5. 机器负载均衡 // 5. 机器负载均衡
double machineLoadBalance = calculateMachineLoadBalance(chromosome); double machineLoadBalance = calculateMachineLoadBalance(chromosome);
chromosome.setMachineLoadStd(machineLoadBalance); chromosome.setMachineLoadStd(machineLoadBalance);
Objectives[i]=machineLoadBalance; Objectives[i] = machineLoadBalance;
} }
i++; i++;
} }
} }
chromosome.setObjectives(Objectives); chromosome.setObjectives(Objectives);
FitnessCalculator fitnessCalculator=new FitnessCalculator(); FitnessCalculator fitnessCalculator = new FitnessCalculator();
if (chromosome.getFitnessLevel()==null) {
chromosome.setFitnessLevel(fitnessCalculator.calculateFitness(chromosome, _globalParam)); chromosome.setFitnessLevel(fitnessCalculator.calculateFitness(chromosome, _globalParam));
}
} }
private double calculateTotalFlowTime(Chromosome chromosome) { private double calculateTotalFlowTime(Chromosome chromosome) {
......
...@@ -111,7 +111,7 @@ int opcount=allOperations.size(); ...@@ -111,7 +111,7 @@ int opcount=allOperations.size();
// 初始化变邻域搜索 // 初始化变邻域搜索
_vns = new VariableNeighborhoodSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights); _vns = new VariableNeighborhoodSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_hillClimbing = new HillClimbing(allOperations); _hillClimbing = new HillClimbing(allOperations);
_simulatedAnnealing = new SimulatedAnnealing(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights); _simulatedAnnealing = new SimulatedAnnealing( allOperations);
_parallelLocalSearch = new ParallelLocalSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights); _parallelLocalSearch = new ParallelLocalSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_tabuSearch = new TabuSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights); _tabuSearch = new TabuSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_tabuSearchWithSA = new TabuSearchWithSA(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights); _tabuSearchWithSA = new TabuSearchWithSA(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
...@@ -142,7 +142,7 @@ int opcount=allOperations.size(); ...@@ -142,7 +142,7 @@ int opcount=allOperations.size();
// 步骤2:对初始种群进行爬山法局部优化 // 步骤2:对初始种群进行爬山法局部优化
if(population.size()<5||opcount<10 ) { if(opcount<20 ) {
FileHelper.writeLogFile("爬山法局部优化-----------开始-------"); FileHelper.writeLogFile("爬山法局部优化-----------开始-------");
GeneticDecoder hillClimbingDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId); GeneticDecoder hillClimbingDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
...@@ -156,7 +156,7 @@ int opcount=allOperations.size(); ...@@ -156,7 +156,7 @@ int opcount=allOperations.size();
// 步骤2:对初始种群进行模拟退火+爬山法优化 // 步骤2:对初始种群进行模拟退火+爬山法优化
GeneticDecoder saDecoder1 = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId); GeneticDecoder saDecoder1 = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
if(population.size()>5||opcount<2000 ) { if(opcount<800 ) {
FileHelper.writeLogFile("模拟退火+爬山法优化-----------开始-------"); FileHelper.writeLogFile("模拟退火+爬山法优化-----------开始-------");
Chromosome saHcOptimized = _simulatedAnnealing.batchSearchGetMax(population, saDecoder1, machines); Chromosome saHcOptimized = _simulatedAnnealing.batchSearchGetMax(population, saDecoder1, machines);
FileHelper.writeLogFile("模拟退火+爬山法优化-----------结束-------"); FileHelper.writeLogFile("模拟退火+爬山法优化-----------结束-------");
......
...@@ -934,6 +934,9 @@ public class MachineCalculator { ...@@ -934,6 +934,9 @@ public class MachineCalculator {
LocalDateTime end) { LocalDateTime end) {
CopyOnWriteArrayList<TimeSegment> conflictIntervals = new CopyOnWriteArrayList<>(); CopyOnWriteArrayList<TimeSegment> conflictIntervals = new CopyOnWriteArrayList<>();
// 1. 维护窗口冲突(优化重叠判断,更严谨) // 1. 维护窗口冲突(优化重叠判断,更严谨)
if (machine.getMaintenanceWindows() != null && !machine.getMaintenanceWindows().isEmpty()) { if (machine.getMaintenanceWindows() != null && !machine.getMaintenanceWindows().isEmpty()) {
// 过滤重叠的维护窗口并转换为TimeSegment // 过滤重叠的维护窗口并转换为TimeSegment
......
...@@ -474,18 +474,18 @@ public class OrderSortService { ...@@ -474,18 +474,18 @@ public class OrderSortService {
if (!Objects.equals(prev.getSerie(), order.getSerie())) flags.append("serie变 "); if (!Objects.equals(prev.getSerie(), order.getSerie())) flags.append("serie变 ");
if (!Objects.equals(prev.getMaterialCode(), order.getMaterialCode())) flags.append("material变"); if (!Objects.equals(prev.getMaterialCode(), order.getMaterialCode())) flags.append("material变");
} }
costLog.append(String.format(" %2d. %s, routingId=%s, serie=%s, materialCode=%s, cost=%.0f %s\n", // costLog.append(String.format(" %2d. %s, routingId=%s, serie=%s, materialCode=%s, cost=%.0f %s\n",
(i + 1), // (i + 1),
order.getOrderCode(), // order.getOrderCode(),
order.getRoutingId(), // order.getRoutingId(),
order.getSerie(), // order.getSerie(),
order.getMaterialCode(), // order.getMaterialCode(),
costToPrev, // costToPrev,
flags.toString())); // flags.toString()));
totalCost += costToPrev; totalCost += costToPrev;
} }
costLog.append(String.format("[换线明细] 总换线成本 = %.0f\n", totalCost)); // costLog.append(String.format("[换线明细] 总换线成本 = %.0f\n", totalCost));
log.debug(costLog.toString()); // log.debug(costLog.toString());
// ================================== // ==================================
// 为最小化换线后的订单分配层级序号 // 为最小化换线后的订单分配层级序号
......
...@@ -29,6 +29,8 @@ public class TabuSearch { ...@@ -29,6 +29,8 @@ public class TabuSearch {
this.fitnessCalculator = fitnessCalculator; this.fitnessCalculator = fitnessCalculator;
this.objectiveWeights = objectiveWeights; this.objectiveWeights = objectiveWeights;
this.tabuList = new ArrayList<>(); this.tabuList = new ArrayList<>();
// 工序越多,禁忌表越长(适配1000+工序)
this.tabuListSize = Math.min(50, allOperations.size() / 30);
} }
/** /**
......
...@@ -39,8 +39,8 @@ public class PlanResultServiceTest { ...@@ -39,8 +39,8 @@ public class PlanResultServiceTest {
// TestSortService sortService=new TestSortService(); // TestSortService sortService=new TestSortService();
// sortService.test1(); // sortService.test1();
// nsgaiiUtils.Test(); // nsgaiiUtils.Test();
// planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4");//2000 planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4");//2000
planResultService.execute2("C8B533BD8944405B9A2F8823C575C204");//500 // planResultService.execute2("C8B533BD8944405B9A2F8823C575C204");//500
// planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");//20 // planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");//20
// planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D"); // planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment