Commit f2a1529b authored by Tong Li's avatar Tong Li

Merge remote-tracking branch 'origin/tl'

parents bb00017a f1998b61
......@@ -32,6 +32,11 @@ public class Chromosome {
/// </summary>
private List<Integer> machineSelection;
// 缓存标记
private transient boolean machineStrDirty = true;
private transient boolean operationStrDirty = true;
private transient boolean geneStrDirty = true;
/// <summary>
/// 工序排序部分(工件/订单ID)
/// </summary>
......@@ -43,7 +48,10 @@ public class Chromosome {
private String geneStr;
public String getGeneStr() {
geneStr=getMachineStr()+"_"+getOperationStr();
if (geneStrDirty || machineStrDirty || operationStrDirty) {
geneStr = getMachineStr() + "_" + getOperationStr();
geneStrDirty = false;
}
return geneStr;
}
......@@ -51,26 +59,44 @@ public class Chromosome {
public String getMachineStr() {
machineStr= Optional.ofNullable(machineSelection)
if (machineStrDirty) {
machineStr = Optional.ofNullable(machineSelection)
.orElse(Collections.emptyList())
.stream()
.map(String::valueOf) // Integer转String
.map(String::valueOf)
.collect(Collectors.joining(","));
machineStrDirty = false;
geneStrDirty = true;
}
return machineStr;
}
public String getOperationStr() {
operationStr= Optional.ofNullable(operationSequencing)
if (operationStrDirty) {
operationStr = Optional.ofNullable(operationSequencing)
.orElse(Collections.emptyList())
.stream()
.map(String::valueOf) // Integer转String
.map(String::valueOf)
.collect(Collectors.joining(","));
operationStrDirty = false;
geneStrDirty = true;
}
return operationStr;
}
// 重写 setter 方法,在设置时标记为脏
public void setMachineSelection(List<Integer> machineSelection) {
this.machineSelection = machineSelection;
this.machineStrDirty = true;
this.geneStrDirty = true;
}
public void setOperationSequencing(List<Integer> operationSequencing) {
this.operationSequencing = operationSequencing;
this.operationStrDirty = true;
this.geneStrDirty = true;
}
......
......@@ -15,7 +15,7 @@ public class ScheduleParams {
// 基础参数(自适应调整的基准值)
private static final int MIN_POPULATION_SIZE = 10;
private static final int MAX_POPULATION_SIZE = 50;
private static final int MAX_POPULATION_SIZE = 20;
private static final int MIN_MAX_ITERATIONS = 50;
private static final int MAX_MAX_ITERATIONS = 100;
private static final float MIN_CROSSOVER_PROB = 0.6f;
......@@ -172,10 +172,14 @@ public class ScheduleParams {
// 1. 种群大小:50 ~ 500,随工序数线性增加
populationSize = (int) Math.max(MIN_POPULATION_SIZE,
Math.min(MAX_POPULATION_SIZE, MIN_POPULATION_SIZE + totalOps * populationSizeCoeff));
int maxthead= Runtime.getRuntime().availableProcessors() - 1;
populationSize= populationSize / maxthead*maxthead;
// 确保偶数(方便交叉)
if (populationSize % 2 != 0) {
populationSize += 1;
}
// if (populationSize % 2 != 0) {
// populationSize += 1;
// }
// 2. 最大迭代次数:50 ~ 200,随工序数线性减少
maxIterations = (int) Math.max(MIN_MAX_ITERATIONS,
......
......@@ -73,11 +73,11 @@ public class GlobalParam {
public GlobalParam() {
// 初始化默认目标值配置
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_MAKESPAN, true, 1, 0.6));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_FLOW_TIME, false, 2, 0.1));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_MAKESPAN, true, 1, 0.3));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_FLOW_TIME, true, 2, 0.1));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_SETUP_TIME, true, 2, 0.1));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_MACHINE_LOAD, false, 3, 0.1));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_TARDINESS, true, 1, 0.3));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_MACHINE_LOAD, true, 1, 0.1));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_TARDINESS, true, 1, 0.6));
objectiveConfigs.sort(Comparator.comparing((ObjectiveConfig op) -> op.getLevel()));
}
......
package com.aps.entity.basic;
/**
* 作者:佟礼
* 时间:2026-04-09
*/
public class KpiTargetConfig {
}
......@@ -157,6 +157,11 @@ public class Order {
*/
private boolean newCreate = false;
/**
* 是否新创建半成品,默认值:false
*/
private boolean newSfCreate = false;
/**
* 是否创建BOM,默认值:false
*/
......
......@@ -21,8 +21,10 @@ public class FitnessCalculator {
ArrayList<Double> list = new ArrayList<>();
double fitness=0;
double total=0;
int i=0;
int level=-1;
double[] weightedObjectives=new double[chromosome.getObjectives().length];
for (ObjectiveConfig config : param.getObjectiveConfigs()) {
if( config.isEnabled()) {
......@@ -65,7 +67,9 @@ public class FitnessCalculator {
if (!param.isPureNSGAIIMode()) {
val = val * config.getWeight();
}
weightedObjectives[i]=val;
fitness += val;
total+=val;
i++;
}
}
......@@ -87,6 +91,8 @@ public class FitnessCalculator {
// fitness ≈ 0.01
// 适应度值(越大越好)
chromosome.setFitness(total);
chromosome.setWeightedObjectives(weightedObjectives);
return list.stream().mapToDouble(Double::doubleValue).toArray();
}
......@@ -147,7 +153,7 @@ public class FitnessCalculator {
// 2. 计算每个个体与平均值的平方差之和
float sumSqDiff = 0.0f;
for (Chromosome chromosome : population) {
double diff = chromosome.getWeightedObjective() - avgFitness;
double diff = chromosome.getFitness() - avgFitness;
sumSqDiff += diff * diff;
}
......@@ -155,6 +161,19 @@ public class FitnessCalculator {
return (double) Math.sqrt(sumSqDiff / popSize);
}
/**
* 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/
public boolean isBetter(Chromosome c1, Chromosome c2) {
for (int i = 0; i < c1.getFitnessLevel().length; i++) {
double[] Fitness1 = c1.getFitnessLevel();
double[] Fitness2 = c2.getFitnessLevel();
if (Fitness1[i] > Fitness2[i]) {
return true;
}
}
return false;
}
......
......@@ -425,7 +425,7 @@ public class GeneticAlgorithm {
// chromosome.setResultOld(new CopyOnWriteArrayList<>());
// }
decoder.decodeChromosomeWithCache(chromosome);
decoder.decodeChromosomeWithCache(chromosome,false);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights));
}
......
......@@ -88,17 +88,17 @@ public class GeneticDecoder {
{
FileHelper.writeLogFile("解码---------------"+population.size() );
boolean ismore=false;
boolean ismore=true;
if(ismore) {
CompletableFuture.allOf(population.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> decodeChromosomeWithCache(chromosome), decodeExecutor))
.map(chromosome -> CompletableFuture.runAsync(() -> decodeChromosomeWithCache(chromosome,false), decodeExecutor))
.toArray(CompletableFuture[]::new))
.join();
} else {
if (population != null && population.size() > 0) {
population.forEach(chromosome -> {
decodeChromosomeWithCache( chromosome);
decodeChromosomeWithCache( chromosome,false);
});
}
}
......@@ -176,7 +176,7 @@ public class GeneticDecoder {
// return chromosome;
// }
public Chromosome decodeChromosomeWithCache(Chromosome chromosome) {
public Chromosome decodeChromosomeWithCache(Chromosome chromosome,boolean isParallel) {
String cacheKey = createCacheKey(chromosome);
// FileHelper.writeLogFile("解码-----------开始-------"+chromosome.getID()+":"+cacheKey );
......@@ -214,7 +214,7 @@ public class GeneticDecoder {
return chromosome;
}
// 3. 缓存未命中:执行解码逻辑
decode(chromosome);
decode(chromosome,isParallel);
// 4. 将解码结果存入缓存(无锁,ConcurrentHashMap 线程安全)
decodingCache.putIfAbsent(cacheKey, chromosome);
......@@ -266,7 +266,7 @@ public class GeneticDecoder {
Initialization initialization=new Initialization();
initialization.generateInitialSFPopulation(chromosome,globalOpList);
chromosome.getGlobalOpList().addAll(globalOpList);
return 1;
return 1;
}
private void CreateNewOpSequence(Chromosome chromosome)
......@@ -279,10 +279,10 @@ return 1;
.distinct()
.collect(Collectors.toList());
if(finishedOrder==null||finishedOrder.size()==0)
{
if(finishedOrder==null||finishedOrder.size()==0)
{
return;
}
}
List<Integer> oldSequence=chromosome.getOperationSequencing();
List<Integer> finalSequence = new ArrayList<>();
......@@ -367,12 +367,11 @@ if(finishedOrder==null||finishedOrder.size()==0)
orderProcessCounter.put(orderid, scheduledCount);
}
public void decode(Chromosome chromosome) {
int operationCount = chromosome.getAllOperations().size();
int cpuCores = Runtime.getRuntime().availableProcessors();
public void decode(Chromosome chromosome,boolean isParallel) {
//
// // 根据工序数量和CPU核心数决定是否使用内部并行
if (operationCount > 5000 && cpuCores > 4) {
if (isParallel) {
// 使用设备并行处理
// FileHelper.writeLogFile("使用并行处理 _s");
parallelDecodeByMachine(chromosome);
......@@ -392,7 +391,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
public void serialDecode(Chromosome chromosome) {
// List<OrderMaterialRequirement> orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam);
List<OrderMaterialRequirement> orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam);
chromosome.setScenarioID(sceneId);
if(_globalParam.isIsCheckSf()) {
int isnew= generateGlobalOpList(chromosome);
......@@ -473,12 +472,15 @@ if(finishedOrder==null||finishedOrder.size()==0)
Map<Integer, Integer> orderLastEndTime = new HashMap<>();
Map<Integer, Entry> entryIndexById = new HashMap<>();
Map<Integer, List<Entry>> entrysBygroupId = new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById = new ConcurrentHashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
orderLastEndTime.putIfAbsent(groupId, 0);
entryIndexById.put(op.getId(),op);
entrysBygroupId.computeIfAbsent(groupId, k -> new ArrayList<>()).add(op);
//scheduleIndexById.put(op.getId(),null);
}
// Map<Long, String> machineState = chromosome.getMachines().stream()
......@@ -487,9 +489,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
// List<Entry> allScheduledOps = new ArrayList<>();
// 缓存机器任务
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache = new HashMap<>();
for (Entry op : allOperations) {
}
for (int groupId : chromosome.getOperationSequencing()) {
int scheduledCount = orderProcessCounter.get(groupId);
List<Entry> orderOps = entrysBygroupId.get(groupId).stream()
......@@ -555,7 +555,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
// Machine machine = machineIdMap.get(machineId);
// int changeoverTime =0; //(lastDiscreteParameter.isEmpty() ||
// lastDiscreteParameter.equals(currentOp.getDiscreteParameter())) ? 0 : 0;
int actualEndTime = processOperation(currentOp,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache);
int actualEndTime = processOperation(currentOp,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache,entryIndexById,scheduleIndexById);
// int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime,machineTasksCache);
orderProcessCounter.put(groupId, orderProcessCounter.get(groupId) + 1);
......@@ -570,131 +570,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
calculateScheduleResult(chromosome);
}
public void parallelDecode(Chromosome chromosome) {
FileHelper.writeLogFile("构建工序依赖图 _s");
// 1. 构建工序依赖图
Map<Integer, List<Integer>> dependencyGraph = buildDependencyGraph(chromosome);
FileHelper.writeLogFile("拓扑排序 _s");
// 2. 拓扑排序
List<Integer> topologicalOrder = topologicalSort(dependencyGraph,chromosome);
FileHelper.writeLogFile("按设备分组 _s");
// 3. 按设备分组
Map<Long, List<Integer>> machineToOpsMap = new HashMap<>();
Map<Integer, Integer> opToGroupIdMap = new HashMap<>();
Map<Integer, Long> opToMachineMap = new HashMap<>();
List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList();
// 步骤1:生成“工序→机器/加工时间”映射
List<OpMachine> opMachineMap = new ArrayList<>();
Map<String, OpMachine> opMachineKeyMap = new HashMap<>();
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache = new HashMap<>();
Map<Long, Machine> machineIdMap = chromosome.getMachines().stream()
.collect(Collectors.toMap(Machine::getId, m -> m));
// 构建工序ID索引:opId -> Entry(O(1)查找)
Map<Integer, Entry> opIdIndex = buildOpIdIndex(chromosome);
for (GlobalOperationInfo globalOp : globalOpList) {
int globalOpId = globalOp.getGlobalOpId();
Entry op = globalOp.getOp();
int groupId = globalOp.getGroupId();
int sequence = globalOp.getSequence();
// 从MachineSelection中获取当前工序的机器选择顺序号
int machineSeq = chromosome.getMachineSelection().get(globalOpId);
List<MachineOption> optionalMachines = op.getMachineOptions();
// 验证:机器顺序号必须在可选范围内
if (machineSeq < 1 || machineSeq > optionalMachines.size()) {
throw new IllegalStateException(String.format(
"全局工序%d(订单%d工序%d)的机器顺序号%d超出范围(1-%d)",
globalOpId, groupId, sequence, machineSeq, optionalMachines.size()));
}
// 获取选择的设备ID和加工时间
MachineOption selectedMachine = optionalMachines.get(machineSeq - 1);
OpMachine opMachine=new OpMachine();
opMachine.setGroupId(groupId);
opMachine.setSequence(sequence);
opMachine.setMachineId(selectedMachine.getMachineId());
opMachine.setProcessingTime(selectedMachine.getProcessingTime());
opMachine.setRuntime(selectedMachine.getRuntime());
opMachine.setSingleOut(selectedMachine.getSingleOut());
opMachineMap.add(opMachine);
String key = opMachine.getGroupId() + "_" + opMachine.getSequence();
opMachineKeyMap.put(key, opMachine);
}
FileHelper.writeLogFile("预处理工序信息 _s");
// 预处理工序信息
for (int opId : topologicalOrder) {
// Entry op = findOperationById(chromosome, opId);
Entry op = opIdIndex.get(opId);
if (op != null) {
// 假设已经为工序分配了设备
String opMachineKey = op.getGroupId() + "_" + op.getSequence();
OpMachine machineOption = opMachineKeyMap.get(opMachineKey);
if (machineOption != null) {
machineToOpsMap.computeIfAbsent(machineOption.getMachineId(), k -> new ArrayList<>()).add(opId);
opToGroupIdMap.put(opId, op.getGroupId());
opToMachineMap.put(opId, machineOption.getMachineId());
}
}
}
// 4. 并行处理
Map<Integer, CompletableFuture<Void>> opFutures = new HashMap<>();
Map<Long, CompletableFuture<Void>> machineFutures = new HashMap<>();
FileHelper.writeLogFile("并行处理 _s");
for (int opId : topologicalOrder) {
// 获取当前工序的依赖
// Entry op = findOperationById(chromosome, opId);
Entry op = opIdIndex.get(opId);
List<Integer> dependencies = dependencyGraph.getOrDefault(opId, Collections.emptyList());
// 等待所有依赖完成
List<CompletableFuture<Void>> dependencyFutures = dependencies.stream()
.map(opFutures::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
String opMachineKey = op.getGroupId() + "_" + op.getSequence();
OpMachine machineOption = opMachineKeyMap.get(opMachineKey);
Long machineId = machineOption.getMachineId();
double processTime = machineOption.getProcessingTime();
// 等待当前设备的上一个工序完成
CompletableFuture<Void> machineFuture = machineFutures.getOrDefault(machineId, CompletableFuture.completedFuture(null));
// 合并所有依赖
List<CompletableFuture<Void>> allDependencies = new ArrayList<>(dependencyFutures);
allDependencies.add(machineFuture);
// 创建当前工序的处理任务
CompletableFuture<Void> currentFuture = CompletableFuture.allOf(allDependencies.toArray(new CompletableFuture[0]))
.thenRunAsync(() -> {
// 处理当前工序
int actualEndTime = processOperation(op,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache);
});
// 保存当前工序的Future
opFutures.put(opId, currentFuture);
// 更新设备的Future
machineFutures.put(machineId, currentFuture);
}
// 等待所有工序完成
CompletableFuture.allOf(opFutures.values().toArray(new CompletableFuture[0])).join();
FileHelper.writeLogFile("calculateScheduleResult _s");
if(chromosome.getReOrderids()!=null&&chromosome.getReOrderids().size()>0) {
chromosome.getOperationSequencing().removeIf(t -> chromosome.getReOrderids().contains(t));
}
calculateScheduleResult(chromosome);
}
public void parallelDecodeByMachine(Chromosome chromosome) {
// 1. 获取工序处理顺序
List<Integer> operationSequencing = chromosome.getOperationSequencing();
......@@ -748,9 +624,15 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 初始化订单处理计数器
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
Map<Integer, Entry> entryIndexById = new HashMap<>();
Map<Integer, List<Entry>> entrysBygroupId = new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById= new ConcurrentHashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
entryIndexById.put(op.getId(),op);
entrysBygroupId.computeIfAbsent(groupId, k -> new ArrayList<>()).add(op);
}
Map<Long, List<Entry>> machineToOpsMap = new HashMap<>();
//按照 OperationSequencing 顺序生成 machineToOpsMap
......@@ -886,11 +768,11 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 工序超过500的设备直接在主线程串行处理
if (ops.size() > 500) {
// FileHelper.writeLogFile("设备 " + machineId + " 有 " + ops.size() + " 个工序,直接串行处理");
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock, opMachineKeyMap, machineIdMap, machineTasksCache);
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock, opMachineKeyMap, machineIdMap, machineTasksCache, entryIndexById,scheduleIndexById);
} else {
// 工序少的设备创建线程处理
Thread thread = new Thread(() -> {
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock, opMachineKeyMap, machineIdMap, machineTasksCache);
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock, opMachineKeyMap, machineIdMap, machineTasksCache, entryIndexById,scheduleIndexById);
});
thread.start();
threads.add(thread);
......@@ -920,7 +802,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
*/
private void processMachineOps(Chromosome chromosome, Long machineId, List<Entry> ops,
Map<Integer, List<Integer>> dependencyGraph,
Map<Integer, Boolean> opCompleted, Object lock,Map<String, OpMachine> opMachineKeyMap,Map<Long, Machine> machineIdMap,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
Map<Integer, Boolean> opCompleted, Object lock,Map<String, OpMachine> opMachineKeyMap,Map<Long, Machine> machineIdMap,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
//long machineStartTime = System.currentTimeMillis();
for (int i = 0; i < ops.size(); i++) {
......@@ -956,7 +838,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 处理当前工序
// long processStartTime = System.currentTimeMillis();
int actualEndTime = processOperation(op,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache);
int actualEndTime = processOperation(op,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache, entryIndexById,scheduleIndexById);
// long processEndTime = System.currentTimeMillis();
......@@ -1114,7 +996,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
private int processOperation(Entry currentOp,Long machineId,double processTime,OpMachine machineOption,Chromosome chromosome,Map<Long, Machine> machineIdMap,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache)
private int processOperation(Entry currentOp,Long machineId,double processTime,OpMachine machineOption,Chromosome chromosome,Map<Long, Machine> machineIdMap,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById)
{
Machine targetMachine = machineIdMap.get(machineId);
......@@ -1123,7 +1005,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
int teardownTime = currentOp.getTeardownTime();
if (!currentOp.getPrevEntryIds().isEmpty()) {
// 处理多个前工序
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine);
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine,entryIndexById, scheduleIndexById);
}
int bomtime = getOperationBOMTime(currentOp,chromosome);
......@@ -1131,14 +1013,14 @@ if(finishedOrder==null||finishedOrder.size()==0)
int prevendtime=prevtime;
prevtime = Math.max(prevtime, bomtime);
Machine machine = machineIdMap.get(machineId);
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime,machineTasksCache);
return actualEndTime;
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime,machineTasksCache,entryIndexById, scheduleIndexById);
return actualEndTime;
}
private int processWithSingleMachine(Entry operation, Machine machine, double processingTime,
int prevOperationEndTime,OpMachine machineOption, Chromosome chromosome,boolean calbom,int prevendtime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
int prevOperationEndTime,OpMachine machineOption, Chromosome chromosome,boolean calbom,int prevendtime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
int processingTimeTotal=0;
int earliestStartTime = prevOperationEndTime;
if(operation.getConstTime()==1)//常数时间
......@@ -1239,7 +1121,7 @@ return actualEndTime;
: earliestStartTime;
}
bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache);
bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache, entryIndexById, scheduleIndexById);
if(bomtime>prevendtime&&bomtime<earliestStartTimeold)
......@@ -1394,7 +1276,7 @@ return actualEndTime;
if (machineTasks != null) {
machineTasks.add(result);
}
scheduleIndexById.put(operation.getId(),result);
return endTime;
}
......@@ -1405,16 +1287,18 @@ return actualEndTime;
* @param chromosome
* @return
*/
private int CalPrevtime(int prevtime,Entry currentOp,Chromosome chromosome,double processTime,Machine machine) {
private int CalPrevtime(int prevtime,Entry currentOp,Chromosome chromosome,double processTime,Machine machine,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
List<OperationDependency> FsOperations = currentOp.getPrevEntryIds().stream()
.filter(t -> t.getDependencyType() == DependencyType.FinishToStart)
.collect(Collectors.toList());//串行
if (FsOperations != null && FsOperations.size() > 0) {
for (OperationDependency opid : FsOperations) {
List<GAScheduleResult> prevOperations = chromosome.getResult().stream()
.filter(t -> t.getGroupId() == currentOp.getGroupId() && t.getOperationId() == opid.getPrevOperationId())
.collect(Collectors.toList());//多台
for (GAScheduleResult prevOp : prevOperations) {
// List<GAScheduleResult> prevOperations = chromosome.getResult().stream()
// .filter(t -> t.getOperationId() == opid.getPrevOperationId())
// .collect(Collectors.toList());//
GAScheduleResult prevOp= scheduleIndexById.get(opid.getPrevOperationId());
// for (GAScheduleResult prevOp : prevOperations) {
if(prevOp!=null){
//加上后处理时间
prevtime = Math.max(prevtime, prevOp.getEndTime() + currentOp.getTeardownTime());
}
......@@ -1431,10 +1315,13 @@ return actualEndTime;
for (int j=0;j<SSOperations.size();j++)
{
OperationDependency opid=SSOperations.get(j);
List<GAScheduleResult> prevOperations = chromosome.getResult().stream()
.filter(t -> t.getGroupId() == currentOp.getGroupId() && t.getOperationId() == opid.getPrevOperationId())
.collect(Collectors.toList());//多台
for (GAScheduleResult prevOp : prevOperations) {
// List<GAScheduleResult> prevOperations = chromosome.getResult().stream()
// .filter(t -> t.getOperationId() == opid.getPrevOperationId())
// .collect(Collectors.toList());//多台
GAScheduleResult prevOp= scheduleIndexById.get(opid.getPrevOperationId());
// for (GAScheduleResult prevOp : prevOperations) {
if(prevOp!=null){
newScheduleResult.add(prevOp);
newScheduleResultDetails.addAll(prevOp.getGeneDetails());
}
......@@ -1444,15 +1331,17 @@ return actualEndTime;
prevtime = Math.max(prevtime, prevtime1);
}else {
Entry entry= chromosome.getAllOperations().stream()
.filter(t->t.getId()==opid.getPrevOperationId())
.findFirst().orElse(null);
// Entry entry= chromosome.getAllOperations().stream()
// .filter(t->t.getId()==opid.getPrevOperationId())
// .findFirst().orElse(null);
Entry entry=entryIndexById.get(opid.getPrevOperationId());
OperationDependency opid2=SSOperations.get(j+1);
Entry entry1= chromosome.getAllOperations().stream()
.filter(t->t.getId()==opid2.getPrevOperationId())
.findFirst().orElse(null);
if(entry.getRoutingDetailId()!=entry1.getRoutingDetailId())
// Entry entry1= chromosome.getAllOperations().stream()
// .filter(t->t.getId()==opid2.getPrevOperationId())
// .findFirst().orElse(null);
Entry entry1=entryIndexById.get(opid2.getPrevOperationId());
//不是同一前工序,效率不能合并 newScheduleResult 清空,如何是一个工序就合并计算
if(entry!=null&&entry1!=null&&entry.getRoutingDetailId()!=entry1.getRoutingDetailId())
{
int prevtime1 = CalSSPrevtime(newScheduleResult,newScheduleResultDetails, prevtime, currentOp, chromosome, processTime, machine);
......@@ -1577,7 +1466,7 @@ return actualEndTime;
return Math.max(rawTime, sfTime);
}
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements();
......@@ -1585,13 +1474,13 @@ return actualEndTime;
{
return 0;
}
LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime);
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache);
return getOperationBOMTime(currentOp, chromosome);
LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime);
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById, baseTime);
return getOperationBOMTime(currentOp, chromosome);
}
public void EditorderOperation(Chromosome chromosome, int groupId,double needed,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache){
public void EditorderOperation(Chromosome chromosome, int groupId,double needed,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById){
List<Entry> orderOps = chromosome.getAllOperations().stream()
.filter(t -> t.getGroupId() == groupId)
.sorted(Comparator.comparing(Entry::getSequence))
......@@ -1635,7 +1524,7 @@ return getOperationBOMTime(currentOp, chromosome);
int teardownTime = currentOp.getTeardownTime();
if (!currentOp.getPrevEntryIds().isEmpty()) {
// 处理多个前工序
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine);
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine, entryIndexById,scheduleIndexById);
}
// 上个离散参数
......@@ -1650,7 +1539,7 @@ return getOperationBOMTime(currentOp, chromosome);
.findFirst()
.orElse(null);
// 缓存机器任务
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,opMachine, chromosome,true,prevendtime,machineTasksCache);
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,opMachine, chromosome,true,prevendtime,machineTasksCache, entryIndexById, scheduleIndexById);
}
......@@ -1687,10 +1576,10 @@ return getOperationBOMTime(currentOp, chromosome);
&& t.getProductOrderID() != null && !t.getProductOrderID().isEmpty()
)
.collect(Collectors.toList());
if(MaterialRequirements==null||MaterialRequirements.size()==0)
{
if(MaterialRequirements==null||MaterialRequirements.size()==0)
{
continue;
}
}
for (OrderMaterialRequirement orderMaterial:MaterialRequirements) {
List<Integer> orderids= orderMaterial.getProductOrderID();
if(orderids!=null&&orderids.size()>0) {
......@@ -2443,7 +2332,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
.filter(t -> orderIds.contains(t.getOrderId()))
.max(Comparator.comparing(Order::getDueDate))
.orElse(null);
if (order.isNewCreate()) {
if (order.isNewSfCreate()) {
continue;
}
LocalDateTime dueDateTime = order.getDueDate();
......
......@@ -25,6 +25,10 @@ public class GeneticOperations {
private static ScheduleParams param;
public GeneticOperations() {
}
public GeneticOperations(GlobalParam globalParam,List<Entry> _allOperations,ScheduleParams _param) {
_GlobalParam=globalParam;
allOperations = _allOperations;
......@@ -424,10 +428,12 @@ public class GeneticOperations {
public void DelOrder(Chromosome chromosome) {
List<Entry> allOperations = chromosome.getAllOperations();
List<GlobalOperationInfo> globalOpList= chromosome.getGlobalOpList();
if(chromosome.getOrders()==null||chromosome.getOrders().size()==0)
return;
List<Order> orders = chromosome.getOrders();
List<Integer> OperationSequencing= chromosome.getOperationSequencing();
List<Integer> newoorderids= orders.stream()
.filter(t->t.isNewCreate())
.filter(t->t.isNewSfCreate())
.map(Order::getId)
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
......
package com.aps.service.Algorithm;
import com.aps.common.util.FileHelper;
import com.aps.common.util.GlobalCacheUtil;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
......@@ -21,6 +22,11 @@ public class HillClimbing {
private List<Entry> allOperations;
private List<Order> orders;
private List<Material> materials;
private List<GroupResult> _entryRel;
//按优先级分组工序
private Map<Double, List<Entry>> priorityGroups;
......@@ -30,10 +36,17 @@ public class HillClimbing {
// 从List转为Map op.getGroupId() + "_" + op.getSequence(); 做主键
private Map<String, Entry> entrys;
public HillClimbing(List<Entry> allOperations) {
private FitnessCalculator fitnessCalculator;
public HillClimbing(List<Entry> allOperations, List<Order> orders,
List<Material> materials,List<GroupResult> entryRel, FitnessCalculator _fitnessCalculator) {
this.allOperations = allOperations;
this.orders = orders;
this.materials = materials;
_entryRel=entryRel;
fitnessCalculator=_fitnessCalculator;
// 按优先级分组工序
priorityGroups = groupOperationsByPriority();
......@@ -92,7 +105,7 @@ public class HillClimbing {
Chromosome machineChange = generateMachineChange(current, op.getMachineOptions(), maPos);
if (machineChange != null) {
decode(decoder, machineChange);
decode(decoder, machineChange,machines);
if (isBetter(machineChange, current)) {
current = machineChange;
if (isBetter(current, best)) {
......@@ -263,7 +276,7 @@ public class HillClimbing {
Chromosome machineChange = generateMachineChange(current, op.getMachineOptions(), maPos);
if (machineChange != null) {
decode(decoder, machineChange);
decode(decoder, machineChange,machines);
if (isBetter(machineChange, current)) {
current = machineChange;
if (isBetter(current, best)) {
......@@ -328,7 +341,7 @@ public class HillClimbing {
}
Chromosome newChromosome = swapAtDistance(current, opPos, -s * step);
decode(decoder, newChromosome);
decode(decoder, newChromosome,machines);
if (isBetter(newChromosome, current)) {
current = newChromosome;
......@@ -357,7 +370,7 @@ public class HillClimbing {
}
Chromosome newChromosome = swapAtDistance(current, opPos, s * step);
decode(decoder, newChromosome);
decode(decoder, newChromosome,machines);
if (isBetter(newChromosome, current)) {
current = newChromosome;
......@@ -411,21 +424,24 @@ public class HillClimbing {
}
/**
* 构建位置索引:groupId_sequence -> position
*/
private Map<String, Integer> buildPositionIndex(Chromosome chromosome) {
String fitness="";
private void writeKpi(Chromosome chromosome) {
String fitness = "";
double[] fitness1 = chromosome.getFitnessLevel();
for (int i = 0; i < fitness1.length; i++) {
fitness+=fitness1[i]+",";
fitness += fitness1[i] + ",";
}
FileHelper.writeLogFile(String.format("爬山法 - kpi:%s", fitness));
}
/**
* 构建位置索引:groupId_sequence -> position
*/
private Map<String, Integer> buildPositionIndex(Chromosome chromosome) {
writeKpi(chromosome);
Map<String, Integer> index = new HashMap<>();
List<Integer> os = chromosome.getOperationSequencing();
......@@ -546,114 +562,6 @@ public class HillClimbing {
}
return neighbor;
}
/**
* 生成邻域解
*/
private List<Chromosome> generateNeighbors(Chromosome chromosome) {
List<Chromosome> neighbors = new ArrayList<>();
// 生成交换邻域
neighbors.add(generateSwapNeighbor(chromosome));
// 生成反转邻域
neighbors.add(generateReverseNeighbor(chromosome));
// 生成插入邻域
neighbors.add(generateInsertNeighbor(chromosome));
// 生成机器选择邻域
neighbors.add(generateMachineChangeNeighbor(chromosome));
return neighbors;
}
/**
* 生成交换邻域解
*/
private Chromosome generateSwapNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
while (idx2 == idx1) {
idx2 = rnd.nextInt(os.size());
}
java.util.Collections.swap(os, idx1, idx2);
neighbor.setOperationSequencing(os);
}
return neighbor;
}
/**
* 生成反转邻域解
*/
private Chromosome generateReverseNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int start = rnd.nextInt(os.size());
int end = rnd.nextInt(os.size());
while (end <= start) {
end = rnd.nextInt(os.size());
}
java.util.Collections.reverse(os.subList(start, end + 1));
neighbor.setOperationSequencing(os);
}
return neighbor;
}
/**
* 生成插入邻域解
*/
private Chromosome generateInsertNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
while (idx2 == idx1) {
idx2 = rnd.nextInt(os.size());
}
int value = os.remove(idx1);
os.add(idx2, value);
neighbor.setOperationSequencing(os);
}
return neighbor;
}
/**
* 生成机器选择邻域解
*/
private Chromosome generateMachineChangeNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> ms = neighbor.getMachineSelection();
List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList();
if (!ms.isEmpty()) {
int idx = rnd.nextInt(ms.size());
GlobalOperationInfo globalOp = globalOpList.get(idx);
Entry op = globalOp.getOp();
if (op.getMachineOptions().size() > 1) {
int currentMachineSeq = ms.get(idx);
List<Integer> availableMachines = new ArrayList<>();
for (int i = 1; i <= op.getMachineOptions().size(); i++) {
if (i != currentMachineSeq) {
availableMachines.add(i);
}
}
if (!availableMachines.isEmpty()) {
int newMachineSeq = availableMachines.get(rnd.nextInt(availableMachines.size()));
ms.set(idx, newMachineSeq);
neighbor.setMachineSelection(ms);
}
}
}
return neighbor;
}
/**
* 生成机器选择邻域解
*/
......@@ -703,11 +611,34 @@ public class HillClimbing {
/**
* 解码染色体
*/
private void decode(GeneticDecoder decoder, Chromosome chromosome) {
// chromosome.setResult(new java.util.concurrent.CopyOnWriteArrayList<>());
decoder.decodeChromosomeWithCache(chromosome);
private void decode(GeneticDecoder decoder, Chromosome chromosome , List<Machine> machines) {
chromosome.setResult(new CopyOnWriteArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setOrders(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(orders), Order.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setOperatRel(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(_entryRel), GroupResult.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setMaterials(ProductionDeepCopyUtil.deepCopyList(materials,Material.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(allOperations), Entry.class) ); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
// chromosome.setBaseTime(param.getBaseTime());
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
// 加载锁定工单到ResultOld
List<GAScheduleResult> lockedOrders = GlobalCacheUtil.get("locked_orders_" + chromosome.getScenarioID());
if (lockedOrders != null && !lockedOrders.isEmpty()) {
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(lockedOrders, GAScheduleResult.class));
FileHelper.writeLogFile("将 " + lockedOrders.size() + " 个锁定工单加载到初始种群中");
} else {
chromosome.setResultOld(new CopyOnWriteArrayList<>());
}
decoder.decodeChromosomeWithCache(chromosome,false);
}
/**
* 比较两个染色体的优劣
......
package com.aps.service.Algorithm;
import com.aps.common.util.DateTimeUtil;
import com.aps.common.util.DeepCopyUtil;
import com.aps.common.util.FileHelper;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.common.util.*;
import com.aps.entity.Algorithm.*;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.basic.*;
import com.aps.service.plan.MachineSchedulerService;
......@@ -55,11 +52,11 @@ public class HybridAlgorithm {
// 初始化算法实例
private HillClimbing _hillClimbing;
private SimulatedAnnealing _simulatedAnnealing;
private ParallelLocalSearch _parallelLocalSearch;
// 初始化算法实例
private TabuSearch _tabuSearch;
private TabuSearchWithSA _tabuSearchWithSA;
public HybridAlgorithm(GlobalParam globalParam,List<Machine> machines, List<Order> orders,
......@@ -109,18 +106,16 @@ int opcount=allOperations.size();
// 预生成全局工序列表(所有初始化方法共享同一顺序)
List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList();
// 初始化变邻域搜索
_vns = new VariableNeighborhoodSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_hillClimbing = new HillClimbing(allOperations);
_simulatedAnnealing = new SimulatedAnnealing( allOperations);
_parallelLocalSearch = new ParallelLocalSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_tabuSearch = new TabuSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_tabuSearchWithSA = new TabuSearchWithSA(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_vns = new VariableNeighborhoodSearch( allOperations,orders,materials,_entryRel, _fitnessCalculator );
_hillClimbing = new HillClimbing(allOperations,orders,materials,_entryRel, _fitnessCalculator);
_simulatedAnnealing = new SimulatedAnnealing( allOperations,orders,materials,_entryRel, _fitnessCalculator);
_tabuSearch = new TabuSearch(allOperations,orders,materials,_entryRel, _fitnessCalculator);
FileHelper.writeLogFile("初始化种群-----------开始-------");
// 步骤1:使用构造启发式算法生成初始种群
FileHelper.writeLogFile("构造启发式初始化-----------开始-------");
List<Chromosome> population = initialization.generateHeuristicInitialPopulation(param, globalOpList);
List<Chromosome> population = initialization.generateHeuristicInitialPopulation(param);
FileHelper.writeLogFile("构造启发式初始化-----------结束-------");
......@@ -138,15 +133,15 @@ int opcount=allOperations.size();
FileHelper.writeLogFile("按Objectives去重-----------开始-------" + population.size());
population = chromosomeDistinctByObjectives(population);
FileHelper.writeLogFile("按Objectives去重-----------结束-------" + population.size());
// if(1==1)
// return getBestChromosome(population.get(0), param.getBaseTime(), starttime);
// 步骤2:对初始种群进行爬山法局部优化
if(opcount<20 ) {
FileHelper.writeLogFile("爬山法局部优化-----------开始-------");
GeneticDecoder hillClimbingDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
Chromosome optimized = _hillClimbing.BatchSearchAll(population,machines, hillClimbingDecoder);
Chromosome optimized = _hillClimbing.search(population.get(0), hillClimbingDecoder,machines);
FileHelper.writeLogFile("爬山法局部优化-----------结束-------");
return getBestChromosome(optimized, param.getBaseTime(), starttime);
}
......@@ -156,27 +151,37 @@ int opcount=allOperations.size();
// 步骤2:对初始种群进行模拟退火+爬山法优化
GeneticDecoder saDecoder1 = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
GeneticDecoder vnsDecoder1 = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
GeneticDecoder tabuDecoder1 = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
if(opcount<800 ) {
FileHelper.writeLogFile("模拟退火+爬山法优化-----------开始-------");
Chromosome saHcOptimized = _simulatedAnnealing.batchSearchGetMax(population, saDecoder1, machines);
Chromosome saHcOptimized = _simulatedAnnealing.searchWithHillClimbing(population.get(0),_vns, saDecoder1, machines);
FileHelper.writeLogFile("模拟退火+爬山法优化-----------结束-------");
return getBestChromosome(saHcOptimized, param.getBaseTime(), starttime);
}
if(opcount>=800 ) {
Chromosome best=population.get(0);
best = _simulatedAnnealing.search(best, _tabuSearch, _vns, saDecoder1, machines);
best = _vns.search(best, vnsDecoder1, machines);
best = _tabuSearch.search(best, _vns, tabuDecoder1, machines);
return getBestChromosome(best, param.getBaseTime(), starttime);
}
List<List<Chromosome>> combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(population);
Chromosome best=ProductionDeepCopyUtil.deepCopy(population.get(0), Chromosome.class); // GetBest(combinedFronts,"初始");
int ordercount = globalOpList.stream()
.mapToInt(GlobalOperationInfo::getGroupId)
.max()
.orElse(0);
Chromosome best=GetBest(combinedFronts,"初始");
// best=fronts.get(0).stream()
// .max(Comparator.comparingDouble(Chromosome::getFitness))
// .orElse(null);
double bestFitness=best.getFitness();
if(population.size()<param.getTournamentSize())
{
......@@ -185,7 +190,8 @@ int opcount=allOperations.size();
}
int Iteration=0;
int noImproveCount = 0;
int maxNoImprove = 10;
// 步骤2:迭代进化
FileHelper.writeLogFile("迭代进化-----------开始-------"+param.getMaxIterations());
for (int iter = 0; iter < param.getMaxIterations(); iter++) {
......@@ -193,6 +199,7 @@ int opcount=allOperations.size();
FileHelper.writeLogFile("迭代进化------"+iter+"-----开始-------");
// 计算种群适应度标准差,微调参数
double fitnessStd = _fitnessCalculator.calculateFitnessStd(population);
param.fineTuneParams(iter, fitnessStd);
......@@ -204,141 +211,62 @@ int opcount=allOperations.size();
}
FileHelper.writeLogFile("选择操作-----------开始-------");
// 选择前移除适应度为 0 或明显劣于当前最优解的个体,减少选择池规模:
double minValidFitness = bestFitness * 0.5; // 保留最优解50%以上的个体
List<Chromosome> validPopulation = population.stream()
.filter(c -> c.getFitness() >= minValidFitness)
.collect(Collectors.toList());
// 选择操作
List<Chromosome> selected = geneticOps.tournamentSelection(validPopulation);
List<Chromosome> selected = geneticOps.tournamentSelection(population);
FileHelper.writeLogFile("选择操作-----------结束-------");
// 变邻域搜索
FileHelper.writeLogFile("变邻域搜索-----------开始-------");
GeneticDecoder vnsDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> vnsImproved = _vns.search(selected, vnsDecoder, param);
selected.addAll(vnsImproved);
FileHelper.writeLogFile("变邻域搜索-----------结束-------");
// 模拟退火全局搜索
FileHelper.writeLogFile("模拟退火搜索-----------开始-------");
GeneticDecoder saDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> saImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
// Chromosome saOptimized = _simulatedAnnealing.search(chromosome, saDecoder, param);
// saImproved.add(saOptimized);
}
selected.addAll(saImproved);
FileHelper.writeLogFile("模拟退火搜索-----------结束-------");
// 多种局部搜索算法并行
FileHelper.writeLogFile("并行局部搜索-----------开始-------");
GeneticDecoder parallelDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> parallelImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
Chromosome parallelOptimized = _parallelLocalSearch.search(chromosome, parallelDecoder, param);
parallelImproved.add(parallelOptimized);
}
selected.addAll(parallelImproved);
FileHelper.writeLogFile("并行局部搜索-----------结束-------");
// 禁忌搜索+模拟退火
FileHelper.writeLogFile("禁忌搜索+模拟退火-----------开始-------");
GeneticDecoder tsDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> tsImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
Chromosome tsOptimized = _tabuSearchWithSA.search(chromosome, tsDecoder, param);
tsImproved.add(tsOptimized);
}
selected.addAll(tsImproved);
FileHelper.writeLogFile("禁忌搜索+模拟退火-----------结束-------");
// 交叉操作
FileHelper.writeLogFile("交叉操作-----------开始-------");
List<Chromosome> nextPopulation = new ArrayList<>();
for (int i = 0; i < selected.size(); i += 2) {
if (i + 1 >= selected.size()) {
selected.get(i).setID(UUID.randomUUID().toString());
nextPopulation.add(selected.get(i));
break;
}
Chromosome parent1 = selected.get(i);
Chromosome parent2 = selected.get(i + 1);
if (rnd.nextDouble() < param.getCrossoverProb()) {
// 假设PoxCrossover返回包含两个子染色体的数组
Pair<Chromosome, Chromosome> children = geneticOps.poxCrossover(parent1, parent2, ordercount);
nextPopulation.add(children.getFirst());
nextPopulation.add(children.getSecond());
} else {
nextPopulation.add(parent1);
nextPopulation.add(parent2);
}
}
FileHelper.writeLogFile("交叉操作-----------结束-------");
FileHelper.writeLogFile("变异操作-----------开始-------");
// 变异操作
List<Chromosome> nextPopulation1 = new ArrayList<>();
for (Chromosome chromosome : nextPopulation) {
if (rnd.nextDouble() < param.getMutationProb()) {
Chromosome chromosome1= ProductionDeepCopyUtil.deepCopy(chromosome,Chromosome.class);
chromosome1.setID(UUID.randomUUID().toString());
geneticOps.mutate(chromosome1, globalOpList);
nextPopulation1.add(chromosome1);
}
}
nextPopulation.addAll(nextPopulation1);
FileHelper.writeLogFile("变异操作-----------结束-------");
FileHelper.writeLogFile("变异批量解码-----------开始-------");
List<Chromosome> newPopulation = new ArrayList<>();
newPopulation.add(best);
int n=0;
while (newPopulation.size() < param.getPopulationSize()) {
// 选择父代
FileHelper.writeLogFile("交叉-----------开始-------"+n);
Chromosome parent1 = selected.get(rnd.nextInt(selected.size()));
Chromosome parent2 = selected.get(rnd.nextInt(selected.size()));
// 交叉
Chromosome child = parent1;
// if (rnd.nextDouble() < param.getCrossoverProb()) {
// // 假设PoxCrossover返回包含两个子染色体的数组
// Pair<Chromosome, Chromosome> children = geneticOps.poxCrossover(parent1, parent2, ordercount);
// child=children.getFirst();
// initDataToChromosome(child,param, allOperations,globalOpList);
// child.setID(UUID.randomUUID().toString());
// }
// // 变异
// if (rnd.nextDouble() < param.getMutationProb()) {
// geneticOps.mutate(child, globalOpList);
// }
// 核心融合链(工业级标准顺序:GA生成子代 → SA跳坑 → VNS扩邻域 → TS精优化)
child = _simulatedAnnealing.search(child,_tabuSearch,_vns, saDecoder1, machines);
child = _vns.search(child, vnsDecoder1, machines);
child = _tabuSearch.search(child, _vns,tabuDecoder1, machines);
Chromosomedecode(param,allOperations,globalOpList,nextPopulation);
FileHelper.writeLogFile("变异批量解码-----------结束-------");
// // 精英保留
// List<Chromosome> population1 = population.stream()
// .sorted((c1, c2) -> Double.compare(c2.getFitness(), c1.getFitness()))
// .collect(Collectors.toList()); // 降序排序
//
//
// List<Chromosome> elites = population1.subList(0, param.getElitismCount());
newPopulation.add(child);
List<Chromosome> newPopulation = new ArrayList<>();
//保留一定数量的上一代
List<Chromosome> populationcopy = _nsgaIIUtils.selectNextPopulation(combinedFronts, param.getPopulationSize()/5);
newPopulation.addAll(populationcopy);
newPopulation.addAll(nextPopulation);
newPopulation= chromosomeDistinct1(newPopulation);
FileHelper.writeLogFile("非支配排序-----------开始-------");
// 2.7 非支配排序
combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(newPopulation);
FileHelper.writeLogFile("非支配排序-----------结束-------");
// 2.8 选择下一代种群
population = _nsgaIIUtils.selectNextPopulation(combinedFronts, param.getPopulationSize());
// 更新种群
// population = newPopulation.stream()
// .limit(param.getPopulationSize() )
// .collect(Collectors.toList());
FileHelper.writeLogFile("交叉-----------结束-------"+n);
}
population= chromosomeDistinctByObjectives(newPopulation);;
best= GetBest(combinedFronts,String.valueOf(iter));
if(bestFitness<best.getFitness())
if(_fitnessCalculator.isBetter(population.get(0),best))
{
bestFitness=best.getFitness();
Iteration=1;
best=ProductionDeepCopyUtil.deepCopy(population.get(0), Chromosome.class); // GetBest(combinedFronts,"初始");
noImproveCount=1;
}else {
Iteration++;
if (Iteration > 5) {
noImproveCount++;
if (noImproveCount > 5) {
// 当连续 5 代无最优解提升时,降低交叉概率(如从 0.8 降至 0.5)、提高变异概率(如从 0.1 升至 0.2)
param.fineTuneParams();
}
}
if(Iteration>10)
if(noImproveCount>maxNoImprove)
{
break;
}
......@@ -379,18 +307,7 @@ int opcount=allOperations.size();
return best;
}
private Chromosome GetBest(List<List<Chromosome>> fronts,String msg)
{
// WriteKpis(fronts,msg);
List<Chromosome> fChromosomes= fronts.get(0);
fChromosomes.sort((c1, c2) -> {
int rankCompare = Double.compare(c1.getCrowdingDistance(), c2.getCrowdingDistance());
return rankCompare != 0 ? rankCompare : Double.compare(c1.getFitness(), c2.getFitness());
});
Chromosome best=fChromosomes.get(0);
// WriteKpi(best,"最大");
return best;
}
private List<Chromosome> chromosomeDistinct(List<Chromosome> population)
{
if(population==null)
......@@ -413,7 +330,7 @@ int opcount=allOperations.size();
}
/**
* 按Objectives去重,相同目标值的方案只保留一个(保留fitness最大的)
* 按Objectives去重
*/
private List<Chromosome> chromosomeDistinctByObjectives(List<Chromosome> population)
{
......@@ -440,34 +357,36 @@ int opcount=allOperations.size();
}
}
return new ArrayList<>(objectivesMap.values());
// 按 fitnessLevel 倒序排序(多层次比较)
List<Chromosome> result = new ArrayList<>(objectivesMap.values());
result.sort((c1, c2) -> {
if (isBetter(c1, c2)) {
return -1; // c1 比 c2 好,c1 应该排在前面
} else if (isBetter(c2, c1)) {
return 1; // c2 比 c1 好,c2 应该排在前面
} else {
return 0; // 两者相等
}
});
private List<Chromosome> chromosomeDistinct1(List<Chromosome> population)
{
if(population==null)
{
FileHelper.writeLogFile(String.format("排产-----------方案数量---%d-------",0 ));
return population;
return result;
}
/**
* 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/
private boolean isBetter(Chromosome c1, Chromosome c2) {
for (int i = 0; i < c1.getFitnessLevel().length; i++) {
double[] Fitness1 = c1.getFitnessLevel();
double[] Fitness2 = c2.getFitnessLevel();
if (Fitness1[i] > Fitness2[i]) {
return true;
}
}
return false;
}
// List<Chromosome> population1 = population.stream().filter(t->t.getGeneStr()==null).collect(Collectors.toList());
population = population.stream()
.collect(Collectors.toMap(
Chromosome::getGeneStr, // key:去重的字段(GeneStr)
u -> u, // value:Chromosome对象
(u1, u2) -> u1.getFitness() > u2.getFitness() ? u1 : u2 // 重复时保留第一个元素
))
.values() // 获取去重后的
.stream()
.collect(Collectors.toList());
return population;
}
private void WriteKpis(List<List<Chromosome>> fronts,String index) {
for (int i=0;i<fronts.size();i++)
{
......@@ -496,6 +415,40 @@ int opcount=allOperations.size();
new ThreadPoolExecutor.CallerRunsPolicy() // 任务满了主线程执行,不丢失任务
);
private void initDataToChromosome(Chromosome chromosome,ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList) {
if (chromosome==null){
System.out.println("chromosome==null");
return;
}
chromosome.setResult(new CopyOnWriteArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setOrders(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(orders), Order.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setOperatRel(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(_entryRel), GroupResult.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setMaterials(ProductionDeepCopyUtil.deepCopyList(materials,Material.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(allOperations), Entry.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(ProductionDeepCopyUtil.deepCopyList(globalOpList, GlobalOperationInfo.class) ); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
chromosome.setBaseTime(param.getBaseTime());
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
// 加载锁定工单到ResultOld
List<GAScheduleResult> lockedOrders = GlobalCacheUtil.get("locked_orders_" + sceneId);
if (lockedOrders != null && !lockedOrders.isEmpty()) {
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(lockedOrders, GAScheduleResult.class));
FileHelper.writeLogFile("将 " + lockedOrders.size() + " 个锁定工单加载到初始种群中");
} else {
chromosome.setResultOld(new CopyOnWriteArrayList<>());
}
}
private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population)
{
FileHelper.writeLogFile("解码---------------"+population.size() );
......@@ -542,7 +495,7 @@ int opcount=allOperations.size();
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder.decodeChromosomeWithCache(chromosome);
decoder.decodeChromosomeWithCache(chromosome,false);
// if (chromosome.getFitness() == 0) {
// chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights));
// }
......
......@@ -343,7 +343,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
/**
* 使用构造启发式算法生成初始种群
*/
public List<Chromosome> generateHeuristicInitialPopulation(ScheduleParams param, List<GlobalOperationInfo> globalOpList) {
public List<Chromosome> generateHeuristicInitialPopulation(ScheduleParams param) {
List<Chromosome> population = new ArrayList<>();
int populationSize = param.getPopulationSize();
this.baseTime=param.getBaseTime();
......
......@@ -179,7 +179,7 @@ public class MaterialRequirementService {
double allneeded = component.getSpentQty().doubleValue()/ component.getMainQty().doubleValue() * operation.getQuantity();
OrderMaterialRequirement orderMaterialRequirement = CreateMaterialRequirement(material, orderId, "", operation,
allneeded,component.getSpentQty().doubleValue(), component.getMainQty().doubleValue(),operation.getQuantity());
allneeded,component.getSpentQty().doubleValue(), component.getMainQty().doubleValue(),operation.getQuantity(),baseTime);
orderMaterialRequirement.setBomId(component.getStrId());
if (!material.getMaterialTypeName().equals("MP") && isIsCheckSf) {
materialIds.add(materialId);//半成品ID
......@@ -503,8 +503,6 @@ public class MaterialRequirementService {
* @return 所有物料需求列表
*/
public List<OrderMaterialRequirement> buildMultiLevelRequirementNetwork(Chromosome chromosome,String sceneId, LocalDateTime _baseTime,GlobalParam _globalParam) {
baseTime=_baseTime;
globalParam=_globalParam;
List<OrderMaterialRequirement> allRequirements = new ArrayList<>();
List<Order> childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
......@@ -519,7 +517,7 @@ public class MaterialRequirementService {
.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> 0));
List<Integer> operationSequencing=chromosome.getOperationSequencing();
List<Integer> operationSequencing= new ArrayList<>(chromosome.getOperationSequencing());
orders.forEach(t->clearFinishOrder(t));
......@@ -546,7 +544,7 @@ public class MaterialRequirementService {
// 调用BuildOperationBOM方法(返回结果对象替代out参数)
BOMBuildResult operationResult = buildOperationSFBOM(operation.getOrderId(), "",
operation.getQuantity(), operation, 1,demand,sceneId,chromosome);
operation.getQuantity(), operation, 1,demand,sceneId,chromosome,_baseTime,_globalParam);
// // 合并物料需求和子订单
if(operationResult!=null) {
allRequirements.addAll(operationResult.getMaterialRequirements());
......@@ -567,13 +565,13 @@ public class MaterialRequirementService {
return allRequirements;
}
private void clearFinishOrder (Order order)
{
private void clearFinishOrder (Order order)
{
if (order.getFinishOrderId() == null) {
order.setFinishOrderId(new ArrayList<>());
order.setTargetFinishedOperationId(new ArrayList<>());
}
}
}
/**
* 构建订单BOM
......@@ -586,7 +584,7 @@ private void clearFinishOrder (Order order)
* @return 包含物料需求列表和子订单列表的结果对象
*/
public BOMBuildResult buildOrderBOM(String sceneId,int parent, String materialID, String mainorderId,
String childorderId, double parentQuantity, int level,Order forder,int finishOpertionID,Chromosome chromosome) {
String childorderId, double parentQuantity, int level,Order forder,int finishOpertionID,Chromosome chromosome, LocalDateTime baseTime, GlobalParam globalParam) {
forder.setCreateBom(true);
List<RoutingHeader> headers=GetRoutingHeader(sceneId);
......@@ -627,7 +625,7 @@ private void clearFinishOrder (Order order)
}
// 调用BuildOperationBOM方法(返回结果对象替代out参数)
BOMBuildResult operationResult = buildOperationBOM(mainorderId, childorderId,
parentQuantity, operation, level,forder,sceneId,chromosome);
parentQuantity, operation, level,forder,sceneId,chromosome, baseTime, globalParam);
// // 合并物料需求和子订单
if(operationResult!=null) {
materialRequirements.addAll(operationResult.getMaterialRequirements());
......@@ -650,7 +648,7 @@ private void clearFinishOrder (Order order)
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public BOMBuildResult buildOperationBOM(String orderId, String childorderId, double parentQuantity,
Entry operation, int level,Order forder,String sceneId,Chromosome chromosome) {
Entry operation, int level,Order forder,String sceneId,Chromosome chromosome, LocalDateTime baseTime, GlobalParam globalParam) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
List<Order> _childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
......@@ -678,7 +676,7 @@ private void clearFinishOrder (Order order)
return null;
}
OrderMaterialRequirement orderMaterial= CreateMaterialRequirement(material,orderId,childorderId,operation,allneeded,component.getSpentQty().doubleValue(), component.getMainQty().doubleValue() , parentQuantity);
OrderMaterialRequirement orderMaterial= CreateMaterialRequirement(material,orderId,childorderId,operation,allneeded,component.getSpentQty().doubleValue(), component.getMainQty().doubleValue() , parentQuantity, baseTime);
orderMaterial.setLevel(level);
orderMaterial.setBomId(component.getStrId());
materialRequirements.add(orderMaterial);
......@@ -713,7 +711,7 @@ private void clearFinishOrder (Order order)
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, order.getOrderId(),
order.getQuantity(), l,order,operation.getId(),chromosome);
order.getQuantity(), l,order,operation.getId(),chromosome, baseTime, globalParam);
// materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
......@@ -743,7 +741,7 @@ private void clearFinishOrder (Order order)
childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(forder.getId());
childorder.setNewCreate(true);
childorder.setNewSfCreate(true);
childorder.setTargetFinishedOperationId(new ArrayList<>());
childorder.getTargetFinishedOperationId().add(operation.getId());
childorder.setSerie(forder.getSerie());
......@@ -769,7 +767,7 @@ private void clearFinishOrder (Order order)
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, childorder.getOrderId(),
childorder.getQuantity(), l,childorder,0,chromosome);
childorder.getQuantity(), l,childorder,0,chromosome, baseTime, globalParam);
// materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
......@@ -792,10 +790,10 @@ private void clearFinishOrder (Order order)
RoutingHeader headers1= headers.stream()
.filter(t->t.getMaterialId().equals(materialID))
.findFirst().orElse(null);
if(headers1==null)
{
if(headers1==null)
{
return null;
}
}
routingIds=headers1.getId().longValue();
......@@ -921,7 +919,7 @@ if(headers1==null)
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public BOMBuildResult buildOperationSFBOM(String orderId, String childorderId, double parentQuantity,
Entry operation, int level,Order forder,String sceneId,Chromosome chromosome) {
Entry operation, int level,Order forder,String sceneId,Chromosome chromosome, LocalDateTime baseTime, GlobalParam globalParam) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
List<Order> _childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
......@@ -980,7 +978,7 @@ if(headers1==null)
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, order.getOrderId(),
order.getQuantity(), l,order,operation.getId(),chromosome);
order.getQuantity(), l,order,operation.getId(),chromosome, baseTime, globalParam);
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
......@@ -1010,7 +1008,7 @@ if(headers1==null)
childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(forder.getId());
childorder.setNewCreate(true);
childorder.setNewSfCreate(true);
childorder.setTargetFinishedOperationId(new ArrayList<>());
childorder.getTargetFinishedOperationId().add(operation.getId());
childorder.setSerie(forder.getSerie());
......@@ -1036,7 +1034,7 @@ if(headers1==null)
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, childorder.getOrderId(),
childorder.getQuantity(), l,childorder,0,chromosome);
childorder.getQuantity(), l,childorder,0,chromosome, baseTime, globalParam);
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
......@@ -1089,7 +1087,7 @@ if(headers1==null)
}
private OrderMaterialRequirement CreateMaterialRequirement(Material material,String orderId, String childorderId, Entry operation,double need,double spentQty,double mainQty,double qty) {
private OrderMaterialRequirement CreateMaterialRequirement(Material material,String orderId, String childorderId, Entry operation,double need,double spentQty,double mainQty,double qty, LocalDateTime baseTime) {
OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement();
orderMaterial.setOrderId(orderId);
......@@ -1140,7 +1138,7 @@ if(headers1==null)
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public void EditOperationBOM(Entry operation,Chromosome chromosome,LocalDateTime earliestStartTime,GeneticDecoder coder,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
public void EditOperationBOM(Entry operation,Chromosome chromosome,LocalDateTime earliestStartTime,GeneticDecoder coder,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById, LocalDateTime baseTime) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
String sceneId=chromosome.getScenarioID();
......@@ -1247,7 +1245,7 @@ if(headers1==null)
continue;
}
MaterialInTransit(material,"",orderMaterial,needed,earliestStartTime);
MaterialInTransit(material,"",orderMaterial,needed,earliestStartTime, materials);
needed -= orderMaterial.getUseTransit();
......@@ -1268,7 +1266,7 @@ if(headers1==null)
break;
}
MaterialInTransit(material1,rsr.getMaterialid(),orderMaterial1,needed,earliestStartTime);
MaterialInTransit(material1,rsr.getMaterialid(),orderMaterial1,needed,earliestStartTime, materials);
needed -= orderMaterial1.getUseTransit();
......@@ -1319,7 +1317,7 @@ if(headers1==null)
for (Integer orderid : orderids) {
coder.ClearorderOperationResult(chromosome, orderid);
coder.EditorderOperation(chromosome, orderid, needed,machineTasksCache);
coder.EditorderOperation(chromosome, orderid, needed,machineTasksCache, entryIndexById, scheduleIndexById);
}
}else {
......@@ -1376,14 +1374,14 @@ if(headers1==null)
private void MaterialInTransit(Material material,String materialId, OrderMaterialRequirement orderMaterial, double needed,LocalDateTime earliestStartTime ){
private void MaterialInTransit(Material material,String materialId, OrderMaterialRequirement orderMaterial, double needed,LocalDateTime earliestStartTime, List<Material> materials ){
// 处理在途物料
double accumulated = 0;
LocalDateTime earliestTime = LocalDateTime.of(2000,1,1,0,0,0);
double useTransit = 0;
if (material == null) {
material = _materials.stream()
material = materials.stream()
.filter(m -> m.getId().equals(materialId))
.findFirst()
.orElse(null);
......
......@@ -894,7 +894,7 @@ public class MaterialRequirementServicebf {
childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(forder.getId());
childorder.setNewCreate(true);
childorder.setNewSfCreate(true);
childorder.setTargetFinishedOperationId(new ArrayList<>());
childorder.getTargetFinishedOperationId().add(operation.getId());
childorder.setSerie(forder.getSerie());
......
package com.aps.service.Algorithm;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
* 多种局部搜索算法并行
*/
public class ParallelLocalSearch {
private final ExecutorService executor;
private GlobalParam globalParam;
private List<Entry> allOperations;
private List<GlobalOperationInfo> globalOpList;
private FitnessCalculator fitnessCalculator;
private ObjectiveWeights objectiveWeights;
public ParallelLocalSearch(GlobalParam globalParam, List<Entry> allOperations, List<GlobalOperationInfo> globalOpList, FitnessCalculator fitnessCalculator, ObjectiveWeights objectiveWeights) {
this.globalParam = globalParam;
this.allOperations = allOperations;
this.globalOpList = globalOpList;
this.fitnessCalculator = fitnessCalculator;
this.objectiveWeights = objectiveWeights;
this.executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
}
/**
* 并行局部搜索
*/
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
List<Callable<Chromosome>> tasks = new ArrayList<>();
// 添加爬山法任务
// tasks.add(() -> {
// HillClimbing hillClimbing = new HillClimbing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
// return hillClimbing.search(chromosome, decoder, param);
// });
// 添加变邻域搜索任务
tasks.add(() -> {
VariableNeighborhoodSearch vns = new VariableNeighborhoodSearch(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
return vns.search(chromosome, decoder, param);
});
// 添加模拟退火任务
// tasks.add(() -> {
// SimulatedAnnealing sa = new SimulatedAnnealing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
// return sa.search(chromosome, decoder, param);
// });
// 执行所有任务
List<Chromosome> results = new ArrayList<>();
try {
List<Future<Chromosome>> futures = executor.invokeAll(tasks);
for (Future<Chromosome> future : futures) {
results.add(future.get());
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
// 选择最优解
Chromosome best = chromosome;
for (Chromosome result : results) {
if (isBetter(result, best)) {
best = result;
}
}
return best;
}
/**
* 比较两个染色体的优劣
*/
private boolean isBetter(Chromosome c1, Chromosome c2) {
return c1.getFitness() > c2.getFitness();
}
/**
* 关闭线程池
*/
public void shutdown() {
executor.shutdown();
}
}
\ No newline at end of file
......@@ -1885,7 +1885,7 @@ if(targetOp.getSequence()>1) {
decoder.decode(chromosome);
decoder.decode(chromosome,false);
KpiCalculator kpiCalculator=new KpiCalculator(chromosome);
kpiCalculator.calculatekpi();
......
package com.aps.service.Algorithm;
import com.aps.common.util.FileHelper;
import com.aps.common.util.GlobalCacheUtil;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import com.aps.entity.basic.Machine;
import com.aps.entity.basic.MachineOption;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.basic.*;
import java.util.*;
import java.util.concurrent.*;
......@@ -18,17 +17,39 @@ import java.util.stream.Collectors;
public class SimulatedAnnealing {
private final Random rnd = new Random();
private void log(String message) {
log(message, false);
}
private void log(String message, boolean enableLogging) {
if (enableLogging) {
FileHelper.writeLogFile(message);
}
}
private List<Entry> allOperations;
private Map<String, Entry> entrys;
private List<Order> orders;
private List<Material> materials;
private List<GroupResult> _entryRel;
private FitnessCalculator fitnessCalculator;
private Map<String, Entry> entrys;
private Map<Integer, Entry> entrybyids;
public SimulatedAnnealing( List<Entry> allOperations) {
public SimulatedAnnealing( List<Entry> allOperations, List<Order> orders,
List<Material> materials,List<GroupResult> entryRel, FitnessCalculator _fitnessCalculator) {
this.allOperations = allOperations;
this.orders = orders;
this.materials = materials;
Map<Integer, Object> mp = buildEntryKey();
_entryRel=entryRel;
Map<Integer, Object> mp = buildEntryKey();
this.fitnessCalculator = _fitnessCalculator;
entrys=(Map<String, Entry>)mp.get(1);
entrybyids=(Map<Integer, Entry>)mp.get(2);
......@@ -40,7 +61,7 @@ private Map<String, Entry> entrys;
new ArrayBlockingQueue<>(200), // 有界队列,避免内存溢出
new ThreadPoolExecutor.CallerRunsPolicy() // 任务满了主线程执行,不丢失任务
);
public List<Chromosome> batchSearch(List<Chromosome> chromosomes, GeneticDecoder decoder, List<Machine> machines) {
public List<Chromosome> batchSearch(List<Chromosome> chromosomes,VariableNeighborhoodSearch vns, GeneticDecoder decoder, List<Machine> machines) {
List<Chromosome> saHcOptimized=new ArrayList<>();
// CompletableFuture.allOf(chromosomes.stream()
// .map(chromosome -> CompletableFuture.runAsync(() -> {
......@@ -50,15 +71,15 @@ private Map<String, Entry> entrys;
// .toArray(CompletableFuture[]::new))
// .join();
for (Chromosome chromosome:chromosomes) {
Chromosome optimized = searchWithHillClimbing(chromosome, decoder, machines);
Chromosome optimized = searchWithHillClimbing(chromosome,vns, decoder, machines);
saHcOptimized.add(optimized);
}
return saHcOptimized;
}
public Chromosome batchSearchGetMax(List<Chromosome> chromosomes, GeneticDecoder decoder, List<Machine> machines) {
List<Chromosome> saHcOptimized=batchSearch(chromosomes,decoder,machines);
public Chromosome batchSearchGetMax(List<Chromosome> chromosomes,VariableNeighborhoodSearch vns, GeneticDecoder decoder, List<Machine> machines) {
List<Chromosome> saHcOptimized=batchSearch(chromosomes,vns,decoder,machines);
int bestidx= Getbest(saHcOptimized,null);
if(bestidx>-1) {
......@@ -72,17 +93,18 @@ private Map<String, Entry> entrys;
* 模拟退火搜索,当温度降低到一定程度后切换到爬山法
* 流程:模拟退火全局探索(按概率接受劣解)→ 降温 → 温度低时爬山法局部求精 → 输出最优
*/
public Chromosome searchWithHillClimbing(Chromosome chromosome, GeneticDecoder decoder, List<Machine> machines) {
FileHelper.writeLogFile("模拟退火+爬山法 - 开始执行");
public Chromosome searchWithHillClimbing(Chromosome chromosome, VariableNeighborhoodSearch vns,GeneticDecoder decoder, List<Machine> machines) {
log("模拟退火+爬山法 - 开始执行",true);
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
writeKpi(best);
// 初始化解码
// 记录初始KPI用于计算改进率
double[] initialFitnessLevel = best.getFitnessLevel().clone();
double initialFitness = best.getFitness();
// FileHelper.writeLogFile("模拟退火+爬山法 - 初始化解码完成");
// log("模拟退火+爬山法 - 初始化解码完成");
// 初始化温度
double temperature = 100.0;
......@@ -90,19 +112,26 @@ private Map<String, Entry> entrys;
double temperatureThreshold = 1.0;
int maxIterations = 300;
int noImproveCount = 0;
int maxNoImprove = 50;
int maxNoImprove = 30; // 降低最大无改进次数
// 新增:改进率监控参数
int stagnantWindow = 15; // 观察窗口大小
int[] recentImprovements = new int[stagnantWindow]; // 记录最近窗口内的改进情况
double improvementRateThreshold = 0.05; // 改进率阈值(5%)
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 参数配置:温度=%.1f, 降温率=%.2f, 阈值=%.1f, 最大迭代=%d",
temperature, coolingRate, temperatureThreshold, maxIterations));
log(String.format("模拟退火+爬山法 - 参数配置:温度=%.1f, 降温率=%.2f, 阈值=%.1f, 最大迭代=%d, 最大无改进=%d",
temperature, coolingRate, temperatureThreshold, maxIterations, maxNoImprove));
int acceptCount = 0;
int improveCount = 0;
int totalIterations = 0;
for (int i = 0; i < maxIterations; i++) {
totalIterations = i + 1;
boolean improved = false;
// 1. 使用智能策略生成邻域解(找瓶颈工序/设备)
Chromosome neighbor = generateNeighbor(current);
Chromosome neighbor = vns.generateNeighbor(current);
// 2. 解码
decode(decoder, neighbor,machines);
......@@ -124,7 +153,10 @@ private Map<String, Entry> entrys;
improved = true;
improveCount++;
noImproveCount = 0;
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 迭代%d:找到更优解,fitness=%.4f", i, best.getFitness()));
// 记录改进详情
logImprovementDetails(best, initialFitnessLevel, initialFitness, totalIterations);
log(String.format("模拟退火+爬山法 - 迭代%d:找到更优解,fitness=%.4f", totalIterations, best.getFitness()),true);
}
}
......@@ -132,713 +164,330 @@ private Map<String, Entry> entrys;
noImproveCount++;
}
// 5. 降温
temperature *= coolingRate;
// 每50次迭代输出一次状态
if ((i + 1) % 50 == 0) {
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 迭代%d/%d:温度=%.4f, 接受数=%d, 改进数=%d, 无改进连续=%d",
i + 1, maxIterations, temperature, acceptCount, improveCount, noImproveCount));
// 记录本次改进情况
if (totalIterations <= stagnantWindow) {
recentImprovements[totalIterations - 1] = improved ? 1 : 0;
}
// 6. 提前停止条件:温度低于阈值 或 连续多次没改进
if (temperature < temperatureThreshold || noImproveCount >= maxNoImprove) {
String stopReason = temperature < temperatureThreshold ? "温度低于阈值" : "连续无改进达到上限";
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 提前停止:%s,迭代%d次,最终温度=%.4f",
stopReason, i + 1, temperature));
FileHelper.writeLogFile("模拟退火+爬山法 - 切换到爬山法求精");
HillClimbing hillClimbing = new HillClimbing( allOperations);
Chromosome refined = hillClimbing.search(best, decoder, machines);
FileHelper.writeLogFile("模拟退火+爬山法 - 爬山法求精完成");
// 5. 降温
temperature *= coolingRate;
return refined;
}
// 每30次迭代输出一次状态
if ((totalIterations) % 30 == 0) {
log(String.format("模拟退火+爬山法 - 迭代%d/%d:温度=%.4f, 接受数=%d, 改进数=%d, 无改进连续=%d, 总改进率=%.2f%%",
totalIterations, maxIterations, temperature, acceptCount, improveCount, noImproveCount,
totalIterations > 0 ? (double)improveCount / totalIterations * 100 : 0));
}
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 完成所有%d次迭代,最终fitness=%.4f",
maxIterations, best.getFitness()));
// 6. 提前停止条件
boolean shouldStop = false;
String stopReason = "";
// 7. 输出全局最优排产
return best;
if (temperature < temperatureThreshold) {
shouldStop = true;
stopReason = "温度低于阈值";
} else if (noImproveCount >= maxNoImprove) {
shouldStop = true;
stopReason = String.format("连续无改进达到上限(%d次)", maxNoImprove);
} else if (totalIterations >= stagnantWindow) {
// 检查改进率是否过低
double recentImproveRate = calculateRecentImprovementRate(recentImprovements, stagnantWindow);
if (recentImproveRate < improvementRateThreshold) {
shouldStop = true;
stopReason = String.format("最近%d次迭代改进率过低(%.2f%%)", stagnantWindow, recentImproveRate * 100);
}
private void writeKpi(Chromosome chromosome) {
String fitness = "";
double[] fitness1 = chromosome.getFitnessLevel();
for (int i = 0; i < fitness1.length; i++) {
fitness += fitness1[i] + ",";
}
FileHelper.writeLogFile(String.format("爬山法 - kpi:%s", fitness));
if (shouldStop) {
log(String.format("模拟退火+爬山法 - 提前停止:%s,迭代%d次,最终温度=%.4f",
stopReason, totalIterations, temperature));
logFinalSummary(best, initialFitnessLevel, initialFitness, improveCount, totalIterations);
}
/**
* 计算能量差(基于fitnessLevel数组的比较)
*/
private double calculateEnergyDifference(Chromosome neighbor, Chromosome current) {
double[] neighborFitness = neighbor.getFitnessLevel();
double[] currentFitness = current.getFitnessLevel();
log("模拟退火+爬山法 - 切换到爬山法求精");
HillClimbing hillClimbing = new HillClimbing( allOperations,orders,materials,_entryRel,fitnessCalculator);
Chromosome refined = hillClimbing.search(best, decoder, machines);
log("模拟退火+爬山法 - 爬山法求精完成");
// 计算加权能量差
double diff = 0;
for (int i = 0; i < neighborFitness.length; i++) {
diff += (neighborFitness[i] - currentFitness[i]);
return refined;
}
return diff;
}
/**
* 按优先级分组工序
*/
private Map<Double, List<Entry>> groupOperationsByPriority() {
Map<Double, List<Entry>> groups = new HashMap<>();
for (Entry op : allOperations) {
double priority = op.getPriority();
groups.computeIfAbsent(priority, k -> new ArrayList<>()).add(op);
}
// 过滤掉:设备只有一个且只有一个GroupId的优先级组
Map<Double, List<Entry>> filteredGroups = new HashMap<>();
for (Map.Entry<Double, List<Entry>> entry : groups.entrySet()) {
List<Entry> ops = entry.getValue();
// 检查是否所有工序都只有一个设备选项
boolean allSingleMachine = ops.stream()
.allMatch(op -> op.getMachineOptions().size() <= 1);
log(String.format("模拟退火+爬山法 - 完成所有%d次迭代,最终fitness=%.4f",
maxIterations, best.getFitness()),true);
logFinalSummary(best, initialFitnessLevel, initialFitness, improveCount, totalIterations);
// 检查是否只有一个GroupId
Set<Integer> groupIds = ops.stream()
.map(Entry::getGroupId)
.collect(Collectors.toSet());
// 如果两个条件都满足,过滤掉这个优先级组
if (!(allSingleMachine && groupIds.size() <= 1)) {
filteredGroups.put(entry.getKey(), ops);
}
// 7. 输出全局最优排产
return best;
}
return filteredGroups;
}
/**
* 构建位置索引:groupId_sequence -> position
* 模拟退火搜索
* 流程:模拟退火全局探索(按概率接受劣解)→ 降温 → 输出最优
*/
private Map<String, Integer> buildPositionIndex(Chromosome chromosome) {
Map<String, Integer> index = new HashMap<>();
List<Integer> os = chromosome.getOperationSequencing();
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
for (int i = 0; i < os.size(); i++) {
int groupId = os.get(i);
int count = orderProcessCounter.getOrDefault(groupId, 0) + 1;
orderProcessCounter.put(groupId, count);
String key = groupId + "_" + count;
index.put(key, i);
}
return index;
}
public Chromosome search(Chromosome chromosome,TabuSearch tabusearch,VariableNeighborhoodSearch vns, GeneticDecoder decoder, List<Machine> machines) {
log("模拟退火 - 开始执行",true);
/**
* 构建位置索引:groupId_sequence -> Machines position
*/
private Map<String, Integer> buildEntryMachinePositionIndex(Chromosome chromosome) {
Map<String, Integer> index = new HashMap<>();
List<GlobalOperationInfo> globalOpList = chromosome.getGlobalOpList();
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
decode(decoder, current,machines);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
writeKpi(best);
// 初始化解码
for (int i = 0; i < globalOpList.size(); i++) {
GlobalOperationInfo globalOp = globalOpList.get(i);
Entry op = globalOp.getOp();
int groupId = op.getGroupId();
int count = op.getSequence();
// 记录初始KPI用于计算改进率
double[] initialFitnessLevel = best.getFitnessLevel().clone();
double initialFitness = best.getFitness();
String key = groupId + "_" + count;
index.put(key, i);
}
return index;
}
// log("模拟退火+爬山法 - 初始化解码完成");
/**
* 构建位置->Entry索引
*/
private Map<Integer, Entry> buildPositionToEntryIndex(Chromosome chromosome,Map<String, Entry> entrys) {
Map<Integer, Entry> index = new HashMap<>();
List<Integer> os = chromosome.getOperationSequencing();
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
// 初始化温度
double temperature = 100.0;
double coolingRate = 0.95;
double temperatureThreshold = 1.0;
int maxIterations = 300;
int noImproveCount = 0;
int maxNoImprove = 20; // 降低最大无改进次数,更快提前结束
for (int i = 0; i < os.size(); i++) {
int groupId = os.get(i);
int count = orderProcessCounter.getOrDefault(groupId, 0) + 1;
orderProcessCounter.put(groupId, count);
// 新增:改进率监控参数
int stagnantWindow = 10; // 观察窗口大小
int[] recentImprovements = new int[stagnantWindow]; // 记录最近窗口内的改进情况
double improvementRateThreshold = 0.001; // 改进率阈值
String key = groupId + "_" + count;
Entry op = entrys.get(key);
log(String.format("模拟退火 - 参数配置:温度=%.1f, 降温率=%.2f, 阈值=%.1f, 最大迭代=%d, 最大无改进=%d",
temperature, coolingRate, temperatureThreshold, maxIterations, maxNoImprove));
if (op != null) {
index.put(i, op);
}
}
return index;
}
/**
* 构建Entry索引:op.getGroupId() + "_" + op.getSequence() -> Entry
*/
private Map<Integer, Object> buildEntryKey() {
Map<Integer, Object> index0 = new HashMap<>();
Map<String, Entry> index = new HashMap<>();
Map<Integer, Entry> index2 = new HashMap<>();
List<Entry> allOps = this.allOperations;
int acceptCount = 0;
int improveCount = 0;
int totalIterations = 0;
for (Entry op : allOps) {
String key = op.getGroupId() + "_" + op.getSequence();
for (int i = 0; i < maxIterations; i++) {
totalIterations = i + 1;
boolean improved = false;
log(String.format("模拟退火 - 迭代%d:", totalIterations));
index.put(key, op);
index2.put(op.getId(), op);
}
index0.put(1,index);
index0.put(2,index2);
return index0;
// 1. 使用智能策略生成邻域解(找瓶颈工序/设备)
Chromosome neighbor = vns.generateNeighbor(current);
// 2. 解码
decode(decoder, neighbor,machines);
// 跳过禁忌解(除非是最优解)
if (tabusearch.isTabu(neighbor.getGeneStr()) && !isBetter(current,best)) {
temperature *= coolingRate;
noImproveCount++;
// 记录本次无改进
if (totalIterations <= stagnantWindow) {
recentImprovements[totalIterations - 1] = 0;
}
/**
* 生成邻域解 - 智能策略:优先处理瓶颈工序/设备
* 策略:
* 1. 优先处理瓶颈设备上的工序(换设备)
* 2. 瓶颈设备上的工序往前移动
* 3. 非瓶颈设备上的工序往后移动(给瓶颈工序腾位置)
*/
private Chromosome generateNeighbor(Chromosome chromosome) {
List<GAScheduleResult> results = chromosome.getResult();
if (results == null || results.isEmpty()) {
return generateRandomNeighbor(chromosome, entrys);
continue;
}
// 构建位置索引
Map<String, Integer> positionIndex = buildPositionIndex(chromosome);
Map<Integer, Entry> positionToEntryIndex = buildPositionToEntryIndex(chromosome, entrys);
Map<String, Integer> MachinePositionIndex = buildEntryMachinePositionIndex(chromosome);
// 1. 找出瓶颈设备
Long bottleneckMachineId = findBottleneckMachine(chromosome);
// 3. 计算能量差
double energyDifference = calculateEnergyDifference(neighbor, current);
if (bottleneckMachineId != null) {
// 找出瓶颈设备上的工序
List<GAScheduleResult> bottleneckOps = findOpsOnBottleneckMachine(chromosome, bottleneckMachineId);
// 4. 按概率接受新解(模拟退火核心:有概率接受劣解)
boolean accepted = false;
if (energyDifference > 0 || rnd.nextDouble() < Math.exp(energyDifference / temperature)) {
current = neighbor;
if (!bottleneckOps.isEmpty()) {
// 70%概率优先处理瓶颈设备
if (rnd.nextDouble() < 0.7) {
int strategy = rnd.nextInt(10);
acceptCount++;
if (isBetter(current, best)) {
best = ProductionDeepCopyUtil.deepCopy(current, Chromosome.class);
tabusearch.addToTabuList(best.getGeneStr());
writeKpi(best);
improved = true;
improveCount++;
noImproveCount = 0;
if(strategy<=3)
{
// 策略1:瓶颈设备上的工序换设备
return tryChangeMachineForBottleneckOp(chromosome, bottleneckOps, entrys, MachinePositionIndex);
}
else if(strategy<=8) {
// 策略2:瓶颈设备上的工序往前移动
return tryMoveBottleneckOpForward(chromosome, bottleneckOps, positionIndex, positionToEntryIndex, entrys);
}else if(strategy<=10) {
// 策略3:非瓶颈设备上的工序往后移动
return tryMoveNonBottleneckOpBackward(chromosome, bottleneckMachineId, positionIndex, positionToEntryIndex, entrys);
}
}
// 记录改进详情
logImprovementDetails(best, initialFitnessLevel, initialFitness, totalIterations);
log(String.format("模拟退火 - 迭代%d:找到更优解,fitness=%.4f", totalIterations, best.getFitness()));
}
}
// 默认策略:随机邻域
return generateRandomNeighbor(chromosome, entrys);
}
/**
* 识别瓶颈设备(利用率最高的设备)
*/
private Long findBottleneckMachine(Chromosome chromosome) {
Map<Long, Double> utilization = calculateMachineUtilization(chromosome);
if (utilization.isEmpty()) {
return null;
if (!improved) {
noImproveCount++;
}
return utilization.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse(null);
// 记录本次改进情况
if (totalIterations <= stagnantWindow) {
recentImprovements[totalIterations - 1] = improved ? 1 : 0;
}
/**
* 查找在瓶颈设备上的工序
*/
private List<GAScheduleResult> findOpsOnBottleneckMachine(Chromosome chromosome, Long bottleneckMachineId) {
if (bottleneckMachineId == null) {
return new ArrayList<>();
}
// 5. 降温
temperature *= coolingRate;
return chromosome.getResult().stream()
.filter(r -> r.getMachineId() == bottleneckMachineId)
.collect(Collectors.toList());
// 每次迭代都输出状态
log(String.format("模拟退火 - 迭代%d/%d:温度=%.4f, 接受数=%d, 改进数=%d, 无改进连续=%d, 总改进率=%.2f%%",
totalIterations, maxIterations, temperature, acceptCount, improveCount, noImproveCount,
totalIterations > 0 ? (double)improveCount / totalIterations * 100 : 0));
// 6. 检查提前停止条件
boolean shouldStop = false;
String stopReason = "";
if (temperature < temperatureThreshold) {
shouldStop = true;
stopReason = "温度低于阈值";
} else if (noImproveCount >= maxNoImprove) {
shouldStop = true;
stopReason = String.format("连续无改进达到上限(%d次)", maxNoImprove);
} else if (totalIterations >= stagnantWindow) {
// 检查改进率是否过低
double recentImproveRate = calculateRecentImprovementRate(recentImprovements, stagnantWindow);
if (recentImproveRate < improvementRateThreshold) {
shouldStop = true;
stopReason = String.format("最近%d次迭代改进率过低(%.2f%%)", stagnantWindow, recentImproveRate * 100);
}
}
if (shouldStop) {
log(String.format("模拟退火 - 提前停止:%s,迭代%d次,最终温度=%.4f",
stopReason, totalIterations, temperature));
logFinalSummary(best, initialFitnessLevel, initialFitness, improveCount, totalIterations);
return best;
}
/**
* 计算设备利用率
*/
private Map<Long, Double> calculateMachineUtilization(Chromosome chromosome) {
Map<Long, Double> utilization = new HashMap<>();
List<GAScheduleResult> results = chromosome.getResult();
if (results == null || results.isEmpty()) {
return utilization;
}
int maxEndTime = results.stream()
.mapToInt(GAScheduleResult::getEndTime)
.max()
.orElse(1);
log(String.format("模拟退火 - 完成所有%d次迭代,最终fitness=%.4f",
maxIterations, best.getFitness()),true);
logFinalSummary(best, initialFitnessLevel, initialFitness, improveCount, totalIterations);
Map<Long, List<GAScheduleResult>> machineResults = results.stream()
.collect(Collectors.groupingBy(GAScheduleResult::getMachineId));
for (Map.Entry<Long, List<GAScheduleResult>> entry : machineResults.entrySet()) {
long machineId = entry.getKey();
List<GAScheduleResult> machineOps = entry.getValue();
int totalProcessingTime = machineOps.stream()
.mapToInt(r -> r.getEndTime() - r.getStartTime())
.sum();
double util = (double) totalProcessingTime / maxEndTime;
utilization.put(machineId, util);
// 7. 输出全局最优排产
return best;
}
return utilization;
}
/**
* 尝试给瓶颈设备上的工序换设备
* 记录改进详情
*/
private Chromosome tryChangeMachineForBottleneckOp(Chromosome chromosome, List<GAScheduleResult> bottleneckOps, Map<String, Entry> entrys,Map<String, Integer> MachinePositionIndex) {
// 优先选择有多设备选项的工序
List<GAScheduleResult> candidates = bottleneckOps.stream()
.filter(op -> {
Entry entry = entrybyids.get(op.getOperationId());
return entry != null && entry.getMachineOptions().size() > 1;
})
.collect(Collectors.toList());
if (candidates.isEmpty()) {
return generateRandomNeighbor(chromosome, entrys);
}
// 从候选中随机选择一个工序,给它换设备
GAScheduleResult selectedOp = candidates.get(rnd.nextInt(candidates.size()));
private void logImprovementDetails(Chromosome best, double[] initialFitnessLevel, double initialFitness, int iteration) {
StringBuilder sb = new StringBuilder("模拟退火 - 改进详情: 迭代" + iteration + ", ");
double[] currentFitness = best.getFitnessLevel();
// 找到这个工序在globalOpList中的位置
int maPos = -1;
Entry entry= entrybyids.get(selectedOp.getOperationId());
if (entry != null && entry.getMachineOptions().size() > 1) {
maPos = MachinePositionIndex.get(entry.getGroupId() + "_" + entry.getSequence());
if (maPos >= 0) {
return generateMachineChangeForSpecificOp(chromosome, entry.getMachineOptions(), maPos);
}
}
// 直接换设备
return generateMachineChangeNeighbor(chromosome);
}
/**
* 给指定位置的工序换设备
*/
private Chromosome generateMachineChangeForSpecificOp(Chromosome chromosome, List<MachineOption> machineOptions, int idx) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> ms = neighbor.getMachineSelection();
if (!ms.isEmpty() && idx >= 0 && idx < ms.size()) {
if (machineOptions.size() > 1) {
int currentMachineSeq = ms.get(idx);
List<Integer> availableMachines = new ArrayList<>();
for (int i = 1; i <= machineOptions.size(); i++) {
if (i != currentMachineSeq) {
availableMachines.add(i);
}
for (int i = 0; i < currentFitness.length; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(+%.4f) ", i+1, initialFitnessLevel[i], currentFitness[i], improvement));
}
if (!availableMachines.isEmpty()) {
int newMachineSeq = availableMachines.get(rnd.nextInt(availableMachines.size()));
ms.set(idx, newMachineSeq);
neighbor.setMachineSelection(ms);
}
}
}
return neighbor;
double totalImprovement = best.getFitness() - initialFitness;
sb.append(String.format("总Fitness: %.4f→%.4f(+%.4f)", initialFitness, best.getFitness(), totalImprovement));
log(sb.toString());
}
/**
* 尝试将瓶颈设备上的工序往前移动
* 计算最近改进率
*/
private Chromosome tryMoveBottleneckOpForward(Chromosome chromosome, List<GAScheduleResult> bottleneckOps,
Map<String, Integer> positionIndex,
Map<Integer, Entry> positionToEntryIndex,
Map<String, Entry> entrys) {
if (bottleneckOps.isEmpty()) {
return generateSwapNeighbor(chromosome, entrys);
}
// 随机选择一个瓶颈工序
// GAScheduleResult randomOp = bottleneckOps.get(rnd.nextInt(bottleneckOps.size()));
// 计算所有订单的完成时间
List<GAScheduleResult> allResults = chromosome.getResult();
Map<Integer, Integer> orderCompletionTimes = calculateOrderCompletionTimes(allResults);
// 找出最晚完成的订单(延期候选)
int latestCompletionTime = orderCompletionTimes.values().stream()
.mapToInt(Integer::intValue)
.max()
.orElse(0);
// 按优先级和订单完成时间排序:优先选择高优先级+延期订单的工序
List<GAScheduleResult> sortedBottleneckOps = new ArrayList<>(bottleneckOps);
sortedBottleneckOps.sort((a, b) -> {
Entry entryA = entrybyids.get(a.getOperationId());
Entry entryB = entrybyids.get(b.getOperationId());
if (entryA != null && entryB != null) {
// 首先比较优先级(高优先级在前)
int priorityCompare = Double.compare(entryB.getPriority(), entryA.getPriority());
if (priorityCompare != 0) {
return priorityCompare;
}
// 优先级相同,比较订单完成时间(晚完成的在前,即更可能延期)
int endTimeA = orderCompletionTimes.getOrDefault(a.getGroupId(), 0);
int endTimeB = orderCompletionTimes.getOrDefault(b.getGroupId(), 0);
return Integer.compare(endTimeB, endTimeA);
}
return 0;
});
GAScheduleResult selectedOp = sortedBottleneckOps.get(rnd.nextInt(Math.min(5, sortedBottleneckOps.size())));
Entry entry=entrybyids.get(selectedOp.getOperationId()) ;
String key = entry.getGroupId() + "_" + entry.getSequence();
Integer opPos = positionIndex.get(key);
if (opPos == null || opPos <= 0) {
return generateSwapNeighbor(chromosome, entrys);
}
// 往前移动1-3步
// int steps = rnd.nextInt(3) + 1;
// return moveOperationForward(chromosome,positionToEntryIndex, opPos, steps);
// 使用插入方式往前移动(1-5步)
int steps = rnd.nextInt(5) + 1;
return insertOperationForward(chromosome, opPos, steps, entrys);
}
/**
* 计算每个订单的最后完成时间
*/
private Map<Integer, Integer> calculateOrderCompletionTimes(List<GAScheduleResult> allResults) {
Map<Integer, Integer> orderEndTimes = new HashMap<>();
for (GAScheduleResult result : allResults) {
int groupId = result.getGroupId();
int endTime = result.getEndTime();
orderEndTimes.put(groupId, Math.max(orderEndTimes.getOrDefault(groupId, 0), endTime));
}
return orderEndTimes;
}
/**
* 尝试将非瓶颈设备上的工序往后移动(给瓶颈工序腾位置)
*/
private Chromosome tryMoveNonBottleneckOpBackward(Chromosome chromosome, Long bottleneckMachineId,
Map<String, Integer> positionIndex,
Map<Integer, Entry> positionToEntryIndex,
Map<String, Entry> entrys) {
List<GAScheduleResult> results = chromosome.getResult();
if (results == null) {
return generateSwapNeighbor(chromosome, entrys);
}
// 找出非瓶颈设备上的工序
List<GAScheduleResult> nonBottleneckOps = results.stream()
.filter(r -> r.getMachineId() != bottleneckMachineId)
.collect(Collectors.toList());
if (nonBottleneckOps.isEmpty()) {
return generateSwapNeighbor(chromosome, entrys);
private double calculateRecentImprovementRate(int[] recentImprovements, int windowSize) {
int improveCount = 0;
for (int i = 0; i < windowSize; i++) {
improveCount += recentImprovements[i];
}
// 随机选择一个非瓶颈工序
GAScheduleResult randomOp = nonBottleneckOps.get(rnd.nextInt(nonBottleneckOps.size()));
Entry entry=entrybyids.get(randomOp.getOperationId());
String key = entry.getGroupId()+"_"+entry.getSequence();
Integer opPos = positionIndex.get(key);
if (opPos == null || opPos >= chromosome.getOperationSequencing().size() - 1) {
return generateSwapNeighbor(chromosome, entrys);
return (double) improveCount / windowSize;
}
// 往后移动1-3步
int steps = rnd.nextInt(3) + 1;
return moveOperationBackward(chromosome,positionToEntryIndex, opPos, steps);
}
/**
* 将工序往前移动
* 记录最终总结
*/
private Chromosome moveOperationForward(Chromosome chromosome, Map<Integer, Entry> originalPositionIndex,int pos, int steps) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
private void logFinalSummary(Chromosome best, double[] initialFitnessLevel, double initialFitness, int improveCount, int totalIterations) {
StringBuilder sb = new StringBuilder("模拟退火 - 最终总结: ");
double[] currentFitness = best.getFitnessLevel();
if (pos <= 0 || pos >= os.size()) {
return neighbor;
}
sb.append(String.format("总迭代%d次, 成功改进%d次, 改进率%.2f%%. ",
totalIterations, improveCount, totalIterations > 0 ? (double)improveCount / totalIterations * 100 : 0));
// 获取要移动的工序和目标位置的工序(基于原始chromosome)
Entry opToMove = originalPositionIndex.get(pos);
if (opToMove == null) {
return neighbor;
for (int i = 0; i < currentFitness.length; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i],
initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0));
}
int targetPos = Math.max(0, pos - steps);
Entry targetOp = originalPositionIndex.get(targetPos);
// 检查是否可以交换
if (targetOp != null && opToMove.getGroupId() == targetOp.getGroupId()) {
return neighbor;
}
if (targetOp != null && Math.abs(targetOp.getPriority() - opToMove.getPriority()) > 0.001) {
return neighbor;
double totalImprovement = best.getFitness() - initialFitness;
sb.append(String.format("总Fitness: %.4f→%.4f(%.2f%%)", initialFitness, best.getFitness(),
initialFitness > 0 ? totalImprovement / initialFitness * 100 : 0));
log(sb.toString());
}
// 直接交换到目标位置
java.util.Collections.swap(os, pos, targetPos);
neighbor.setOperationSequencing(os);
return neighbor;
}
/**
* 将工序往后移动
*/
private Chromosome moveOperationBackward(Chromosome chromosome,Map<Integer, Entry> originalPositionIndex, int pos, int steps) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (pos < 0 || pos >= os.size() - 1) {
return neighbor;
}
// 获取要移动的工序和目标位置的工序(基于原始chromosome)
private void writeKpi(Chromosome chromosome) {
String fitness = "";
double[] fitness1 = chromosome.getFitnessLevel();
for (int i = 0; i < fitness1.length; i++) {
Entry opToMove = originalPositionIndex.get(pos);
if (opToMove == null) {
return neighbor;
fitness += fitness1[i] + ",";
}
int targetPos = Math.min(os.size() - 1, pos + steps);
Entry targetOp = originalPositionIndex.get(targetPos);
log(String.format("模拟退火 - kpi:%s", fitness),true);
// 检查是否可以交换
if (targetOp != null && opToMove.getGroupId() == targetOp.getGroupId()) {
return neighbor;
}
if (targetOp != null && Math.abs(targetOp.getPriority() - opToMove.getPriority()) > 0.001) {
return neighbor;
}
// 直接交换到目标位置
java.util.Collections.swap(os, pos, targetPos);
neighbor.setOperationSequencing(os);
return neighbor;
}
/**
* 将工序往前插入(不交换,直接插入到目标位置
* 计算能量差(基于fitnessLevel数组的比较
*/
private Chromosome insertOperationForward(Chromosome chromosome, int pos, int steps, Map<String, Entry> entrys) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (pos <= 0 || pos >= os.size()) {
return neighbor;
}
// 获取要移动的工序(基于原始chromosome)
Map<Integer, Entry> originalPositionIndex = buildPositionToEntryIndex(chromosome, entrys);
Entry opToMove = originalPositionIndex.get(pos);
if (opToMove == null) {
return neighbor;
}
// 找到最远可以插入的位置(不打破优先级)
int targetPos = Math.max(0, pos - steps);
int finalTargetPos = pos;
private double calculateEnergyDifference(Chromosome neighbor, Chromosome current) {
double[] neighborFitness = neighbor.getFitnessLevel();
double[] currentFitness = current.getFitnessLevel();
for (int i = pos - 1; i >= targetPos; i--) {
Entry leftOp = originalPositionIndex.get(i);
if (leftOp != null && opToMove.getGroupId() == leftOp.getGroupId()) {
break;
}
if (leftOp != null && Math.abs(leftOp.getPriority() - opToMove.getPriority()) > 0.001) {
break;
}
finalTargetPos = i;
// 计算加权能量差
double diff = 0;
for (int i = 0; i < neighborFitness.length; i++) {
diff += (neighborFitness[i] - currentFitness[i]);
}
if (finalTargetPos == pos) {
return neighbor;
return diff;
}
// 执行插入:移除原位置,插入到目标位置
int value = os.remove(pos);
os.add(finalTargetPos, value);
neighbor.setOperationSequencing(os);
return neighbor;
}
/**
* 随机生成邻域解(兜底策略)
*/
private Chromosome generateRandomNeighbor(Chromosome chromosome, Map<String, Entry> entrys) {
int neighborType = rnd.nextInt(4);
switch (neighborType) {
case 0:
return generateSwapNeighbor(chromosome, entrys);
case 1:
return generateReverseNeighbor(chromosome, entrys);
case 2:
return generateInsertNeighbor(chromosome, entrys);
case 3:
return generateMachineChangeNeighbor(chromosome);
default:
return generateSwapNeighbor(chromosome, entrys);
}
}
/**
* 生成交换邻域解 - 只在相同优先级的工序之间交换
* 按优先级分组工序
*/
private Chromosome generateSwapNeighbor(Chromosome chromosome,Map<String, Entry> entrys) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
Map<Integer, Entry> positionIndex = buildPositionToEntryIndex(neighbor,entrys);
int maxAttempts = 50;
for (int attempt = 0; attempt < maxAttempts; attempt++) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
if (idx1 == idx2) continue;
Entry op1 = positionIndex.get(idx1);
Entry op2 = positionIndex.get(idx2);
if (op1 != null && op2 != null) {
if (Math.abs(op1.getPriority() - op2.getPriority()) < 0.001) {
java.util.Collections.swap(os, idx1, idx2);
neighbor.setOperationSequencing(os);
break;
}
}
}
}
return neighbor;
private Map<Double, List<Entry>> groupOperationsByPriority() {
Map<Double, List<Entry>> groups = new HashMap<>();
for (Entry op : allOperations) {
double priority = op.getPriority();
groups.computeIfAbsent(priority, k -> new ArrayList<>()).add(op);
}
/**
* 生成反转邻域解 - 只反转相同优先级的连续工序
*/
private Chromosome generateReverseNeighbor(Chromosome chromosome,Map<String, Entry> entrys) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
Map<Integer, Entry> positionIndex = buildPositionToEntryIndex(neighbor,entrys);
int maxAttempts = 50;
for (int attempt = 0; attempt < maxAttempts; attempt++) {
int start = rnd.nextInt(os.size());
int end = rnd.nextInt(os.size());
if (end <= start) continue;
// 过滤掉:设备只有一个且只有一个GroupId的优先级组
Map<Double, List<Entry>> filteredGroups = new HashMap<>();
for (Map.Entry<Double, List<Entry>> entry : groups.entrySet()) {
List<Entry> ops = entry.getValue();
Entry startOp = positionIndex.get(start);
if (startOp == null) continue;
// 检查是否所有工序都只有一个设备选项
boolean allSingleMachine = ops.stream()
.allMatch(op -> op.getMachineOptions().size() <= 1);
double priority = startOp.getPriority();
boolean allSamePriority = true;
// 检查是否只有一个GroupId
Set<Integer> groupIds = ops.stream()
.map(Entry::getGroupId)
.collect(Collectors.toSet());
for (int i = start; i <= end; i++) {
Entry op = positionIndex.get(i);
if (op == null || Math.abs(op.getPriority() - priority) > 0.001) {
allSamePriority = false;
break;
// 如果两个条件都满足,过滤掉这个优先级组
if (!(allSingleMachine && groupIds.size() <= 1)) {
filteredGroups.put(entry.getKey(), ops);
}
}
if (allSamePriority) {
java.util.Collections.reverse(os.subList(start, end + 1));
neighbor.setOperationSequencing(os);
break;
}
}
}
return neighbor;
return filteredGroups;
}
/**
* 生成插入邻域解 - 只插入到相同优先级的位置
* 构建Entry索引:op.getGroupId() + "_" + op.getSequence() -> Entry
*/
private Chromosome generateInsertNeighbor(Chromosome chromosome,Map<String, Entry> entrys) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
Map<Integer, Entry> positionIndex = buildPositionToEntryIndex(neighbor,entrys);
int maxAttempts = 50;
for (int attempt = 0; attempt < maxAttempts; attempt++) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
if (idx1 == idx2) continue;
private Map<Integer, Object> buildEntryKey() {
Map<Integer, Object> index0 = new HashMap<>();
Map<String, Entry> index = new HashMap<>();
Map<Integer, Entry> index2 = new HashMap<>();
List<Entry> allOps = this.allOperations;
Entry op1 = positionIndex.get(idx1);
Entry op2 = positionIndex.get(idx2);
for (Entry op : allOps) {
String key = op.getGroupId() + "_" + op.getSequence();
if (op1 != null && op2 != null) {
if (Math.abs(op1.getPriority() - op2.getPriority()) < 0.001) {
int value = os.remove(idx1);
os.add(idx2, value);
neighbor.setOperationSequencing(os);
break;
}
}
}
index.put(key, op);
index2.put(op.getId(), op);
}
return neighbor;
index0.put(1,index);
index0.put(2,index2);
return index0;
}
/**
* 生成机器选择邻域解 - 不受优先级限制
* 解码染色体
*/
private Chromosome generateMachineChangeNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> ms = neighbor.getMachineSelection();
if (!ms.isEmpty()) {
int idx = rnd.nextInt(ms.size());
GlobalOperationInfo globalOp = chromosome.getGlobalOpList().get(idx);
Entry op = globalOp.getOp();
if (op.getMachineOptions().size() > 1) {
int currentMachineSeq = ms.get(idx);
List<Integer> availableMachines = new ArrayList<>();
for (int i = 1; i <= op.getMachineOptions().size(); i++) {
if (i != currentMachineSeq) {
availableMachines.add(i);
}
}
if (!availableMachines.isEmpty()) {
int newMachineSeq = availableMachines.get(rnd.nextInt(availableMachines.size()));
ms.set(idx, newMachineSeq);
neighbor.setMachineSelection(ms);
}
}
}
return neighbor;
}
/**
* 解码染色体
*/
......@@ -847,24 +496,35 @@ private Map<String, Entry> entrys;
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines, Machine.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setOrders(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(orders), Order.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setOperatRel(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(_entryRel), GroupResult.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setMaterials(ProductionDeepCopyUtil.deepCopyList(materials,Material.class)); // 简单拷贝,实际可能需要深拷贝
decoder.decodeChromosomeWithCache(chromosome);
chromosome.setAllOperations(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(allOperations), Entry.class) ); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
// chromosome.setBaseTime(param.getBaseTime());
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
// 加载锁定工单到ResultOld
List<GAScheduleResult> lockedOrders = GlobalCacheUtil.get("locked_orders_" + chromosome.getScenarioID());
if (lockedOrders != null && !lockedOrders.isEmpty()) {
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(lockedOrders, GAScheduleResult.class));
log("将 " + lockedOrders.size() + " 个锁定工单加载到初始种群中");
} else {
chromosome.setResultOld(new CopyOnWriteArrayList<>());
}
decoder.decodeChromosomeWithCache(chromosome,true);
}
/**
* 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/
private boolean isBetter(Chromosome c1, Chromosome c2) {
for (int i = 0; i < c1.getFitnessLevel().length; i++) {
double[] Fitness1 = c1.getFitnessLevel();
double[] Fitness2 = c2.getFitnessLevel();
if (Fitness1[i] > Fitness2[i]) {
return true;
}
}
return false;
return fitnessCalculator.isBetter(c1,c2);
}
private int Getbest(List<Chromosome> candidates,Chromosome best) {
// 找出最佳候选方案
......
package com.aps.service.Algorithm;
import com.aps.common.util.FileHelper;
import com.aps.common.util.GlobalCacheUtil;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.basic.*;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 禁忌搜索算法
*/
public class TabuSearch {
private final Random rnd = new Random();
private GlobalParam globalParam;
private List<Entry> allOperations;
private List<GlobalOperationInfo> globalOpList;
private FitnessCalculator fitnessCalculator;
private ObjectiveWeights objectiveWeights;
private void log(String message) {
log(message, false);
}
private void log(String message, boolean enableLogging) {
if (enableLogging) {
FileHelper.writeLogFile(message);
}
}
private FitnessCalculator fitnessCalculator;
// 禁忌表
private List<Chromosome> tabuList;
private List<String> tabuList;
private int tabuListSize = 50;
public TabuSearch(GlobalParam globalParam, List<Entry> allOperations, List<GlobalOperationInfo> globalOpList, FitnessCalculator fitnessCalculator, ObjectiveWeights objectiveWeights) {
this.globalParam = globalParam;
this.allOperations = allOperations;
this.globalOpList = globalOpList;
this.fitnessCalculator = fitnessCalculator;
this.objectiveWeights = objectiveWeights;
private List<Machine> cachedMachines;
private List<Order> cachedOrders;
private List<GroupResult> cachedEntryRel;
private List<Material> cachedMaterials;
private List<Entry> cachedAllOperations;
// 渴望准则:记录最优解的 fitness
private double[] bestFitness;
public TabuSearch(List<Entry> allOperations, List<Order> orders,
List<Material> materials,List<GroupResult> entryRel, FitnessCalculator _fitnessCalculator) {
this.tabuList = new ArrayList<>();
// 工序越多,禁忌表越长(适配1000+工序)
this.tabuListSize = Math.min(50, allOperations.size() / 30);
fitnessCalculator=_fitnessCalculator;
// 预缓存解码需要的深拷贝列表,避免重复拷贝
cachedAllOperations = ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(allOperations), Entry.class);
cachedOrders = ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(orders), Order.class);
cachedEntryRel = ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(entryRel), GroupResult.class);
cachedMaterials = ProductionDeepCopyUtil.deepCopyList(materials, Material.class);
}
/**
* 禁忌搜索
* 禁忌搜索(优化版)
*/
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
public Chromosome search(Chromosome chromosome, VariableNeighborhoodSearch vns,
GeneticDecoder decoder, List<Machine> machines) {
log("禁忌搜索 - 开始执行",true);
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
this.bestFitness = best.getFitnessLevel().clone();
writeKpi(best);
// 记录初始KPI用于计算改进率
double[] initialFitnessLevel = best.getFitnessLevel().clone();
double initialFitness = best.getFitness();
int iterations = 0;
int maxIterations = 1000;
int improveCount = 0;
int noImprovementCount = 0;
int maxNoImprovement = 100;
int maxNoImprovement = 15; // 降低到15次无改进则停止
int maxIterations = Math.min(cachedAllOperations.size(), 80); // 降低到最多80次
// 改进率监控
int stagnantWindow = 10;
int[] recentImprovements = new int[stagnantWindow];
double improvementRateThreshold = 0.1; // 10%改进率阈值
while (iterations < maxIterations && noImprovementCount < maxNoImprovement) {
// 生成邻域解
List<Chromosome> neighbors = generateNeighbors(current);
// 多样性参数
int diversificationInterval = 20; // 每20次迭代尝试一次多样化
int lastDiversificationIteration = 0;
// 过滤禁忌解
List<Chromosome> validNeighbors = filterTabuSolutions(neighbors);
log(String.format("禁忌搜索 - 参数:最大迭代=%d, 最大无改进=%d", maxIterations, maxNoImprovement));
// 评估所有邻域解
Chromosome bestNeighbor = null;
double bestNeighborFitness = Double.NEGATIVE_INFINITY;
for (int i = 0; i < maxIterations; i++) {
iterations++;
// 使用 VNS 生成邻域解(成功率排序后的策略)
Chromosome neighbor = vns.generateNeighbor(current);
for (Chromosome neighbor : validNeighbors) {
decode(decoder, neighbor, param);
if (neighbor.getFitness() > bestNeighborFitness) {
bestNeighborFitness = neighbor.getFitness();
bestNeighbor = neighbor;
if (neighbor == null) {
log("禁忌搜索 - 生成邻居失败,跳过");
noImprovementCount++;
// 记录无改进
if (iterations <= stagnantWindow) {
recentImprovements[iterations - 1] = 0;
}
continue;
}
// 先检查禁忌(不需要解码!只需要 machineSelection 和 operationSequencing)
String neighborGeneStr = neighbor.getGeneStr();
String currentGeneStr = current.getGeneStr();
boolean isTabu = isTabu(neighborGeneStr);
// 方案 1:快速跳过和 current 一样的解(不用解码!)
if (neighborGeneStr.equals(currentGeneStr)) {
// 和当前解一样,跳过,不用解码
addToTabuList(neighborGeneStr);
noImprovementCount++;
if (iterations <= stagnantWindow) {
recentImprovements[iterations - 1] = 0;
}
continue;
}
if (bestNeighbor != null) {
// 更新当前解
current = bestNeighbor;
// 添加到禁忌表(无论是否接受都先记下来)
addToTabuList(neighborGeneStr);
// 更新禁忌表
addToTabuList(current);
boolean accept = false;
boolean isBetterThanBest = false;
boolean isBetterThanCurrent = false;
// 解码(需要比较 fitness)
decode(decoder, neighbor, machines);
isBetterThanBest = isBetter(neighbor, best);
isBetterThanCurrent = isBetter(neighbor, current);
// 判断是否接受这个邻居
if (!isTabu) {
// 非禁忌,接受
accept = true;
} else if (isBetterThanBest) {
// 禁忌但比最优解好(渴望准则),接受
log("禁忌搜索 - 触发渴望准则,接受禁忌解");
accept = true;
}
// else:禁忌且没有比最优解好,不接受
boolean improvedThisIteration = false;
if (accept) {
// 接受这个邻居
current = ProductionDeepCopyUtil.deepCopy(neighbor, Chromosome.class);
// 更新最优解
if (isBetter(current, best)) {
best = current;
if (isBetterThanBest) {
best = ProductionDeepCopyUtil.deepCopy(current, Chromosome.class);
this.bestFitness = best.getFitnessLevel().clone();
writeKpi(best);
noImprovementCount = 0;
improveCount++;
improvedThisIteration = true;
logTabuImprovement(best, initialFitnessLevel, initialFitness, iterations);
log(String.format("禁忌搜索 - 找到更好解,迭代=%d", iterations),true);
} else if (isBetterThanCurrent) {
// 比当前解好但没有比最优解好
noImprovementCount = 0;
improvedThisIteration = true;
} else {
// 没有改进
noImprovementCount++;
}
} else {
// 不接受,无改进计数+1
noImprovementCount++;
}
iterations++;
// 记录本次改进情况
if (iterations <= stagnantWindow) {
recentImprovements[iterations - 1] = improvedThisIteration ? 1 : 0;
}
return best;
// 每10次迭代输出一次状态
if (iterations % 10 == 0) {
log(String.format("禁忌搜索 - 迭代%d/%d, 改进数=%d, 无改进连续=%d, 改进率=%.2f%%",
iterations, maxIterations, improveCount, noImprovementCount,
iterations > 0 ? (double)improveCount / iterations * 100 : 0));
}
/**
* 生成邻域解
*/
private List<Chromosome> generateNeighbors(Chromosome chromosome) {
List<Chromosome> neighbors = new ArrayList<>();
// 生成多个邻域解
for (int i = 0; i < 10; i++) {
int neighborType = rnd.nextInt(4);
switch (neighborType) {
case 0:
neighbors.add(generateSwapNeighbor(chromosome));
break;
case 1:
neighbors.add(generateReverseNeighbor(chromosome));
break;
case 2:
neighbors.add(generateInsertNeighbor(chromosome));
break;
case 3:
neighbors.add(generateMachineChangeNeighbor(chromosome));
break;
}
}
// 检查提前停止条件
boolean shouldStop = false;
String stopReason = "";
return neighbors;
if (noImprovementCount >= maxNoImprovement) {
shouldStop = true;
stopReason = String.format("连续%d次无改进", maxNoImprovement);
} else if (iterations >= stagnantWindow) {
double recentImproveRate = calculateRecentImprovementRate(recentImprovements, stagnantWindow);
if (recentImproveRate < improvementRateThreshold) {
shouldStop = true;
stopReason = String.format("最近%d次迭代改进率过低(%.2f%%)", stagnantWindow, recentImproveRate * 100);
}
}
/**
* 过滤禁忌解
*/
private List<Chromosome> filterTabuSolutions(List<Chromosome> neighbors) {
List<Chromosome> validNeighbors = new ArrayList<>();
for (Chromosome neighbor : neighbors) {
if (!isTabu(neighbor)) {
validNeighbors.add(neighbor);
if (shouldStop) {
log(String.format("禁忌搜索 - 提前停止:%s", stopReason));
logTabuFinalSummary(best, initialFitnessLevel, initialFitness, iterations, improveCount);
break;
}
}
// 如果没有有效邻域解,返回所有邻域解
if (validNeighbors.isEmpty()) {
return neighbors;
logTabuFinalSummary(best, initialFitnessLevel, initialFitness, iterations, improveCount);
log(String.format("禁忌搜索 - 结束,总迭代=%d", iterations),true);
return best;
}
private void writeKpi(Chromosome chromosome) {
String fitness = "";
double[] fitness1 = chromosome.getFitnessLevel();
for (int i = 0; i < fitness1.length; i++) {
return validNeighbors;
fitness += fitness1[i] + ",";
}
log(String.format("变邻域搜索 - kpi:%s", fitness),true);
}
/**
* 检查解是否在禁忌表中
* 记录禁忌搜索改进详情
*/
private boolean isTabu(Chromosome chromosome) {
for (Chromosome tabuChromosome : tabuList) {
if (chromosome.getGeneStr().equals(tabuChromosome.getGeneStr())) {
return true;
}
private void logTabuImprovement(Chromosome best, double[] initialFitnessLevel, double initialFitness, int iteration) {
StringBuilder sb = new StringBuilder("禁忌搜索 - 改进详情: 迭代" + iteration + ", ");
double[] currentFitness = best.getFitnessLevel();
for (int i = 0; i < currentFitness.length; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(+%.4f) ", i+1, initialFitnessLevel[i], currentFitness[i], improvement));
}
return false;
double totalImprovement = best.getFitness() - initialFitness;
sb.append(String.format("总Fitness: %.4f→%.4f(+%.4f)", initialFitness, best.getFitness(), totalImprovement));
log(sb.toString());
}
/**
* 添加解到禁忌表
* 计算最近改进率
*/
private void addToTabuList(Chromosome chromosome) {
tabuList.add(chromosome);
if (tabuList.size() > tabuListSize) {
tabuList.remove(0);
private double calculateRecentImprovementRate(int[] recentImprovements, int windowSize) {
int improveCount = 0;
for (int i = 0; i < windowSize; i++) {
improveCount += recentImprovements[i];
}
return (double) improveCount / windowSize;
}
/**
* 生成交换邻域解
* 记录禁忌搜索最终总结
*/
private Chromosome generateSwapNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
while (idx2 == idx1) {
idx2 = rnd.nextInt(os.size());
}
Collections.swap(os, idx1, idx2);
neighbor.setOperationSequencing(os);
}
return neighbor;
private void logTabuFinalSummary(Chromosome best, double[] initialFitnessLevel, double initialFitness,
int totalIterations, int improveCount) {
StringBuilder sb = new StringBuilder("禁忌搜索 - 最终总结: ");
double[] currentFitness = best.getFitnessLevel();
sb.append(String.format("总迭代%d次, 成功改进%d次, 改进率%.2f%%. ",
totalIterations, improveCount, totalIterations > 0 ? (double)improveCount / totalIterations * 100 : 0));
for (int i = 0; i < currentFitness.length; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i],
initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0));
}
double totalImprovement = best.getFitness() - initialFitness;
sb.append(String.format("总Fitness: %.4f→%.4f(%.2f%%)", initialFitness, best.getFitness(),
initialFitness > 0 ? totalImprovement / initialFitness * 100 : 0));
log(sb.toString());
}
/**
* 生成反转邻域解
* 检查解是否在禁忌表中
*/
private Chromosome generateReverseNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int start = rnd.nextInt(os.size());
int end = rnd.nextInt(os.size());
while (end <= start) {
end = rnd.nextInt(os.size());
}
Collections.reverse(os.subList(start, end + 1));
neighbor.setOperationSequencing(os);
}
return neighbor;
public boolean isTabu(String GeneStr) {
return tabuList.contains(GeneStr);
}
/**
* 生成插入邻域解
* 添加解到禁忌表(FIFO策略)
*/
private Chromosome generateInsertNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
while (idx2 == idx1) {
idx2 = rnd.nextInt(os.size());
}
int value = os.remove(idx1);
os.add(idx2, value);
neighbor.setOperationSequencing(os);
public void addToTabuList(String geneStr) {
tabuList.add(geneStr);
if (tabuList.size() > tabuListSize) {
// 移除最早加入的禁忌解
tabuList.remove(0);
}
return neighbor;
}
/**
* 生成机器选择邻域解
*/
private Chromosome generateMachineChangeNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> ms = neighbor.getMachineSelection();
if (!ms.isEmpty()) {
int idx = rnd.nextInt(ms.size());
GlobalOperationInfo globalOp = globalOpList.get(idx);
Entry op = globalOp.getOp();
if (op.getMachineOptions().size() > 1) {
int currentMachineSeq = ms.get(idx);
List<Integer> availableMachines = new ArrayList<>();
for (int i = 1; i <= op.getMachineOptions().size(); i++) {
if (i != currentMachineSeq) {
availableMachines.add(i);
}
}
private void decode(GeneticDecoder decoder, Chromosome chromosome , List<Machine> machines) {
chromosome.setResult(new CopyOnWriteArrayList<>());
if (!availableMachines.isEmpty()) {
int newMachineSeq = availableMachines.get(rnd.nextInt(availableMachines.size()));
ms.set(idx, newMachineSeq);
neighbor.setMachineSelection(ms);
}
}
}
return neighbor;
// 缓存 Machine 列表(第一次调用时缓存)
if (cachedMachines == null) {
cachedMachines = ProductionDeepCopyUtil.deepCopyList(machines, Machine.class);
}
/**
* 解码染色体
*/
private void decode(GeneticDecoder decoder, Chromosome chromosome, ScheduleParams param) {
chromosome.setResult(new java.util.concurrent.CopyOnWriteArrayList<>());
decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(fitnessCalculator.calculateFitness(chromosome, objectiveWeights));
// 使用缓存的列表,避免重复深拷贝
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(cachedMachines, Machine.class));
chromosome.setOrders(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(cachedOrders), Order.class));
chromosome.setOperatRel(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(cachedEntryRel), GroupResult.class));
chromosome.setMaterials(ProductionDeepCopyUtil.deepCopyList(cachedMaterials, Material.class));
chromosome.setAllOperations(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(cachedAllOperations), Entry.class));
// 加载锁定工单到ResultOld
List<GAScheduleResult> lockedOrders = GlobalCacheUtil.get("locked_orders_" + chromosome.getScenarioID());
if (lockedOrders != null && !lockedOrders.isEmpty()) {
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(lockedOrders, GAScheduleResult.class));
} else {
chromosome.setResultOld(new CopyOnWriteArrayList<>());
}
decoder.decodeChromosomeWithCache(chromosome,true);
}
/**
* 比较两个染色体的优劣
* 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/
private boolean isBetter(Chromosome c1, Chromosome c2) {
return c1.getFitness() > c2.getFitness();
return fitnessCalculator.isBetter(c1,c2);
}
}
\ No newline at end of file
package com.aps.service.Algorithm;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import java.util.*;
/**
* 禁忌搜索+模拟退火混合算法
*/
public class TabuSearchWithSA {
private final Random rnd = new Random();
private GlobalParam globalParam;
private List<Entry> allOperations;
private List<GlobalOperationInfo> globalOpList;
private FitnessCalculator fitnessCalculator;
private ObjectiveWeights objectiveWeights;
// 禁忌表
private List<Chromosome> tabuList;
private int tabuListSize = 50;
public TabuSearchWithSA(GlobalParam globalParam, List<Entry> allOperations, List<GlobalOperationInfo> globalOpList, FitnessCalculator fitnessCalculator, ObjectiveWeights objectiveWeights) {
this.globalParam = globalParam;
this.allOperations = allOperations;
this.globalOpList = globalOpList;
this.fitnessCalculator = fitnessCalculator;
this.objectiveWeights = objectiveWeights;
this.tabuList = new ArrayList<>();
}
/**
* 禁忌搜索+模拟退火混合搜索
*/
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
// 初始化温度
double temperature = 100.0;
double coolingRate = 0.95;
int iterations = 0;
int maxIterations = 1000;
int noImprovementCount = 0;
int maxNoImprovement = 100;
while (iterations < maxIterations && noImprovementCount < maxNoImprovement) {
// 生成邻域解
List<Chromosome> neighbors = generateNeighbors(current);
// 过滤禁忌解
List<Chromosome> validNeighbors = filterTabuSolutions(neighbors);
// 评估所有邻域解
Chromosome bestNeighbor = null;
double bestNeighborFitness = Double.NEGATIVE_INFINITY;
for (Chromosome neighbor : validNeighbors) {
decode(decoder, neighbor, param);
if (neighbor.getFitness() > bestNeighborFitness) {
bestNeighborFitness = neighbor.getFitness();
bestNeighbor = neighbor;
}
}
if (bestNeighbor != null) {
// 计算能量差
decode(decoder, current, param);
double energyDifference = bestNeighbor.getFitness() - current.getFitness();
// 结合模拟退火的概率接受机制
if (energyDifference > 0 || rnd.nextDouble() < Math.exp(energyDifference / temperature)) {
// 更新当前解
current = bestNeighbor;
// 更新禁忌表
addToTabuList(current);
// 更新最优解
if (isBetter(current, best)) {
best = current;
noImprovementCount = 0;
} else {
noImprovementCount++;
}
}
}
// 降温
temperature *= coolingRate;
iterations++;
}
return best;
}
/**
* 生成邻域解
*/
private List<Chromosome> generateNeighbors(Chromosome chromosome) {
List<Chromosome> neighbors = new ArrayList<>();
// 生成多个邻域解
for (int i = 0; i < 10; i++) {
int neighborType = rnd.nextInt(4);
switch (neighborType) {
case 0:
neighbors.add(generateSwapNeighbor(chromosome));
break;
case 1:
neighbors.add(generateReverseNeighbor(chromosome));
break;
case 2:
neighbors.add(generateInsertNeighbor(chromosome));
break;
case 3:
neighbors.add(generateMachineChangeNeighbor(chromosome));
break;
}
}
return neighbors;
}
/**
* 过滤禁忌解
*/
private List<Chromosome> filterTabuSolutions(List<Chromosome> neighbors) {
List<Chromosome> validNeighbors = new ArrayList<>();
for (Chromosome neighbor : neighbors) {
if (!isTabu(neighbor)) {
validNeighbors.add(neighbor);
}
}
// 如果没有有效邻域解,返回所有邻域解
if (validNeighbors.isEmpty()) {
return neighbors;
}
return validNeighbors;
}
/**
* 检查解是否在禁忌表中
*/
private boolean isTabu(Chromosome chromosome) {
for (Chromosome tabuChromosome : tabuList) {
if (chromosome.getGeneStr().equals(tabuChromosome.getGeneStr())) {
return true;
}
}
return false;
}
/**
* 添加解到禁忌表
*/
private void addToTabuList(Chromosome chromosome) {
tabuList.add(chromosome);
if (tabuList.size() > tabuListSize) {
tabuList.remove(0);
}
}
/**
* 生成交换邻域解
*/
private Chromosome generateSwapNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
while (idx2 == idx1) {
idx2 = rnd.nextInt(os.size());
}
Collections.swap(os, idx1, idx2);
neighbor.setOperationSequencing(os);
}
return neighbor;
}
/**
* 生成反转邻域解
*/
private Chromosome generateReverseNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int start = rnd.nextInt(os.size());
int end = rnd.nextInt(os.size());
while (end <= start) {
end = rnd.nextInt(os.size());
}
Collections.reverse(os.subList(start, end + 1));
neighbor.setOperationSequencing(os);
}
return neighbor;
}
/**
* 生成插入邻域解
*/
private Chromosome generateInsertNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
while (idx2 == idx1) {
idx2 = rnd.nextInt(os.size());
}
int value = os.remove(idx1);
os.add(idx2, value);
neighbor.setOperationSequencing(os);
}
return neighbor;
}
/**
* 生成机器选择邻域解
*/
private Chromosome generateMachineChangeNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> ms = neighbor.getMachineSelection();
if (!ms.isEmpty()) {
int idx = rnd.nextInt(ms.size());
GlobalOperationInfo globalOp = globalOpList.get(idx);
Entry op = globalOp.getOp();
if (op.getMachineOptions().size() > 1) {
int currentMachineSeq = ms.get(idx);
List<Integer> availableMachines = new ArrayList<>();
for (int i = 1; i <= op.getMachineOptions().size(); i++) {
if (i != currentMachineSeq) {
availableMachines.add(i);
}
}
if (!availableMachines.isEmpty()) {
int newMachineSeq = availableMachines.get(rnd.nextInt(availableMachines.size()));
ms.set(idx, newMachineSeq);
neighbor.setMachineSelection(ms);
}
}
}
return neighbor;
}
/**
* 解码染色体
*/
private void decode(GeneticDecoder decoder, Chromosome chromosome, ScheduleParams param) {
chromosome.setResult(new java.util.concurrent.CopyOnWriteArrayList<>());
decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(fitnessCalculator.calculateFitness(chromosome, objectiveWeights));
}
}
/**
* 比较两个染色体的优劣
*/
private boolean isBetter(Chromosome c1, Chromosome c2) {
return c1.getFitness() > c2.getFitness();
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -222,7 +222,7 @@ public class PlanResultService {
lockedOrderProcessorService.markLockedOrdersOccupiedTime(machines, timeConfig.getBaseTime());
// 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,Materials1,materialIds,machineScheduler,entryRel,materialRequirementService,_sceneService,SceneId); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
HybridAlgorithm scheduler =new HybridAlgorithm(globalParam,machines,orders,Materials1,materialIds,machineScheduler,entryRel,materialRequirementService,_sceneService,SceneId); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
param.initAdaptiveParams(entrys.size());
double[] customWeights = new double[] { 0.4, 0.1, 0.1, 0.1, 0.3 }; // 延迟时间权重提升到0.5
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
......@@ -238,7 +238,7 @@ public class PlanResultService {
_sceneService.saveChromosomeToFile(chromosome, SceneId);
WriteScheduleSummary(chromosome);
// WriteScheduleSummary(chromosome);
return chromosome;
......
......@@ -132,7 +132,7 @@ public class SceneService {
try {
ObjectMapper objectMapper = createObjectMapper();
SceneChromsome sceneChromsome=(SceneChromsome)redisUtils.get("SceneId."+sceneId);
SceneChromsome sceneChromsome=null;//(SceneChromsome)redisUtils.get("SceneId."+sceneId);
if(sceneChromsome==null)
{
sceneChromsome=new SceneChromsome();
......@@ -163,7 +163,7 @@ public class SceneService {
sceneChromsome.getSceneDetails().add(sceneDetail);
redisUtils.set("SceneId."+sceneId,sceneChromsome);
// redisUtils.set("SceneId."+sceneId,sceneChromsome);
File file = getChromosomeFile(sceneId,sceneChromsome.getVersion().toString());
......
......@@ -39,7 +39,8 @@ public class PlanResultServiceTest {
// TestSortService sortService=new TestSortService();
// sortService.test1();
// nsgaiiUtils.Test();
planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4");//2000
planResultService.execute2("08B1D87FE1B84ECDBAC2E546DDB6FB81");//2000
// planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4");//2000
// planResultService.execute2("C8B533BD8944405B9A2F8823C575C204");//500
// planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");//20
// 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