Commit ee5baba2 authored by Tong Li's avatar Tong Li

遗传算法-优化

parent 19a1519c
...@@ -59,7 +59,7 @@ public class GeneticAlgorithm { ...@@ -59,7 +59,7 @@ public class GeneticAlgorithm {
} }
public Chromosome Run(ScheduleParams param, List<Entry> allOperations) { public Chromosome Run(ScheduleParams param, List<Entry> allOperations) {
if(_GlobalParam.isIsCheckBom()) { if(_GlobalParam.isIsCheckBom()&&materials!=null&&materials.size()>0) {
materialRequirementService.init(materials, orders, allOperations, _entryRel, machineScheduler, machines); materialRequirementService.init(materials, orders, allOperations, _entryRel, machineScheduler, machines);
orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(param.getBaseTime()); orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(param.getBaseTime());
......
...@@ -58,7 +58,7 @@ public class GeneticDecoder { ...@@ -58,7 +58,7 @@ public class GeneticDecoder {
} }
public Chromosome decodeChromosomeWithCache(Chromosome chromosome) { public Chromosome decodeChromosomeWithCache(Chromosome chromosome) {
_allOperations=chromosome.getAllOperations(); _allOperations=chromosome.getAllOperations();
if(_globalParam.isIsCheckBom()) { if(_globalParam.isIsCheckBom()&&orderMaterials!=null&&orderMaterials.size()>0) {
CreateNewOpSequence(chromosome); CreateNewOpSequence(chromosome);
} }
...@@ -571,7 +571,7 @@ public class GeneticDecoder { ...@@ -571,7 +571,7 @@ public class GeneticDecoder {
private int getOperationBOMTime(Entry currentOp, Chromosome chromosome) { private int getOperationBOMTime(Entry currentOp, Chromosome chromosome) {
if(!_globalParam.isIsCheckBom()) if(!_globalParam.isIsCheckBom()||orderMaterials==null)
{ {
return 0; return 0;
} }
......
...@@ -77,46 +77,48 @@ public class GeneticOperations { ...@@ -77,46 +77,48 @@ public class GeneticOperations {
* 改进POX交叉(工序排序部分) * 改进POX交叉(工序排序部分)
*/ */
public Pair<Chromosome, Chromosome> poxCrossover(Chromosome parent1, Chromosome parent2, int orderCount) { public Pair<Chromosome, Chromosome> poxCrossover(Chromosome parent1, Chromosome parent2, int orderCount) {
// 前置校验:确保父代序列长度一致(避免数组越界)
int seqLength = parent1.getOperationSequencing().size();
if (seqLength != parent2.getOperationSequencing().size()) {
throw new IllegalArgumentException("父代操作序列长度不一致,无法交叉!");
}
// 步骤1:统计两个父代中每个工件的出现次数,确定最大允许次数
Map<Integer, Integer> parent1JobCount = countJobOccurrences(parent1.getOperationSequencing());
Map<Integer, Integer> parent2JobCount = countJobOccurrences(parent2.getOperationSequencing());
Map<Integer, Integer> maxAllowedCount = new HashMap<>();
for (int job = 1; job <= orderCount; job++) {
int count1 = parent1JobCount.getOrDefault(job, 0);
int count2 = parent2JobCount.getOrDefault(job, 0);
maxAllowedCount.put(job, Math.max(count1, count2)); // 取父代中该工件的最大出现次数
}
// 步骤1:随机划分工件集 // 步骤1:随机划分工件集
List<Integer> jobset1 = new ArrayList<>(); List<Integer> jobset1 = new ArrayList<>();
for (int i = 0; i < orderCount; i++) { for (int i = 1; i <= orderCount; i++) {
jobset1.add(i); jobset1.add(i);
} }
Collections.shuffle(jobset1, rnd); Collections.shuffle(jobset1, rnd);
jobset1 = jobset1.subList(0, orderCount / 2); // 当orderCount为奇数时,避免jobset1过短(取ceil(orderCount/2),确保划分均衡)
int jobset1Size = (orderCount + 1) / 2;
jobset1 = jobset1.subList(0, jobset1Size);
Set<Integer> jobset1Set = new HashSet<>(jobset1); Set<Integer> jobset1Set = new HashSet<>(jobset1);
List<Integer> jobset2 = new ArrayList<>(); List<Integer> jobset2 = new ArrayList<>();
for (int i = 0; i < orderCount; i++) { for (int i = 1; i <= orderCount; i++) {
if (!jobset1Set.contains(i)) { if (!jobset1Set.contains(i)) {
jobset2.add(i); jobset2.add(i);
} }
} }
// 步骤2:生成子代1 // 步骤3:生成子代1(控制工件出现次数不超过父代最大值)
List<Integer> child1Os = new ArrayList<>(); List<Integer> child1Os = generateChildOsWithCountLimit(
for (int i = 0; i < parent1.getOperationSequencing().size(); i++) { parent1, parent2, jobset1Set, maxAllowedCount, seqLength
int op1 = parent1.getOperationSequencing().get(i); );
int op2 = parent2.getOperationSequencing().get(i); // 步骤4:生成子代2(控制工件出现次数不超过父代最大值)
if (jobset1Set.contains(op1) || jobset1Set.contains(op2)) { List<Integer> child2Os = generateChildOsWithCountLimit(
child1Os.add(op1); parent2, parent1, jobset1Set, maxAllowedCount, seqLength
} else { );
child1Os.add(op2);
}
}
// 步骤3:生成子代2
List<Integer> child2Os = new ArrayList<>();
for (int i = 0; i < parent2.getOperationSequencing().size(); i++) {
int op1 = parent1.getOperationSequencing().get(i);
int op2 = parent2.getOperationSequencing().get(i);
if (jobset1Set.contains(op2) || jobset1Set.contains(op1)) {
child2Os.add(op2);
} else {
child2Os.add(op1);
}
}
// 机器选择部分交叉 // 机器选择部分交叉
List<Integer> child1Ms = new ArrayList<>(); List<Integer> child1Ms = new ArrayList<>();
List<Integer> child2Ms = new ArrayList<>(); List<Integer> child2Ms = new ArrayList<>();
...@@ -133,18 +135,91 @@ public class GeneticOperations { ...@@ -133,18 +135,91 @@ public class GeneticOperations {
} }
Chromosome child1 = new Chromosome(); Chromosome child1 = new Chromosome();
child1.setOrders(parent1.getOrders());
child1.setMachineSelection(child1Ms); child1.setMachineSelection(child1Ms);
child1.setOperationSequencing(child1Os); child1.setOperationSequencing(child1Os);
Chromosome child2 = new Chromosome(); Chromosome child2 = new Chromosome();
child2.setOrders(parent1.getOrders());
child2.setMachineSelection(child2Ms); child2.setMachineSelection(child2Ms);
child2.setOperationSequencing(child2Os); child2.setOperationSequencing(child2Os);
return new Pair<>(child1, child2); return new Pair<>(child1, child2);
} }
/**
* 核心方法:生成子代操作序列(遵循POX规则 + 工件出现次数限制)
* @param mainParent 主父代(优先取其基因)
* @param secondaryParent 次父代(备选基因)
* @param jobset1Set POX交叉的工件集判断依据
* @param maxAllowedCount 每个工件的最大允许出现次数
* @param seqLength 序列长度
* @return 符合规则的子代序列
*/
private List<Integer> generateChildOsWithCountLimit(
Chromosome mainParent, Chromosome secondaryParent,
Set<Integer> jobset1Set, Map<Integer, Integer> maxAllowedCount,
int seqLength
) {
List<Integer> childOs = new ArrayList<>();
List<Integer> mainSeq = mainParent.getOperationSequencing();
List<Integer> secondarySeq = secondaryParent.getOperationSequencing();
// 实时统计子代中每个工件的当前出现次数
Map<Integer, Integer> childJobCount = new HashMap<>();
for (int i = 0; i < seqLength; i++) {
int mainOp = mainSeq.get(i); // 主父代当前位置工件
int secondaryOp = secondarySeq.get(i); // 次父代当前位置工件
int selectedOp = mainOp; // 先按POX规则初始化候选工件
// 步骤1:遵循原POX交叉规则筛选候选工件
if (!(jobset1Set.contains(mainOp) || jobset1Set.contains(secondaryOp))) {
selectedOp = secondaryOp;
}
// 步骤2:检查候选工件是否超过最大允许次数,若超过则切换到另一个父代的工件
int currentCount = childJobCount.getOrDefault(selectedOp, 0);
if (currentCount >= maxAllowedCount.get(selectedOp)) {
// 切换到另一个父代的工件
selectedOp = (selectedOp == mainOp) ? secondaryOp : mainOp;
// 步骤3:极端情况:切换后仍超过次数,从所有工件中选一个未超次数的(确保序列有效)
if (childJobCount.getOrDefault(selectedOp, 0) >= maxAllowedCount.get(selectedOp)) {
selectedOp = findValidJob(maxAllowedCount, childJobCount);
}
}
// 步骤4:更新子代工件计数并添加到序列
childJobCount.put(selectedOp, childJobCount.getOrDefault(selectedOp, 0) + 1);
childOs.add(selectedOp);
}
return childOs;
}
/**
* 辅助方法:找到一个未超过最大允许次数的工件(极端情况兜底)
*/
private int findValidJob(Map<Integer, Integer> maxAllowedCount, Map<Integer, Integer> childJobCount) {
for (Map.Entry<Integer, Integer> entry : maxAllowedCount.entrySet()) {
int job = entry.getKey();
int maxCount = entry.getValue();
int currentCount = childJobCount.getOrDefault(job, 0);
if (currentCount < maxCount) {
return job;
}
}
// 理论上不会走到这里(因序列长度=父代长度,总次数不会超父代总和)
throw new IllegalStateException("无可用工件,序列生成失败!");
}
/**
* 辅助方法:统计操作序列中每个工件的出现次数
*/
private Map<Integer, Integer> countJobOccurrences(List<Integer> operationSequencing) {
Map<Integer, Integer> countMap = new HashMap<>();
for (int job : operationSequencing) {
countMap.put(job, countMap.getOrDefault(job, 0) + 1);
}
return countMap;
}
/** /**
* 变异操作 * 变异操作
*/ */
......
...@@ -628,6 +628,13 @@ public class ScheduleOperationService { ...@@ -628,6 +628,13 @@ public class ScheduleOperationService {
} }
public void DelOrder(Chromosome chromosome, int orderId, GlobalParam globalParam) {
}
/** /**
* 重新解码 * 重新解码
* @param chromosome 原方案 * @param chromosome 原方案
......
...@@ -325,7 +325,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0)); ...@@ -325,7 +325,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
// 3. 构建订单-工序数据 // 3. 构建订单-工序数据
List<Order> orders=InitOrder(ProdLaunchOrders); List<Order> orders=InitOrder(ProdLaunchOrders);
List<Material> Materials= InitMaterial(); List<Material> Materials=null;// InitMaterial();
Map<Integer,Object> list= InitEntrys(SceneId,ProdEquipments,orders); Map<Integer,Object> list= InitEntrys(SceneId,ProdEquipments,orders);
List<Entry> entrys=(List<Entry>)list.get(1); List<Entry> entrys=(List<Entry>)list.get(1);
...@@ -550,7 +550,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0)); ...@@ -550,7 +550,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
List<Order> orders=InitOrder(ProdLaunchOrders); List<Order> orders=InitOrder(ProdLaunchOrders);
List<Material> Materials= InitMaterial();
Map<Integer,Object> list= InitEntrys(SceneId,ProdEquipments,orders); Map<Integer,Object> list= InitEntrys(SceneId,ProdEquipments,orders);
List<Entry> entrys=(List<Entry>)list.get(1); List<Entry> entrys=(List<Entry>)list.get(1);
List<GroupResult> entryRel=(List<GroupResult>)list.get(2); List<GroupResult> entryRel=(List<GroupResult>)list.get(2);
...@@ -558,7 +558,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0)); ...@@ -558,7 +558,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
GlobalParam globalParam=InitGlobalParam(); GlobalParam globalParam=InitGlobalParam();
// 5. 执行调度算法 // 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,entryRel,materialRequirementService); //new GeneticAlgorithm(products, machines, orders, machineScheduler); GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,Materials,machineScheduler,entryRel,materialRequirementService); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
param.initAdaptiveParams(entrys.size()); param.initAdaptiveParams(entrys.size());
// double[] customWeights = new double[] { 0.2, 0.1, 0.1, 0.1, 0.5 }; // 延迟时间权重提升到0.5 // double[] customWeights = new double[] { 0.2, 0.1, 0.1, 0.1, 0.5 }; // 延迟时间权重提升到0.5
...@@ -914,9 +914,7 @@ private GlobalParam InitGlobalParam() ...@@ -914,9 +914,7 @@ private GlobalParam InitGlobalParam()
List<String> ids=new ArrayList<>();
MaterialInfoWrapper.in(MaterialInfo::getId,ids);
List<MaterialInfo> materiallist= materialInfoMapper.selectList(MaterialInfoWrapper); List<MaterialInfo> materiallist= materialInfoMapper.selectList(MaterialInfoWrapper);
......
...@@ -22,6 +22,11 @@ public class PlanResultServiceTest { ...@@ -22,6 +22,11 @@ public class PlanResultServiceTest {
@Autowired @Autowired
private SceneService sceneService; private SceneService sceneService;
@Test
public void testExecute() {
planResultService.execute2("");
}
@Test @Test
public void testExecute2() { public void testExecute2() {
// 这里需要一个有效的SceneId来测试 // 这里需要一个有效的SceneId来测试
......
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