Commit 4e4ca06f authored by Tong Li's avatar Tong Li

优化速度

parent d49ae691
...@@ -20,8 +20,8 @@ public class ScheduleParams { ...@@ -20,8 +20,8 @@ public class ScheduleParams {
private static final int MAX_MAX_ITERATIONS = 200; private static final int MAX_MAX_ITERATIONS = 200;
private static final float MIN_CROSSOVER_PROB = 0.6f; private static final float MIN_CROSSOVER_PROB = 0.6f;
private static final float MAX_CROSSOVER_PROB = 0.9f; private static final float MAX_CROSSOVER_PROB = 0.9f;
private static final float MIN_MUTATION_PROB = 0.3f; private static final float MIN_MUTATION_PROB = 0.2f;
private static final float MAX_MUTATION_PROB = 0.7f; private static final float MAX_MUTATION_PROB = 0.5f;
private static final int MIN_TOURNAMENT_SIZE = 3; private static final int MIN_TOURNAMENT_SIZE = 3;
private static final int MAX_TOURNAMENT_SIZE = 7; private static final int MAX_TOURNAMENT_SIZE = 7;
...@@ -81,6 +81,13 @@ public class ScheduleParams { ...@@ -81,6 +81,13 @@ public class ScheduleParams {
return maxIterations; return maxIterations;
} }
/// <summary>
/// 交叉概率
/// </summary>
public float setCrossoverProb(float crossoverProb) {
return this.crossoverProb=crossoverProb;
}
/// <summary> /// <summary>
/// 交叉概率 /// 交叉概率
/// </summary> /// </summary>
...@@ -235,6 +242,26 @@ public class ScheduleParams { ...@@ -235,6 +242,26 @@ public class ScheduleParams {
} }
} }
public void fineTuneParams() {
// 适应度标准差阈值(可调整):小于0.05视为收敛过慢,大于0.2视为收敛过快
final float LOW_STD_THRESHOLD = 0.05f;
final float HIGH_STD_THRESHOLD = 0.2f;
final float ADJUST_STEP = 0.05f; // 调整步长
DecimalFormat df = new DecimalFormat("#.000");
// 1. 收敛过慢(适应度方差小):增加变异概率,降低交叉概率
mutationProb = Math.max(MIN_MUTATION_PROB,
Math.min(MAX_MUTATION_PROB, mutationProb + 0.05f));
crossoverProb = Math.max(MIN_CROSSOVER_PROB,
Math.min(MAX_CROSSOVER_PROB, crossoverProb - 0.1f));
}
// 测试示例 // 测试示例
public void test() { public void test() {
ScheduleParams params = new ScheduleParams(); ScheduleParams params = new ScheduleParams();
......
...@@ -13,6 +13,9 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -13,6 +13,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -98,7 +101,7 @@ public class GeneticAlgorithm { ...@@ -98,7 +101,7 @@ public class GeneticAlgorithm {
List<Chromosome> population = initialization.generateInitialPopulation(param, globalOpList); List<Chromosome> population = initialization.generateInitialPopulation(param, globalOpList);
//population= chromosomeDistinct(population); population= chromosomeDistinct(population);
...@@ -137,8 +140,14 @@ public class GeneticAlgorithm { ...@@ -137,8 +140,14 @@ public class GeneticAlgorithm {
} }
FileHelper.writeLogFile("选择操作-----------开始-------"); 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(population); List<Chromosome> selected = geneticOps.tournamentSelection(validPopulation);
FileHelper.writeLogFile("选择操作-----------结束-------"); FileHelper.writeLogFile("选择操作-----------结束-------");
// 交叉操作 // 交叉操作
FileHelper.writeLogFile("交叉操作-----------开始-------"); FileHelper.writeLogFile("交叉操作-----------开始-------");
...@@ -178,7 +187,7 @@ public class GeneticAlgorithm { ...@@ -178,7 +187,7 @@ public class GeneticAlgorithm {
FileHelper.writeLogFile("变异批量解码-----------开始-------"); FileHelper.writeLogFile("变异批量解码-----------开始-------");
nextPopulation= chromosomeDistinct(nextPopulation);
Chromosomedecode(param,allOperations,globalOpList,nextPopulation); Chromosomedecode(param,allOperations,globalOpList,nextPopulation);
FileHelper.writeLogFile("变异批量解码-----------结束-------"); FileHelper.writeLogFile("变异批量解码-----------结束-------");
// // 精英保留 // // 精英保留
...@@ -192,7 +201,7 @@ public class GeneticAlgorithm { ...@@ -192,7 +201,7 @@ public class GeneticAlgorithm {
List<Chromosome> newPopulation = new ArrayList<>(); List<Chromosome> newPopulation = new ArrayList<>();
newPopulation.addAll(population); newPopulation.addAll(population);
newPopulation.addAll(nextPopulation); newPopulation.addAll(nextPopulation);
newPopulation= chromosomeDistinct(newPopulation); newPopulation= chromosomeDistinct1(newPopulation);
FileHelper.writeLogFile("非支配排序-----------开始-------"); FileHelper.writeLogFile("非支配排序-----------开始-------");
// 2.7 非支配排序 // 2.7 非支配排序
List<List<Chromosome>> combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(newPopulation); List<List<Chromosome>> combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(newPopulation);
...@@ -208,19 +217,26 @@ public class GeneticAlgorithm { ...@@ -208,19 +217,26 @@ public class GeneticAlgorithm {
best= GetBest(combinedFronts,String.valueOf(iter)); best= GetBest(combinedFronts,String.valueOf(iter));
if(bestFitness<best.getFitness()) if(bestFitness<best.getFitness())
{ {
bestFitness=best.getFitness(); bestFitness=best.getFitness();
Iteration=1; Iteration=1;
}else { }else {
Iteration++; Iteration++;
if (Iteration > 5) {
// 当连续 5 代无最优解提升时,降低交叉概率(如从 0.8 降至 0.5)、提高变异概率(如从 0.1 升至 0.2)
param.fineTuneParams();
}
} }
if(Iteration>10) if(Iteration>10)
{ {
break; break;
} }
// 当种群适应度标准差小于阈值(如 0.001)时,说明种群已收敛,提前终止迭代
fitnessStd = _fitnessCalculator.calculateFitnessStd(population);
if (fitnessStd < 0.001) {
FileHelper.writeLogFile("种群已收敛,提前终止迭代");
break;
}
FileHelper.writeLogFile("迭代进化------"+iter+"-----结束-------"); FileHelper.writeLogFile("迭代进化------"+iter+"-----结束-------");
} }
...@@ -256,11 +272,9 @@ public class GeneticAlgorithm { ...@@ -256,11 +272,9 @@ public class GeneticAlgorithm {
// WriteKpi(best,"最大"); // WriteKpi(best,"最大");
return best; return best;
} }
private List<Chromosome> chromosomeDistinct(List<Chromosome> population) private List<Chromosome> chromosomeDistinct(List<Chromosome> population)
{ {
if(orders.size()<10)
{
population = population.stream() population = population.stream()
.collect(Collectors.toMap( .collect(Collectors.toMap(
Chromosome::getGeneStr, // key:去重的字段(GeneStr) Chromosome::getGeneStr, // key:去重的字段(GeneStr)
...@@ -270,7 +284,22 @@ public class GeneticAlgorithm { ...@@ -270,7 +284,22 @@ public class GeneticAlgorithm {
.values() // 获取去重后的 .values() // 获取去重后的
.stream() .stream()
.collect(Collectors.toList()); .collect(Collectors.toList());
return population;
} }
private List<Chromosome> chromosomeDistinct1(List<Chromosome> population)
{
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; return population;
} }
...@@ -292,6 +321,7 @@ public class GeneticAlgorithm { ...@@ -292,6 +321,7 @@ public class GeneticAlgorithm {
FileHelper.writeLogFile(String.format(" KPI---%f-------",d)); FileHelper.writeLogFile(String.format(" KPI---%f-------",d));
} }
} }
private ExecutorService decodeExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population) private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population)
{ {
...@@ -299,13 +329,19 @@ public class GeneticAlgorithm { ...@@ -299,13 +329,19 @@ public class GeneticAlgorithm {
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,orderMaterials); GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,orderMaterials);
if(population!=null&&population.size()>0) { CompletableFuture.allOf(population.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> decode(decoder,chromosome,param,allOperations,globalOpList), decodeExecutor))
.toArray(CompletableFuture[]::new))
.join();
if(1==2) {
if (population != null && population.size() > 0) {
population.parallelStream().forEach(chromosome -> { population.parallelStream().forEach(chromosome -> {
chromosome.setResult(new ArrayList<>()); chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射 // 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝 // chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝 chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(allOperations); // 简单拷贝,实际可能需要深拷贝 chromosome.setAllOperations(allOperations); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝 chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights); //chromosome.setObjectiveWeights(_objectiveWeights);
...@@ -314,12 +350,31 @@ public class GeneticAlgorithm { ...@@ -314,12 +350,31 @@ public class GeneticAlgorithm {
decoder.decodeChromosomeWithCache(chromosome); decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) { if (chromosome.getFitness() == 0) {
chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome,_objectiveWeights)); chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights));
} }
}); });
} }
} }
}
private void decode(GeneticDecoder decoder,Chromosome chromosome,ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList) {
chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(allOperations); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
chromosome.setBaseTime(param.getBaseTime());
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights));
}
}
} }
...@@ -33,11 +33,80 @@ public class GeneticOperations { ...@@ -33,11 +33,80 @@ public class GeneticOperations {
* 锦标赛选择 * 锦标赛选择
*/ */
public List<Chromosome> tournamentSelection(List<Chromosome> population, int tournamentSize) { public List<Chromosome> tournamentSelection(List<Chromosome> population, int tournamentSize) {
// 前置边界校验(避免NPE和无效计算)
if (population == null || population.isEmpty()) {
return new ArrayList<>();
}
int populationSize = population.size();
// 预计算需要选中的个体数量,避免动态判断
int needSelectCount = populationSize - Math.max(1, Math.min(tournamentSize, populationSize));
List<Chromosome> selected = new ArrayList<>(needSelectCount); // 预初始化容量
// 边界值处理:锦标赛规模不能超过种群规模,且至少为1
int effectiveTournamentSize = Math.max(1, Math.min(tournamentSize, populationSize));
List<Chromosome> selectedtemp = new ArrayList<>(needSelectCount); // 预初始化容量
// 预生成随机索引,减少Random对象创建开销
Random random = this.rnd;
// 固定次数循环,替代动态终止条件
for (int selectIdx = 0; selectIdx < needSelectCount; selectIdx++) {
// 优化1:Fisher-Yates抽样(无重复、无冲突,比HashSet高效)
List<Integer> indices = new ArrayList<>(populationSize);
for (int i = 0; i < populationSize; i++) {
indices.add(i);
}
// 仅打乱前effectiveTournamentSize个索引,减少计算量
for (int i = 0; i < effectiveTournamentSize; i++) {
int swapIdx = i + random.nextInt(populationSize - i);
Collections.swap(indices, i, swapIdx);
}
Chromosome bestCandidate=null;
for (int i = 0; i < effectiveTournamentSize; i++) {
int idx = indices.get(i);
Chromosome curr= population.get(idx);
if(bestCandidate!=null)
{
int rankCompare = Integer.compare(curr.getRank(), bestCandidate.getRank());
if(rankCompare==0)
{
int crowdingCompare = Double.compare(curr.getCrowdingDistance(), bestCandidate.getCrowdingDistance());
if(crowdingCompare<0)
{
bestCandidate=curr;
}
}else {
if(rankCompare<0)
{
bestCandidate=curr;
}
}
}else {
bestCandidate=curr;
}
}
if (bestCandidate != null) {
selected.add(bestCandidate);
}
}
return selected;// ProductionDeepCopyUtil.deepCopyList(selected, Chromosome.class);
}
/**
* 锦标赛选择
*/
public List<Chromosome> tournamentSelection1(List<Chromosome> population, int tournamentSize) {
int populationSize = population.size(); int populationSize = population.size();
List<Chromosome> selected = new ArrayList<>(); // 预初始化容量 List<Chromosome> selected = new ArrayList<>(); // 预初始化容量
// 边界值处理:锦标赛规模不能超过种群规模,且至少为1 // 边界值处理:锦标赛规模不能超过种群规模,且至少为1
int effectiveTournamentSize = Math.max(1, Math.min(tournamentSize, populationSize)); int effectiveTournamentSize = Math.max(1, Math.min(tournamentSize, populationSize));
while (selected.size() < populationSize-tournamentSize) { while (selected.size() < populationSize-tournamentSize) {
// 优化1:不复制整个种群,直接随机抽取有效锦标赛规模的个体,避免大量内存拷贝和shuffle开销 // 优化1:不复制整个种群,直接随机抽取有效锦标赛规模的个体,避免大量内存拷贝和shuffle开销
...@@ -60,6 +129,7 @@ public class GeneticOperations { ...@@ -60,6 +129,7 @@ public class GeneticOperations {
return selected; return selected;
} }
// 重载,使用默认锦标赛大小3 // 重载,使用默认锦标赛大小3
public List<Chromosome> tournamentSelection(List<Chromosome> population) { public List<Chromosome> tournamentSelection(List<Chromosome> population) {
return tournamentSelection(population, param.getTournamentSize()); return tournamentSelection(population, param.getTournamentSize());
...@@ -259,8 +329,8 @@ public class GeneticOperations { ...@@ -259,8 +329,8 @@ public class GeneticOperations {
.findFirst().orElse(0); .findFirst().orElse(0);
List<Integer> MachineSelections= chromosome.getMachineSelection();
int machineSeq = chromosome.getMachineSelection().get(pos); int machineSeq = MachineSelections.get(pos);
// 选择当前所选设备外最短加工时间的机器 // 选择当前所选设备外最短加工时间的机器
...@@ -274,7 +344,8 @@ public class GeneticOperations { ...@@ -274,7 +344,8 @@ public class GeneticOperations {
.orElse(currentMachine); // 如果没有其他机器,保持当前 .orElse(currentMachine); // 如果没有其他机器,保持当前
machineSeq = optionalMachines.indexOf(minLoadMachine) + 1; machineSeq = optionalMachines.indexOf(minLoadMachine) + 1;
chromosome.getMachineSelection().set(pos, machineSeq); MachineSelections.set(pos, machineSeq);
chromosome.setMachineSelection(MachineSelections);
i++; i++;
} }
...@@ -298,6 +369,7 @@ public class GeneticOperations { ...@@ -298,6 +369,7 @@ public class GeneticOperations {
// 交换位置 // 交换位置
List<Integer> os = chromosome.getOperationSequencing(); List<Integer> os = chromosome.getOperationSequencing();
Collections.swap(os, idx1, idx2); Collections.swap(os, idx1, idx2);
chromosome.setOperationSequencing(os);
} else { } else {
// 反转:仅对高优先级工序集中的子序列反转 // 反转:仅对高优先级工序集中的子序列反转
OperationSequencingWeight osStart = selectHighPriorityIndex(chromosome.getOperationSequencing(), 0); OperationSequencingWeight osStart = selectHighPriorityIndex(chromosome.getOperationSequencing(), 0);
...@@ -318,6 +390,7 @@ public class GeneticOperations { ...@@ -318,6 +390,7 @@ public class GeneticOperations {
int pos2 = end - i; int pos2 = end - i;
Collections.swap(os, pos1, pos2); Collections.swap(os, pos1, pos2);
} }
chromosome.setOperationSequencing(os);
} }
} }
......
...@@ -668,7 +668,7 @@ public class IdGroupingWithDualSerial { ...@@ -668,7 +668,7 @@ public class IdGroupingWithDualSerial {
nodeInfo.getNewParentIds().isEmpty() ? "无" : nodeInfo.getNewParentIds(), nodeInfo.getNewParentIds().isEmpty() ? "无" : nodeInfo.getNewParentIds(),
nodeInfo.getNewChildIds()); nodeInfo.getNewChildIds());
} }
System.out.println("------------------------"); // System.out.println("------------------------");
} }
} }
} }
...@@ -65,7 +65,7 @@ int populationSize=param.getPopulationSize(); ...@@ -65,7 +65,7 @@ int populationSize=param.getPopulationSize();
.forEach(i -> { .forEach(i -> {
Chromosome chromo = new Chromosome(); // 初始化染色体 Chromosome chromo = new Chromosome(); // 初始化染色体
// chromo.setObjectiveWeights(_objectiveWeights); // chromo.setObjectiveWeights(_objectiveWeights);
chromo.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // chromo.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines));
chromo.setOrders(orders); chromo.setOrders(orders);
// 全局选择(GS):按GlobalOpId顺序生成MachineSelection // 全局选择(GS):按GlobalOpId顺序生成MachineSelection
if (i < gsCount) { if (i < gsCount) {
......
...@@ -129,7 +129,7 @@ public class MachineCalculator { ...@@ -129,7 +129,7 @@ public class MachineCalculator {
st = shiftStart; st = shiftStart;
remainingTime = processingTime; remainingTime = processingTime;
prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0, 0); prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0, 0);
oldTimes.addAll(ProductionDeepCopyUtil.deepCopyList(times)); oldTimes.addAll(ProductionDeepCopyUtil.deepCopyList(times,ScheduleResultDetail.class));
times.clear(); times.clear();
continue; continue;
} }
...@@ -538,15 +538,19 @@ i++; ...@@ -538,15 +538,19 @@ i++;
if (newSegments == null || newSegments.isEmpty()) { if (newSegments == null || newSegments.isEmpty()) {
return; return;
} }
List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability());
availabilitySnapshot.addAll(newSegments);
List<TimeSegment> mergedSegments = MergeSegments(availabilitySnapshot);
// 追加新片段,对应C#的 machine.Availability.AddRange(newSegments) synchronized (machine.getAvailability()) {
machine.getAvailability().addAll(newSegments); // 合并片段(去重+排序),
// 合并片段(去重+排序),并重新赋值给设备的可用片段列表,对应C#的 machine.Availability = MergeSegments(...)
List<TimeSegment> mergedSegments = MergeSegments(machine.getAvailability());
machine.setAvailability(mergedSegments); machine.setAvailability(mergedSegments);
} }
}
private boolean CheckTask(Machine machine,List<GAScheduleResult> machineTasks,LocalDateTime prevEnd,LocalDateTime shiftStart) { private boolean CheckTask(Machine machine,List<GAScheduleResult> machineTasks,LocalDateTime prevEnd,LocalDateTime shiftStart) {
LocalDateTime finalPrevEnd = prevEnd; LocalDateTime finalPrevEnd = prevEnd;
boolean hasTask = machineTasks.stream() boolean hasTask = machineTasks.stream()
...@@ -572,10 +576,10 @@ i++; ...@@ -572,10 +576,10 @@ i++;
*/ */
private TimeSegment GetCurrentOrNextShift(Machine machine, LocalDateTime time, String prevtime, boolean checkprevtime) { private TimeSegment GetCurrentOrNextShift(Machine machine, LocalDateTime time, String prevtime, boolean checkprevtime) {
TimeSegment start = null; TimeSegment start = null;
List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability());
if(machine.getAvailability()!=null) if (!availabilitySnapshot.isEmpty())
{ {
start = machine.getAvailability().stream() start = availabilitySnapshot.stream()
.filter(slot -> !slot.isUsed() && slot.getType() != SegmentType.MAINTENANCE) .filter(slot -> !slot.isUsed() && slot.getType() != SegmentType.MAINTENANCE)
.filter(slot -> slot.getStart().isAfter(time) || slot.getEnd().isAfter(time)) .filter(slot -> slot.getStart().isAfter(time) || slot.getEnd().isAfter(time))
.findFirst() .findFirst()
...@@ -590,8 +594,9 @@ i++; ...@@ -590,8 +594,9 @@ i++;
// 生成新时间段 // 生成新时间段
List<TimeSegment> timeSegments = machineScheduler.generateTimeSegment(machine, time.plusDays(1),0); List<TimeSegment> timeSegments = machineScheduler.generateTimeSegment(machine, time.plusDays(1),0);
synchronized (machine.getAvailability()) {
machine.getAvailability().addAll(timeSegments); machine.getAvailability().addAll(timeSegments);
}
// 更新设备时间线 // 更新设备时间线
Machine originalMachine = machines.stream() Machine originalMachine = machines.stream()
.filter(t -> t.getId() == machine.getId()) .filter(t -> t.getId() == machine.getId())
...@@ -815,14 +820,15 @@ i++; ...@@ -815,14 +820,15 @@ i++;
private void RemoveMachineAvailable(Machine machine, ScheduleResultDetail geneDetails) { private void RemoveMachineAvailable(Machine machine, ScheduleResultDetail geneDetails) {
List<TimeSegment> timeSegments = new ArrayList<>(); List<TimeSegment> timeSegments = new ArrayList<>();
int index = machine.getAvailability().stream() List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability());
int index = availabilitySnapshot.stream()
.filter(t -> t.getKey().equals(geneDetails.getKey())) .filter(t -> t.getKey().equals(geneDetails.getKey()))
.findFirst() .findFirst()
.map(machine.getAvailability()::indexOf) .map(machine.getAvailability()::indexOf)
.orElse(-1); .orElse(-1);
if (index > -1) { if (index > -1) {
TimeSegment targetSegment = machine.getAvailability().get(index); TimeSegment targetSegment = availabilitySnapshot.get(index);
LocalDateTime geneEndTime = baseTime.plusSeconds(geneDetails.getEndTime()); LocalDateTime geneEndTime = baseTime.plusSeconds(geneDetails.getEndTime());
if (targetSegment.getEnd().isAfter(geneEndTime)) { if (targetSegment.getEnd().isAfter(geneEndTime)) {
...@@ -843,22 +849,29 @@ i++; ...@@ -843,22 +849,29 @@ i++;
} }
if (!timeSegments.isEmpty()) { if (!timeSegments.isEmpty()) {
machine.getAvailability().addAll(timeSegments); availabilitySnapshot.addAll(timeSegments);
}
availabilitySnapshot.sort(Comparator.comparing(TimeSegment::getStart));
// 关键修复2:加锁(若多线程访问),避免并发修改
synchronized (machine.getAvailability()) {
machine.setAvailability(availabilitySnapshot);
} }
machine.getAvailability().sort(Comparator.comparing(TimeSegment::getStart));
} }
public void AddMachineAvailable(Machine machine, List<ScheduleResultDetail> geneDetails) { public void AddMachineAvailable(Machine machine, List<ScheduleResultDetail> geneDetails) {
if (geneDetails == null || geneDetails.isEmpty()) return; if (geneDetails == null || geneDetails.isEmpty()) return;
List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability());
for (ScheduleResultDetail detail : geneDetails) { for (ScheduleResultDetail detail : geneDetails) {
machine.getAvailability().stream() availabilitySnapshot.stream()
.filter(t -> t.getKey().equals(detail.getKey())) .filter(t -> t.getKey().equals(detail.getKey()))
.findFirst() .findFirst()
.ifPresent(t -> t.setUsed(false)); .ifPresent(t -> t.setUsed(false));
} }
availabilitySnapshot= MergeSegments(availabilitySnapshot);
machine.setAvailability(MergeSegments(machine.getAvailability())); synchronized (machine.getAvailability()) {
machine.setAvailability(availabilitySnapshot);
}
} }
/** /**
* 分割设备可用时间段 * 分割设备可用时间段
......
...@@ -269,9 +269,8 @@ public class RoutingDataService { ...@@ -269,9 +269,8 @@ public class RoutingDataService {
entrys.add(entry); entrys.add(entry);
} }
// 输出每个节点的详细信息
System.out.println("------------------------");
} }
list.put(1,entrys); list.put(1,entrys);
list.put(2,results); list.put(2,results);
......
...@@ -927,13 +927,13 @@ Integer newMachineId1=newMachineId.intValue(); ...@@ -927,13 +927,13 @@ Integer newMachineId1=newMachineId.intValue();
GeneticDecoder decoder = new GeneticDecoder(globalParam,baseTime, chromosome.getMachines(), GeneticDecoder decoder = new GeneticDecoder(globalParam,baseTime, chromosome.getMachines(),
chromosome.getOrders(), null, machineScheduler,chromosome.getOrderMaterials()); chromosome.getOrders(), null, machineScheduler,chromosome.getOrderMaterials());
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult())); chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult(),GAScheduleResult.class));
chromosome.getResult().clear(); chromosome.getResult().clear();
List<GAScheduleResult> Resultlock= chromosome.getResult().stream() List<GAScheduleResult> Resultlock= chromosome.getResult().stream()
.filter(o -> o.isIsLocked() == true) .filter(o -> o.isIsLocked() == true)
.collect(Collectors.toList()); .collect(Collectors.toList());
chromosome.setResult(ProductionDeepCopyUtil.deepCopyList(Resultlock)); chromosome.setResult(ProductionDeepCopyUtil.deepCopyList(Resultlock,GAScheduleResult.class));
decoder.decode(chromosome); decoder.decode(chromosome);
......
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