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

优化速度

parent d49ae691
......@@ -20,8 +20,8 @@ public class ScheduleParams {
private static final int MAX_MAX_ITERATIONS = 200;
private static final float MIN_CROSSOVER_PROB = 0.6f;
private static final float MAX_CROSSOVER_PROB = 0.9f;
private static final float MIN_MUTATION_PROB = 0.3f;
private static final float MAX_MUTATION_PROB = 0.7f;
private static final float MIN_MUTATION_PROB = 0.2f;
private static final float MAX_MUTATION_PROB = 0.5f;
private static final int MIN_TOURNAMENT_SIZE = 3;
private static final int MAX_TOURNAMENT_SIZE = 7;
......@@ -81,6 +81,13 @@ public class ScheduleParams {
return maxIterations;
}
/// <summary>
/// 交叉概率
/// </summary>
public float setCrossoverProb(float crossoverProb) {
return this.crossoverProb=crossoverProb;
}
/// <summary>
/// 交叉概率
/// </summary>
......@@ -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() {
ScheduleParams params = new ScheduleParams();
......
......@@ -13,6 +13,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
/**
......@@ -98,7 +101,7 @@ public class GeneticAlgorithm {
List<Chromosome> population = initialization.generateInitialPopulation(param, globalOpList);
//population= chromosomeDistinct(population);
population= chromosomeDistinct(population);
......@@ -137,8 +140,14 @@ public class GeneticAlgorithm {
}
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("交叉操作-----------开始-------");
......@@ -178,7 +187,7 @@ public class GeneticAlgorithm {
FileHelper.writeLogFile("变异批量解码-----------开始-------");
nextPopulation= chromosomeDistinct(nextPopulation);
Chromosomedecode(param,allOperations,globalOpList,nextPopulation);
FileHelper.writeLogFile("变异批量解码-----------结束-------");
// // 精英保留
......@@ -192,7 +201,7 @@ public class GeneticAlgorithm {
List<Chromosome> newPopulation = new ArrayList<>();
newPopulation.addAll(population);
newPopulation.addAll(nextPopulation);
newPopulation= chromosomeDistinct(newPopulation);
newPopulation= chromosomeDistinct1(newPopulation);
FileHelper.writeLogFile("非支配排序-----------开始-------");
// 2.7 非支配排序
List<List<Chromosome>> combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(newPopulation);
......@@ -208,19 +217,26 @@ public class GeneticAlgorithm {
best= GetBest(combinedFronts,String.valueOf(iter));
if(bestFitness<best.getFitness())
{
bestFitness=best.getFitness();
Iteration=1;
}else {
Iteration++;
if (Iteration > 5) {
// 当连续 5 代无最优解提升时,降低交叉概率(如从 0.8 降至 0.5)、提高变异概率(如从 0.1 升至 0.2)
param.fineTuneParams();
}
}
if(Iteration>10)
{
break;
}
// 当种群适应度标准差小于阈值(如 0.001)时,说明种群已收敛,提前终止迭代
fitnessStd = _fitnessCalculator.calculateFitnessStd(population);
if (fitnessStd < 0.001) {
FileHelper.writeLogFile("种群已收敛,提前终止迭代");
break;
}
FileHelper.writeLogFile("迭代进化------"+iter+"-----结束-------");
}
......@@ -256,21 +272,34 @@ public class GeneticAlgorithm {
// WriteKpi(best,"最大");
return best;
}
private List<Chromosome> chromosomeDistinct(List<Chromosome> population)
{
if(orders.size()<10)
{
population = population.stream()
.collect(Collectors.toMap(
Chromosome::getGeneStr, // key:去重的字段(GeneStr)
u -> u, // value:Chromosome对象
(u1, u2) -> u1 // 重复时保留第一个元素
))
.values() // 获取去重后的
.stream()
.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 // 重复时保留第一个元素
(u1, u2) -> u1.getFitness() > u2.getFitness() ? u1 : u2 // 重复时保留第一个元素
))
.values() // 获取去重后的
.stream()
.collect(Collectors.toList());
}
return population;
}
......@@ -292,6 +321,7 @@ public class GeneticAlgorithm {
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)
{
......@@ -299,26 +329,51 @@ public class GeneticAlgorithm {
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,orderMaterials);
if(population!=null&&population.size()>0) {
population.parallelStream().forEach(chromosome -> {
chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
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));
}
});
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 -> {
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));
}
});
}
}
}
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 {
* 锦标赛选择
*/
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();
List<Chromosome> selected = new ArrayList<>(); // 预初始化容量
// 边界值处理:锦标赛规模不能超过种群规模,且至少为1
int effectiveTournamentSize = Math.max(1, Math.min(tournamentSize, populationSize));
while (selected.size() < populationSize-tournamentSize) {
// 优化1:不复制整个种群,直接随机抽取有效锦标赛规模的个体,避免大量内存拷贝和shuffle开销
......@@ -46,9 +115,9 @@ public class GeneticOperations {
List<Chromosome> chromosomes=population.subList(0, endIndex);
chromosomes.sort((c1, c2) -> {
int rankCompare = Integer.compare(c1.getRank(), c2.getRank());
return rankCompare != 0 ? rankCompare : Double.compare(c1.getCrowdingDistance(), c2.getCrowdingDistance());
});
int rankCompare = Integer.compare(c1.getRank(), c2.getRank());
return rankCompare != 0 ? rankCompare : Double.compare(c1.getCrowdingDistance(), c2.getCrowdingDistance());
});
Chromosome bestCandidate = chromosomes.get(0);
......@@ -60,6 +129,7 @@ public class GeneticOperations {
return selected;
}
// 重载,使用默认锦标赛大小3
public List<Chromosome> tournamentSelection(List<Chromosome> population) {
return tournamentSelection(population, param.getTournamentSize());
......@@ -259,8 +329,8 @@ public class GeneticOperations {
.findFirst().orElse(0);
int machineSeq = chromosome.getMachineSelection().get(pos);
List<Integer> MachineSelections= chromosome.getMachineSelection();
int machineSeq = MachineSelections.get(pos);
// 选择当前所选设备外最短加工时间的机器
......@@ -274,7 +344,8 @@ public class GeneticOperations {
.orElse(currentMachine); // 如果没有其他机器,保持当前
machineSeq = optionalMachines.indexOf(minLoadMachine) + 1;
chromosome.getMachineSelection().set(pos, machineSeq);
MachineSelections.set(pos, machineSeq);
chromosome.setMachineSelection(MachineSelections);
i++;
}
......@@ -298,6 +369,7 @@ public class GeneticOperations {
// 交换位置
List<Integer> os = chromosome.getOperationSequencing();
Collections.swap(os, idx1, idx2);
chromosome.setOperationSequencing(os);
} else {
// 反转:仅对高优先级工序集中的子序列反转
OperationSequencingWeight osStart = selectHighPriorityIndex(chromosome.getOperationSequencing(), 0);
......@@ -318,6 +390,7 @@ public class GeneticOperations {
int pos2 = end - i;
Collections.swap(os, pos1, pos2);
}
chromosome.setOperationSequencing(os);
}
}
......
......@@ -668,7 +668,7 @@ public class IdGroupingWithDualSerial {
nodeInfo.getNewParentIds().isEmpty() ? "无" : nodeInfo.getNewParentIds(),
nodeInfo.getNewChildIds());
}
System.out.println("------------------------");
// System.out.println("------------------------");
}
}
}
......@@ -65,7 +65,7 @@ int populationSize=param.getPopulationSize();
.forEach(i -> {
Chromosome chromo = new Chromosome(); // 初始化染色体
// chromo.setObjectiveWeights(_objectiveWeights);
chromo.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines));
// chromo.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines));
chromo.setOrders(orders);
// 全局选择(GS):按GlobalOpId顺序生成MachineSelection
if (i < gsCount) {
......
......@@ -129,7 +129,7 @@ public class MachineCalculator {
st = shiftStart;
remainingTime = processingTime;
prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0, 0);
oldTimes.addAll(ProductionDeepCopyUtil.deepCopyList(times));
oldTimes.addAll(ProductionDeepCopyUtil.deepCopyList(times,ScheduleResultDetail.class));
times.clear();
continue;
}
......@@ -538,13 +538,17 @@ i++;
if (newSegments == null || newSegments.isEmpty()) {
return;
}
List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability());
availabilitySnapshot.addAll(newSegments);
List<TimeSegment> mergedSegments = MergeSegments(availabilitySnapshot);
synchronized (machine.getAvailability()) {
// 合并片段(去重+排序),
machine.setAvailability(mergedSegments);
}
// 追加新片段,对应C#的 machine.Availability.AddRange(newSegments)
machine.getAvailability().addAll(newSegments);
// 合并片段(去重+排序),并重新赋值给设备的可用片段列表,对应C#的 machine.Availability = MergeSegments(...)
List<TimeSegment> mergedSegments = MergeSegments(machine.getAvailability());
machine.setAvailability(mergedSegments);
}
private boolean CheckTask(Machine machine,List<GAScheduleResult> machineTasks,LocalDateTime prevEnd,LocalDateTime shiftStart) {
......@@ -572,10 +576,10 @@ i++;
*/
private TimeSegment GetCurrentOrNextShift(Machine machine, LocalDateTime time, String prevtime, boolean checkprevtime) {
TimeSegment start = null;
if(machine.getAvailability()!=null)
List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability());
if (!availabilitySnapshot.isEmpty())
{
start = machine.getAvailability().stream()
start = availabilitySnapshot.stream()
.filter(slot -> !slot.isUsed() && slot.getType() != SegmentType.MAINTENANCE)
.filter(slot -> slot.getStart().isAfter(time) || slot.getEnd().isAfter(time))
.findFirst()
......@@ -590,8 +594,9 @@ i++;
// 生成新时间段
List<TimeSegment> timeSegments = machineScheduler.generateTimeSegment(machine, time.plusDays(1),0);
machine.getAvailability().addAll(timeSegments);
synchronized (machine.getAvailability()) {
machine.getAvailability().addAll(timeSegments);
}
// 更新设备时间线
Machine originalMachine = machines.stream()
.filter(t -> t.getId() == machine.getId())
......@@ -815,14 +820,15 @@ i++;
private void RemoveMachineAvailable(Machine machine, ScheduleResultDetail geneDetails) {
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()))
.findFirst()
.map(machine.getAvailability()::indexOf)
.orElse(-1);
if (index > -1) {
TimeSegment targetSegment = machine.getAvailability().get(index);
TimeSegment targetSegment = availabilitySnapshot.get(index);
LocalDateTime geneEndTime = baseTime.plusSeconds(geneDetails.getEndTime());
if (targetSegment.getEnd().isAfter(geneEndTime)) {
......@@ -843,22 +849,29 @@ i++;
}
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) {
if (geneDetails == null || geneDetails.isEmpty()) return;
List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability());
for (ScheduleResultDetail detail : geneDetails) {
machine.getAvailability().stream()
availabilitySnapshot.stream()
.filter(t -> t.getKey().equals(detail.getKey()))
.findFirst()
.ifPresent(t -> t.setUsed(false));
}
machine.setAvailability(MergeSegments(machine.getAvailability()));
availabilitySnapshot= MergeSegments(availabilitySnapshot);
synchronized (machine.getAvailability()) {
machine.setAvailability(availabilitySnapshot);
}
}
/**
* 分割设备可用时间段
......
......@@ -269,9 +269,8 @@ public class RoutingDataService {
entrys.add(entry);
}
// 输出每个节点的详细信息
System.out.println("------------------------");
}
list.put(1,entrys);
list.put(2,results);
......
......@@ -927,13 +927,13 @@ Integer newMachineId1=newMachineId.intValue();
GeneticDecoder decoder = new GeneticDecoder(globalParam,baseTime, chromosome.getMachines(),
chromosome.getOrders(), null, machineScheduler,chromosome.getOrderMaterials());
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult()));
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult(),GAScheduleResult.class));
chromosome.getResult().clear();
List<GAScheduleResult> Resultlock= chromosome.getResult().stream()
.filter(o -> o.isIsLocked() == true)
.collect(Collectors.toList());
chromosome.setResult(ProductionDeepCopyUtil.deepCopyList(Resultlock));
chromosome.setResult(ProductionDeepCopyUtil.deepCopyList(Resultlock,GAScheduleResult.class));
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