Commit 111874b6 authored by Tong Li's avatar Tong Li

优化

parent 40085732
...@@ -45,6 +45,16 @@ public class RedisUtils { ...@@ -45,6 +45,16 @@ public class RedisUtils {
@Getter @Getter
public static String prefix = "aps:"; public static String prefix = "aps:";
/**
* 最大重试次数
*/
private static final int MAX_RETRY_TIMES = 3;
/**
* 重试间隔(毫秒)
*/
private static final long RETRY_DELAY_MS = 500;
/** /**
* 设置redis前缀进行操作 * 设置redis前缀进行操作
* *
...@@ -62,7 +72,7 @@ public class RedisUtils { ...@@ -62,7 +72,7 @@ public class RedisUtils {
* @return: boolean * @return: boolean
*/ */
public boolean exists(final String key) { public boolean exists(final String key) {
return redisTemplate.hasKey(prefix + key); return executeWithRetry(() -> redisTemplate.hasKey(prefix + key), "exists(" + key + ")");
} }
public Set<String> keys(final String pattern) { public Set<String> keys(final String pattern) {
...@@ -164,6 +174,7 @@ public class RedisUtils { ...@@ -164,6 +174,7 @@ public class RedisUtils {
* @param key 可以传一个值 或多个 * @param key 可以传一个值 或多个
*/ */
public void del(String... key) { public void del(String... key) {
executeWithRetry(() -> {
if (key != null && key.length > 0) { if (key != null && key.length > 0) {
if (key.length == 1) { if (key.length == 1) {
redisTemplate.delete(prefix + key[0]); redisTemplate.delete(prefix + key[0]);
...@@ -171,6 +182,7 @@ public class RedisUtils { ...@@ -171,6 +182,7 @@ public class RedisUtils {
redisTemplate.delete(Arrays.asList(key).stream().map(e -> prefix + e).collect(Collectors.toList())); redisTemplate.delete(Arrays.asList(key).stream().map(e -> prefix + e).collect(Collectors.toList()));
} }
} }
}, "del(" + Arrays.toString(key) + ")");
} }
public void del(Collection<String> keys) { public void del(Collection<String> keys) {
...@@ -184,7 +196,7 @@ public class RedisUtils { ...@@ -184,7 +196,7 @@ public class RedisUtils {
* @return 值 * @return 值
*/ */
public Object get(String key) { public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(prefix + key); return executeWithRetry(() -> key == null ? null : redisTemplate.opsForValue().get(prefix + key), "get(" + key + ")");
} }
/** /**
...@@ -207,6 +219,7 @@ public class RedisUtils { ...@@ -207,6 +219,7 @@ public class RedisUtils {
* @return true成功 false失败 * @return true成功 false失败
*/ */
public Boolean set(String key, Object value) { public Boolean set(String key, Object value) {
return executeWithRetry(() -> {
try { try {
redisTemplate.opsForValue().set(prefix + key, value); redisTemplate.opsForValue().set(prefix + key, value);
return true; return true;
...@@ -214,6 +227,7 @@ public class RedisUtils { ...@@ -214,6 +227,7 @@ public class RedisUtils {
log.error("Exception: {}", e.getMessage()); log.error("Exception: {}", e.getMessage());
return false; return false;
} }
}, "set(" + key + ")");
} }
/** /**
...@@ -814,4 +828,120 @@ public class RedisUtils { ...@@ -814,4 +828,120 @@ public class RedisUtils {
redisLockUtil.releaseLock(prefix + key, ""); redisLockUtil.releaseLock(prefix + key, "");
} }
/**
* 通用重试执行器:用于处理 Redis 连接异常
* @param operation Redis 操作函数
* @param operationName 操作名称(用于日志)
* @param <T> 返回值类型
* @return 操作结果
*/
private <T> T executeWithRetry(java.util.function.Supplier<T> operation, String operationName) {
Exception lastException = null;
for (int attempt = 1; attempt <= MAX_RETRY_TIMES; attempt++) {
try {
if (attempt > 1) {
log.warn("Redis 操作重试 {}/{}: {}", attempt, MAX_RETRY_TIMES, operationName);
}
return operation.get();
} catch (Exception e) {
lastException = e;
log.error("Redis 操作失败 {}/{}: {}, 错误: {}", attempt, MAX_RETRY_TIMES, operationName, e.getMessage());
if (attempt < MAX_RETRY_TIMES) {
try {
log.warn("等待 {}ms 后重试...", RETRY_DELAY_MS);
Thread.sleep(RETRY_DELAY_MS);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("Redis 操作重试被中断", ie);
}
}
}
}
throw new RuntimeException("Redis 操作失败,已重试 " + MAX_RETRY_TIMES + " 次: " + operationName, lastException);
}
/**
* 无返回值的重试执行器
* @param operation Redis 操作函数
* @param operationName 操作名称(用于日志)
*/
private void executeWithRetry(Runnable operation, String operationName) {
executeWithRetry(() -> {
operation.run();
return null;
}, operationName);
}
// ==================== 以下是添加了重试机制的方法 ====================
/**
* 判断是否有这个缓存key(带重试)
* @param key 缓存key
* @return boolean
*/
public boolean existsWithRetry(final String key) {
return executeWithRetry(() -> exists(key), "exists(" + key + ")");
}
/**
* 普通缓存获取(带重试)
* @param key 键
* @return 值
*/
public Object getWithRetry(String key) {
return executeWithRetry(() -> get(key), "get(" + key + ")");
}
/**
* 普通缓存放入(带重试)
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public Boolean setWithRetry(String key, Object value) {
return executeWithRetry(() -> set(key, value), "set(" + key + ")");
}
/**
* 普通缓存放入并设置时间(带重试)
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return true成功 false失败
*/
public Boolean setWithRetry(String key, Object value, Long time) {
return executeWithRetry(() -> set(key, value, time), "set(" + key + ", " + time + "s)");
}
/**
* 删除缓存(带重试)
* @param key 可以传一个值 或多个
*/
public void delWithRetry(String... key) {
executeWithRetry(() -> del(key), "del(" + Arrays.toString(key) + ")");
}
/**
* HashGet(带重试)
* @param key 键 不能为 null
* @param item 项 不能为 null
* @return 值
*/
public Object hgetWithRetry(String key, String item) {
return executeWithRetry(() -> hget(key, item), "hget(" + key + ", " + item + ")");
}
/**
* HashSet(带重试)
* @param key 键
* @param map 对应多个键值
* @return true成功 false失败
*/
public Boolean hmsetWithRetry(String key, Map<String, Object> map) {
return executeWithRetry(() -> hmset(key, map), "hmset(" + key + ")");
}
} }
...@@ -116,53 +116,53 @@ public class Chromosome { ...@@ -116,53 +116,53 @@ public class Chromosome {
private List<GlobalOperationInfo> globalOpList; private List<GlobalOperationInfo> globalOpList = new ArrayList<>();
private CopyOnWriteArrayList<Entry> allOperations; private CopyOnWriteArrayList<Entry> allOperations = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<Order> orders; private CopyOnWriteArrayList<Order> orders = new CopyOnWriteArrayList<>();
private List<Machine> InitMachines; private List<Machine> InitMachines = new ArrayList<>();
private List<OrderMaterialRequirement> orderMaterials; private List<OrderMaterialRequirement> orderMaterials = new ArrayList<>();
private CopyOnWriteArrayList<GroupResult> OperatRel; private CopyOnWriteArrayList<GroupResult> OperatRel = new CopyOnWriteArrayList<>();
private ObjectiveWeights objectiveWeights; private ObjectiveWeights objectiveWeights;
private List<Material> materials; private List<Material> materials = new ArrayList<>();
private List<String> materialIds; private List<String> materialIds = new ArrayList<>();
/* /*
* 最早完工时间(最小化) 最小化总加工时间 最小总换型时间 * 最早完工时间(最小化) 最小化总加工时间 最小总换型时间
*/ */
private double[] Objectives ; // 多目标值:[Makespan, TotalFlowTime, TotalChangeover, LoadStd, Delay] private double[] Objectives = new double[0]; // 多目标值:[Makespan, TotalFlowTime, TotalChangeover, LoadStd, Delay]
private double[] MaxObjectives ; // private double[] MaxObjectives = new double[0]; //
private double[] MinObjectives ; // private double[] MinObjectives = new double[0]; //
private int Rank; // 非支配排序等级(1最优) private int Rank; // 非支配排序等级(1最优)
private double CrowdingDistance =0; // 拥挤距离 越小越优 private double CrowdingDistance =0; // 拥挤距离 越小越优
/* /*
*(Objectives - min) / (max - min); *(Objectives - min) / (max - min);
*/ */
private double[] WeightedObjectives;//越靠近1越优 private double[] WeightedObjectives = new double[0];//越靠近1越优
private double WeightedObjective =0; // 加权目标值(用于自定义权重) private double WeightedObjective =0; // 加权目标值(用于自定义权重)
/// <summary> /// <summary>
/// 适应度值 /// 适应度值
/// </summary> /// </summary>
private double[] fitnessLevel; private double[] fitnessLevel = new double[0];
/// <summary> /// <summary>
/// 适应度值 /// 适应度值
/// </summary> /// </summary>
private double Fitness; private double Fitness = 0.0;
/// <summary> /// <summary>
/// 机器 /// 机器
/// </summary> /// </summary>
private List<Machine> Machines; private List<Machine> Machines = new ArrayList<>();
/// <summary> /// <summary>
/// 解码后的调度结果 /// 解码后的调度结果
/// </summary> /// </summary>
private CopyOnWriteArrayList<GAScheduleResult> Result; private CopyOnWriteArrayList<GAScheduleResult> Result = new CopyOnWriteArrayList<>();
/// <summary> /// <summary>
/// 解码后的调度结果 /// 解码后的调度结果
...@@ -172,33 +172,33 @@ public class Chromosome { ...@@ -172,33 +172,33 @@ public class Chromosome {
/// <summary> /// <summary>
/// 最早完工时间 /// 最早完工时间
/// </summary> /// </summary>
private double Makespan; private double Makespan = 0.0;
/// <summary> /// <summary>
/// 总流程时间 /// 总流程时间
/// </summary> /// </summary>
private double TotalFlowTime; private double TotalFlowTime = 0.0;
/// <summary> /// <summary>
/// 总换型时间 /// 总换型时间
/// </summary> /// </summary>
private double TotalChangeoverTime; private double TotalChangeoverTime = 0.0;
/// <summary> /// <summary>
/// 机器负载标准差(越小越均衡) /// 机器负载标准差(越小越均衡)
/// </summary> /// </summary>
private double MachineLoadStd; private double MachineLoadStd = 0.0;
/// <summary> /// <summary>
/// 交付期延迟时间 /// 交付期延迟时间
/// </summary> /// </summary>
private double DelayTime; private double DelayTime = 0.0;
private String ScenarioID; private String ScenarioID = "";
private String ScenarioName; private String ScenarioName = "";
private LocalDateTime BaseTime ; // 当前基准时间 private LocalDateTime BaseTime; // 当前基准时间
private List<Integer> reOrderids=new ArrayList<>(); private List<Integer> reOrderids=new ArrayList<>();
......
...@@ -165,15 +165,30 @@ public class FitnessCalculator { ...@@ -165,15 +165,30 @@ public class FitnessCalculator {
* 比较两个染色体的优劣(基于fitnessLevel多层次比较) * 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/ */
public boolean isBetter(Chromosome c1, Chromosome c2) { public boolean isBetter(Chromosome c1, Chromosome c2) {
for (int i = 0; i < c1.getFitnessLevel().length; i++) { double[] fitness1 = c1.getFitnessLevel();
double[] Fitness1 = c1.getFitnessLevel(); double[] fitness2 = c2.getFitnessLevel();
double[] Fitness2 = c2.getFitnessLevel();
if (Fitness1[i] > Fitness2[i]) { // 处理null或空数组的情况
return true; if (fitness1 == null || fitness1.length == 0) {
return false; // c1没有fitness,认为c2更优
} }
if (fitness2 == null || fitness2.length == 0) {
return true; // c2没有fitness,认为c1更优
} }
// 取两个数组中较小的长度进行比较
int minLength = Math.min(fitness1.length, fitness2.length);
for (int i = 0; i < minLength; i++) {
if (fitness1[i] > fitness2[i]) {
return true;
} else if (fitness1[i] < fitness2[i]) {
return false; return false;
} }
}
// 如果前面都相等,长度更长的视为更优(有更多维度)
return fitness1.length > fitness2.length;
}
......
...@@ -193,7 +193,8 @@ public class GeneticDecoder { ...@@ -193,7 +193,8 @@ public class GeneticDecoder {
// 缓存命中:复用缓存结果 // 缓存命中:复用缓存结果
// 赋值给染色体 // 赋值给染色体
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(cachedResult.getInitMachines(),Machine.class)); // chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(cachedResult.getInitMachines(),Machine.class));
chromosome.setFitnessLevel(cachedResult.getFitnessLevel());
chromosome.setFitness(cachedResult.getFitness());
chromosome.setObjectives(cachedResult.getObjectives()); chromosome.setObjectives(cachedResult.getObjectives());
chromosome.setMakespan(cachedResult.getMakespan()); chromosome.setMakespan(cachedResult.getMakespan());
chromosome.setTotalFlowTime(cachedResult.getTotalFlowTime()); chromosome.setTotalFlowTime(cachedResult.getTotalFlowTime());
......
...@@ -643,16 +643,29 @@ public class HillClimbing { ...@@ -643,16 +643,29 @@ public class HillClimbing {
/** /**
* 比较两个染色体的优劣 * 比较两个染色体的优劣
*/ */
private boolean isBetter(Chromosome c1, Chromosome c2) { public boolean isBetter(Chromosome c1, Chromosome c2) {
double[] fitness1 = c1.getFitnessLevel();
double[] fitness2 = c2.getFitnessLevel();
for (int i = 0; i < c1.getFitnessLevel().length; i++) { // 处理null或空数组的情况
double[] Fitness1 = c1.getFitnessLevel(); if (fitness1 == null || fitness1.length == 0) {
double[] Fitness2 = c2.getFitnessLevel(); return false; // c1没有fitness,认为c2更优
if (Fitness1[i] > Fitness2[i]) {
return true;
} }
if (fitness2 == null || fitness2.length == 0) {
return true; // c2没有fitness,认为c1更优
} }
// 取两个数组中较小的长度进行比较
int minLength = Math.min(fitness1.length, fitness2.length);
for (int i = 0; i < minLength; i++) {
if (fitness1[i] > fitness2[i]) {
return true;
} else if (fitness1[i] < fitness2[i]) {
return false; return false;
}
}
// 如果前面都相等,长度更长的视为更优(有更多维度)
return fitness1.length > fitness2.length;
} }
} }
\ No newline at end of file
...@@ -104,7 +104,7 @@ public class HybridAlgorithm { ...@@ -104,7 +104,7 @@ public class HybridAlgorithm {
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 = initialization.generateGlobalOpList(); List<GlobalOperationInfo> globalOpList =new ArrayList<>();// initialization.generateGlobalOpList();
// 初始化变邻域搜索 // 初始化变邻域搜索
_vns = new VariableNeighborhoodSearch( allOperations,orders,materials,_entryRel, _fitnessCalculator ); _vns = new VariableNeighborhoodSearch( allOperations,orders,materials,_entryRel, _fitnessCalculator );
_hillClimbing = new HillClimbing(allOperations,orders,materials,_entryRel, _fitnessCalculator); _hillClimbing = new HillClimbing(allOperations,orders,materials,_entryRel, _fitnessCalculator);
...@@ -137,11 +137,13 @@ int opcount=allOperations.size(); ...@@ -137,11 +137,13 @@ int opcount=allOperations.size();
// return getBestChromosome(population.get(0), param.getBaseTime(), starttime); // return getBestChromosome(population.get(0), param.getBaseTime(), starttime);
// 步骤2:对初始种群进行爬山法局部优化 // 步骤2:对初始种群进行爬山法局部优化
if(opcount<20 ) { if(opcount<100 ) {
Chromosome best=population.get(0);
geneticOps.DelOrder(best);
FileHelper.writeLogFile("爬山法局部优化-----------开始-------"); FileHelper.writeLogFile("爬山法局部优化-----------开始-------");
GeneticDecoder hillClimbingDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId); GeneticDecoder hillClimbingDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
Chromosome optimized = _hillClimbing.search(population.get(0), hillClimbingDecoder,machines); Chromosome optimized = _hillClimbing.searchAll(best,machines,hillClimbingDecoder);
FileHelper.writeLogFile("爬山法局部优化-----------结束-------"); FileHelper.writeLogFile("爬山法局部优化-----------结束-------");
return getBestChromosome(optimized, param.getBaseTime(), starttime); return getBestChromosome(optimized, param.getBaseTime(), starttime);
} }
...@@ -158,14 +160,17 @@ int opcount=allOperations.size(); ...@@ -158,14 +160,17 @@ int opcount=allOperations.size();
if(opcount<800 ) { if(opcount<800 ) {
Chromosome best=population.get(0);
geneticOps.DelOrder(best);
FileHelper.writeLogFile("模拟退火+爬山法优化-----------开始-------"); FileHelper.writeLogFile("模拟退火+爬山法优化-----------开始-------");
Chromosome saHcOptimized = _simulatedAnnealing.searchWithHillClimbing(population.get(0),_vns, saDecoder1, machines); Chromosome saHcOptimized = _simulatedAnnealing.searchWithHillClimbing(best,_vns, saDecoder1, machines);
FileHelper.writeLogFile("模拟退火+爬山法优化-----------结束-------"); FileHelper.writeLogFile("模拟退火+爬山法优化-----------结束-------");
return getBestChromosome(saHcOptimized, param.getBaseTime(), starttime); return getBestChromosome(saHcOptimized, param.getBaseTime(), starttime);
} }
if(opcount>=800 ) { if(opcount>=800 ) {
Chromosome best=population.get(0); Chromosome best=population.get(0);
geneticOps.DelOrder(best);
best = _simulatedAnnealing.search(best, _tabuSearch, _vns, saDecoder1, machines); best = _simulatedAnnealing.search(best, _tabuSearch, _vns, saDecoder1, machines);
best = _vns.search(best, vnsDecoder1, machines); best = _vns.search(best, vnsDecoder1, machines);
best = _tabuSearch.search(best, _vns, tabuDecoder1, machines); best = _tabuSearch.search(best, _vns, tabuDecoder1, machines);
...@@ -194,6 +199,7 @@ int opcount=allOperations.size(); ...@@ -194,6 +199,7 @@ int opcount=allOperations.size();
int maxNoImprove = 10; int maxNoImprove = 10;
// 步骤2:迭代进化 // 步骤2:迭代进化
FileHelper.writeLogFile("迭代进化-----------开始-------"+param.getMaxIterations()); FileHelper.writeLogFile("迭代进化-----------开始-------"+param.getMaxIterations());
for (int iter = 0; iter < param.getMaxIterations(); iter++) { for (int iter = 0; iter < param.getMaxIterations(); iter++) {
// 解码并计算适应度 // 解码并计算适应度
FileHelper.writeLogFile("迭代进化------"+iter+"-----开始-------"); FileHelper.writeLogFile("迭代进化------"+iter+"-----开始-------");
...@@ -212,7 +218,7 @@ int opcount=allOperations.size(); ...@@ -212,7 +218,7 @@ int opcount=allOperations.size();
FileHelper.writeLogFile("选择操作-----------开始-------"); FileHelper.writeLogFile("选择操作-----------开始-------");
// 选择操作 // 选择操作
List<Chromosome> selected = geneticOps.tournamentSelection(population); List<Chromosome> selected = geneticOps.tournamentSelection2(population);
FileHelper.writeLogFile("选择操作-----------结束-------"); FileHelper.writeLogFile("选择操作-----------结束-------");
...@@ -230,13 +236,13 @@ int opcount=allOperations.size(); ...@@ -230,13 +236,13 @@ int opcount=allOperations.size();
Chromosome parent2 = selected.get(rnd.nextInt(selected.size())); Chromosome parent2 = selected.get(rnd.nextInt(selected.size()));
// 交叉 // 交叉
Chromosome child = parent1; Chromosome child = parent1;
// if (rnd.nextDouble() < param.getCrossoverProb()) { if (rnd.nextDouble() < param.getCrossoverProb()) {
// // 假设PoxCrossover返回包含两个子染色体的数组 // 假设PoxCrossover返回包含两个子染色体的数组
// Pair<Chromosome, Chromosome> children = geneticOps.poxCrossover(parent1, parent2, ordercount); Pair<Chromosome, Chromosome> children = geneticOps.poxCrossover(parent1, parent2, ordercount);
// child=children.getFirst(); child=children.getFirst();
// initDataToChromosome(child,param, allOperations,globalOpList); // initDataToChromosome(child,param, allOperations,globalOpList);
// child.setID(UUID.randomUUID().toString()); child.setID(UUID.randomUUID().toString());
// } }
// // 变异 // // 变异
// if (rnd.nextDouble() < param.getMutationProb()) { // if (rnd.nextDouble() < param.getMutationProb()) {
// geneticOps.mutate(child, globalOpList); // geneticOps.mutate(child, globalOpList);
...@@ -249,7 +255,7 @@ int opcount=allOperations.size(); ...@@ -249,7 +255,7 @@ int opcount=allOperations.size();
newPopulation.add(child); newPopulation.add(child);
FileHelper.writeLogFile("交叉-----------结束-------"+n); FileHelper.writeLogFile("交叉-----------结束-------"+n);
n++;
} }
population= chromosomeDistinctByObjectives(newPopulation);; population= chromosomeDistinctByObjectives(newPopulation);;
...@@ -375,14 +381,7 @@ int opcount=allOperations.size(); ...@@ -375,14 +381,7 @@ int opcount=allOperations.size();
* 比较两个染色体的优劣(基于fitnessLevel多层次比较) * 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/ */
private boolean isBetter(Chromosome c1, Chromosome c2) { private boolean isBetter(Chromosome c1, Chromosome c2) {
for (int i = 0; i < c1.getFitnessLevel().length; i++) { return _fitnessCalculator.isBetter(c1,c2);
double[] Fitness1 = c1.getFitnessLevel();
double[] Fitness2 = c2.getFitnessLevel();
if (Fitness1[i] > Fitness2[i]) {
return true;
}
}
return false;
} }
......
...@@ -149,10 +149,13 @@ public class MaterialRequirementService { ...@@ -149,10 +149,13 @@ public class MaterialRequirementService {
if(MaterialRequirements!=null) if(MaterialRequirements!=null)
{ {
List<Entry> Operations= _allOperations.stream() List<Entry> Operations= _allOperations.stream().filter(t -> t.getOrderId() != null)
.filter(t->t.getOrderId().equals(orderId)) .filter(t->t.getOrderId().equals(orderId))
.collect(Collectors.toList()); .collect(Collectors.toList());
if(Operations==null)
{
int i=1;
}
for (Entry operation : Operations) { for (Entry operation : Operations) {
List<Routingsupporting> MaterialRequirement_entrys = routingsupportings.stream() List<Routingsupporting> MaterialRequirement_entrys = routingsupportings.stream()
.filter(t -> t.getRoutingDetailId().equals(operation.getRoutingDetailId())) .filter(t -> t.getRoutingDetailId().equals(operation.getRoutingDetailId()))
...@@ -524,7 +527,10 @@ public class MaterialRequirementService { ...@@ -524,7 +527,10 @@ public class MaterialRequirementService {
for (Integer groupId : operationSequencing) for (Integer groupId : operationSequencing)
{ {
Order demand=orders.stream().filter(t->t.getId()==groupId).findFirst().orElse(null); Order demand=orders.stream().filter(t->t.getId()==groupId).findFirst().orElse(null);
if(demand==null)
{
continue;
}
if (demand.getFinishOrderId() != null && !demand.getFinishOrderId().isEmpty()) { if (demand.getFinishOrderId() != null && !demand.getFinishOrderId().isEmpty()) {
continue; continue;
} }
...@@ -606,7 +612,7 @@ public class MaterialRequirementService { ...@@ -606,7 +612,7 @@ public class MaterialRequirementService {
List<Entry> _allOperations= chromosome.getAllOperations(); List<Entry> _allOperations= chromosome.getAllOperations();
List<Entry> Operations= _allOperations.stream() List<Entry> Operations= _allOperations.stream().filter(t -> t.getOrderId() != null)
.filter(t->t.getOrderId().equals(childorderId)) .filter(t->t.getOrderId().equals(childorderId))
.collect(Collectors.toList()); .collect(Collectors.toList());
......
...@@ -232,6 +232,7 @@ public class RoutingDataService { ...@@ -232,6 +232,7 @@ public class RoutingDataService {
entry.setProductCode(order.getMaterialCode()); entry.setProductCode(order.getMaterialCode());
entry.setProductName(order.getMaterialName()); entry.setProductName(order.getMaterialName());
entry.setPriority(order.getActualPriority()); entry.setPriority(order.getActualPriority());
order.setId(entry.getGroupId()); order.setId(entry.getGroupId());
} }
List<ProdEquipment> Equipments = ProdEquipments.stream() List<ProdEquipment> Equipments = ProdEquipments.stream()
......
...@@ -106,13 +106,13 @@ public class SimulatedAnnealing { ...@@ -106,13 +106,13 @@ public class SimulatedAnnealing {
// log("模拟退火+爬山法 - 初始化解码完成"); // log("模拟退火+爬山法 - 初始化解码完成");
// 初始化温度 // 初始化温度(优化:更快收敛)
double temperature = 100.0; double temperature = 100.0;
double coolingRate = 0.95; double coolingRate = 0.90; // 优化:降温更快
double temperatureThreshold = 1.0; double temperatureThreshold = 5.0; // 优化:温度阈值更高
int maxIterations = 300; int maxIterations = 100; // 优化:从300减少到100次
int noImproveCount = 0; int noImproveCount = 0;
int maxNoImprove = 30; // 降低最大无改进次数 int maxNoImprove = 15; // 优化:从30减少到15次
// 新增:改进率监控参数 // 新增:改进率监控参数
int stagnantWindow = 15; // 观察窗口大小 int stagnantWindow = 15; // 观察窗口大小
...@@ -239,13 +239,13 @@ public class SimulatedAnnealing { ...@@ -239,13 +239,13 @@ public class SimulatedAnnealing {
// log("模拟退火+爬山法 - 初始化解码完成"); // log("模拟退火+爬山法 - 初始化解码完成");
// 初始化温度 // 初始化温度(优化:更快收敛)
double temperature = 100.0; double temperature = 100.0;
double coolingRate = 0.95; double coolingRate = 0.90; // 优化:降温更快
double temperatureThreshold = 1.0; double temperatureThreshold = 5.0; // 优化:温度阈值更高
int maxIterations = 300; int maxIterations = 80; // 优化:从300减少到80次
int noImproveCount = 0; int noImproveCount = 0;
int maxNoImprove = 20; // 降低最大无改进次数,更快提前结束 int maxNoImprove = 10; // 优化:从20减少到10次
// 新增:改进率监控参数 // 新增:改进率监控参数
int stagnantWindow = 10; // 观察窗口大小 int stagnantWindow = 10; // 观察窗口大小
...@@ -361,10 +361,17 @@ public class SimulatedAnnealing { ...@@ -361,10 +361,17 @@ public class SimulatedAnnealing {
StringBuilder sb = new StringBuilder("模拟退火 - 改进详情: 迭代" + iteration + ", "); StringBuilder sb = new StringBuilder("模拟退火 - 改进详情: 迭代" + iteration + ", ");
double[] currentFitness = best.getFitnessLevel(); double[] currentFitness = best.getFitnessLevel();
for (int i = 0; i < currentFitness.length; i++) { // 处理null或空数组的情况
if (currentFitness != null && currentFitness.length > 0 &&
initialFitnessLevel != null && initialFitnessLevel.length > 0) {
int minLength = Math.min(currentFitness.length, initialFitnessLevel.length);
for (int i = 0; i < minLength; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i]; double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(+%.4f) ", i+1, initialFitnessLevel[i], currentFitness[i], improvement)); sb.append(String.format("KPI%d: %.4f→%.4f(+%.4f) ", i+1, initialFitnessLevel[i], currentFitness[i], improvement));
} }
} else {
sb.append("(KPI数据不可用) ");
}
double totalImprovement = best.getFitness() - initialFitness; double totalImprovement = best.getFitness() - initialFitness;
sb.append(String.format("总Fitness: %.4f→%.4f(+%.4f)", initialFitness, best.getFitness(), totalImprovement)); sb.append(String.format("总Fitness: %.4f→%.4f(+%.4f)", initialFitness, best.getFitness(), totalImprovement));
...@@ -392,11 +399,18 @@ public class SimulatedAnnealing { ...@@ -392,11 +399,18 @@ public class SimulatedAnnealing {
sb.append(String.format("总迭代%d次, 成功改进%d次, 改进率%.2f%%. ", sb.append(String.format("总迭代%d次, 成功改进%d次, 改进率%.2f%%. ",
totalIterations, improveCount, totalIterations > 0 ? (double)improveCount / totalIterations * 100 : 0)); totalIterations, improveCount, totalIterations > 0 ? (double)improveCount / totalIterations * 100 : 0));
for (int i = 0; i < currentFitness.length; i++) { // 处理null或空数组的情况
if (currentFitness != null && currentFitness.length > 0 &&
initialFitnessLevel != null && initialFitnessLevel.length > 0) {
int minLength = Math.min(currentFitness.length, initialFitnessLevel.length);
for (int i = 0; i < minLength; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i]; double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i], sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i],
initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0)); initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0));
} }
} else {
sb.append("(KPI数据不可用) ");
}
double totalImprovement = best.getFitness() - initialFitness; double totalImprovement = best.getFitness() - initialFitness;
sb.append(String.format("总Fitness: %.4f→%.4f(%.2f%%)", initialFitness, best.getFitness(), sb.append(String.format("总Fitness: %.4f→%.4f(%.2f%%)", initialFitness, best.getFitness(),
...@@ -408,10 +422,13 @@ public class SimulatedAnnealing { ...@@ -408,10 +422,13 @@ public class SimulatedAnnealing {
private void writeKpi(Chromosome chromosome) { private void writeKpi(Chromosome chromosome) {
String fitness = ""; String fitness = "";
double[] fitness1 = chromosome.getFitnessLevel(); double[] fitness1 = chromosome.getFitnessLevel();
if (fitness1 != null) {
for (int i = 0; i < fitness1.length; i++) { for (int i = 0; i < fitness1.length; i++) {
fitness += fitness1[i] + ","; fitness += fitness1[i] + ",";
} }
} else {
fitness = "null (未计算)";
}
log(String.format("模拟退火 - kpi:%s", fitness),true); log(String.format("模拟退火 - kpi:%s", fitness),true);
......
...@@ -65,7 +65,7 @@ public class TabuSearch { ...@@ -65,7 +65,7 @@ public class TabuSearch {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
this.bestFitness = best.getFitnessLevel().clone(); this.bestFitness = best.getFitnessLevel().clone();
writeKpi(best); writeKpi(best);
// 记录初始KPI用于计算改进率 // 记录初始KPI用于计算改进率
double[] initialFitnessLevel = best.getFitnessLevel().clone(); double[] initialFitnessLevel = best.getFitnessLevel().clone();
double initialFitness = best.getFitness(); double initialFitness = best.getFitness();
...@@ -73,8 +73,8 @@ writeKpi(best); ...@@ -73,8 +73,8 @@ writeKpi(best);
int iterations = 0; int iterations = 0;
int improveCount = 0; int improveCount = 0;
int noImprovementCount = 0; int noImprovementCount = 0;
int maxNoImprovement = 15; // 降低到15次无改进则停止 int maxNoImprovement = 5; // 优化:5次无改进则停止
int maxIterations = Math.min(cachedAllOperations.size(), 80); // 降低到最多80次 int maxIterations = Math.min(cachedAllOperations.size(), 20); // 优化:最多20次迭代
// 改进率监控 // 改进率监控
int stagnantWindow = 10; int stagnantWindow = 10;
...@@ -213,12 +213,15 @@ writeKpi(best); ...@@ -213,12 +213,15 @@ writeKpi(best);
private void writeKpi(Chromosome chromosome) { private void writeKpi(Chromosome chromosome) {
String fitness = ""; String fitness = "";
double[] fitness1 = chromosome.getFitnessLevel(); double[] fitness1 = chromosome.getFitnessLevel();
if (fitness1 != null) {
for (int i = 0; i < fitness1.length; i++) { for (int i = 0; i < fitness1.length; i++) {
fitness += fitness1[i] + ","; fitness += fitness1[i] + ",";
} }
} else {
fitness = "null (未计算)";
}
log(String.format("变邻域搜索 - kpi:%s", fitness),true); log(String.format("禁忌搜索 - kpi:%s", fitness),true);
} }
/** /**
...@@ -228,10 +231,17 @@ writeKpi(best); ...@@ -228,10 +231,17 @@ writeKpi(best);
StringBuilder sb = new StringBuilder("禁忌搜索 - 改进详情: 迭代" + iteration + ", "); StringBuilder sb = new StringBuilder("禁忌搜索 - 改进详情: 迭代" + iteration + ", ");
double[] currentFitness = best.getFitnessLevel(); double[] currentFitness = best.getFitnessLevel();
for (int i = 0; i < currentFitness.length; i++) { // 处理null或空数组的情况
if (currentFitness != null && currentFitness.length > 0 &&
initialFitnessLevel != null && initialFitnessLevel.length > 0) {
int minLength = Math.min(currentFitness.length, initialFitnessLevel.length);
for (int i = 0; i < minLength; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i]; double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(+%.4f) ", i+1, initialFitnessLevel[i], currentFitness[i], improvement)); sb.append(String.format("KPI%d: %.4f→%.4f(+%.4f) ", i+1, initialFitnessLevel[i], currentFitness[i], improvement));
} }
} else {
sb.append("(KPI数据不可用) ");
}
double totalImprovement = best.getFitness() - initialFitness; double totalImprovement = best.getFitness() - initialFitness;
sb.append(String.format("总Fitness: %.4f→%.4f(+%.4f)", initialFitness, best.getFitness(), totalImprovement)); sb.append(String.format("总Fitness: %.4f→%.4f(+%.4f)", initialFitness, best.getFitness(), totalImprovement));
...@@ -260,11 +270,18 @@ writeKpi(best); ...@@ -260,11 +270,18 @@ writeKpi(best);
sb.append(String.format("总迭代%d次, 成功改进%d次, 改进率%.2f%%. ", sb.append(String.format("总迭代%d次, 成功改进%d次, 改进率%.2f%%. ",
totalIterations, improveCount, totalIterations > 0 ? (double)improveCount / totalIterations * 100 : 0)); totalIterations, improveCount, totalIterations > 0 ? (double)improveCount / totalIterations * 100 : 0));
for (int i = 0; i < currentFitness.length; i++) { // 处理null或空数组的情况
if (currentFitness != null && currentFitness.length > 0 &&
initialFitnessLevel != null && initialFitnessLevel.length > 0) {
int minLength = Math.min(currentFitness.length, initialFitnessLevel.length);
for (int i = 0; i < minLength; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i]; double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i], sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i],
initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0)); initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0));
} }
} else {
sb.append("(KPI数据不可用) ");
}
double totalImprovement = best.getFitness() - initialFitness; double totalImprovement = best.getFitness() - initialFitness;
sb.append(String.format("总Fitness: %.4f→%.4f(%.2f%%)", initialFitness, best.getFitness(), sb.append(String.format("总Fitness: %.4f→%.4f(%.2f%%)", initialFitness, best.getFitness(),
......
...@@ -21,7 +21,7 @@ public class VariableNeighborhoodSearch { ...@@ -21,7 +21,7 @@ public class VariableNeighborhoodSearch {
// ==================== 常量定义 ==================== // ==================== 常量定义 ====================
private static final int MAX_CONSECUTIVE_SAME_STRATEGY = 3; private static final int MAX_CONSECUTIVE_SAME_STRATEGY = 3;
private static final int MAX_NEIGHBORHOODS = 7; private static final int MAX_NEIGHBORHOODS = 4; // 优化:从7减少到4个邻域
private static final double HIGH_PRIORITY_GROUP_PROBABILITY = 0.7; private static final double HIGH_PRIORITY_GROUP_PROBABILITY = 0.7;
private static final int MAX_ATTEMPTS = 50; private static final int MAX_ATTEMPTS = 50;
private static final int NEIGHBOR_SELECTION_TOP_K = 3; private static final int NEIGHBOR_SELECTION_TOP_K = 3;
...@@ -378,10 +378,17 @@ public class VariableNeighborhoodSearch { ...@@ -378,10 +378,17 @@ public class VariableNeighborhoodSearch {
StringBuilder sb = new StringBuilder("变邻域搜索 - 改进详情: 轮次" + round + ", 邻域=" + neighborhoodName + ", "); StringBuilder sb = new StringBuilder("变邻域搜索 - 改进详情: 轮次" + round + ", 邻域=" + neighborhoodName + ", ");
double[] currentFitness = best.getFitnessLevel(); double[] currentFitness = best.getFitnessLevel();
for (int i = 0; i < currentFitness.length; i++) { // 处理null或空数组的情况
if (currentFitness != null && currentFitness.length > 0 &&
initialFitnessLevel != null && initialFitnessLevel.length > 0) {
int minLength = Math.min(currentFitness.length, initialFitnessLevel.length);
for (int i = 0; i < minLength; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i]; double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(+%.4f) ", i+1, initialFitnessLevel[i], currentFitness[i], improvement)); sb.append(String.format("KPI%d: %.4f→%.4f(+%.4f) ", i+1, initialFitnessLevel[i], currentFitness[i], improvement));
} }
} else {
sb.append("(KPI数据不可用) ");
}
double totalImprovement = best.getFitness() - initialFitness; double totalImprovement = best.getFitness() - initialFitness;
sb.append(String.format("总Fitness: %.4f→%.4f(+%.4f)", initialFitness, best.getFitness(), totalImprovement)); sb.append(String.format("总Fitness: %.4f→%.4f(+%.4f)", initialFitness, best.getFitness(), totalImprovement));
...@@ -409,11 +416,17 @@ public class VariableNeighborhoodSearch { ...@@ -409,11 +416,17 @@ public class VariableNeighborhoodSearch {
sb.append("\n"); sb.append("\n");
// 记录KPI改进 // 记录KPI改进
for (int i = 0; i < currentFitness.length; i++) { if (currentFitness != null && currentFitness.length > 0 &&
initialFitnessLevel != null && initialFitnessLevel.length > 0) {
int minLength = Math.min(currentFitness.length, initialFitnessLevel.length);
for (int i = 0; i < minLength; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i]; double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i], sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i],
initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0)); initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0));
} }
} else {
sb.append("(KPI数据不可用) ");
}
double totalImprovement = best.getFitness() - initialFitness; double totalImprovement = best.getFitness() - initialFitness;
sb.append(String.format("总Fitness: %.4f→%.4f(%.2f%%)", initialFitness, best.getFitness(), sb.append(String.format("总Fitness: %.4f→%.4f(%.2f%%)", initialFitness, best.getFitness(),
...@@ -424,10 +437,13 @@ public class VariableNeighborhoodSearch { ...@@ -424,10 +437,13 @@ public class VariableNeighborhoodSearch {
private void writeKpi(Chromosome chromosome) { private void writeKpi(Chromosome chromosome) {
String fitness = ""; String fitness = "";
double[] fitness1 = chromosome.getFitnessLevel(); double[] fitness1 = chromosome.getFitnessLevel();
if (fitness1 != null) {
for (int i = 0; i < fitness1.length; i++) { for (int i = 0; i < fitness1.length; i++) {
fitness += fitness1[i] + ","; fitness += fitness1[i] + ",";
} }
} else {
fitness = "null (未计算)";
}
log(String.format("变邻域搜索 - kpi:%s", fitness),true); log(String.format("变邻域搜索 - kpi:%s", fitness),true);
...@@ -2024,6 +2040,7 @@ public class VariableNeighborhoodSearch { ...@@ -2024,6 +2040,7 @@ public class VariableNeighborhoodSearch {
} else { } else {
chromosome.setResultOld(new CopyOnWriteArrayList<>()); chromosome.setResultOld(new CopyOnWriteArrayList<>());
} }
//decoder.decodeChromosomeWithCache(chromosome,true);
}); });
log(String.format("变邻域搜索 -复制对象E")); log(String.format("变邻域搜索 -复制对象E"));
......
...@@ -39,8 +39,11 @@ public class PlanResultServiceTest { ...@@ -39,8 +39,11 @@ public class PlanResultServiceTest {
// TestSortService sortService=new TestSortService(); // TestSortService sortService=new TestSortService();
// sortService.test1(); // sortService.test1();
// nsgaiiUtils.Test(); // nsgaiiUtils.Test();
planResultService.execute2("08B1D87FE1B84ECDBAC2E546DDB6FB81");//2000
// planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4");//2000 planResultService.execute2("F6747C64865D4609989D943709939331");//2000
// planResultService.execute2("08B1D87FE1B84ECDBAC2E546DDB6FB81");//2000
// planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4");//5000
// planResultService.execute2("C8B533BD8944405B9A2F8823C575C204");//500 // planResultService.execute2("C8B533BD8944405B9A2F8823C575C204");//500
// planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");//20 // planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");//20
// planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D"); // planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D");
......
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