Commit cd421110 authored by Tong Li's avatar Tong Li

遗传算法-策略

parent e3f49a1d
package com.aps.common.util;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
/**
* 作者:佟礼
* 时间:2025-12-11
*/
public class DateGroupUtil {
/**
* 通用方法:为List中的对象按指定日期字段(dueDate)的5天跨度分组,生成groupDueDate字段的值
* @param list 待处理的对象列表
* @param DateFieldName 日期字段名(如"dueDate")
* @param groupDateFieldName 分组日期字段名(如"groupDueDate")
* @param <T> 泛型对象类型
* @throws Exception 反射/日期处理异常
*/
public static <T> void calculateGroupDueDate(
List<T> list,
String DateFieldName,
String groupDateFieldName,Integer dateDiff
) throws Exception {
if (list == null || list.isEmpty()) {
return;
}
// 1. 反射获取日期字段的Getter/Setter
Class<?> clazz = list.get(0).getClass();
Field dueDateField = clazz.getDeclaredField(DateFieldName);
Field groupDueDateField = clazz.getDeclaredField(groupDateFieldName);
dueDateField.setAccessible(true);
groupDueDateField.setAccessible(true);
// 2. 按dueDate排序(必须先排序,否则分组逻辑失效)
List<T> sortedList = new ArrayList<>(list);
sortedList.sort(Comparator.comparing(obj -> {
try {
return (LocalDateTime) dueDateField.get(obj);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}));
// 3. 分组逻辑:以第一个元素的dueDate为初始分组,后续每超过5天则更新分组日期
LocalDateTime currentGroupDate = (LocalDateTime) dueDateField.get(sortedList.get(0));
for (T obj : sortedList) {
LocalDateTime dueDate = (LocalDateTime) dueDateField.get(obj);
// 计算当前dueDate与当前分组日期的天数差
long daysDiff = ChronoUnit.DAYS.between(currentGroupDate, dueDate);
// 若超过5天,则将当前dueDate设为新的分组日期
if (daysDiff > dateDiff) {
currentGroupDate = dueDate;
}
// 设置groupDueDate
groupDueDateField.set(obj, currentGroupDate);
}
// 4. 将处理后的值写回原列表(保持原列表顺序,因为sortedList是副本)
for (T obj : list) {
LocalDateTime dueDate = (LocalDateTime) dueDateField.get(obj);
// 从sortedList中找到对应dueDate的对象,获取其groupDueDate
for (T sortedObj : sortedList) {
if (Objects.equals(dueDateField.get(sortedObj), dueDate)) {
groupDueDateField.set(obj, groupDueDateField.get(sortedObj));
break;
}
}
}
}
}
...@@ -11,6 +11,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; ...@@ -11,6 +11,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@RestController @RestController
...@@ -45,9 +46,9 @@ public class LanuchController { ...@@ -45,9 +46,9 @@ public class LanuchController {
} }
@GetMapping("/schedule") @GetMapping("/schedule")
public Chromosome schedule(@RequestParam String sceneID) { public Chromosome schedule(@RequestParam String sceneID,@RequestParam LocalDateTime baseTime) {
// 调用 PlanResultService 获取 ScheduleChromosome 列表 // 调用 PlanResultService 获取 ScheduleChromosome 列表
Chromosome scheduleChromosomes = planResultService.schedule(sceneID); Chromosome scheduleChromosomes = planResultService.schedule(sceneID,baseTime);
// 提取所有场景ID // 提取所有场景ID
return scheduleChromosomes; return scheduleChromosomes;
......
...@@ -19,5 +19,5 @@ public class OperationSequencingWeight { ...@@ -19,5 +19,5 @@ public class OperationSequencingWeight {
/** /**
* 权重 * 权重
*/ */
private int Weight; private double Weight;
} }
...@@ -55,7 +55,7 @@ public class Entry { ...@@ -55,7 +55,7 @@ public class Entry {
/** /**
* 基因编号 * 基因编号
*/ */
public int Priority; public double Priority;
/** /**
* 基因编号 * 基因编号
*/ */
......
...@@ -18,6 +18,16 @@ public class GlobalParam { ...@@ -18,6 +18,16 @@ public class GlobalParam {
/// </summary> /// </summary>
private boolean IsMultipleMachine = false; private boolean IsMultipleMachine = false;
/// <summary>
/// 是否启动设备日历
/// </summary>
private boolean IsUseCalendar = true;
/// <summary>
/// 是否启动设备日历
/// </summary>
private boolean IsCheckBom = true;
/// <summary> /// <summary>
/// 是否重叠 /// 是否重叠
/// </summary> /// </summary>
......
...@@ -13,14 +13,19 @@ import java.util.List; ...@@ -13,14 +13,19 @@ import java.util.List;
public class Order { public class Order {
private int id; private int id;
private String OrderId; private String OrderId;
private String orderCode;
private int productId; private int productId;
private String materialId; private String materialId;
private String materialCode;
private String serie;
private Integer routingId; private Integer routingId;
private double quantity = 100; // 100个 private double quantity = 100; // 100个
private double sYQuantity; private double sYQuantity;
private LocalDateTime startDate;
private LocalDateTime dueDate; private LocalDateTime dueDate;
private LocalDateTime groupStartDate;
private LocalDateTime groupDueDate;
private LocalDateTime orderCompletion; private LocalDateTime orderCompletion;
private LocalDateTime orderStart; private LocalDateTime orderStart;
private double machineProcessingTime; private double machineProcessingTime;
......
...@@ -14,8 +14,8 @@ import java.util.Random; ...@@ -14,8 +14,8 @@ import java.util.Random;
public class CommonCalculator { public class CommonCalculator {
public static List<OperationSequencingWeight> getOsw(List<Integer> os, List<Entry> allOperations) { public static List<OperationSequencingWeight> getOsw(List<Integer> os, List<Entry> allOperations) {
// 计算最大优先级并加1 // 计算最大优先级并加1
int maxPriority = allOperations.stream() double maxPriority = allOperations.stream()
.mapToInt(Entry::getPriority) .mapToDouble(Entry::getPriority)
.max() .max()
.orElse(0) + 1; .orElse(0) + 1;
...@@ -39,10 +39,10 @@ public class CommonCalculator { ...@@ -39,10 +39,10 @@ public class CommonCalculator {
} }
public static int getOsIndex(List<OperationSequencingWeight> indexWeights) { public static int getOsIndex(List<OperationSequencingWeight> indexWeights) {
Random rnd = new Random(); Random rnd = new Random();
int totalWeight = indexWeights.stream() double totalWeight = indexWeights.stream()
.mapToInt(OperationSequencingWeight::getWeight) .mapToDouble(OperationSequencingWeight::getWeight)
.sum(); .sum();
int randomWeight = rnd.nextInt(totalWeight); int randomWeight = rnd.nextInt((int)totalWeight);
int cumulativeWeight = 0; int cumulativeWeight = 0;
for (OperationSequencingWeight w : indexWeights) { for (OperationSequencingWeight w : indexWeights) {
cumulativeWeight += w.getWeight(); cumulativeWeight += w.getWeight();
...@@ -54,10 +54,10 @@ public class CommonCalculator { ...@@ -54,10 +54,10 @@ public class CommonCalculator {
} }
public static int getOsIndex2(List<OperationSequencingWeight> weightedOs) { public static int getOsIndex2(List<OperationSequencingWeight> weightedOs) {
Random rnd = new Random(); Random rnd = new Random();
int totalWeight = weightedOs.stream() double totalWeight = weightedOs.stream()
.mapToInt(OperationSequencingWeight::getWeight) .mapToDouble(OperationSequencingWeight::getWeight)
.sum(); .sum();
int randomWeight = rnd.nextInt(totalWeight); int randomWeight = rnd.nextInt((int)totalWeight);
int cumulativeWeight = 0; int cumulativeWeight = 0;
int selectedIndex = -1; int selectedIndex = -1;
for (int i = 0; i < weightedOs.size(); i++) { for (int i = 0; i < weightedOs.size(); i++) {
......
...@@ -235,7 +235,7 @@ public class GeneticOperations { ...@@ -235,7 +235,7 @@ public class GeneticOperations {
/** /**
* 优先选择高优先级工序的索引(用于变异) * 优先选择高优先级工序的索引(用于变异)
*/ */
private OperationSequencingWeight selectHighPriorityIndex(List<Integer> os, int weight) { private OperationSequencingWeight selectHighPriorityIndex(List<Integer> os, double weight) {
Random rnd = new Random(); Random rnd = new Random();
List<OperationSequencingWeight> indexWeights = CommonCalculator.getOsw(os, allOperations); List<OperationSequencingWeight> indexWeights = CommonCalculator.getOsw(os, allOperations);
......
...@@ -154,7 +154,7 @@ int populationSize=param.getPopulationSize(); ...@@ -154,7 +154,7 @@ int populationSize=param.getPopulationSize();
int currentOrderId = -1; int currentOrderId = -1;
Map<Long, Double> machineLoad = new HashMap<>(); Map<Long, Double> machineLoad = new HashMap<>();
List<Integer> osp = new ArrayList<>(); List<Integer> osp = new ArrayList<>();
int prevPriority = -1; double prevPriority = -1;
for (GlobalOperationInfo globalOp : globalOpList) { for (GlobalOperationInfo globalOp : globalOpList) {
Entry op = globalOp.getOp(); Entry op = globalOp.getOp();
...@@ -221,7 +221,7 @@ int populationSize=param.getPopulationSize(); ...@@ -221,7 +221,7 @@ int populationSize=param.getPopulationSize();
List<Integer> os = new ArrayList<>(); List<Integer> os = new ArrayList<>();
Random rnd = new Random(); Random rnd = new Random();
List<Integer> osp = new ArrayList<>(); List<Integer> osp = new ArrayList<>();
int prevPriority = -1; double prevPriority = -1;
for (GlobalOperationInfo globalOp : globalOpList) { for (GlobalOperationInfo globalOp : globalOpList) {
Entry op = globalOp.getOp(); Entry op = globalOp.getOp();
...@@ -266,8 +266,8 @@ int populationSize=param.getPopulationSize(); ...@@ -266,8 +266,8 @@ int populationSize=param.getPopulationSize();
} }
Random rnd = new Random(); Random rnd = new Random();
int maxPriority = allOperations.stream() double maxPriority = allOperations.stream()
.mapToInt(Entry::getPriority) .mapToDouble(Entry::getPriority)
.max() .max()
.orElse(0) + 1; .orElse(0) + 1;
...@@ -285,8 +285,8 @@ int populationSize=param.getPopulationSize(); ...@@ -285,8 +285,8 @@ int populationSize=param.getPopulationSize();
// 按权重随机排序(权重越高,被选中的概率越大) // 按权重随机排序(权重越高,被选中的概率越大)
List<Integer> shuffled = new ArrayList<>(); List<Integer> shuffled = new ArrayList<>();
while (!weightedOs.isEmpty()) { while (!weightedOs.isEmpty()) {
int totalWeight = weightedOs.stream().mapToInt(WeightedGroup::getWeight).sum(); double totalWeight = weightedOs.stream().mapToDouble(WeightedGroup::getWeight).sum();
int randomWeight = rnd.nextInt(totalWeight); int randomWeight = rnd.nextInt((int)totalWeight);
int cumulativeWeight = 0; int cumulativeWeight = 0;
int selectedIndex = -1; int selectedIndex = -1;
...@@ -309,9 +309,9 @@ int populationSize=param.getPopulationSize(); ...@@ -309,9 +309,9 @@ int populationSize=param.getPopulationSize();
*/ */
private static class WeightedGroup { private static class WeightedGroup {
private final int groupId; private final int groupId;
private final int weight; private final double weight;
public WeightedGroup(int groupId, int weight) { public WeightedGroup(int groupId, double weight) {
this.groupId = groupId; this.groupId = groupId;
this.weight = weight; this.weight = weight;
} }
...@@ -320,7 +320,7 @@ int populationSize=param.getPopulationSize(); ...@@ -320,7 +320,7 @@ int populationSize=param.getPopulationSize();
return groupId; return groupId;
} }
public int getWeight() { public double getWeight() {
return weight; return weight;
} }
} }
......
...@@ -259,8 +259,9 @@ public class MaterialRequirementService { ...@@ -259,8 +259,9 @@ public class MaterialRequirementService {
List<ProdLaunchOrder> ProdLaunchOrders=new ArrayList<>(); List<Order> ProdLaunchOrders=new ArrayList<>();
ProdLaunchOrders.add(prodOrderMain); ProdLaunchOrders.add(order);
Map<Integer, Object> list=_routingDataService.CreateEntry( sceneId, ProdEquipmentList, ProdLaunchOrders, routingDiscreteParams, ProdOrderProcesslist, processExecList,_entryRel ); Map<Integer, Object> list=_routingDataService.CreateEntry( sceneId, ProdEquipmentList, ProdLaunchOrders, routingDiscreteParams, ProdOrderProcesslist, processExecList,_entryRel );
......
...@@ -31,18 +31,39 @@ public class OrderSortService { ...@@ -31,18 +31,39 @@ public class OrderSortService {
@PostConstruct @PostConstruct
public void initializeFieldExtractors() { public void initializeFieldExtractors() {
registerFieldExtractor("id", Order::getId); registerFieldExtractor("id", Order::getId);
registerFieldExtractor("productId", Order::getProductId);
registerFieldExtractor("quantity", Order::getQuantity);
registerFieldExtractor("startDate", Order -> {
// 直接返回LocalDate,处理null情况
return Optional.ofNullable(Order.getStartDate())
.map(LocalDateTime::toLocalDate)
.orElse(null);
});
registerFieldExtractor("dueDate", Order -> { registerFieldExtractor("dueDate", Order -> {
// 直接返回LocalDate,处理null情况 // 直接返回LocalDate,处理null情况
return Optional.ofNullable(Order.getDueDate()) return Optional.ofNullable(Order.getDueDate())
.map(LocalDateTime::toLocalDate) .map(LocalDateTime::toLocalDate)
.orElse(null); .orElse(null);
}); });
registerFieldExtractor("groupStartDate", Order -> {
// 直接返回LocalDate,处理null情况
return Optional.ofNullable(Order.getGroupStartDate())
.map(LocalDateTime::toLocalDate)
.orElse(null);
});
registerFieldExtractor("groupDueDate", Order -> {
// 直接返回LocalDate,处理null情况
return Optional.ofNullable(Order.getGroupDueDate())
.map(LocalDateTime::toLocalDate)
.orElse(null);
});
registerFieldExtractor("priority", Order::getPriority); registerFieldExtractor("priority", Order::getPriority);
registerFieldExtractor("tardiness", Order::getTardiness); registerFieldExtractor("materialCode", Order::getMaterialCode);
registerFieldExtractor("canSplit", Order::isCanSplit); registerFieldExtractor("serie", Order::getSerie);
registerFieldExtractor("canInterrupt", Order::isCanInterrupt); registerFieldExtractor("orderCode", Order::getOrderCode);
} }
/** /**
......
...@@ -7,6 +7,7 @@ import com.aps.entity.Algorithm.IDAndChildID.NodeInfo; ...@@ -7,6 +7,7 @@ import com.aps.entity.Algorithm.IDAndChildID.NodeInfo;
import com.aps.entity.Algorithm.OperationDependency; import com.aps.entity.Algorithm.OperationDependency;
import com.aps.entity.basic.Entry; import com.aps.entity.basic.Entry;
import com.aps.entity.basic.MachineOption; import com.aps.entity.basic.MachineOption;
import com.aps.entity.basic.Order;
import com.aps.service.*; import com.aps.service.*;
import com.aps.service.plan.SceneService; import com.aps.service.plan.SceneService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -45,7 +46,7 @@ public class RoutingDataService { ...@@ -45,7 +46,7 @@ public class RoutingDataService {
@Autowired @Autowired
private DiscreteParameterMatrixService _discreteParameterMatrixService; private DiscreteParameterMatrixService _discreteParameterMatrixService;
public Map<Integer, Object> InitEntrys(String SceneId, List<ProdEquipment> ProdEquipments, List<ProdLaunchOrder> ProdLaunchOrders) public Map<Integer, Object> InitEntrys(String SceneId, List<ProdEquipment> ProdEquipments, List<Order> ProdLaunchOrders)
{ {
Map<Integer, Object> list=new HashMap<>(); Map<Integer, Object> list=new HashMap<>();
List<ProdProcessExec> ProdProcessExecs= _prodProcessExecService.lambdaQuery() List<ProdProcessExec> ProdProcessExecs= _prodProcessExecService.lambdaQuery()
...@@ -74,7 +75,7 @@ public class RoutingDataService { ...@@ -74,7 +75,7 @@ public class RoutingDataService {
} }
public Map<Integer, Object> CreateEntry(String SceneId, List<ProdEquipment> ProdEquipments, List<ProdLaunchOrder> ProdLaunchOrders,List<RoutingDiscreteParam> routingDiscreteParams,List<ProdOrderProcess> ProdOrderProcesss,List<ProdProcessExec> ProdProcessExecs,List<GroupResult> existingResults) public Map<Integer, Object> CreateEntry(String SceneId, List<ProdEquipment> ProdEquipments, List<Order> ProdLaunchOrders, List<RoutingDiscreteParam> routingDiscreteParams, List<ProdOrderProcess> ProdOrderProcesss, List<ProdProcessExec> ProdProcessExecs, List<GroupResult> existingResults)
{ {
Map<Integer, Object> list=new HashMap<>(); Map<Integer, Object> list=new HashMap<>();
List<String> soutceExecId = ProdOrderProcesss.stream() List<String> soutceExecId = ProdOrderProcesss.stream()
...@@ -184,11 +185,12 @@ public class RoutingDataService { ...@@ -184,11 +185,12 @@ public class RoutingDataService {
entry.setRoutingDetailId(op.getRoutingDetailId()); entry.setRoutingDetailId(op.getRoutingDetailId());
entry.setTaskSeq(op.getTaskSeq()); entry.setTaskSeq(op.getTaskSeq());
entry.setRoutingDetailName(op.getRoutingDetailName()); entry.setRoutingDetailName(op.getRoutingDetailName());
ProdLaunchOrder order = ProdLaunchOrders.stream() Order order = ProdLaunchOrders.stream()
.filter(t -> t.getOrderId().equals(op.getOrderId())) .filter(t -> t.getOrderId().equals(op.getOrderId()))
.findFirst().orElse(null); .findFirst().orElse(null);
if (order != null) { if (order != null) {
entry.setProductId(order.getMaterialId()); entry.setProductId(order.getMaterialId());
entry.setPriority(order.getActualPriority());
} }
List<ProdEquipment> Equipments = ProdEquipments.stream() List<ProdEquipment> Equipments = ProdEquipments.stream()
.filter(t -> t.getExecId().equals(op.getExecId())) .filter(t -> t.getExecId().equals(op.getExecId()))
......
...@@ -9,10 +9,14 @@ import org.junit.jupiter.api.extension.ExtendWith; ...@@ -9,10 +9,14 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* 订单排序服务测试类 * 订单排序服务测试类
...@@ -35,12 +39,14 @@ class OrderSortServiceTest { ...@@ -35,12 +39,14 @@ class OrderSortServiceTest {
} }
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd");
@Test @Test
void testAssignPriority_WithMultipleConditions() { void testAssignPriority_WithMultipleConditions() {
// 创建多条件排序规则:先按dueDate,再按priority // 创建多条件排序规则:先按dueDate,再按priority
OrderSortRule rule = createMultiConditionRule(); OrderSortRule rule = createMultiConditionRule();
// 执行测试 // 执行测试
orderSortService.assignPriority(testOrders, rule); orderSortService.assignPriority(testOrders, rule);
...@@ -69,7 +75,7 @@ class OrderSortServiceTest { ...@@ -69,7 +75,7 @@ class OrderSortServiceTest {
order.setProductId(100 + i); order.setProductId(100 + i);
order.setQuantity(50.0 * i); order.setQuantity(50.0 * i);
order.setPriority(15 - i); // 优先级:5,4,3,2,1(倒序) order.setPriority(15 - i); // 优先级:5,4,3,2,1(倒序)
//order.setDueDate(OffsetDateTime.now().plusDays(i)); // 到期日递增 order.setDueDate(LocalDateTime.now().plusDays(i)); // 到期日递增
order.setTardiness(i * 0.5); order.setTardiness(i * 0.5);
order.setCanSplit(i % 2 == 0); order.setCanSplit(i % 2 == 0);
order.setCanInterrupt(i % 3 == 0); order.setCanInterrupt(i % 3 == 0);
...@@ -91,12 +97,7 @@ class OrderSortServiceTest { ...@@ -91,12 +97,7 @@ class OrderSortServiceTest {
List<OrderSortRule.SortCondition> conditions = new ArrayList<>(); List<OrderSortRule.SortCondition> conditions = new ArrayList<>();
// 条件1:按是否可拆分
OrderSortRule.SortCondition condition1 = new OrderSortRule.SortCondition();
condition1.setSequence(1);
condition1.setFieldName("canSplit");
condition1.setReverse(true); // 可拆分的在前
conditions.add(condition1);
// 条件2:按到期日 // 条件2:按到期日
OrderSortRule.SortCondition condition2 = new OrderSortRule.SortCondition(); OrderSortRule.SortCondition condition2 = new OrderSortRule.SortCondition();
......
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