Commit 7d27c0ff authored by DESKTOP-VKRD9QF\Administration's avatar DESKTOP-VKRD9QF\Administration

Merge branch 'master' of http://39.100.78.207:1213/tongli/hyh.apsj

# Conflicts:
#	src/main/java/com/aps/entity/Algorithm/Chromosome.java
parents 8231751e 08991d0b
...@@ -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,13 +174,15 @@ public class RedisUtils { ...@@ -164,13 +174,15 @@ public class RedisUtils {
* @param key 可以传一个值 或多个 * @param key 可以传一个值 或多个
*/ */
public void del(String... key) { public void del(String... key) {
if (key != null && key.length > 0) { executeWithRetry(() -> {
if (key.length == 1) { if (key != null && key.length > 0) {
redisTemplate.delete(prefix + key[0]); if (key.length == 1) {
} else { redisTemplate.delete(prefix + key[0]);
redisTemplate.delete(Arrays.asList(key).stream().map(e -> prefix + e).collect(Collectors.toList())); } else {
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,13 +219,15 @@ public class RedisUtils { ...@@ -207,13 +219,15 @@ public class RedisUtils {
* @return true成功 false失败 * @return true成功 false失败
*/ */
public Boolean set(String key, Object value) { public Boolean set(String key, Object value) {
try { return executeWithRetry(() -> {
redisTemplate.opsForValue().set(prefix + key, value); try {
return true; redisTemplate.opsForValue().set(prefix + key, value);
} catch (Exception e) { return true;
log.error("Exception: {}", e.getMessage()); } catch (Exception e) {
return false; log.error("Exception: {}", e.getMessage());
} 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 + ")");
}
} }
...@@ -173,8 +173,11 @@ public class ScheduleParams { ...@@ -173,8 +173,11 @@ public class ScheduleParams {
populationSize = (int) Math.max(MIN_POPULATION_SIZE, populationSize = (int) Math.max(MIN_POPULATION_SIZE,
Math.min(MAX_POPULATION_SIZE, MIN_POPULATION_SIZE + totalOps * populationSizeCoeff)); Math.min(MAX_POPULATION_SIZE, MIN_POPULATION_SIZE + totalOps * populationSizeCoeff));
int maxthead= Runtime.getRuntime().availableProcessors() - 1; int maxthead = Math.max(1, Runtime.getRuntime().availableProcessors() - 1);
populationSize= populationSize / maxthead*maxthead; if (populationSize >= maxthead) {
populationSize = populationSize / maxthead * maxthead;
}
populationSize = Math.max(MIN_POPULATION_SIZE, populationSize);
// 确保偶数(方便交叉) // 确保偶数(方便交叉)
// if (populationSize % 2 != 0) { // if (populationSize % 2 != 0) {
......
...@@ -165,14 +165,29 @@ public class FitnessCalculator { ...@@ -165,14 +165,29 @@ 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或空数组的情况
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; return true;
} else if (fitness1[i] < fitness2[i]) {
return false;
} }
} }
return false;
// 如果前面都相等,长度更长的视为更优(有更多维度)
return fitness1.length > fitness2.length;
} }
......
...@@ -194,7 +194,8 @@ public class GeneticDecoder { ...@@ -194,7 +194,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]) { }
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; 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);
...@@ -140,11 +140,13 @@ int opcount=allOperations.size(); ...@@ -140,11 +140,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);
} }
...@@ -161,14 +163,17 @@ int opcount=allOperations.size(); ...@@ -161,14 +163,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);
...@@ -197,6 +202,7 @@ int opcount=allOperations.size(); ...@@ -197,6 +202,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+"-----开始-------");
...@@ -215,7 +221,7 @@ int opcount=allOperations.size(); ...@@ -215,7 +221,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("选择操作-----------结束-------");
...@@ -233,13 +239,13 @@ int opcount=allOperations.size(); ...@@ -233,13 +239,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);
...@@ -252,7 +258,7 @@ int opcount=allOperations.size(); ...@@ -252,7 +258,7 @@ int opcount=allOperations.size();
newPopulation.add(child); newPopulation.add(child);
FileHelper.writeLogFile("交叉-----------结束-------"+n); FileHelper.writeLogFile("交叉-----------结束-------"+n);
n++;
} }
population= chromosomeDistinctByObjectives(newPopulation);; population= chromosomeDistinctByObjectives(newPopulation);;
...@@ -301,7 +307,7 @@ int opcount=allOperations.size(); ...@@ -301,7 +307,7 @@ int opcount=allOperations.size();
best.setScenarioID(sceneId); best.setScenarioID(sceneId);
// best.setOperatRel(_entryRel); // best.setOperatRel(_entryRel);
if(best.getInitMachines()==null) if(best.getInitMachines()==null||best.getInitMachines().size()==0)
{ {
best.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); best.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class));
} }
...@@ -378,14 +384,7 @@ int opcount=allOperations.size(); ...@@ -378,14 +384,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,9 +361,16 @@ public class SimulatedAnnealing { ...@@ -361,9 +361,16 @@ 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或空数组的情况
double improvement = currentFitness[i] - initialFitnessLevel[i]; if (currentFitness != null && currentFitness.length > 0 &&
sb.append(String.format("KPI%d: %.4f→%.4f(+%.4f) ", i+1, initialFitnessLevel[i], currentFitness[i], improvement)); 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];
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;
...@@ -392,10 +399,17 @@ public class SimulatedAnnealing { ...@@ -392,10 +399,17 @@ 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或空数组的情况
double improvement = currentFitness[i] - initialFitnessLevel[i]; if (currentFitness != null && currentFitness.length > 0 &&
sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i], initialFitnessLevel != null && initialFitnessLevel.length > 0) {
initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0)); int minLength = Math.min(currentFitness.length, initialFitnessLevel.length);
for (int i = 0; i < minLength; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i],
initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0));
}
} else {
sb.append("(KPI数据不可用) ");
} }
double totalImprovement = best.getFitness() - initialFitness; double totalImprovement = best.getFitness() - initialFitness;
...@@ -408,9 +422,12 @@ public class SimulatedAnnealing { ...@@ -408,9 +422,12 @@ 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();
for (int i = 0; i < fitness1.length; i++) { if (fitness1 != null) {
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();
for (int i = 0; i < fitness1.length; i++) { if (fitness1 != null) {
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,9 +231,16 @@ writeKpi(best); ...@@ -228,9 +231,16 @@ 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或空数组的情况
double improvement = currentFitness[i] - initialFitnessLevel[i]; if (currentFitness != null && currentFitness.length > 0 &&
sb.append(String.format("KPI%d: %.4f→%.4f(+%.4f) ", i+1, initialFitnessLevel[i], currentFitness[i], improvement)); 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];
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;
...@@ -260,10 +270,17 @@ writeKpi(best); ...@@ -260,10 +270,17 @@ 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或空数组的情况
double improvement = currentFitness[i] - initialFitnessLevel[i]; if (currentFitness != null && currentFitness.length > 0 &&
sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i], initialFitnessLevel != null && initialFitnessLevel.length > 0) {
initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0)); int minLength = Math.min(currentFitness.length, initialFitnessLevel.length);
for (int i = 0; i < minLength; i++) {
double improvement = currentFitness[i] - initialFitnessLevel[i];
sb.append(String.format("KPI%d: %.4f→%.4f(%.2f%%) ", i+1, initialFitnessLevel[i], currentFitness[i],
initialFitnessLevel[i] > 0 ? improvement / initialFitnessLevel[i] * 100 : 0));
}
} else {
sb.append("(KPI数据不可用) ");
} }
double totalImprovement = best.getFitness() - initialFitness; double totalImprovement = best.getFitness() - initialFitness;
......
...@@ -199,9 +199,14 @@ public class PlanResultService { ...@@ -199,9 +199,14 @@ public class PlanResultService {
for (Machine machine : machines){ for (Machine machine : machines){
Long machineId=machine.getId(); Long machineId=machine.getId();
if(machineId==2406)
{
int i=0;
}
if(machineIds.get(machineId)!=null&&machineIds.get(machineId)>3600*24*200) { if(machineIds.get(machineId)!=null&&machineIds.get(machineId)>3600*24*200) {
int day = (int) (machineIds.get(machineId) / 3600 / 24)+100; int day = (int) (machineIds.get(machineId) / 3600 / 24)+100;
// day=Math.min(day,400);
List<TimeSegment> segments = machineScheduler.generateTimeSegment(machine, null, day); List<TimeSegment> segments = machineScheduler.generateTimeSegment(machine, null, day);
machineScheduler.addSegmentsWithDeduplication(machine, segments); machineScheduler.addSegmentsWithDeduplication(machine, segments);
} }
......
...@@ -163,7 +163,7 @@ public class SceneService { ...@@ -163,7 +163,7 @@ public class SceneService {
sceneChromsome.getSceneDetails().add(sceneDetail); sceneChromsome.getSceneDetails().add(sceneDetail);
// redisUtils.set("SceneId."+sceneId,sceneChromsome); redisUtils.set("SceneId."+sceneId,sceneChromsome);
File file = getChromosomeFile(sceneId,sceneChromsome.getVersion().toString()); File file = getChromosomeFile(sceneId,sceneChromsome.getVersion().toString());
......
...@@ -39,10 +39,13 @@ public class PlanResultServiceTest { ...@@ -39,10 +39,13 @@ 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("E29F2B3ADA8149F6B916B5119296A92B");//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");
// planResultService.execute2("92BB773E1E2447C99D8176C991D5C9D2"); // planResultService.execute2("92BB773E1E2447C99D8176C991D5C9D2");
......
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