Commit 6abaed14 authored by Tong Li's avatar Tong Li

算法优化

parent 47286670
...@@ -14,8 +14,8 @@ public class ScheduleParams { ...@@ -14,8 +14,8 @@ public class ScheduleParams {
private LocalDateTime baseTime ; // 当前基准时间 private LocalDateTime baseTime ; // 当前基准时间
// 基础参数(自适应调整的基准值) // 基础参数(自适应调整的基准值)
private static final int MIN_POPULATION_SIZE = 50; private static final int MIN_POPULATION_SIZE = 10;
private static final int MAX_POPULATION_SIZE = 100; private static final int MAX_POPULATION_SIZE = 50;
private static final int MIN_MAX_ITERATIONS = 50; private static final int MIN_MAX_ITERATIONS = 50;
private static final int MAX_MAX_ITERATIONS = 250; private static final int MAX_MAX_ITERATIONS = 250;
private static final float MIN_CROSSOVER_PROB = 0.6f; private static final float MIN_CROSSOVER_PROB = 0.6f;
...@@ -54,7 +54,7 @@ public class ScheduleParams { ...@@ -54,7 +54,7 @@ public class ScheduleParams {
private double rsRatio = 0.2; // 随机选择占比 private double rsRatio = 0.2; // 随机选择占比
// 自适应调整系数 // 自适应调整系数
private float populationSizeCoeff = 0.05f; // 种群大小对工序数的敏感系数 private float populationSizeCoeff = 0.01f; // 种群大小对工序数的敏感系数
private float maxIterationsCoeff = 0.08f; // 迭代次数对工序数的敏感系数 private float maxIterationsCoeff = 0.08f; // 迭代次数对工序数的敏感系数
private float crossoverProbCoeff = 0.0001f; // 交叉概率对工序数的敏感系数 private float crossoverProbCoeff = 0.0001f; // 交叉概率对工序数的敏感系数
private float mutationProbCoeff = 0.00005f; // 变异概率对工序数的敏感系数 private float mutationProbCoeff = 0.00005f; // 变异概率对工序数的敏感系数
......
...@@ -372,7 +372,7 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -372,7 +372,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
int cpuCores = Runtime.getRuntime().availableProcessors(); int cpuCores = Runtime.getRuntime().availableProcessors();
// //
// // 根据工序数量和CPU核心数决定是否使用内部并行 // // 根据工序数量和CPU核心数决定是否使用内部并行
if (operationCount > 500 && cpuCores > 4) { if (operationCount > 5000 && cpuCores > 4) {
// 使用设备并行处理 // 使用设备并行处理
// FileHelper.writeLogFile("使用并行处理 _s"); // FileHelper.writeLogFile("使用并行处理 _s");
parallelDecodeByMachine(chromosome); parallelDecodeByMachine(chromosome);
......
...@@ -110,7 +110,7 @@ int opcount=allOperations.size(); ...@@ -110,7 +110,7 @@ int opcount=allOperations.size();
List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList(); List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList();
// 初始化变邻域搜索 // 初始化变邻域搜索
_vns = new VariableNeighborhoodSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights); _vns = new VariableNeighborhoodSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_hillClimbing = new HillClimbing(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights); _hillClimbing = new HillClimbing(allOperations);
_simulatedAnnealing = new SimulatedAnnealing(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights); _simulatedAnnealing = new SimulatedAnnealing(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_parallelLocalSearch = new ParallelLocalSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights); _parallelLocalSearch = new ParallelLocalSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_tabuSearch = new TabuSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights); _tabuSearch = new TabuSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
...@@ -146,7 +146,7 @@ int opcount=allOperations.size(); ...@@ -146,7 +146,7 @@ int opcount=allOperations.size();
FileHelper.writeLogFile("爬山法局部优化-----------开始-------"); FileHelper.writeLogFile("爬山法局部优化-----------开始-------");
GeneticDecoder hillClimbingDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId); GeneticDecoder hillClimbingDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
Chromosome optimized = _hillClimbing.BatchSearchAll(population, hillClimbingDecoder, param); Chromosome optimized = _hillClimbing.BatchSearchAll(population,machines, hillClimbingDecoder);
FileHelper.writeLogFile("爬山法局部优化-----------结束-------"); FileHelper.writeLogFile("爬山法局部优化-----------结束-------");
return getBestChromosome(optimized, param.getBaseTime(), starttime); return getBestChromosome(optimized, param.getBaseTime(), starttime);
} }
...@@ -154,14 +154,16 @@ int opcount=allOperations.size(); ...@@ -154,14 +154,16 @@ int opcount=allOperations.size();
// 步骤2:对初始种群进行模拟退火+爬山法优化 // 步骤2:对初始种群进行模拟退火+爬山法优化
FileHelper.writeLogFile("模拟退火+爬山法优化-----------开始-------");
GeneticDecoder saDecoder1 = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> saHcOptimized = _simulatedAnnealing.batchSearch(population, saDecoder1, param); GeneticDecoder saDecoder1 = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
if(population.size()>5||opcount<2000 ) {
FileHelper.writeLogFile("模拟退火+爬山法优化-----------开始-------");
Chromosome saHcOptimized = _simulatedAnnealing.batchSearchGetMax(population, saDecoder1, machines);
FileHelper.writeLogFile("模拟退火+爬山法优化-----------结束-------");
return getBestChromosome(saHcOptimized, param.getBaseTime(), starttime);
}
population = saHcOptimized;
FileHelper.writeLogFile("模拟退火+爬山法优化-----------结束-------");
List<List<Chromosome>> combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(population); List<List<Chromosome>> combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(population);
int ordercount = globalOpList.stream() int ordercount = globalOpList.stream()
...@@ -230,15 +232,6 @@ int opcount=allOperations.size(); ...@@ -230,15 +232,6 @@ int opcount=allOperations.size();
selected.addAll(saImproved); selected.addAll(saImproved);
FileHelper.writeLogFile("模拟退火搜索-----------结束-------"); FileHelper.writeLogFile("模拟退火搜索-----------结束-------");
// 爬山法局部优化
FileHelper.writeLogFile("爬山法局部优化-----------开始-------");
List<Chromosome> hcImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
Chromosome hcOptimized = _hillClimbing.search(chromosome, saDecoder, param);
hcImproved.add(hcOptimized);
}
selected.addAll(hcImproved);
FileHelper.writeLogFile("爬山法局部优化-----------结束-------");
// 多种局部搜索算法并行 // 多种局部搜索算法并行
FileHelper.writeLogFile("并行局部搜索-----------开始-------"); FileHelper.writeLogFile("并行局部搜索-----------开始-------");
...@@ -444,11 +437,6 @@ int opcount=allOperations.size(); ...@@ -444,11 +437,6 @@ int opcount=allOperations.size();
if (existing == null) { if (existing == null) {
// 第一次遇到这个Objectives,直接添加 // 第一次遇到这个Objectives,直接添加
objectivesMap.put(objectivesKey, chromosome); objectivesMap.put(objectivesKey, chromosome);
} else {
// 已经存在,保留fitness更大的那个
if (chromosome.getFitness() > existing.getFitness()) {
objectivesMap.put(objectivesKey, chromosome);
}
} }
} }
...@@ -555,9 +543,9 @@ int opcount=allOperations.size(); ...@@ -555,9 +543,9 @@ int opcount=allOperations.size();
// _sceneService.saveChromosomeToFile(chromosome, "12345679"); // _sceneService.saveChromosomeToFile(chromosome, "12345679");
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));
} // }
} }
......
...@@ -36,10 +36,10 @@ public class ParallelLocalSearch { ...@@ -36,10 +36,10 @@ public class ParallelLocalSearch {
List<Callable<Chromosome>> tasks = new ArrayList<>(); List<Callable<Chromosome>> tasks = new ArrayList<>();
// 添加爬山法任务 // 添加爬山法任务
tasks.add(() -> { // tasks.add(() -> {
HillClimbing hillClimbing = new HillClimbing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights); // HillClimbing hillClimbing = new HillClimbing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
return hillClimbing.search(chromosome, decoder, param); // return hillClimbing.search(chromosome, decoder, param);
}); // });
// 添加变邻域搜索任务 // 添加变邻域搜索任务
tasks.add(() -> { tasks.add(() -> {
......
package com.aps.service.Algorithm; package com.aps.service.Algorithm;
import com.aps.common.util.FileHelper;
import com.aps.common.util.ProductionDeepCopyUtil; import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*; import com.aps.entity.Algorithm.*;
import com.aps.entity.basic.Entry; import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam; import com.aps.entity.basic.GlobalParam;
import com.aps.entity.basic.Machine;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
...@@ -33,39 +35,59 @@ public class SimulatedAnnealing { ...@@ -33,39 +35,59 @@ public class SimulatedAnnealing {
new ArrayBlockingQueue<>(200), // 有界队列,避免内存溢出 new ArrayBlockingQueue<>(200), // 有界队列,避免内存溢出
new ThreadPoolExecutor.CallerRunsPolicy() // 任务满了主线程执行,不丢失任务 new ThreadPoolExecutor.CallerRunsPolicy() // 任务满了主线程执行,不丢失任务
); );
public List<Chromosome> batchSearch(List<Chromosome> chromosomes, GeneticDecoder decoder, ScheduleParams param) { public List<Chromosome> batchSearch(List<Chromosome> chromosomes, GeneticDecoder decoder, List<Machine> machines) {
List<Chromosome> saHcOptimized=new ArrayList<>(); List<Chromosome> saHcOptimized=new ArrayList<>();
CompletableFuture.allOf(chromosomes.stream() // CompletableFuture.allOf(chromosomes.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> { // .map(chromosome -> CompletableFuture.runAsync(() -> {
Chromosome optimized = searchWithHillClimbing(chromosome, decoder, param); // Chromosome optimized = searchWithHillClimbing(chromosome, decoder, param);
// saHcOptimized.add(optimized);
// }, decodeExecutor))
// .toArray(CompletableFuture[]::new))
// .join();
for (Chromosome chromosome:chromosomes) {
Chromosome optimized = searchWithHillClimbing(chromosome, decoder, machines);
saHcOptimized.add(optimized); saHcOptimized.add(optimized);
}, decodeExecutor)) break;
.toArray(CompletableFuture[]::new)) }
.join();
return saHcOptimized; return saHcOptimized;
} }
public Chromosome batchSearchGetMax(List<Chromosome> chromosomes, GeneticDecoder decoder, List<Machine> machines) {
List<Chromosome> saHcOptimized=batchSearch(chromosomes,decoder,machines);
int bestidx= Getbest(saHcOptimized,null);
if(bestidx>-1) {
return saHcOptimized.get(bestidx);
}
return null;
}
/** /**
* 模拟退火搜索,当温度降低到一定程度后切换到爬山法 * 模拟退火搜索,当温度降低到一定程度后切换到爬山法
* 流程:模拟退火迭代 → 随机生成新排产 → 按概率接受 → 降温 → 温度低时爬山法求精 → 输出最优 * 流程:模拟退火迭代 → 随机生成新排产 → 按概率接受 → 降温 → 温度低时爬山法求精 → 输出最优
*/ */
public Chromosome searchWithHillClimbing(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) { public Chromosome searchWithHillClimbing(Chromosome chromosome, GeneticDecoder decoder, List<Machine> machines) {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
// 初始化解码
// decode(decoder, best, param);
// decode(decoder, current, param);
Map<String, Entry> Entrys = buildEntryKey(current); Map<String, Entry> Entrys = buildEntryKey(current);
FileHelper.writeLogFile("模拟退火+爬山法 - 初始化索引完成");
// 初始化温度 - 优化速度:更快降温,更快切换到爬山法 // 初始化温度 - 优化速度:更快降温,更快切换到爬山法
double temperature = 100.0; double temperature = 100.0;
double coolingRate = 0.95; double coolingRate = 0.95;
double temperatureThreshold = 1.0; // 提高阈值,更快切换到爬山法 double temperatureThreshold = 1.0; // 提高阈值,更快切换到爬山法
int maxIterations = 300; // 减少最大迭代次数 int maxIterations = 300; // 减少最大迭代次数
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 参数配置:温度=%.1f, 降温率=%.2f, 阈值=%.1f, 最大迭代=%d",
temperature, coolingRate, temperatureThreshold, maxIterations));
int noImproveCount = 0; int noImproveCount = 0;
int maxNoImprove = 50; // 连续50次没改进就提前停止 int maxNoImprove = 50; // 连续50次没改进就提前停止
int acceptCount = 0;
int improveCount = 0;
for (int i = 0; i < maxIterations; i++) { for (int i = 0; i < maxIterations; i++) {
boolean improved = false; boolean improved = false;
...@@ -73,7 +95,7 @@ public class SimulatedAnnealing { ...@@ -73,7 +95,7 @@ public class SimulatedAnnealing {
Chromosome neighbor = generateNeighbor(current,Entrys); Chromosome neighbor = generateNeighbor(current,Entrys);
// 2. 解码并计算适应度(只解码neighbor,current已经解码过了) // 2. 解码并计算适应度(只解码neighbor,current已经解码过了)
decode(decoder, neighbor, param); decode(decoder, neighbor, machines);
// 3. 计算能量差(fitness差) // 3. 计算能量差(fitness差)
double energyDifference = calculateEnergyDifference(neighbor, current); double energyDifference = calculateEnergyDifference(neighbor, current);
...@@ -81,13 +103,16 @@ public class SimulatedAnnealing { ...@@ -81,13 +103,16 @@ public class SimulatedAnnealing {
// 4. 按概率接受新解 // 4. 按概率接受新解
// - 更优:直接接受 // - 更优:直接接受
// - 较差:概率接受(高温更容易接受) // - 较差:概率接受(高温更容易接受)
boolean accepted = false;
if (energyDifference > 0 || rnd.nextDouble() < Math.exp(energyDifference / temperature)) { if (energyDifference > 0 || rnd.nextDouble() < Math.exp(energyDifference / temperature)) {
current = neighbor; current = neighbor;
accepted = true;
acceptCount++;
// 更新全局最优 // 更新全局最优
if (isBetter(current, best)) { if (isBetter(current, best)) {
best = ProductionDeepCopyUtil.deepCopy(current, Chromosome.class); best = ProductionDeepCopyUtil.deepCopy(current, Chromosome.class);
improved = true; improved = true;
improveCount++;
noImproveCount = 0; noImproveCount = 0;
} }
} }
...@@ -98,16 +123,27 @@ public class SimulatedAnnealing { ...@@ -98,16 +123,27 @@ public class SimulatedAnnealing {
// 5. 降温 // 5. 降温
temperature *= coolingRate; temperature *= coolingRate;
if ((i + 1) % 10 == 0) {
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 迭代%d/%d:温度=%.4f, 接受数=%d, 改进数=%d, 无改进连续=%d",
i + 1, maxIterations, temperature, acceptCount, improveCount, noImproveCount));
}
// 6. 提前停止条件:温度低于阈值 或 连续多次没改进 // 6. 提前停止条件:温度低于阈值 或 连续多次没改进
if (temperature < temperatureThreshold || noImproveCount >= maxNoImprove) { if (temperature < temperatureThreshold || noImproveCount >= maxNoImprove) {
HillClimbing hillClimbing = new HillClimbing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights); String stopReason = temperature < temperatureThreshold ? "温度低于阈值" : "连续无改进达到上限";
Chromosome refined = hillClimbing.search(best, decoder, param); 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("模拟退火+爬山法 - 爬山法求精完成");
// 返回爬山法求精后的结果 // 返回爬山法求精后的结果
return refined; return refined;
} }
} }
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 完成所有%d次迭代,最终fitness=%.4f", maxIterations, best.getFitness()));
// 7. 输出全局最优排产 // 7. 输出全局最优排产
return best; return best;
...@@ -321,11 +357,15 @@ public class SimulatedAnnealing { ...@@ -321,11 +357,15 @@ public class SimulatedAnnealing {
/** /**
* 解码染色体 * 解码染色体
*/ */
private void decode(GeneticDecoder decoder, Chromosome chromosome, ScheduleParams param) { private void decode(GeneticDecoder decoder, Chromosome chromosome , List<Machine> machines) {
chromosome.setResult(new CopyOnWriteArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines, Machine.class)); // 简单拷贝,实际可能需要深拷贝
decoder.decodeChromosomeWithCache(chromosome); decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(fitnessCalculator.calculateFitness(chromosome, objectiveWeights));
}
} }
/** /**
...@@ -341,4 +381,23 @@ public class SimulatedAnnealing { ...@@ -341,4 +381,23 @@ public class SimulatedAnnealing {
} }
return false; return false;
} }
private int Getbest(List<Chromosome> candidates,Chromosome best) {
// 找出最佳候选方案
int bestidx = -1;
if(best==null)
{
best=candidates.get(0);
bestidx=0;
}
for (int i = 0; i < candidates.size(); i++) {
Chromosome candidate = candidates.get(i);
if (isBetter(candidate, best)) {
bestidx = i;
}
}
return bestidx;
}
} }
\ No newline at end of file
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