修复拆分复制报错

parent b1b2a85e
......@@ -248,12 +248,18 @@ public class GeneticDecoder {
public int generateGlobalOpList(Chromosome chromosome) {
// 没有工序时无需生成半成品全局工序,避免后续重建 operationSequencing。
if (chromosome == null || chromosome.getAllOperations() == null || chromosome.getAllOperations().isEmpty()) {
return 0;
}
CopyOnWriteArrayList<Entry> allOperations= chromosome.getAllOperations()
.stream()
.filter(t->t.isNewCreate()==true)
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
if(allOperations==null&&allOperations.size()>0)
// 没有新增工序时直接返回,不触发 CreateNewOpSequence 重建排序。
if(allOperations==null||allOperations.size()==0)
{
return 0;
}
......@@ -328,13 +334,22 @@ public class GeneticDecoder {
Entry entry=allOperations.stream()
.filter(t->t.getGroupId()==num&&t.getSequence()==scheduledCount1)
.findFirst().orElse(null);
// 找不到当前成品工序时跳过,避免重建排序时空指针。
if (entry == null) {
continue;
}
entry.setSchedulingMode(Entry.SchedulingMode.FORWARD.name());
if(entry!=null&&entry.getDependentOnOrderIds().size()>0)
{
for (int order : entry.getDependentOnOrderIds()) {
for (int num1 : sfSequence.get(order)){
// 依赖的半成品订单可能不在旧排序里,缺失时跳过,避免空指针。
List<Integer> childSequence = sfSequence.get(order);
if (childSequence == null || childSequence.isEmpty()) {
continue;
}
for (int num1 : childSequence){
InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence,allOperations);
}
}
......@@ -361,12 +376,21 @@ public class GeneticDecoder {
Entry entry=allOperations.stream()
.filter(t->t.getGroupId()==orderid&&t.getSequence()==scheduledCount1)
.findFirst().orElse(null);
// 找不到下一道工序说明该订单已插够次数,不能再写入 finalSequence。
if (entry == null) {
return;
}
entry.setSchedulingMode(Entry.SchedulingMode.BACKWARD.name());
if(entry!=null&&entry.getDependentOnOrderIds().size()>0) {
for (int order : entry.getDependentOnOrderIds()) {
for (int num1 : sfSequence.get(order)) {
// 依赖的半成品订单可能不在旧排序里,缺失时跳过,避免空指针。
List<Integer> childSequence = sfSequence.get(order);
if (childSequence == null || childSequence.isEmpty()) {
continue;
}
for (int num1 : childSequence) {
InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence,allOperations);
}
}
......@@ -380,6 +404,52 @@ public class GeneticDecoder {
orderProcessCounter.put(orderid, scheduledCount);
}
/**
* 按真实工序数规整工序排序序列。
* operationSequencing 存的是订单 groupId,每出现一次代表调度该订单的下一道工序。
* CreateNewOpSequence 可能重新插入半成品订单,需防止同一订单出现次数超过实际工序数。
*/
private void normalizeOperationSequencing(Chromosome chromosome) {
List<Entry> allOperations = chromosome.getAllOperations();
List<Integer> operationSequencing = chromosome.getOperationSequencing();
if (allOperations == null || operationSequencing == null) {
return;
}
Map<Integer, Long> expectedCounts = allOperations.stream()
.collect(Collectors.groupingBy(Entry::getGroupId, Collectors.counting()));
Map<Integer, Integer> actualCounts = new HashMap<>();
List<Integer> normalized = new ArrayList<>();
// 先保留原序列中的合法次数,超过真实工序数的重复 groupId 丢弃。
for (Integer groupId : operationSequencing) {
if (groupId == null) {
continue;
}
long expected = expectedCounts.getOrDefault(groupId, 0L);
int actual = actualCounts.getOrDefault(groupId, 0);
if (actual < expected) {
normalized.add(groupId);
actualCounts.put(groupId, actual + 1);
}
}
// 如果序列缺少某些工序,再按 groupId + sequence 补齐,保证每道工序都有一次调度机会。
allOperations.stream()
.sorted(Comparator.comparing(Entry::getGroupId).thenComparing(Entry::getSequence))
.forEach(op -> {
int groupId = op.getGroupId();
long expected = expectedCounts.getOrDefault(groupId, 0L);
int actual = actualCounts.getOrDefault(groupId, 0);
if (actual < expected) {
normalized.add(groupId);
actualCounts.put(groupId, actual + 1);
}
});
chromosome.setOperationSequencing(normalized);
}
public void decode(Chromosome chromosome,boolean isParallel) {
//
......@@ -430,6 +500,8 @@ public class GeneticDecoder {
if(isnew==1) {
long t2 = System.nanoTime();
CreateNewOpSequence(chromosome);
// CreateNewOpSequence 会重建半成品插入顺序,生成后再规整一次,避免重复调度同一订单。
normalizeOperationSequencing(chromosome);
// FileHelper.writeLogFile("[PERF] serialDecode CreateNewOpSequence 耗时=" + fmtMs(System.nanoTime() - t2));
}
}
......@@ -600,6 +672,8 @@ public class GeneticDecoder {
if(isnew==1) {
CreateNewOpSequence(chromosome);
// CreateNewOpSequence 会重建半成品插入顺序,生成后再规整一次,避免重复调度同一订单。
normalizeOperationSequencing(chromosome);
}
}
......
......@@ -755,9 +755,57 @@ if(targetOp.getSequence()>1) {
}
}
// 工序拆分会改 allOperations 和 operationSequencing,重解码前先规整,避免同一订单排超次数。
normalizeOperationSequencing(chromosome);
redecode(chromosome, chromosome.getBaseTime(), globalParam);
}
/**
* 按真实工序数规整工序排序序列。
* operationSequencing 存的是订单 groupId,每出现一次代表调度该订单的下一道工序。
* 如果某个 groupId 出现次数超过该订单实际工序数,解码时会出现“工序已全部调度”的异常。
*/
private void normalizeOperationSequencing(Chromosome chromosome) {
List<Entry> allOperations = chromosome.getAllOperations();
List<Integer> operationSequencing = chromosome.getOperationSequencing();
if (allOperations == null || operationSequencing == null) {
return;
}
Map<Integer, Long> expectedCounts = allOperations.stream()
.collect(Collectors.groupingBy(Entry::getGroupId, Collectors.counting()));
Map<Integer, Integer> actualCounts = new HashMap<>();
List<Integer> normalized = new ArrayList<>();
// 先保留原序列中的合法次数,超过真实工序数的重复 groupId 丢弃。
for (Integer groupId : operationSequencing) {
if (groupId == null) {
continue;
}
long expected = expectedCounts.getOrDefault(groupId, 0L);
int actual = actualCounts.getOrDefault(groupId, 0);
if (actual < expected) {
normalized.add(groupId);
actualCounts.put(groupId, actual + 1);
}
}
// 如果序列缺少某些工序,再按 groupId + sequence 补齐,保证每道工序都有一次调度机会。
allOperations.stream()
.sorted(Comparator.comparing(Entry::getGroupId).thenComparing(Entry::getSequence))
.forEach(op -> {
int groupId = op.getGroupId();
long expected = expectedCounts.getOrDefault(groupId, 0L);
int actual = actualCounts.getOrDefault(groupId, 0);
if (actual < expected) {
normalized.add(groupId);
actualCounts.put(groupId, actual + 1);
}
});
chromosome.setOperationSequencing(normalized);
}
public void SpiltOrder(Chromosome chromosome, String orderId,Double[] splitCounts, GlobalParam globalParam)
{
List<Entry> allOperations = chromosome.getAllOperations();
......@@ -1753,7 +1801,8 @@ if(targetOp.getSequence()>1) {
.orElseThrow(() -> new NoSuchElementException("Global operation not found: " + opId));
chromosome.getMachineSelection().add((int)globalOpIndex);
// MachineSelection 与 globalOpList 按 globalOpId 一一对应,删除工序时必须同步删除同索引的机器选择。
chromosome.getMachineSelection().remove((int)globalOpIndex);
globalOpList.remove((int)globalOpIndex);
......
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