Commit 78368160 authored by Tong Li's avatar Tong Li

变领域优化

parent bdfee182
This diff is collapsed.
2026-04-21 19:15:40.112 | main | com.aps.common.util.redis.RedisUtils | Redis 操作失败 1/3: get(material), 错误: Redis exception; nested exception is io.lettuce.core.RedisException: Connection closed
2026-04-21 19:15:40.627 | main | com.aps.common.util.redis.RedisUtils | Redis 操作失败 2/3: get(material), 错误: LettuceConnectionFactory was destroyed and cannot be used anymore
2026-04-21 19:58:28.398 | main | com.aps.common.util.redis.RedisUtils | Redis 操作失败 1/3: get(SceneId.6D63146BE5C84A78B5AB044327BA55BD), 错误: Redis exception; nested exception is io.lettuce.core.RedisException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
2026-04-21 21:22:58.624 | main | com.aps.common.util.redis.RedisUtils | Redis 操作失败 1/3: get(SceneId.6D63146BE5C84A78B5AB044327BA55BD), 错误: Redis exception; nested exception is io.lettuce.core.RedisException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
...@@ -58,7 +58,7 @@ public class GeneticDecoder { ...@@ -58,7 +58,7 @@ public class GeneticDecoder {
private DiscreteParameterMatrixService discreteParameterMatrixService; private DiscreteParameterMatrixService discreteParameterMatrixService;
private String sceneId; private String sceneId;
private boolean rebuildStructureForCurrentDecode = true; private boolean rebuildStructureForCurrentDecode = false;
...@@ -1108,7 +1108,7 @@ public class GeneticDecoder { ...@@ -1108,7 +1108,7 @@ public class GeneticDecoder {
long machineId = machine.getId(); long machineId = machine.getId();
// 只有存在物料约束(或本次被强制要求重算 BOM)的工序,才需要联立求解“机台何时能排”和“物料何时可用”。 // 只有存在物料约束(或本次被强制要求重算 BOM)的工序,才需要联立求解“机台何时能排”和“物料何时可用”。
// targetFinishedOperationId != null 的工序通常由前置成品工序驱动,这里不再额外触发一轮 BOM 试算。 // targetFinishedOperationId != null 的工序通常由前置成品工序驱动,这里不再额外触发一轮 BOM 试算。
boolean needMaterialCheck = (operation.getMaterialRequirements()!=null&&operation.getMaterialRequirements().size()>0&&operation.getTargetFinishedOperationId()==null)||calbom; boolean needMaterialCheck =false;// (operation.getMaterialRequirements()!=null&&operation.getMaterialRequirements().size()>0&&operation.getTargetFinishedOperationId()==null)||calbom;
// 正式落排后还要再做一次带提交的物料校验,把试算阶段推导出的 BOM 状态真正写回 chromosome。 // 正式落排后还要再做一次带提交的物料校验,把试算阶段推导出的 BOM 状态真正写回 chromosome。
boolean commitMaterialCheck = needMaterialCheck; boolean commitMaterialCheck = needMaterialCheck;
// baseEarliestStartTime:不考虑 BOM 推迟时的理论最早开工时间。 // baseEarliestStartTime:不考虑 BOM 推迟时的理论最早开工时间。
......
...@@ -98,11 +98,13 @@ public class HybridAlgorithm { ...@@ -98,11 +98,13 @@ public class HybridAlgorithm {
// } // }
LocalDateTime starttime=LocalDateTime.now(); LocalDateTime starttime=LocalDateTime.now();
FileHelper.writeLogFile("排产-----------开始-----------"+allOperations.get(0).getSceneId()); FileHelper.writeLogFile("排产-----------开始-----------"+allOperations.get(0).getSceneId());
// 在整个流程开始时创建一个全局 shared decoder,所有阶段共享解码缓存
GeneticDecoder sharedDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
Initialization initialization = new Initialization(_GlobalParam,allOperations,orders,machines,_objectiveWeights); Initialization initialization = new Initialization(_GlobalParam,allOperations,orders,machines,_objectiveWeights);
GeneticOperations geneticOps = new GeneticOperations(_GlobalParam,allOperations,param); GeneticOperations geneticOps = new GeneticOperations(_GlobalParam,allOperations,param);
int opcount=allOperations.size(); int opcount=allOperations.size();
// 预生成全局工序列表(所有初始化方法共享同一顺序) // 预生成全局工序列表(所有初始化方法共享同一顺序)
List<GlobalOperationInfo> globalOpList =new ArrayList<>();// initialization.generateGlobalOpList(); List<GlobalOperationInfo> globalOpList =new ArrayList<>();// initialization.generateGlobalOpList();
// 初始化变邻域搜索 // 初始化变邻域搜索
...@@ -119,13 +121,13 @@ int opcount=allOperations.size(); ...@@ -119,13 +121,13 @@ int opcount=allOperations.size();
FileHelper.writeLogFile("构造启发式初始化-----------结束-------"); FileHelper.writeLogFile("构造启发式初始化-----------结束-------");
population= chromosomeDistinct(population).subList(0,1); population= chromosomeDistinct(population);
FileHelper.writeLogFile("初始化种群-----------结束-------"); FileHelper.writeLogFile("初始化种群-----------结束-------");
FileHelper.writeLogFile("初始化批量解码-----------开始-------"); FileHelper.writeLogFile("初始化批量解码-----------开始-------");
Chromosomedecode(param,allOperations,globalOpList,population); Chromosomedecode(sharedDecoder,param,allOperations,globalOpList,population);
FileHelper.writeLogFile("初始化批量解码-----------结束-------"); FileHelper.writeLogFile("初始化批量解码-----------结束-------");
...@@ -145,9 +147,8 @@ int opcount=allOperations.size(); ...@@ -145,9 +147,8 @@ int opcount=allOperations.size();
Chromosome best=population.get(0); Chromosome best=population.get(0);
FileHelper.writeLogFile("爬山法局部优化-----------开始-------"); FileHelper.writeLogFile("爬山法局部优化-----------开始-------");
GeneticDecoder hillClimbingDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
Chromosome optimized = _hillClimbing.searchAll(best,machines,hillClimbingDecoder); Chromosome optimized = _hillClimbing.searchAll(best,machines,sharedDecoder);
FileHelper.writeLogFile("爬山法局部优化-----------结束-------"); FileHelper.writeLogFile("爬山法局部优化-----------结束-------");
return getBestChromosome(optimized, param.getBaseTime(), starttime); return getBestChromosome(optimized, param.getBaseTime(), starttime);
} }
...@@ -156,18 +157,13 @@ int opcount=allOperations.size(); ...@@ -156,18 +157,13 @@ int opcount=allOperations.size();
// 步骤2:对初始种群进行模拟退火+爬山法优化 // 步骤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);
GeneticDecoder tabuDecoder1 = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
if(opcount<800 ) { if(opcount<800 ) {
Chromosome best=population.get(0); Chromosome best=population.get(0);
FileHelper.writeLogFile("模拟退火+爬山法优化-----------开始-------"); FileHelper.writeLogFile("模拟退火+爬山法优化-----------开始-------");
Chromosome saHcOptimized = _simulatedAnnealing.searchWithHillClimbing(best,_vns, saDecoder1, machines); Chromosome saHcOptimized = _simulatedAnnealing.searchWithHillClimbing(best,_vns, sharedDecoder, machines);
FileHelper.writeLogFile("模拟退火+爬山法优化-----------结束-------"); FileHelper.writeLogFile("模拟退火+爬山法优化-----------结束-------");
return getBestChromosome(saHcOptimized, param.getBaseTime(), starttime); return getBestChromosome(saHcOptimized, param.getBaseTime(), starttime);
...@@ -175,9 +171,9 @@ int opcount=allOperations.size(); ...@@ -175,9 +171,9 @@ int opcount=allOperations.size();
if(opcount>=800 ) { if(opcount>=800 ) {
Chromosome best=population.get(0); Chromosome best=population.get(0);
best = _simulatedAnnealing.search(best, _tabuSearch, _vns, saDecoder1, machines); best = _simulatedAnnealing.search(best, _tabuSearch, _vns, sharedDecoder, machines);
best = _vns.search(best, vnsDecoder1, machines); best = _vns.search(best, sharedDecoder, machines);
best = _tabuSearch.search(best, _vns, tabuDecoder1, machines); best = _tabuSearch.search(best, _vns, sharedDecoder, machines);
return getBestChromosome(best, param.getBaseTime(), starttime); return getBestChromosome(best, param.getBaseTime(), starttime);
...@@ -252,9 +248,9 @@ int opcount=allOperations.size(); ...@@ -252,9 +248,9 @@ int opcount=allOperations.size();
// geneticOps.mutate(child, globalOpList); // geneticOps.mutate(child, globalOpList);
// } // }
// 核心融合链(工业级标准顺序:GA生成子代 → SA跳坑 → VNS扩邻域 → TS精优化) // 核心融合链(工业级标准顺序:GA生成子代 → SA跳坑 → VNS扩邻域 → TS精优化)
child = _simulatedAnnealing.search(child,_tabuSearch,_vns, saDecoder1, machines); child = _simulatedAnnealing.search(child,_tabuSearch,_vns, sharedDecoder, machines);
child = _vns.search(child, vnsDecoder1, machines); child = _vns.search(child, sharedDecoder, machines);
child = _tabuSearch.search(child, _vns,tabuDecoder1, machines); child = _tabuSearch.search(child, _vns,sharedDecoder, machines);
newPopulation.add(child); newPopulation.add(child);
...@@ -452,22 +448,22 @@ int opcount=allOperations.size(); ...@@ -452,22 +448,22 @@ int opcount=allOperations.size();
} }
private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population) private void Chromosomedecode(GeneticDecoder sharedDecoder,ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population)
{ {
FileHelper.writeLogFile("解码---------------"+population.size() ); FileHelper.writeLogFile("解码---------------"+population.size() );
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,materialRequirementService, sceneId); // GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,materialRequirementService, sceneId);
boolean ismore=true; boolean ismore=true;
if(ismore) { if(ismore) {
CompletableFuture.allOf(population.stream() CompletableFuture.allOf(population.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> decode(decoder, chromosome, param, allOperations, globalOpList), decodeExecutor)) .map(chromosome -> CompletableFuture.runAsync(() -> decode(sharedDecoder, chromosome, param, allOperations, globalOpList), decodeExecutor))
.toArray(CompletableFuture[]::new)) .toArray(CompletableFuture[]::new))
.join(); .join();
} else { } else {
if (population != null && population.size() > 0) { if (population != null && population.size() > 0) {
population.forEach(chromosome -> { population.forEach(chromosome -> {
decode(decoder, chromosome, param, allOperations, globalOpList); decode(sharedDecoder, chromosome, param, allOperations, globalOpList);
}); });
} }
} }
......
...@@ -238,8 +238,11 @@ public class SimulatedAnnealing { ...@@ -238,8 +238,11 @@ public class SimulatedAnnealing {
public Chromosome search(Chromosome chromosome,TabuSearch tabusearch,VariableNeighborhoodSearch vns, GeneticDecoder decoder, List<Machine> machines) { public Chromosome search(Chromosome chromosome,TabuSearch tabusearch,VariableNeighborhoodSearch vns, GeneticDecoder decoder, List<Machine> machines) {
log("模拟退火 - 开始执行",true); log("模拟退火 - 开始执行",true);
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome current = vns.copyChromosome(chromosome);
decode(decoder, current,machines); decode(decoder, current,machines);
decoder.DelOrder(current); decoder.DelOrder(current);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
writeKpi(best); writeKpi(best);
...@@ -551,7 +554,7 @@ public class SimulatedAnnealing { ...@@ -551,7 +554,7 @@ public class SimulatedAnnealing {
} else { } else {
chromosome.setResultOld(new CopyOnWriteArrayList<>()); chromosome.setResultOld(new CopyOnWriteArrayList<>());
} }
decoder.decodeChromosomeWithCache(chromosome,true); decoder.decodeChromosomeWithCache(chromosome,false);
} }
......
...@@ -347,7 +347,7 @@ public class TabuSearch { ...@@ -347,7 +347,7 @@ public class TabuSearch {
} else { } else {
chromosome.setResultOld(new CopyOnWriteArrayList<>()); chromosome.setResultOld(new CopyOnWriteArrayList<>());
} }
decoder.decodeChromosomeWithCache(chromosome,true); decoder.decodeChromosomeWithCache(chromosome,false);
} }
......
...@@ -62,7 +62,8 @@ public class VariableNeighborhoodSearch { ...@@ -62,7 +62,8 @@ public class VariableNeighborhoodSearch {
private static final int MIN_USE_COUNT_FOR_EXPLORATION_BONUS = 5; // 低使用次数判断的最小阈值 private static final int MIN_USE_COUNT_FOR_EXPLORATION_BONUS = 5; // 低使用次数判断的最小阈值
// ==================== 改进判断参数 ==================== // ==================== 改进判断参数 ====================
private static final double SIGNIFICANT_IMPROVEMENT_THRESHOLD = 0.0001; // 显著改进阈值:只有改进超过这个值才重置无改进计数 private static final double SIGNIFICANT_IMPROVEMENT_THRESHOLD = 0.01; // 显著改进阈值:提高到0.01以减少无效搜索
private static final int MAX_MINOR_IMPROVEMENTS = 3; // 最大连续微小改进次数,超过后提前终止
// 日志级别 // 日志级别
private static final int LOG_LEVEL_DEBUG = 0; private static final int LOG_LEVEL_DEBUG = 0;
...@@ -71,7 +72,7 @@ public class VariableNeighborhoodSearch { ...@@ -71,7 +72,7 @@ public class VariableNeighborhoodSearch {
private int currentLogLevel = LOG_LEVEL_INFO; private int currentLogLevel = LOG_LEVEL_INFO;
// 局部搜索优化 // 局部搜索优化
private static final int MAX_LOCAL_SEARCH_NEIGHBORS = 5; private static final int MAX_LOCAL_SEARCH_NEIGHBORS = 3; // 从5减少到2,大幅减少解码次数
private void log(String message) { private void log(String message) {
log(message, LOG_LEVEL_INFO, false); log(message, LOG_LEVEL_INFO, false);
...@@ -315,6 +316,7 @@ public class VariableNeighborhoodSearch { ...@@ -315,6 +316,7 @@ public class VariableNeighborhoodSearch {
int totalRounds = 0; // 总轮数 int totalRounds = 0; // 总轮数
int totalImprovements = 0; // 总改进次数 int totalImprovements = 0; // 总改进次数
int totalSignificantImprovements = 0; // 显著改进次数 int totalSignificantImprovements = 0; // 显著改进次数
int consecutiveMinorImprovements = 0; // 连续微小改进计数
int k = 0; int k = 0;
// 按成功率排序获取邻域结构(先获取一次) // 按成功率排序获取邻域结构(先获取一次)
...@@ -367,12 +369,21 @@ public class VariableNeighborhoodSearch { ...@@ -367,12 +369,21 @@ public class VariableNeighborhoodSearch {
if (isSignificant) { if (isSignificant) {
k = 0; // 重置邻域索引 k = 0; // 重置邻域索引
noImproveRoundCount = 0; // 只有显著改进才重置无改进计数 noImproveRoundCount = 0; // 只有显著改进才重置无改进计数
consecutiveMinorImprovements = 0; // 重置连续微小改进计数
totalSignificantImprovements++; totalSignificantImprovements++;
logVNSImprovement(best, initialFitnessLevel, initialFitness, totalRounds, neighborhood.name); logVNSImprovement(best, initialFitnessLevel, initialFitness, totalRounds, neighborhood.name);
log(String.format("变邻域搜索 - 邻域成功(显著): %s", neighborhood.name),true); log(String.format("变邻域搜索 - 邻域成功(显著): %s", neighborhood.name),true);
} else { } else {
// 微小改进也接受,但不重置计数,继续尝试 // 微小改进也接受,但不重置计数,继续尝试
log(String.format("变邻域搜索 - 邻域成功(微小): %s", neighborhood.name),true); consecutiveMinorImprovements++;
log(String.format("变邻域搜索 - 邻域成功(微小): %s, 连续微小改进: %d/%d",
neighborhood.name, consecutiveMinorImprovements, MAX_MINOR_IMPROVEMENTS),true);
// 检查连续微小改进是否超过阈值,超过则提前终止
if (consecutiveMinorImprovements >= MAX_MINOR_IMPROVEMENTS) {
log(String.format("变邻域搜索 - 提前终止:连续%d次微小改进,无显著提升", MAX_MINOR_IMPROVEMENTS),true);
break;
}
} }
geneticOperations.DelOrder(current); geneticOperations.DelOrder(current);
} else { } else {
...@@ -1638,7 +1649,7 @@ public class VariableNeighborhoodSearch { ...@@ -1638,7 +1649,7 @@ public class VariableNeighborhoodSearch {
return generateSwapNeighbor(chromosome, positionToEntryIndex, positionByPriority); return generateSwapNeighbor(chromosome, positionToEntryIndex, positionByPriority);
} }
private Chromosome copyChromosome(Chromosome chromosome) public Chromosome copyChromosome(Chromosome chromosome)
{ {
geneticOperations.DelOrder(chromosome); geneticOperations.DelOrder(chromosome);
Chromosome neighbor=new Chromosome(); Chromosome neighbor=new Chromosome();
...@@ -1984,51 +1995,45 @@ public class VariableNeighborhoodSearch { ...@@ -1984,51 +1995,45 @@ public class VariableNeighborhoodSearch {
*/ */
private Chromosome localSearch(Chromosome chromosome, GeneticDecoder decoder, List<Machine> machines) { private Chromosome localSearch(Chromosome chromosome, GeneticDecoder decoder, List<Machine> machines) {
geneticOperations.DelOrder(chromosome); geneticOperations.DelOrder(chromosome);
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome best = copyChromosome(chromosome);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
decode(decoder, best, machines); decode(decoder, best, machines);
writeKpi(best); writeKpi(best);
// 预定义邻域结构,避免每次循环重复创建 // 预定义邻域结构,避免每次循环重复创建
List<NeighborhoodStructure> neighborhoods = defineNeighborhoods(); List<NeighborhoodStructure> neighborhoods = defineNeighborhoods();
boolean improved = true; // 生成邻域解(限制数量以提高性能)
while (improved) { List<Chromosome> neighbors = new ArrayList<>();
improved = false;
// 生成邻域解(限制数量以提高性能)
List<Chromosome> neighbors = new ArrayList<>();
for (NeighborhoodStructure neighborhood : neighborhoods) { for (NeighborhoodStructure neighborhood : neighborhoods) {
if (neighbors.size() >= MAX_LOCAL_SEARCH_NEIGHBORS) { if (neighbors.size() >= MAX_LOCAL_SEARCH_NEIGHBORS) {
break; break;
}
Chromosome neighbor = generateNeighbor(current, neighborhood);
if (neighbor != null) {
neighbors.add(neighbor);
}
} }
if (neighbors.isEmpty()) { Chromosome neighbor = generateNeighbor(best, neighborhood);
break; if (neighbor != null) {
neighbors.add(neighbor);
} }
}
Batchdecode(decoder, neighbors, machines); if (neighbors.isEmpty()) {
return best;
}
// 评估所有邻域解,找到第一个改进就停止(贪心策略) Batchdecode(decoder, neighbors, machines);
for (Chromosome neighbor : neighbors) {
if (neighbor != null && isBetter(neighbor, best)) {
best = neighbor; // 评估所有邻域解,找到最佳改进
writeKpi(best); Chromosome bestNeighbor = best;
current = neighbor; for (Chromosome neighbor : neighbors) {
improved = true; if (neighbor != null && isBetter(neighbor, bestNeighbor)) {
break; // 找到一个改进就退出,提高效率 bestNeighbor = neighbor;
}
} }
} }
return best; if (bestNeighbor != best) {
writeKpi(bestNeighbor);
}
return bestNeighbor;
} }
...@@ -2057,7 +2062,7 @@ public class VariableNeighborhoodSearch { ...@@ -2057,7 +2062,7 @@ public class VariableNeighborhoodSearch {
} else { } else {
chromosome.setResultOld(new CopyOnWriteArrayList<>()); chromosome.setResultOld(new CopyOnWriteArrayList<>());
} }
decoder.decodeChromosomeWithCache(chromosome,true); decoder.decodeChromosomeWithCache(chromosome,false);
} }
private void Batchdecode(GeneticDecoder decoder, List<Chromosome> chromosomes , List<Machine> machines) { private void Batchdecode(GeneticDecoder decoder, List<Chromosome> chromosomes , List<Machine> machines) {
...@@ -2068,7 +2073,7 @@ public class VariableNeighborhoodSearch { ...@@ -2068,7 +2073,7 @@ public class VariableNeighborhoodSearch {
log(String.format("变邻域搜索 -复制对象S, 染色体数=" + chromosomes.size())); log(String.format("变邻域搜索 -复制对象S, 染色体数=" + chromosomes.size()));
// 并行设置染色体字段 // 并行设置染色体字段
chromosomes.parallelStream().forEach(chromosome -> { chromosomes.forEach(chromosome -> {
if (chromosome == null) return; if (chromosome == null) return;
chromosome.setResult(new CopyOnWriteArrayList<>()); chromosome.setResult(new CopyOnWriteArrayList<>());
...@@ -2177,18 +2182,18 @@ public class VariableNeighborhoodSearch { ...@@ -2177,18 +2182,18 @@ public class VariableNeighborhoodSearch {
groupidByPriority.entrySet().removeIf(entry -> entry.getValue().size() == 1); groupidByPriority.entrySet().removeIf(entry -> entry.getValue().size() == 1);
// if(groupidByPriority.size()!=0) // if(groupidByPriority.size()!=0)
// { // {
indexByPriorityMap.keySet().removeIf(key -> !groupidByPriority.containsKey(key)); indexByPriorityMap.keySet().removeIf(key -> !groupidByPriority.containsKey(key));
//} //}
List<Map.Entry<Double, List<Integer>>> sortedEntries = new ArrayList<>(indexByPriorityMap.entrySet()); List<Map.Entry<Double, List<Integer>>> sortedEntries = new ArrayList<>(indexByPriorityMap.entrySet());
// if(groupidByPriority.size()!=0) { // if(groupidByPriority.size()!=0) {
sortedEntries.sort((e1, e2) -> { sortedEntries.sort((e1, e2) -> {
int size1 = groupidByPriority.get(e1.getKey()).size(); int size1 = groupidByPriority.get(e1.getKey()).size();
int size2 = groupidByPriority.get(e2.getKey()).size(); int size2 = groupidByPriority.get(e2.getKey()).size();
return Integer.compare(size2, size1); // 降序:订单数多的排前面 return Integer.compare(size2, size1); // 降序:订单数多的排前面
}); });
// } // }
List<List<Integer>> indexByPriority = new ArrayList<>(); List<List<Integer>> indexByPriority = new ArrayList<>();
for (Map.Entry<Double, List<Integer>> entry : sortedEntries) { for (Map.Entry<Double, List<Integer>> entry : sortedEntries) {
...@@ -2269,6 +2274,10 @@ public class VariableNeighborhoodSearch { ...@@ -2269,6 +2274,10 @@ public class VariableNeighborhoodSearch {
// 构建可用机器列表,按负载从低到高排序 // 构建可用机器列表,按负载从低到高排序
List<MachineOptionWithUtilization> availableMachines = new ArrayList<>(); List<MachineOptionWithUtilization> availableMachines = new ArrayList<>();
for (int seq : availableMachineSeqs) { for (int seq : availableMachineSeqs) {
if(seq - 1>=machineOptions.size())
{
break;
}
MachineOption option = machineOptions.get(seq - 1); MachineOption option = machineOptions.get(seq - 1);
Long machineId = option.getMachineId(); Long machineId = option.getMachineId();
double utilization = machineUtilization.getOrDefault(machineId, 0.0); double utilization = machineUtilization.getOrDefault(machineId, 0.0);
...@@ -2278,6 +2287,10 @@ public class VariableNeighborhoodSearch { ...@@ -2278,6 +2287,10 @@ public class VariableNeighborhoodSearch {
// 按利用率从低到高排序 // 按利用率从低到高排序
availableMachines.sort(Comparator.comparingDouble(m -> m.utilization)); availableMachines.sort(Comparator.comparingDouble(m -> m.utilization));
if(availableMachines.size()==0)
{
return 1;
}
// 70%概率选择负载最低的设备,30%概率随机选择 // 70%概率选择负载最低的设备,30%概率随机选择
if (rnd.nextDouble() < 0.7) { if (rnd.nextDouble() < 0.7) {
return availableMachines.get(0).seq; return availableMachines.get(0).seq;
......
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