Commit 932c42d2 authored by Tong Li's avatar Tong Li

混合算法

parent ad57430d
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -392,7 +392,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);
......@@ -474,7 +474,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
Map<Integer, Entry> entryIndexById = new HashMap<>();
Map<Integer, List<Entry>> entrysBygroupId = new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById = new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById = new ConcurrentHashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
......@@ -627,7 +627,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
Map<Integer, Entry> entryIndexById = new HashMap<>();
Map<Integer, List<Entry>> entrysBygroupId = new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById= new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById= new ConcurrentHashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
......
package com.aps.service.Algorithm;
import com.aps.common.util.DateTimeUtil;
import com.aps.common.util.DateTimeUtil;
import com.aps.common.util.DeepCopyUtil;
import com.aps.common.util.FileHelper;
import com.aps.common.util.ProductionDeepCopyUtil;
......@@ -55,7 +55,7 @@ public class HybridAlgorithm {
// 初始化算法实例
private HillClimbing _hillClimbing;
private SimulatedAnnealing _simulatedAnnealing;
private ParallelLocalSearch _parallelLocalSearch;
// 初始化算法实例
private TabuSearch _tabuSearch;
......@@ -109,11 +109,10 @@ int opcount=allOperations.size();
// 预生成全局工序列表(所有初始化方法共享同一顺序)
List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList();
// 初始化变邻域搜索
_vns = new VariableNeighborhoodSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_vns = new VariableNeighborhoodSearch( allOperations, _fitnessCalculator );
_hillClimbing = new HillClimbing(allOperations);
_simulatedAnnealing = new SimulatedAnnealing( allOperations);
_parallelLocalSearch = new ParallelLocalSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_tabuSearch = new TabuSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_simulatedAnnealing = new SimulatedAnnealing( allOperations, _fitnessCalculator);
_tabuSearch = new TabuSearch(allOperations);
_tabuSearchWithSA = new TabuSearchWithSA(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
FileHelper.writeLogFile("初始化种群-----------开始-------");
......@@ -146,7 +145,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,machines, hillClimbingDecoder);
Chromosome optimized = _hillClimbing.search(population.get(0), hillClimbingDecoder,machines);
FileHelper.writeLogFile("爬山法局部优化-----------结束-------");
return getBestChromosome(optimized, param.getBaseTime(), starttime);
}
......@@ -156,27 +155,25 @@ 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);
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);
}
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 +182,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 +191,7 @@ int opcount=allOperations.size();
FileHelper.writeLogFile("迭代进化------"+iter+"-----开始-------");
// 计算种群适应度标准差,微调参数
double fitnessStd = _fitnessCalculator.calculateFitnessStd(population);
param.fineTuneParams(iter, fitnessStd);
......@@ -204,141 +203,54 @@ 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);
List<Chromosome> newPopulation = new ArrayList<>();
newPopulation.add(best);
while (newPopulation.size() < param.getPopulationSize()) {
// 选择父代
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);
nextPopulation.add(children.getFirst());
nextPopulation.add(children.getSecond());
} else {
nextPopulation.add(parent1);
nextPopulation.add(parent2);
}
child=children.getFirst();
child.setID(UUID.randomUUID().toString());
}
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);
geneticOps.mutate(child, globalOpList);
}
}
nextPopulation.addAll(nextPopulation1);
FileHelper.writeLogFile("变异操作-----------结束-------");
FileHelper.writeLogFile("变异批量解码-----------开始-------");
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());
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());
// 核心融合链(工业级标准顺序:GA生成子代 → SA跳坑 → VNS扩邻域 → TS精优化)
child = _simulatedAnnealing.search(child,_tabuSearch,_vns, saDecoder1, machines);
child = _vns.search(child, vnsDecoder1, machines);
newPopulation.add(child);
}
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;
}
......@@ -413,7 +325,7 @@ int opcount=allOperations.size();
}
/**
* 按Objectives去重,相同目标值的方案只保留一个(保留fitness最大的)
* 按Objectives去重
*/
private List<Chromosome> chromosomeDistinctByObjectives(List<Chromosome> population)
{
......@@ -440,7 +352,32 @@ 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; // 两者相等
}
});
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;
}
private List<Chromosome> chromosomeDistinct1(List<Chromosome> population)
......
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
......@@ -20,15 +20,17 @@ public class SimulatedAnnealing {
private List<Entry> allOperations;
private FitnessCalculator fitnessCalculator;
private Map<String, Entry> entrys;
private Map<Integer, Entry> entrybyids;
public SimulatedAnnealing( List<Entry> allOperations) {
public SimulatedAnnealing( List<Entry> allOperations, FitnessCalculator fitnessCalculator) {
this.allOperations = allOperations;
Map<Integer, Object> mp = buildEntryKey();
this.fitnessCalculator = fitnessCalculator;
entrys=(Map<String, Entry>)mp.get(1);
entrybyids=(Map<Integer, Entry>)mp.get(2);
......@@ -40,7 +42,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 +52,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,7 +74,7 @@ private Map<String, Entry> entrys;
* 模拟退火搜索,当温度降低到一定程度后切换到爬山法
* 流程:模拟退火全局探索(按概率接受劣解)→ 降温 → 温度低时爬山法局部求精 → 输出最优
*/
public Chromosome searchWithHillClimbing(Chromosome chromosome, GeneticDecoder decoder, List<Machine> machines) {
public Chromosome searchWithHillClimbing(Chromosome chromosome, VariableNeighborhoodSearch vns,GeneticDecoder decoder, List<Machine> machines) {
FileHelper.writeLogFile("模拟退火+爬山法 - 开始执行");
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
......@@ -102,7 +104,7 @@ private Map<String, Entry> entrys;
boolean improved = false;
// 1. 使用智能策略生成邻域解(找瓶颈工序/设备)
Chromosome neighbor = generateNeighbor(current);
Chromosome neighbor = vns.generateNeighbor(current);
// 2. 解码
decode(decoder, neighbor,machines);
......@@ -118,14 +120,14 @@ private Map<String, Entry> entrys;
acceptCount++;
// 更新全局最优
if (isBetter(current, best)) {
best = ProductionDeepCopyUtil.deepCopy(current, Chromosome.class);
writeKpi(best);
improved = true;
improveCount++;
noImproveCount = 0;
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 迭代%d:找到更优解,fitness=%.4f", i, best.getFitness()));
}
}
if (!improved) {
......@@ -162,6 +164,95 @@ private Map<String, Entry> entrys;
// 7. 输出全局最优排产
return best;
}
/**
* 模拟退火搜索
* 流程:模拟退火全局探索(按概率接受劣解)→ 降温 → 输出最优
*/
public Chromosome search(Chromosome chromosome,TabuSearch tabusearch,VariableNeighborhoodSearch vns, GeneticDecoder decoder, List<Machine> machines) {
FileHelper.writeLogFile("模拟退火+爬山法 - 开始执行");
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
decode(decoder, current,machines);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
writeKpi(best);
// 初始化解码
// FileHelper.writeLogFile("模拟退火+爬山法 - 初始化解码完成");
// 初始化温度
double temperature = 100.0;
double coolingRate = 0.95;
double temperatureThreshold = 1.0;
int maxIterations = 300;
int noImproveCount = 0;
int maxNoImprove = 50;
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 参数配置:温度=%.1f, 降温率=%.2f, 阈值=%.1f, 最大迭代=%d",
temperature, coolingRate, temperatureThreshold, maxIterations));
int acceptCount = 0;
int improveCount = 0;
for (int i = 0; i < maxIterations; i++) {
boolean improved = false;
// 1. 使用智能策略生成邻域解(找瓶颈工序/设备)
Chromosome neighbor = vns.generateNeighbor(current);
// 2. 解码
decode(decoder, neighbor,machines);
// 跳过禁忌解(除非是最优解)
if (tabusearch.isTabu(neighbor.getGeneStr()) && !isBetter(current,best)) {
temperature *= coolingRate;
continue;
}
// 3. 计算能量差
double energyDifference = calculateEnergyDifference(neighbor, current);
// 4. 按概率接受新解(模拟退火核心:有概率接受劣解)
boolean accepted = false;
if (energyDifference > 0 || rnd.nextDouble() < Math.exp(energyDifference / temperature)) {
current = neighbor;
accepted = true;
acceptCount++;
best = ProductionDeepCopyUtil.deepCopy(current, Chromosome.class);
tabusearch.addToTabuList(best.getGeneStr());
writeKpi(best);
improved = true;
improveCount++;
noImproveCount = 0;
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 迭代%d:找到更优解,fitness=%.4f", i, best.getFitness()));
}
if (!improved) {
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));
}
}
FileHelper.writeLogFile(String.format("模拟退火+爬山法 - 完成所有%d次迭代,最终fitness=%.4f",
maxIterations, best.getFitness()));
// 7. 输出全局最优排产
return best;
}
private void writeKpi(Chromosome chromosome) {
String fitness = "";
double[] fitness1 = chromosome.getFitnessLevel();
......@@ -221,66 +312,7 @@ private Map<String, Entry> entrys;
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;
}
/**
* 构建位置索引:groupId_sequence -> Machines position
*/
private Map<String, Integer> buildEntryMachinePositionIndex(Chromosome chromosome) {
Map<String, Integer> index = new HashMap<>();
List<GlobalOperationInfo> globalOpList = chromosome.getGlobalOpList();
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();
String key = groupId + "_" + count;
index.put(key, i);
}
return index;
}
/**
* 构建位置->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<>();
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;
Entry op = entrys.get(key);
if (op != null) {
index.put(i, op);
}
}
return index;
}
/**
* 构建Entry索引:op.getGroupId() + "_" + op.getSequence() -> Entry
*/
......@@ -301,544 +333,6 @@ private Map<String, Entry> entrys;
return index0;
}
/**
* 生成邻域解 - 智能策略:优先处理瓶颈工序/设备
* 策略:
* 1. 优先处理瓶颈设备上的工序(换设备)
* 2. 瓶颈设备上的工序往前移动
* 3. 非瓶颈设备上的工序往后移动(给瓶颈工序腾位置)
*/
private Chromosome generateNeighbor(Chromosome chromosome) {
List<GAScheduleResult> results = chromosome.getResult();
if (results == null || results.isEmpty()) {
return generateRandomNeighbor(chromosome, entrys);
}
// 构建位置索引
Map<String, Integer> positionIndex = buildPositionIndex(chromosome);
Map<Integer, Entry> positionToEntryIndex = buildPositionToEntryIndex(chromosome, entrys);
Map<String, Integer> MachinePositionIndex = buildEntryMachinePositionIndex(chromosome);
// 1. 找出瓶颈设备
Long bottleneckMachineId = findBottleneckMachine(chromosome);
if (bottleneckMachineId != null) {
// 找出瓶颈设备上的工序
List<GAScheduleResult> bottleneckOps = findOpsOnBottleneckMachine(chromosome, bottleneckMachineId);
if (!bottleneckOps.isEmpty()) {
// 70%概率优先处理瓶颈设备
if (rnd.nextDouble() < 0.7) {
int strategy = rnd.nextInt(10);
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);
}
}
}
}
// 默认策略:随机邻域
return generateRandomNeighbor(chromosome, entrys);
}
/**
* 识别瓶颈设备(利用率最高的设备)
*/
private Long findBottleneckMachine(Chromosome chromosome) {
Map<Long, Double> utilization = calculateMachineUtilization(chromosome);
if (utilization.isEmpty()) {
return null;
}
return utilization.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse(null);
}
/**
* 查找在瓶颈设备上的工序
*/
private List<GAScheduleResult> findOpsOnBottleneckMachine(Chromosome chromosome, Long bottleneckMachineId) {
if (bottleneckMachineId == null) {
return new ArrayList<>();
}
return chromosome.getResult().stream()
.filter(r -> r.getMachineId() == bottleneckMachineId)
.collect(Collectors.toList());
}
/**
* 计算设备利用率
*/
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);
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);
}
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()));
// 找到这个工序在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);
}
}
if (!availableMachines.isEmpty()) {
int newMachineSeq = availableMachines.get(rnd.nextInt(availableMachines.size()));
ms.set(idx, newMachineSeq);
neighbor.setMachineSelection(ms);
}
}
}
return neighbor;
}
/**
* 尝试将瓶颈设备上的工序往前移动
*/
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);
}
// 随机选择一个非瓶颈工序
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);
}
// 往后移动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();
if (pos <= 0 || pos >= os.size()) {
return neighbor;
}
// 获取要移动的工序和目标位置的工序(基于原始chromosome)
Entry opToMove = originalPositionIndex.get(pos);
if (opToMove == null) {
return neighbor;
}
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;
}
// 直接交换到目标位置
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)
Entry opToMove = originalPositionIndex.get(pos);
if (opToMove == null) {
return neighbor;
}
int targetPos = Math.min(os.size() - 1, 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;
}
// 直接交换到目标位置
java.util.Collections.swap(os, pos, targetPos);
neighbor.setOperationSequencing(os);
return neighbor;
}
/**
* 将工序往前插入(不交换,直接插入到目标位置)
*/
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;
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;
}
if (finalTargetPos == pos) {
return neighbor;
}
// 执行插入:移除原位置,插入到目标位置
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 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;
Entry startOp = positionIndex.get(start);
if (startOp == null) continue;
double priority = startOp.getPriority();
boolean allSamePriority = true;
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 (allSamePriority) {
java.util.Collections.reverse(os.subList(start, end + 1));
neighbor.setOperationSequencing(os);
break;
}
}
}
return neighbor;
}
/**
* 生成插入邻域解 - 只插入到相同优先级的位置
*/
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;
Entry op1 = positionIndex.get(idx1);
Entry op2 = positionIndex.get(idx2);
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;
}
}
}
}
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 = 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;
}
/**
* 解码染色体
*/
......@@ -857,14 +351,7 @@ private Map<String, Entry> entrys;
* 比较两个染色体的优劣(基于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) {
// 找出最佳候选方案
......
......@@ -11,251 +11,59 @@ import java.util.*;
* 禁忌搜索算法
*/
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 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;
public TabuSearch(List<Entry> allOperations) {
this.tabuList = new ArrayList<>();
// 工序越多,禁忌表越长(适配1000+工序)
this.tabuListSize = Math.min(50, allOperations.size() / 30);
}
/**
* 禁忌搜索
*/
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
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) {
// 更新当前解
current = bestNeighbor;
// 更新禁忌表
addToTabuList(current);
// 更新最优解
if (isBetter(current, best)) {
best = current;
noImprovementCount = 0;
} else {
noImprovementCount++;
}
}
iterations++;
}
return best;
}
/**
* 生成邻域解
* 检查解是否在禁忌表中
*/
private List<Chromosome> generateNeighbors(Chromosome chromosome) {
List<Chromosome> neighbors = new ArrayList<>();
public boolean isTabu(String GeneStr) {
// 生成多个邻域解
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 tabuList.contains(GeneStr);
return neighbors;
}
/**
* 过滤禁忌解
* 添加解到禁忌表
*/
private List<Chromosome> filterTabuSolutions(List<Chromosome> neighbors) {
List<Chromosome> validNeighbors = new ArrayList<>();
for (Chromosome neighbor : neighbors) {
if (!isTabu(neighbor)) {
validNeighbors.add(neighbor);
public void addToTabuList(String GeneStr) {
tabuList.add(GeneStr);
if (tabuList.size() > tabuListSize) {
// 移除最早加入的禁忌解(FIFO策略)
Iterator<String> iterator = tabuList.iterator();
iterator.next();
iterator.remove();
}
}
// 如果没有有效邻域解,返回所有邻域解
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
......@@ -6,6 +6,7 @@ import com.aps.entity.basic.*;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
/**
* 变邻域搜索算法
......@@ -14,28 +15,34 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public class VariableNeighborhoodSearch {
private final Random rnd = new Random();
private GlobalParam globalParam;
private List<Entry> allOperations;
private List<GlobalOperationInfo> globalOpList;
private FitnessCalculator fitnessCalculator;
private ObjectiveWeights objectiveWeights;
public VariableNeighborhoodSearch(GlobalParam globalParam, List<Entry> allOperations, List<GlobalOperationInfo> globalOpList, FitnessCalculator fitnessCalculator, ObjectiveWeights objectiveWeights) {
this.globalParam = globalParam;
private Map<String, Entry> entrys;
private Map<Integer, Entry> entrybyids;
public VariableNeighborhoodSearch( List<Entry> allOperations, FitnessCalculator fitnessCalculator) {
this.allOperations = allOperations;
this.globalOpList = globalOpList;
this.fitnessCalculator = fitnessCalculator;
this.objectiveWeights = objectiveWeights;
Map<Integer, Object> mp = buildEntryKey();
entrys=(Map<String, Entry>)mp.get(1);
entrybyids=(Map<Integer, Entry>)mp.get(2);
}
/**
* 对种群中的每个个体进行变邻域搜索
*/
public List<Chromosome> search(List<Chromosome> population, GeneticDecoder decoder, ScheduleParams param) {
public List<Chromosome> search(List<Chromosome> population, GeneticDecoder decoder, List<Machine> machines) {
List<Chromosome> improvedPopulation = new ArrayList<>();
for (Chromosome chromosome : population) {
Chromosome improvedChromosome = search(chromosome, decoder, param);
Chromosome improvedChromosome = search(chromosome, decoder, machines);
improvedPopulation.add(improvedChromosome);
}
......@@ -45,7 +52,7 @@ public class VariableNeighborhoodSearch {
/**
* 对单个个体进行变邻域搜索
*/
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);
......@@ -59,10 +66,10 @@ public class VariableNeighborhoodSearch {
NeighborhoodStructure neighborhood = neighborhoods.get(k);
// 生成邻域解
Chromosome neighbor = generateNeighbor(current, neighborhood);
Chromosome neighbor = generateNeighbor(current);
// 局部搜索
Chromosome localBest = localSearch(neighbor, decoder, param);
Chromosome localBest = localSearch(neighbor, decoder,null);
// 邻域移动
if (isBetter(localBest, best)) {
......@@ -99,11 +106,540 @@ public class VariableNeighborhoodSearch {
}
/**
* 生成邻域解
* 生成邻域解 - 智能策略:优先处理瓶颈工序/设备
* 策略:
* 1. 优先处理瓶颈设备上的工序(换设备)
* 2. 瓶颈设备上的工序往前移动
* 3. 非瓶颈设备上的工序往后移动(给瓶颈工序腾位置)
*/
private Chromosome generateNeighbor(Chromosome chromosome, NeighborhoodStructure neighborhood) {
public Chromosome generateNeighbor(Chromosome chromosome) {
List<GAScheduleResult> results = chromosome.getResult();
if (results == null || results.isEmpty()) {
return generateRandomNeighbor(chromosome, entrys);
}
// 构建位置索引
Map<String, Integer> positionIndex = buildPositionIndex(chromosome);
Map<Integer, Entry> positionToEntryIndex = buildPositionToEntryIndex(chromosome, entrys);
Map<String, Integer> MachinePositionIndex = buildEntryMachinePositionIndex(chromosome);
// 1. 找出瓶颈设备
Long bottleneckMachineId = findBottleneckMachine(chromosome);
if (bottleneckMachineId != null) {
// 找出瓶颈设备上的工序
List<GAScheduleResult> bottleneckOps = findOpsOnBottleneckMachine(chromosome, bottleneckMachineId);
if (!bottleneckOps.isEmpty()) {
// 70%概率优先处理瓶颈设备
if (rnd.nextDouble() < 0.7) {
int strategy = rnd.nextInt(10);
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);
}
}
}
}
// 默认策略:随机邻域
return generateRandomNeighbor(chromosome, entrys);
}
/**
* 识别瓶颈设备(利用率最高的设备)
*/
private Long findBottleneckMachine(Chromosome chromosome) {
Map<Long, Double> utilization = calculateMachineUtilization(chromosome);
if (utilization.isEmpty()) {
return null;
}
return utilization.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse(null);
}
/**
* 查找在瓶颈设备上的工序
*/
private List<GAScheduleResult> findOpsOnBottleneckMachine(Chromosome chromosome, Long bottleneckMachineId) {
if (bottleneckMachineId == null) {
return new ArrayList<>();
}
return chromosome.getResult().stream()
.filter(r -> r.getMachineId() == bottleneckMachineId)
.collect(Collectors.toList());
}
/**
* 计算设备利用率
*/
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);
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);
}
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()));
// 找到这个工序在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);
neighborhood.apply(neighbor);
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);
}
}
if (!availableMachines.isEmpty()) {
int newMachineSeq = availableMachines.get(rnd.nextInt(availableMachines.size()));
ms.set(idx, newMachineSeq);
neighbor.setMachineSelection(ms);
}
}
}
return neighbor;
}
/**
* 尝试将瓶颈设备上的工序往前移动
*/
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);
}
// 随机选择一个非瓶颈工序
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);
}
// 往后移动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();
if (pos <= 0 || pos >= os.size()) {
return neighbor;
}
// 获取要移动的工序和目标位置的工序(基于原始chromosome)
Entry opToMove = originalPositionIndex.get(pos);
if (opToMove == null) {
return neighbor;
}
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;
}
// 直接交换到目标位置
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)
Entry opToMove = originalPositionIndex.get(pos);
if (opToMove == null) {
return neighbor;
}
int targetPos = Math.min(os.size() - 1, 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;
}
// 直接交换到目标位置
java.util.Collections.swap(os, pos, targetPos);
neighbor.setOperationSequencing(os);
return neighbor;
}
/**
* 将工序往前插入(不交换,直接插入到目标位置)
*/
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;
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;
}
if (finalTargetPos == pos) {
return neighbor;
}
// 执行插入:移除原位置,插入到目标位置
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 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;
Entry startOp = positionIndex.get(start);
if (startOp == null) continue;
double priority = startOp.getPriority();
boolean allSamePriority = true;
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 (allSamePriority) {
java.util.Collections.reverse(os.subList(start, end + 1));
neighbor.setOperationSequencing(os);
break;
}
}
}
return neighbor;
}
/**
* 生成插入邻域解 - 只插入到相同优先级的位置
*/
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;
Entry op1 = positionIndex.get(idx1);
Entry op2 = positionIndex.get(idx2);
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;
}
}
}
}
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 = 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;
}
......@@ -121,12 +657,12 @@ public class VariableNeighborhoodSearch {
// 生成所有可能的邻域解
List<Chromosome> neighbors = new ArrayList<>();
for (NeighborhoodStructure neighborhood : defineNeighborhoods()) {
neighbors.add(generateNeighbor(current, neighborhood));
neighbors.add(generateNeighbor(current));
}
// 评估所有邻域解
for (Chromosome neighbor : neighbors) {
decode(decoder, neighbor, param);
decode(decoder, neighbor, null);
if (isBetter(neighbor, best)) {
best = neighbor;
current = neighbor;
......@@ -138,15 +674,19 @@ public class VariableNeighborhoodSearch {
return best;
}
/**
* 解码染色体
*/
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));
}
}
/**
......@@ -216,7 +756,7 @@ public class VariableNeighborhoodSearch {
if (ms.isEmpty()) return;
int idx = rnd.nextInt(ms.size());
GlobalOperationInfo globalOp = globalOpList.get(idx);
GlobalOperationInfo globalOp = chromosome.getGlobalOpList().get(idx);
Entry op = globalOp.getOp();
if (op.getMachineOptions().size() > 1) {
......@@ -235,6 +775,86 @@ public class VariableNeighborhoodSearch {
}
}
}
/**
* 构建位置索引: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;
}
/**
* 构建位置索引:groupId_sequence -> Machines position
*/
private Map<String, Integer> buildEntryMachinePositionIndex(Chromosome chromosome) {
Map<String, Integer> index = new HashMap<>();
List<GlobalOperationInfo> globalOpList = chromosome.getGlobalOpList();
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();
String key = groupId + "_" + count;
index.put(key, i);
}
return index;
}
/**
* 构建位置->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<>();
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;
Entry op = entrys.get(key);
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;
for (Entry op : allOps) {
String key = op.getGroupId() + "_" + op.getSequence();
index.put(key, op);
index2.put(op.getId(), op);
}
index0.put(1,index);
index0.put(2,index2);
return index0;
}
/**
* 邻域结构接口
......
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