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;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
@RestController
......@@ -45,9 +46,9 @@ public class LanuchController {
}
@GetMapping("/schedule")
public Chromosome schedule(@RequestParam String sceneID) {
public Chromosome schedule(@RequestParam String sceneID,@RequestParam LocalDateTime baseTime) {
// 调用 PlanResultService 获取 ScheduleChromosome 列表
Chromosome scheduleChromosomes = planResultService.schedule(sceneID);
Chromosome scheduleChromosomes = planResultService.schedule(sceneID,baseTime);
// 提取所有场景ID
return scheduleChromosomes;
......
......@@ -19,5 +19,5 @@ public class OperationSequencingWeight {
/**
* 权重
*/
private int Weight;
private double Weight;
}
......@@ -55,7 +55,7 @@ public class Entry {
/**
* 基因编号
*/
public int Priority;
public double Priority;
/**
* 基因编号
*/
......
......@@ -18,6 +18,16 @@ public class GlobalParam {
/// </summary>
private boolean IsMultipleMachine = false;
/// <summary>
/// 是否启动设备日历
/// </summary>
private boolean IsUseCalendar = true;
/// <summary>
/// 是否启动设备日历
/// </summary>
private boolean IsCheckBom = true;
/// <summary>
/// 是否重叠
/// </summary>
......
......@@ -13,14 +13,19 @@ import java.util.List;
public class Order {
private int id;
private String OrderId;
private String orderCode;
private int productId;
private String materialId;
private String materialCode;
private String serie;
private Integer routingId;
private double quantity = 100; // 100个
private double sYQuantity;
private LocalDateTime startDate;
private LocalDateTime dueDate;
private LocalDateTime groupStartDate;
private LocalDateTime groupDueDate;
private LocalDateTime orderCompletion;
private LocalDateTime orderStart;
private double machineProcessingTime;
......
......@@ -14,8 +14,8 @@ import java.util.Random;
public class CommonCalculator {
public static List<OperationSequencingWeight> getOsw(List<Integer> os, List<Entry> allOperations) {
// 计算最大优先级并加1
int maxPriority = allOperations.stream()
.mapToInt(Entry::getPriority)
double maxPriority = allOperations.stream()
.mapToDouble(Entry::getPriority)
.max()
.orElse(0) + 1;
......@@ -39,10 +39,10 @@ public class CommonCalculator {
}
public static int getOsIndex(List<OperationSequencingWeight> indexWeights) {
Random rnd = new Random();
int totalWeight = indexWeights.stream()
.mapToInt(OperationSequencingWeight::getWeight)
double totalWeight = indexWeights.stream()
.mapToDouble(OperationSequencingWeight::getWeight)
.sum();
int randomWeight = rnd.nextInt(totalWeight);
int randomWeight = rnd.nextInt((int)totalWeight);
int cumulativeWeight = 0;
for (OperationSequencingWeight w : indexWeights) {
cumulativeWeight += w.getWeight();
......@@ -54,10 +54,10 @@ public class CommonCalculator {
}
public static int getOsIndex2(List<OperationSequencingWeight> weightedOs) {
Random rnd = new Random();
int totalWeight = weightedOs.stream()
.mapToInt(OperationSequencingWeight::getWeight)
double totalWeight = weightedOs.stream()
.mapToDouble(OperationSequencingWeight::getWeight)
.sum();
int randomWeight = rnd.nextInt(totalWeight);
int randomWeight = rnd.nextInt((int)totalWeight);
int cumulativeWeight = 0;
int selectedIndex = -1;
for (int i = 0; i < weightedOs.size(); i++) {
......
......@@ -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();
List<OperationSequencingWeight> indexWeights = CommonCalculator.getOsw(os, allOperations);
......
......@@ -154,7 +154,7 @@ int populationSize=param.getPopulationSize();
int currentOrderId = -1;
Map<Long, Double> machineLoad = new HashMap<>();
List<Integer> osp = new ArrayList<>();
int prevPriority = -1;
double prevPriority = -1;
for (GlobalOperationInfo globalOp : globalOpList) {
Entry op = globalOp.getOp();
......@@ -221,7 +221,7 @@ int populationSize=param.getPopulationSize();
List<Integer> os = new ArrayList<>();
Random rnd = new Random();
List<Integer> osp = new ArrayList<>();
int prevPriority = -1;
double prevPriority = -1;
for (GlobalOperationInfo globalOp : globalOpList) {
Entry op = globalOp.getOp();
......@@ -266,8 +266,8 @@ int populationSize=param.getPopulationSize();
}
Random rnd = new Random();
int maxPriority = allOperations.stream()
.mapToInt(Entry::getPriority)
double maxPriority = allOperations.stream()
.mapToDouble(Entry::getPriority)
.max()
.orElse(0) + 1;
......@@ -285,8 +285,8 @@ int populationSize=param.getPopulationSize();
// 按权重随机排序(权重越高,被选中的概率越大)
List<Integer> shuffled = new ArrayList<>();
while (!weightedOs.isEmpty()) {
int totalWeight = weightedOs.stream().mapToInt(WeightedGroup::getWeight).sum();
int randomWeight = rnd.nextInt(totalWeight);
double totalWeight = weightedOs.stream().mapToDouble(WeightedGroup::getWeight).sum();
int randomWeight = rnd.nextInt((int)totalWeight);
int cumulativeWeight = 0;
int selectedIndex = -1;
......@@ -309,9 +309,9 @@ int populationSize=param.getPopulationSize();
*/
private static class WeightedGroup {
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.weight = weight;
}
......@@ -320,7 +320,7 @@ int populationSize=param.getPopulationSize();
return groupId;
}
public int getWeight() {
public double getWeight() {
return weight;
}
}
......
......@@ -259,8 +259,9 @@ public class MaterialRequirementService {
List<ProdLaunchOrder> ProdLaunchOrders=new ArrayList<>();
ProdLaunchOrders.add(prodOrderMain);
List<Order> ProdLaunchOrders=new ArrayList<>();
ProdLaunchOrders.add(order);
Map<Integer, Object> list=_routingDataService.CreateEntry( sceneId, ProdEquipmentList, ProdLaunchOrders, routingDiscreteParams, ProdOrderProcesslist, processExecList,_entryRel );
......
......@@ -31,18 +31,39 @@ public class OrderSortService {
@PostConstruct
public void initializeFieldExtractors() {
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 -> {
// 直接返回LocalDate,处理null情况
return Optional.ofNullable(Order.getDueDate())
.map(LocalDateTime::toLocalDate)
.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("tardiness", Order::getTardiness);
registerFieldExtractor("canSplit", Order::isCanSplit);
registerFieldExtractor("canInterrupt", Order::isCanInterrupt);
registerFieldExtractor("materialCode", Order::getMaterialCode);
registerFieldExtractor("serie", Order::getSerie);
registerFieldExtractor("orderCode", Order::getOrderCode);
}
/**
......
......@@ -7,6 +7,7 @@ import com.aps.entity.Algorithm.IDAndChildID.NodeInfo;
import com.aps.entity.Algorithm.OperationDependency;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.MachineOption;
import com.aps.entity.basic.Order;
import com.aps.service.*;
import com.aps.service.plan.SceneService;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -45,7 +46,7 @@ public class RoutingDataService {
@Autowired
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<>();
List<ProdProcessExec> ProdProcessExecs= _prodProcessExecService.lambdaQuery()
......@@ -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<>();
List<String> soutceExecId = ProdOrderProcesss.stream()
......@@ -184,11 +185,12 @@ public class RoutingDataService {
entry.setRoutingDetailId(op.getRoutingDetailId());
entry.setTaskSeq(op.getTaskSeq());
entry.setRoutingDetailName(op.getRoutingDetailName());
ProdLaunchOrder order = ProdLaunchOrders.stream()
Order order = ProdLaunchOrders.stream()
.filter(t -> t.getOrderId().equals(op.getOrderId()))
.findFirst().orElse(null);
if (order != null) {
entry.setProductId(order.getMaterialId());
entry.setPriority(order.getActualPriority());
}
List<ProdEquipment> Equipments = ProdEquipments.stream()
.filter(t -> t.getExecId().equals(op.getExecId()))
......
......@@ -9,10 +9,14 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* 订单排序服务测试类
......@@ -35,12 +39,14 @@ class OrderSortServiceTest {
}
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd");
@Test
void testAssignPriority_WithMultipleConditions() {
// 创建多条件排序规则:先按dueDate,再按priority
OrderSortRule rule = createMultiConditionRule();
// 执行测试
orderSortService.assignPriority(testOrders, rule);
......@@ -69,7 +75,7 @@ class OrderSortServiceTest {
order.setProductId(100 + i);
order.setQuantity(50.0 * i);
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.setCanSplit(i % 2 == 0);
order.setCanInterrupt(i % 3 == 0);
......@@ -91,12 +97,7 @@ class OrderSortServiceTest {
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:按到期日
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