Commit 6086d002 authored by Tong Li's avatar Tong Li

Merge remote-tracking branch 'origin/tl'

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