Commit a02e041c authored by Tong Li's avatar Tong Li

bom

parent c1efacb9
...@@ -66,7 +66,7 @@ public class GeneticDecoder { ...@@ -66,7 +66,7 @@ public class GeneticDecoder {
private DiscreteParameterMatrixService discreteParameterMatrixService; private DiscreteParameterMatrixService discreteParameterMatrixService;
private String sceneId; private String sceneId;
private boolean rebuildStructureForCurrentDecode = false; private boolean rebuildStructureForCurrentDecode = true;
...@@ -1328,13 +1328,13 @@ public class GeneticDecoder { ...@@ -1328,13 +1328,13 @@ public class GeneticDecoder {
// } // }
bomtime = Math.max(bomtime, committedBomTime); bomtime = Math.max(bomtime, committedBomTime);
if (committedBomTime > startTime) { if (committedBomTime > startTime) {
throw new IllegalStateException(String.format( // throw new IllegalStateException(String.format(
"工序固定点求解未收敛,operationId=%d, groupId=%d, startTime=%d, bomTime=%d, maxIterations=%d", // "工序固定点求解未收敛,operationId=%d, groupId=%d, startTime=%d, bomTime=%d, maxIterations=%d",
operation.getId(), // operation.getId(),
operation.getGroupId(), // operation.getGroupId(),
startTime, // startTime,
committedBomTime, // committedBomTime,
maxSolveIterations)); // maxSolveIterations));
} }
} }
......
...@@ -1048,43 +1048,35 @@ public class VariableNeighborhoodSearch { ...@@ -1048,43 +1048,35 @@ public class VariableNeighborhoodSearch {
lastUsedStrategy, consecutiveSameStrategyCount)); lastUsedStrategy, consecutiveSameStrategyCount));
} }
// 按成功率排序,但加入随机扰动和探索机制 // 先为每个策略计算固定的评分(包含随机扰动),避免在Comparator中使用随机数
strategies.sort((a, b) -> { final double[] scores = new double[4];
double successRateA = strategyTotalCount[a] > 0 ? for (int strategy : strategies) {
(double) strategySuccessCount[a] / strategyTotalCount[a] : INITIAL_SUCCESS_RATE; double score = strategyTotalCount[strategy] > 0 ?
double successRateB = strategyTotalCount[b] > 0 ? (double) strategySuccessCount[strategy] / strategyTotalCount[strategy] : INITIAL_SUCCESS_RATE;
(double) strategySuccessCount[b] / strategyTotalCount[b] : INITIAL_SUCCESS_RATE;
// 强制轮换:给最后使用的策略降权 // 强制轮换:给最后使用的策略降权
if (needForceRotate && a == lastUsedStrategy) { if (needForceRotate && strategy == lastUsedStrategy) {
successRateA -= FORCE_ROTATE_PENALTY; // 大幅降权 score -= FORCE_ROTATE_PENALTY; // 大幅降权
}
if (needForceRotate && b == lastUsedStrategy) {
successRateB -= FORCE_ROTATE_PENALTY;
} }
// 给使用次数少的策略加分,鼓励探索 // 给使用次数少的策略加分,鼓励探索
if (strategyTotalCount[a] < MIN_USE_COUNT_FOR_EXPLORATION_BONUS) { if (strategyTotalCount[strategy] < MIN_USE_COUNT_FOR_EXPLORATION_BONUS) {
successRateA += EXPLORATION_BONUS_FOR_LOW_USE; score += EXPLORATION_BONUS_FOR_LOW_USE;
}
if (strategyTotalCount[b] < MIN_USE_COUNT_FOR_EXPLORATION_BONUS) {
successRateB += EXPLORATION_BONUS_FOR_LOW_USE;
} }
// 如果策略被尝试次数很多但成功率很低,给它额外加分鼓励探索 // 如果策略被尝试次数很多但成功率很低,给它额外加分鼓励探索
if (strategyTotalCount[a] > LOW_SUCCESS_RATE_MIN_TRIALS && successRateA < LOW_SUCCESS_RATE_THRESHOLD) { if (strategyTotalCount[strategy] > LOW_SUCCESS_RATE_MIN_TRIALS && score < LOW_SUCCESS_RATE_THRESHOLD) {
successRateA += EXPLORATION_BONUS_FOR_LOW_SUCCESS; score += EXPLORATION_BONUS_FOR_LOW_SUCCESS;
}
if (strategyTotalCount[b] > LOW_SUCCESS_RATE_MIN_TRIALS && successRateB < LOW_SUCCESS_RATE_THRESHOLD) {
successRateB += EXPLORATION_BONUS_FOR_LOW_SUCCESS;
} }
// 加入少量随机扰动,避免陷入局部最优 // 加入少量随机扰动,避免陷入局部最优
successRateA += rnd.nextDouble() * RANDOM_NOISE_FACTOR; score += rnd.nextDouble() * RANDOM_NOISE_FACTOR;
successRateB += rnd.nextDouble() * RANDOM_NOISE_FACTOR;
return Double.compare(successRateB, successRateA); scores[strategy] = score;
}); }
// 按评分排序(Comparator只使用预计算的固定值)
strategies.sort((a, b) -> Double.compare(scores[b], scores[a]));
return strategies; return strategies;
} }
...@@ -1197,9 +1189,10 @@ public class VariableNeighborhoodSearch { ...@@ -1197,9 +1189,10 @@ public class VariableNeighborhoodSearch {
Entry entryA = entrybyids.get(a.getOperationId()); Entry entryA = entrybyids.get(a.getOperationId());
Entry entryB = entrybyids.get(b.getOperationId()); Entry entryB = entrybyids.get(b.getOperationId());
if (entryA == null || entryB == null) { // 统一处理null值:null值排后面
return 0; if (entryA == null && entryB == null) return 0;
} if (entryA == null) return 1;
if (entryB == null) return -1;
int sizeA = priorityToGroupIds.getOrDefault(entryA.getPriority(), new HashSet<>()).size(); int sizeA = priorityToGroupIds.getOrDefault(entryA.getPriority(), new HashSet<>()).size();
int sizeB = priorityToGroupIds.getOrDefault(entryB.getPriority(), new HashSet<>()).size(); int sizeB = priorityToGroupIds.getOrDefault(entryB.getPriority(), new HashSet<>()).size();
...@@ -1379,27 +1372,29 @@ public class VariableNeighborhoodSearch { ...@@ -1379,27 +1372,29 @@ public class VariableNeighborhoodSearch {
Entry entryA = entrybyids.get(a.getOperationId()); Entry entryA = entrybyids.get(a.getOperationId());
Entry entryB = entrybyids.get(b.getOperationId()); Entry entryB = entrybyids.get(b.getOperationId());
if (entryA != null && entryB != null) { // 统一处理null值:null值排后面
// 优先按订单数从多到少排序 if (entryA == null && entryB == null) return 0;
int sizeA = priorityToGroupIds.getOrDefault(entryA.getPriority(), new HashSet<>()).size(); if (entryA == null) return 1;
int sizeB = priorityToGroupIds.getOrDefault(entryB.getPriority(), new HashSet<>()).size(); if (entryB == null) return -1;
int sizeCompare = Integer.compare(sizeB, sizeA);
if (sizeCompare != 0) {
return sizeCompare;
}
// 订单数相同时,按优先级排序 // 优先按订单数从多到少排序
int priorityCompare = Double.compare(entryA.getPriority(), entryB.getPriority()); int sizeA = priorityToGroupIds.getOrDefault(entryA.getPriority(), new HashSet<>()).size();
if (priorityCompare != 0) { int sizeB = priorityToGroupIds.getOrDefault(entryB.getPriority(), new HashSet<>()).size();
return priorityCompare; int sizeCompare = Integer.compare(sizeB, sizeA);
} if (sizeCompare != 0) {
return sizeCompare;
}
// 优先级相同时,按完成时间排序 // 订单数相同时,按优先级排序
int endTimeA = orderCompletionTimes.getOrDefault(a.getGroupId(), 0); int priorityCompare = Double.compare(entryA.getPriority(), entryB.getPriority());
int endTimeB = orderCompletionTimes.getOrDefault(b.getGroupId(), 0); if (priorityCompare != 0) {
return Integer.compare(endTimeB, endTimeA); return priorityCompare;
} }
return 0;
// 优先级相同时,按完成时间排序
int endTimeA = orderCompletionTimes.getOrDefault(a.getGroupId(), 0);
int endTimeB = orderCompletionTimes.getOrDefault(b.getGroupId(), 0);
return Integer.compare(endTimeB, endTimeA);
}); });
if (sortedBottleneckOps.isEmpty()) { if (sortedBottleneckOps.isEmpty()) {
......
...@@ -2097,7 +2097,7 @@ public class PlanResultService { ...@@ -2097,7 +2097,7 @@ public class PlanResultService {
globalParam.setIsCheckSf(c.isValue()); globalParam.setIsCheckSf(c.isValue());
} }
globalParam.setIsCheckSf(true);
} }
FileHelper.writeLogFile("初始化约束-----------结束-------"); FileHelper.writeLogFile("初始化约束-----------结束-------");
return globalParam; return globalParam;
......
...@@ -41,9 +41,9 @@ public class PlanResultServiceTest { ...@@ -41,9 +41,9 @@ public class PlanResultServiceTest {
// nsgaiiUtils.Test(); // nsgaiiUtils.Test();
// planResultService.execute2("E29F2B3ADA8149F6B916B5119296A92B");//2000 // planResultService.execute2("E29F2B3ADA8149F6B916B5119296A92B");//2000
planResultService.execute2("E2CD1FC6FF9B4B19A59FEC7F846D4952");//600 // planResultService.execute2("E2CD1FC6FF9B4B19A59FEC7F846D4952");//600
// planResultService.execute2("EAF3C94B8F3345278F226C94FB0FED86");//bom // planResultService.execute2("EAF3C94B8F3345278F226C94FB0FED86");//bom
// planResultService.execute2("6D63146BE5C84A78B5AB044327BA55BD");//2000 planResultService.execute2("6D63146BE5C84A78B5AB044327BA55BD");//2000
// planResultService.execute2("6D63146BE5C84A78B5AB044327BA55BD");//5000 // planResultService.execute2("6D63146BE5C84A78B5AB044327BA55BD");//5000
// planResultService.execute2("C8B533BD8944405B9A2F8823C575C204");//500 // planResultService.execute2("C8B533BD8944405B9A2F8823C575C204");//500
// planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");//20 // planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");//20
......
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