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

算法优化

parent 47286670
......@@ -14,8 +14,8 @@ public class ScheduleParams {
private LocalDateTime baseTime ; // 当前基准时间
// 基础参数(自适应调整的基准值)
private static final int MIN_POPULATION_SIZE = 50;
private static final int MAX_POPULATION_SIZE = 100;
private static final int MIN_POPULATION_SIZE = 10;
private static final int MAX_POPULATION_SIZE = 50;
private static final int MIN_MAX_ITERATIONS = 50;
private static final int MAX_MAX_ITERATIONS = 250;
private static final float MIN_CROSSOVER_PROB = 0.6f;
......@@ -54,7 +54,7 @@ public class ScheduleParams {
private double rsRatio = 0.2; // 随机选择占比
// 自适应调整系数
private float populationSizeCoeff = 0.05f; // 种群大小对工序数的敏感系数
private float populationSizeCoeff = 0.01f; // 种群大小对工序数的敏感系数
private float maxIterationsCoeff = 0.08f; // 迭代次数对工序数的敏感系数
private float crossoverProbCoeff = 0.0001f; // 交叉概率对工序数的敏感系数
private float mutationProbCoeff = 0.00005f; // 变异概率对工序数的敏感系数
......
......@@ -372,7 +372,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
int cpuCores = Runtime.getRuntime().availableProcessors();
//
// // 根据工序数量和CPU核心数决定是否使用内部并行
if (operationCount > 500 && cpuCores > 4) {
if (operationCount > 5000 && cpuCores > 4) {
// 使用设备并行处理
// FileHelper.writeLogFile("使用并行处理 _s");
parallelDecodeByMachine(chromosome);
......
package com.aps.service.Algorithm;
import com.aps.common.util.FileHelper;
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.MachineOption;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.basic.*;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
......@@ -16,24 +17,35 @@ import java.util.concurrent.Executors;
*/
public class HillClimbing {
private final Random rnd = new Random();
private GlobalParam globalParam;
private List<Entry> allOperations;
private List<GlobalOperationInfo> globalOpList;
private FitnessCalculator fitnessCalculator;
private ObjectiveWeights objectiveWeights;
public HillClimbing(GlobalParam globalParam, List<Entry> allOperations, List<GlobalOperationInfo> globalOpList, FitnessCalculator fitnessCalculator, ObjectiveWeights objectiveWeights) {
this.globalParam = globalParam;
//按优先级分组工序
private Map<Double, List<Entry>> priorityGroups;
// 按优先级从高到低处理
private List<Double> sortedPriorities ;
// 从List转为Map op.getGroupId() + "_" + op.getSequence(); 做主键
private Map<String, Entry> entrys;
public HillClimbing(List<Entry> allOperations) {
this.allOperations = allOperations;
this.globalOpList = globalOpList;
this.fitnessCalculator = fitnessCalculator;
this.objectiveWeights = objectiveWeights;
// 按优先级分组工序
priorityGroups = groupOperationsByPriority();
// 按优先级从高到低处理
sortedPriorities= new ArrayList<>(priorityGroups.keySet());
entrys = buildEntryKey();
}
public Chromosome BatchSearchAll(List<Chromosome> population, GeneticDecoder decoder, ScheduleParams param) {
public Chromosome BatchSearchAll(List<Chromosome> population, List<Machine> machines, GeneticDecoder decoder) {
List<Chromosome> optimizedPopulation=new ArrayList<>();
for (Chromosome chromosome : population) {
Chromosome optimized = searchAll(chromosome, decoder, param);
Chromosome optimized = searchAll(chromosome,machines, decoder);
optimizedPopulation.add(optimized);
}
int bestidx= Getbest(optimizedPopulation,null);
......@@ -46,31 +58,19 @@ public class HillClimbing {
/**
* 穷举搜索
*/
public Chromosome searchAll(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
public Chromosome searchAll(Chromosome chromosome, List<Machine> machines, GeneticDecoder decoder) {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
// 按优先级分组工序
Map<Double, List<Entry>> priorityGroups = groupOperationsByPriority();
// 按优先级从高到低处理
List<Double> sortedPriorities = new ArrayList<>(priorityGroups.keySet());
// 构建位置索引映射:groupId_sequence -> position
Map<String, Integer> positionIndex = buildPositionIndex(current);
Map<String, Integer> MachinePositionIndex = buildEntryMachinePositionIndex(current);
Map<String, Entry> Entrys = buildEntryKey(current);
// 构建位置到Entry的映射:position -> Entry
Map<Integer, Entry> entryIndex = buildEntryIndex(current,Entrys);
Map<Integer, Entry> entryIndex = buildEntryIndex(current, entrys);
for (Double priority : sortedPriorities) {
List<Entry> priorityOps = priorityGroups.get(priority);
......@@ -79,19 +79,18 @@ public class HillClimbing {
}
// 根据当前优先级的工序数确定迭代次数和step
int priorityIterations = Math.max(5, priorityOps.size()/2);
int priorityIterations = Math.max(5, priorityOps.size() / 2);
// 200/10 =20
// 1
int step = Math.max(1, (int) Math.ceil(priorityOps.size() / 10.0));
// 200/20=10;
//
int stepCount = Math.max(1, (int) Math.ceil(priorityOps.size() / step));
Set<Integer> Groupid=new HashSet<>();
Set<Integer> Groupid = new HashSet<>();
for (int pi = 0; pi < priorityIterations; pi++) {
// 随机取该优先级的工序
Entry randomOp = priorityOps.get(rnd.nextInt(priorityOps.size()));
if(Groupid.contains(randomOp.getGroupId()))
{
if (Groupid.contains(randomOp.getGroupId())) {
continue;
}
Groupid.add(randomOp.getGroupId());
......@@ -99,7 +98,7 @@ public class HillClimbing {
String key = randomOp.getGroupId() + "_" + randomOp.getSequence();
Integer opPos = positionIndex.get(key);
Integer maPos = MachinePositionIndex.get(key);
List<MachineOption> MachineOptions=randomOp.getMachineOptions();
List<MachineOption> MachineOptions = randomOp.getMachineOptions();
if (opPos == null) {
continue;
}
......@@ -110,7 +109,7 @@ public class HillClimbing {
List<Chromosome> candidates = new ArrayList<>();
List<Chromosome> candidates1 = new ArrayList<>();
if(MachineOptions.size()>1) {
if (MachineOptions.size() > 1) {
Chromosome machineChange = generateMachineChange(current, MachineOptions, maPos);
if (machineChange != null) {
candidates.add(machineChange);
......@@ -122,12 +121,12 @@ public class HillClimbing {
for (int s = 1; s <= stepCount; s++) {
Entry leftOp = entryIndex.get(opPos - s * step);
if (leftOp != null&&randomOp.getGroupId()!=leftOp.getGroupId() && Math.abs(leftOp.getPriority() - priority) <= 0.001) {
if (leftOp != null && randomOp.getGroupId() != leftOp.getGroupId() && Math.abs(leftOp.getPriority() - priority) <= 0.001) {
Chromosome newChromosome = swapAtDistance(current, opPos, -s * step);
candidates.add(newChromosome);
candidates1.add(newChromosome);
if(MachineOptions.size()>1) {
if (MachineOptions.size() > 1) {
Chromosome machineChange = generateMachineChange(newChromosome, MachineOptions, maPos);
if (machineChange != null) {
candidates.add(machineChange);
......@@ -136,11 +135,11 @@ public class HillClimbing {
}
}else {
} else {
break;
}
if (candidates1.size() > 5) {
batchDecode(decoder,candidates1);
batchDecode(decoder, candidates1, machines);
candidates1.clear();
}
}
......@@ -153,7 +152,7 @@ public class HillClimbing {
Chromosome newChromosome = swapAtDistance(current, opPos, s * step);
candidates.add(newChromosome);
candidates1.add(newChromosome);
if(MachineOptions.size()>1) {
if (MachineOptions.size() > 1) {
Chromosome machineChange = generateMachineChange(newChromosome, MachineOptions, maPos);
if (machineChange != null) {
candidates.add(machineChange);
......@@ -165,55 +164,40 @@ public class HillClimbing {
break;
}
if (candidates1.size() > 5) {
batchDecode(decoder,candidates1);
batchDecode(decoder, candidates1, machines);
candidates1.clear();
}
}
// 限制最多5个方案并行
if (candidates1.size() > 0) {
batchDecode(decoder, candidates1);
batchDecode(decoder, candidates1, machines);
}
if(candidates.size()== 0)
{
if (candidates.size() == 0) {
break;
}
int bestidx= Getbest(candidates,best);
if(bestidx>-1) {
best=candidates.get(bestidx);
current=best;
int bestidx = Getbest(candidates, best);
if (bestidx > -1) {
best = candidates.get(bestidx);
current =ProductionDeepCopyUtil.deepCopy(best, Chromosome.class);
positionIndex = buildPositionIndex(current);
entryIndex = buildEntryIndex(current,Entrys);
entryIndex = buildEntryIndex(current, entrys);
}
}
}
return best;
}
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder , List<Machine> machines) {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
// 按优先级分组工序
Map<Double, List<Entry>> priorityGroups = groupOperationsByPriority();
// 按优先级从高到低处理
List<Double> sortedPriorities = new ArrayList<>(priorityGroups.keySet());
// 构建位置索引映射:groupId_sequence -> position
......@@ -221,11 +205,10 @@ public class HillClimbing {
Map<String, Integer> MachinePositionIndex = buildEntryMachinePositionIndex(current);
Map<String, Entry> Entrys = buildEntryKey(current);
// 构建位置到Entry的映射:position -> Entry
Map<Integer, Entry> entryIndex = buildEntryIndex(current,Entrys);
Map<Integer, Entry> entryIndex = buildEntryIndex(current,entrys);
boolean improved = true;
for (Double priority : sortedPriorities) {
List<Entry> priorityOps = priorityGroups.get(priority);
......@@ -242,6 +225,8 @@ boolean improved = true;
//
int stepCount = Math.max(1, (int) Math.ceil(priorityOps.size() / step));
Set<Integer> Groupid=new HashSet<>();
int noImproveCount = 0;
int maxNoImprove = 20; // 连续50次没改进就提前停止
for (int pi = 0; pi < priorityIterations; pi++) {
improved = false;
// 随机取该优先级的工序
......@@ -292,17 +277,18 @@ boolean improved = true;
break;
}
if (candidates.size() > 5) {
batchDecode(decoder,candidates);
batchDecode(decoder,candidates,machines);
int bestidx= Getbest(candidates,best);
if(bestidx>-1)
{
best=candidates.get(bestidx);
current=best;
current=ProductionDeepCopyUtil.deepCopy(best, Chromosome.class);;
improved=true;
// 更新索引
noImproveCount=0;
positionIndex = buildPositionIndex(current);
entryIndex = buildEntryIndex(current,Entrys);
entryIndex = buildEntryIndex(current,entrys);
break;
}
candidates.clear();
......@@ -334,15 +320,16 @@ boolean improved = true;
break;
}
if (candidates.size() > 5) {
batchDecode(decoder,candidates);
batchDecode(decoder,candidates,machines);
int bestidx= Getbest(candidates,best);
if(bestidx>-1)
{
best=candidates.get(bestidx);
current=best;
current=ProductionDeepCopyUtil.deepCopy(best, Chromosome.class);;
// 更新索引
noImproveCount=0;
positionIndex = buildPositionIndex(current);
entryIndex = buildEntryIndex(current,Entrys);
entryIndex = buildEntryIndex(current,entrys);
improved=true;
break;
}
......@@ -360,21 +347,29 @@ boolean improved = true;
{
break;
}else {
batchDecode(decoder, candidates);
batchDecode(decoder, candidates,machines);
}
int bestidx= Getbest(candidates,best);
if(bestidx>-1)
{
best=candidates.get(bestidx);
current=best;
current=ProductionDeepCopyUtil.deepCopy(best, Chromosome.class);;
// 更新索引
noImproveCount=0;
positionIndex = buildPositionIndex(current);
entryIndex = buildEntryIndex(current,Entrys);
entryIndex = buildEntryIndex(current,entrys);
improved=true;
break;
}
if (noImproveCount >= maxNoImprove) {
FileHelper.writeLogFile(String.format("爬山法 - 提前停止:连续未优化 迭代%d次", pi + 1));
noImproveCount=0;
}
noImproveCount++;
}
}
......@@ -409,6 +404,17 @@ boolean improved = true;
* 构建位置索引:groupId_sequence -> position
*/
private Map<String, Integer> buildPositionIndex(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));
Map<String, Integer> index = new HashMap<>();
List<Integer> os = chromosome.getOperationSequencing();
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
......@@ -470,12 +476,10 @@ boolean improved = true;
/**
* 构建Entry索引:op.getGroupId() + "_" + op.getSequence() -> Entry
*/
private Map<String, Entry> buildEntryKey(Chromosome chromosome) {
private Map<String, Entry> buildEntryKey() {
Map<String, Entry> index = new HashMap<>();
List<Entry> allOps = chromosome.getAllOperations();
for (Entry op : allOps) {
for (Entry op : allOperations) {
String key = op.getGroupId() + "_" + op.getSequence();
index.put(key, op);
......@@ -593,6 +597,7 @@ boolean improved = true;
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);
......@@ -647,8 +652,18 @@ boolean improved = true;
return neighbor;
}
private void batchDecode(GeneticDecoder decoder,List<Chromosome> chromosomes )
private void batchDecode(GeneticDecoder decoder,List<Chromosome> chromosomes, List<Machine> machines )
{
for (Chromosome chromosome :chromosomes) {
chromosome.setResult(new CopyOnWriteArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
}
// 并行解码所有候选方案
decoder.Chromosomedecode(chromosomes);
}
......
......@@ -110,7 +110,7 @@ int opcount=allOperations.size();
List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList();
// 初始化变邻域搜索
_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);
_parallelLocalSearch = new ParallelLocalSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_tabuSearch = new TabuSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
......@@ -146,7 +146,7 @@ int opcount=allOperations.size();
FileHelper.writeLogFile("爬山法局部优化-----------开始-------");
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("爬山法局部优化-----------结束-------");
return getBestChromosome(optimized, param.getBaseTime(), starttime);
}
......@@ -154,14 +154,16 @@ int opcount=allOperations.size();
// 步骤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);
int ordercount = globalOpList.stream()
......@@ -230,15 +232,6 @@ int opcount=allOperations.size();
selected.addAll(saImproved);
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("并行局部搜索-----------开始-------");
......@@ -444,11 +437,6 @@ int opcount=allOperations.size();
if (existing == null) {
// 第一次遇到这个Objectives,直接添加
objectivesMap.put(objectivesKey, chromosome);
} else {
// 已经存在,保留fitness更大的那个
if (chromosome.getFitness() > existing.getFitness()) {
objectivesMap.put(objectivesKey, chromosome);
}
}
}
......@@ -555,9 +543,9 @@ int opcount=allOperations.size();
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights));
}
// if (chromosome.getFitness() == 0) {
// chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights));
// }
}
......
......@@ -36,10 +36,10 @@ public class ParallelLocalSearch {
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(() -> {
// HillClimbing hillClimbing = new HillClimbing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
// return hillClimbing.search(chromosome, decoder, param);
// });
// 添加变邻域搜索任务
tasks.add(() -> {
......
package com.aps.service.Algorithm;
import com.aps.common.util.FileHelper;
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 java.util.*;
import java.util.concurrent.*;
......@@ -33,39 +35,59 @@ public class SimulatedAnnealing {
new ArrayBlockingQueue<>(200), // 有界队列,避免内存溢出
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<>();
CompletableFuture.allOf(chromosomes.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> {
Chromosome optimized = searchWithHillClimbing(chromosome, decoder, param);
// CompletableFuture.allOf(chromosomes.stream()
// .map(chromosome -> CompletableFuture.runAsync(() -> {
// 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);
}, decodeExecutor))
.toArray(CompletableFuture[]::new))
.join();
break;
}
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 best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
// 初始化解码
// decode(decoder, best, param);
// decode(decoder, current, param);
Map<String, Entry> Entrys = buildEntryKey(current);
FileHelper.writeLogFile("模拟退火+爬山法 - 初始化索引完成");
// 初始化温度 - 优化速度:更快降温,更快切换到爬山法
double temperature = 100.0;
double coolingRate = 0.95;
double temperatureThreshold = 1.0; // 提高阈值,更快切换到爬山法
int maxIterations = 300; // 减少最大迭代次数
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 参数配置:温度=%.1f, 降温率=%.2f, 阈值=%.1f, 最大迭代=%d",
temperature, coolingRate, temperatureThreshold, maxIterations));
int noImproveCount = 0;
int maxNoImprove = 50; // 连续50次没改进就提前停止
int acceptCount = 0;
int improveCount = 0;
for (int i = 0; i < maxIterations; i++) {
boolean improved = false;
......@@ -73,7 +95,7 @@ public class SimulatedAnnealing {
Chromosome neighbor = generateNeighbor(current,Entrys);
// 2. 解码并计算适应度(只解码neighbor,current已经解码过了)
decode(decoder, neighbor, param);
decode(decoder, neighbor, machines);
// 3. 计算能量差(fitness差)
double energyDifference = calculateEnergyDifference(neighbor, current);
......@@ -81,13 +103,16 @@ public class SimulatedAnnealing {
// 4. 按概率接受新解
// - 更优:直接接受
// - 较差:概率接受(高温更容易接受)
boolean accepted = false;
if (energyDifference > 0 || rnd.nextDouble() < Math.exp(energyDifference / temperature)) {
current = neighbor;
accepted = true;
acceptCount++;
// 更新全局最优
if (isBetter(current, best)) {
best = ProductionDeepCopyUtil.deepCopy(current, Chromosome.class);
improved = true;
improveCount++;
noImproveCount = 0;
}
}
......@@ -98,16 +123,27 @@ public class SimulatedAnnealing {
// 5. 降温
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. 提前停止条件:温度低于阈值 或 连续多次没改进
if (temperature < temperatureThreshold || noImproveCount >= maxNoImprove) {
HillClimbing hillClimbing = new HillClimbing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
Chromosome refined = hillClimbing.search(best, decoder, param);
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("模拟退火+爬山法 - 爬山法求精完成");
// 返回爬山法求精后的结果
return refined;
}
}
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 完成所有%d次迭代,最终fitness=%.4f", maxIterations, best.getFitness()));
// 7. 输出全局最优排产
return best;
......@@ -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);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(fitnessCalculator.calculateFitness(chromosome, objectiveWeights));
}
}
/**
......@@ -341,4 +381,23 @@ public class SimulatedAnnealing {
}
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