Commit e1e21676 authored by Tong Li's avatar Tong Li

遗传算法

parent cfcaec50
This diff is collapsed.
......@@ -133,8 +133,8 @@ public class ResourceGanttController {
return scheduleChromosomes;
}
@GetMapping("/Move")
public Chromosome Move(String SceneId,int opid,LocalDateTime newStartTime,
@GetMapping("/operationMove")
public Chromosome OperationMove(String SceneId,int opid,LocalDateTime newStartTime,
Long newMachineId) {
// opid=1;
// newStartTime= LocalDateTime.of(2025, 12, 7, 0, 0);
......@@ -146,8 +146,26 @@ public class ResourceGanttController {
// 提取所有场景ID
return scheduleChromosomes;
}
@PostMapping("/operationedit")
public Chromosome editOperation(@RequestParam String SceneId,
@RequestBody Entry operation) {
Chromosome scheduleChromosomes = planResultService.EditOperation(SceneId,operation);
@PostMapping("/SpiltOperation")
// 提取所有场景ID
return scheduleChromosomes;
}
@PostMapping("/changebasetime")
public Chromosome ChangeBaseTime(@RequestParam String SceneId,
@RequestParam LocalDateTime BaseTime) {
Chromosome scheduleChromosomes = planResultService.ChangeBaseTime(SceneId,BaseTime);
// 提取所有场景ID
return scheduleChromosomes;
}
@PostMapping("/operationspilt")
public Chromosome SpiltOperation(@RequestParam String SceneId,
@RequestParam int opid,
@RequestBody List<Double> splitCounts) {
......@@ -165,7 +183,7 @@ public class ResourceGanttController {
// 提取所有场景ID
return scheduleChromosomes;
}
@PostMapping("/delOperation")
@PostMapping("/operationdel")
public Chromosome DelOperation(@RequestParam String SceneId,
@RequestParam int opid) {
opid=1;
......@@ -177,7 +195,7 @@ public class ResourceGanttController {
// 提取所有场景ID
return scheduleChromosomes;
}
@PostMapping("/LockedOperation")
@PostMapping("/operationlocked")
public Chromosome LockedOperation(@RequestParam String SceneId,
@RequestParam int opid,@RequestParam boolean isLocked) {
opid=1;
......@@ -190,6 +208,47 @@ public class ResourceGanttController {
return scheduleChromosomes;
}
@PostMapping("/orderspilt")
public Chromosome SpiltOrder(@RequestParam String SceneId,
@RequestParam String orderid,
@RequestBody List<Double> splitCounts) {
orderid="fcc0892a-0483-4da7-8414-9ce98be36e53";
// newStartTime= LocalDateTime.of(2025, 12, 7, 0, 0);
// newMachineId=3402L;
splitCounts=new ArrayList<>();
splitCounts.add(20000d);
splitCounts.add(20000d);
splitCounts.add(10000d);
SceneId="B571EF6682DB463AB2977B1055A74112";
// 数组第一个是0,为复制
//splitCounts=new ArrayList<>();
// splitCounts.add(0);
// splitCounts.add(50000d);
// 调用 PlanResultService 获取 ScheduleChromosome 列表
Chromosome scheduleChromosomes = planResultService.SpiltOrder(SceneId,orderid,splitCounts.toArray(new Double[0]));
// 提取所有场景ID
return scheduleChromosomes;
}
@PostMapping("/ordermerge")
public Chromosome OrderMerge(@RequestParam String SceneId,
@RequestParam String sourceorderid,
@RequestParam String targetorderid) {
sourceorderid="5be078b725b34ade8b6638f74dad6b10";
targetorderid="2a0f23d2429f4e5da7b3929da75a803d";
SceneId="B571EF6682DB463AB2977B1055A74112";
// 调用 PlanResultService 获取 ScheduleChromosome 列表
Chromosome scheduleChromosomes = planResultService.MergeOrder(SceneId,sourceorderid,targetorderid);
// 提取所有场景ID
return scheduleChromosomes;
}
......
......@@ -65,6 +65,12 @@ public class Entry {
* 可选设备列表
*/
public List<MachineOption> MachineOptions ;
/**
* 选择的设备
*/
public Long SelectMachineID ;
/**
* 前工单ID
*/
......
......@@ -25,5 +25,5 @@ public class Order {
private boolean canSplit = false;
private boolean canInterrupt = false;
private double actualPriority;
private String mainId;
}
\ No newline at end of file
......@@ -152,21 +152,21 @@ public class GeneticAlgorithm {
// decoder.decodeChromosomeWithCache(chromosome, globalOpList, allOperations);
// chromosome.setFitness(fitnessCalc.calculateFitness(chromosome));
// });
population.forEach(chromosome -> {
chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(allOperations); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝
Chromosome chromosomen= decoder.decodeChromosomeWithCache(chromosome);
if(chromosomen.getFitness()==0) {
chromosomen.setFitness(fitnessCalc.calculateFitness(chromosomen));
}
});
if(population!=null&&population.size()>0) {
population.forEach(chromosome -> {
chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(allOperations); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝
Chromosome chromosomen = decoder.decodeChromosomeWithCache(chromosome);
if (chromosomen.getFitness() == 0) {
chromosomen.setFitness(fitnessCalc.calculateFitness(chromosomen));
}
});
}
}
}
......@@ -360,6 +360,7 @@ public class GeneticDecoder {
result.setOrderId(operation.getOrderId());
result.setProductId(operation.getProductId());
result.setMachineId(machine.getId());
operation.setSelectMachineID(machine.getId());
result.setQuantity(operation.getQuantity());
result.setStartTime(startTime);
result.setEndTime(endTime);
......
......@@ -381,10 +381,10 @@ public class IdGroupingWithDualSerial {
return newResults;
}
/**
* 添加新数据(支持仅孤立节点的场景
* 添加新数据(按连通性分组
* @param existingResults 已有分组结果
* @param newIdList 新数据的ID列表
* @param newChildIdList 新数据的ChildID列表(允许空值)
* @param newChildIdList 新数据的ChildID列表
* @return 包含新分组的结果列表
*/
public static List<GroupResult> addNewDataWithIsolatedGroup(List<GroupResult> existingResults, List<String> newIdList, List<String> newChildIdList) {
......@@ -396,38 +396,32 @@ public class IdGroupingWithDualSerial {
newChildIdList = new ArrayList<>();
}
// 1. 初始化数据结构
Set<String> allNewNodes = new HashSet<>(newIdList); // 所有新节点
Map<String, String> idToChild = new HashMap<>(); // 临时存储ID与ChildID的映射
// 1. 构建全量节点集合和父子映射
Set<String> allNodes = new HashSet<>();
Map<String, Set<String>> parentToChildren = new HashMap<>();
Map<String, Set<String>> childToParents = new HashMap<>();
// 构建ID→ChildID映射(处理空值)
for (int i = 0; i < newIdList.size(); i++) {
String id = newIdList.get(i);
String parentId = newIdList.get(i);
String childId = i < newChildIdList.size() ? newChildIdList.get(i) : "";
if (id != null && !id.trim().isEmpty()) {
idToChild.put(id, (childId == null ? "" : childId.trim()));
allNewNodes.add(id); // 确保ID被加入
if (!childId.trim().isEmpty()) {
allNewNodes.add(childId.trim()); // 子节点也加入
}
}
}
// 2. 分离孤立节点和关联节点
List<String> isolatedNodes = new ArrayList<>();
List<String> relationNodes = new ArrayList<>();
if (parentId == null || parentId.trim().isEmpty()) {
continue;
}
allNodes.add(parentId);
for (String node : allNewNodes) {
String childId = idToChild.getOrDefault(node, "");
// 孤立节点:无ChildID,且不是任何节点的ChildID
boolean isIsolated = childId.isEmpty() && !idToChild.values().contains(node);
if (isIsolated) {
isolatedNodes.add(node);
} else {
relationNodes.add(node);
if (childId == null || childId.trim().isEmpty()) {
continue;
}
allNodes.add(childId);
parentToChildren.computeIfAbsent(parentId, k -> new HashSet<>()).add(childId);
childToParents.computeIfAbsent(childId, k -> new HashSet<>()).add(parentId);
}
// 2. 识别连通分量(通过DFS)
List<Set<String>> connectedComponents = findConnectedComponents(allNodes, parentToChildren, childToParents);
// 3. 获取现有结果的最大全局序号
int maxGlobalSerial = existingResults.stream()
.flatMap(g -> g.getNodeInfoList().stream())
......@@ -436,19 +430,123 @@ public class IdGroupingWithDualSerial {
.orElse(0);
int[] globalCounter = {maxGlobalSerial + 1};
// 4. 处理关联节点(如果有)
if (!relationNodes.isEmpty()) {
GroupResult relationGroup = createRelationGroup(idToChild, relationNodes, globalCounter);
existingResults.add(relationGroup);
// 4. 为每个连通分量创建独立分组
for (Set<String> component : connectedComponents) {
GroupResult group = createGroupFromComponent(component, parentToChildren, childToParents, globalCounter);
existingResults.add(group);
}
// 5. 处理孤立节点(即使只有孤立节点也创建分组)
for (String isolatedNode : isolatedNodes) {
GroupResult isolatedGroup = createIsolatedGroup(isolatedNode, globalCounter);
existingResults.add(isolatedGroup);
return existingResults;
}
/**
* 识别连通分量(DFS)
*/
private static List<Set<String>> findConnectedComponents(Set<String> allNodes,
Map<String, Set<String>> parentToChildren,
Map<String, Set<String>> childToParents) {
List<Set<String>> components = new ArrayList<>();
Set<String> visited = new HashSet<>();
for (String node : allNodes) {
if (!visited.contains(node)) {
Set<String> component = new HashSet<>();
dfs(node, component, visited, parentToChildren, childToParents);
components.add(component);
}
}
return components;
}
/**
* DFS遍历连通分量
*/
private static void dfs(String node, Set<String> component, Set<String> visited,
Map<String, Set<String>> parentToChildren,
Map<String, Set<String>> childToParents) {
if (visited.contains(node)) {
return;
}
visited.add(node);
component.add(node);
// 遍历子节点
if (parentToChildren.containsKey(node)) {
for (String child : parentToChildren.get(node)) {
dfs(child, component, visited, parentToChildren, childToParents);
}
}
return existingResults;
// 遍历父节点(确保双向连通)
if (childToParents.containsKey(node)) {
for (String parent : childToParents.get(node)) {
dfs(parent, component, visited, parentToChildren, childToParents);
}
}
}
/**
* 从连通分量创建分组
*/
private static GroupResult createGroupFromComponent(Set<String> component,
Map<String, Set<String>> parentToChildren,
Map<String, Set<String>> childToParents,
int[] globalCounter) {
// 识别根节点(无父节点的节点)
List<String> rootNodes = component.stream()
.filter(node -> !childToParents.containsKey(node) || childToParents.get(node).isEmpty())
.collect(Collectors.toList());
if (rootNodes.isEmpty()) {
rootNodes.add(component.iterator().next()); // 兜底:取任意节点作为根
}
// BFS构建节点列表
List<NodeInfo> nodeList = new ArrayList<>();
Map<String, Integer> serialMap = new HashMap<>();
Queue<String> queue = new LinkedList<>(rootNodes);
Set<String> visited = new HashSet<>(rootNodes);
int groupCounter = 1;
// 处理根节点
for (String root : rootNodes) {
serialMap.put(root, globalCounter[0]);
nodeList.add(new NodeInfo(root, globalCounter[0]++, groupCounter++, new ArrayList<>(), new ArrayList<>()));
}
// 处理子节点
while (!queue.isEmpty()) {
String parent = queue.poll();
if (parentToChildren.containsKey(parent)) {
for (String child : parentToChildren.get(parent)) {
if (!component.contains(child) || visited.contains(child)) {
continue;
}
visited.add(child);
// 获取父节点的全局序号列表
List<Integer> parentSerials = childToParents.getOrDefault(child, new HashSet<>()).stream()
.filter(p -> serialMap.containsKey(p))
.map(serialMap::get)
.collect(Collectors.toList());
serialMap.put(child, globalCounter[0]);
nodeList.add(new NodeInfo(child, globalCounter[0]++, groupCounter++, parentSerials, new ArrayList<>()));
queue.add(child);
}
}
}
// 填充子ID列表
for (NodeInfo node : nodeList) {
String originalId = node.getOriginalId();
if (parentToChildren.containsKey(originalId)) {
List<Integer> childSerials = parentToChildren.get(originalId).stream()
.filter(c -> serialMap.containsKey(c))
.map(serialMap::get)
.collect(Collectors.toList());
node.setNewChildIds(childSerials);
}
}
return new GroupResult(nodeList, serialMap);
}
/**
* 创建关联节点的分组(20→21→22)
......
......@@ -318,11 +318,24 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
}
ScheduleOperationService ScheduleOperation=new ScheduleOperationService();
ScheduleParams param = new ScheduleParams();
param.setBaseTime(LocalDateTime.of(2025, 11, 1, 0, 0, 0));
GlobalParam globalParam=new GlobalParam();
ScheduleOperation.redecode(chromosome,param.getBaseTime(), globalParam);
ScheduleOperation.redecode(chromosome,chromosome.getBaseTime(), globalParam);
return chromosome;
}
public Chromosome ChangeBaseTime(String SceneId,LocalDateTime BaseTime) {
Chromosome chromosome= _sceneService.loadChromosomeFromFile(SceneId);
if (chromosome == null || chromosome.getAllOperations() == null) {
return chromosome; // 直接返回,空值由上层处理
}
chromosome.setBaseTime(BaseTime);
ScheduleOperationService ScheduleOperation=new ScheduleOperationService();
GlobalParam globalParam=new GlobalParam();
ScheduleOperation.redecode(chromosome,chromosome.getBaseTime(), globalParam);
return chromosome;
}
......@@ -372,7 +385,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
ScheduleOperationService ScheduleOperation=new ScheduleOperationService();
ScheduleOperation.DelOperation(chromosome,opId, globalParam);
WriteScheduleSummary(chromosome);
// WriteScheduleSummary(chromosome);
_sceneService.saveChromosomeToFile(chromosome, SceneId);
return chromosome;
......@@ -389,11 +402,47 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
ScheduleOperationService ScheduleOperation=new ScheduleOperationService();
ScheduleOperation.LockOperation(chromosome,opId,isLocked, globalParam);
//WriteScheduleSummary(chromosome);
_sceneService.saveChromosomeToFile(chromosome, SceneId);
return chromosome;
}
public Chromosome SpiltOrder(String SceneId,String orderId,Double[] splitCounts) {
GlobalParam globalParam=new GlobalParam();
Chromosome chromosome= _sceneService.loadChromosomeFromFile(SceneId);
//this.baseTime=param.getBaseTime();
// WriteScheduleSummary(chromosome);
ScheduleOperationService ScheduleOperation=new ScheduleOperationService();
ScheduleOperation.SpiltOrder(chromosome,orderId,splitCounts, globalParam);
WriteScheduleSummary(chromosome);
_sceneService.saveChromosomeToFile(chromosome, SceneId);
return chromosome;
}
public Chromosome MergeOrder(String SceneId,String sourceorderId,String targetorderId) {
GlobalParam globalParam=new GlobalParam();
Chromosome chromosome= _sceneService.loadChromosomeFromFile(SceneId);
//this.baseTime=param.getBaseTime();
// WriteScheduleSummary(chromosome);
ScheduleOperationService ScheduleOperation=new ScheduleOperationService();
ScheduleOperation.MergeOrder(chromosome,sourceorderId,targetorderId, globalParam);
WriteScheduleSummary(chromosome);
// _sceneService.saveChromosomeToFile(chromosome, SceneId);
return chromosome;
}
......@@ -452,6 +501,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
// 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
Chromosome chromosomes =scheduler.Run(param,entrys);
chromosomes.setScenarioID(SceneId);
chromosomes.setBaseTime(param.getBaseTime());
chromosomes.setOperatRel(entryRel);
......
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