Commit 638640d4 authored by Tong Li's avatar Tong Li

遗传算法-bom

parent f4f283b7
package com.aps.entity.Algorithm;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.Machine;
import com.aps.entity.basic.Order;
import java.util.List;
......@@ -12,9 +14,15 @@ public class BOMBuildResult {
private List<OrderMaterialRequirement> materialRequirements;
private List<Order> childOrders;
public BOMBuildResult(List<OrderMaterialRequirement> materialRequirements, List<Order> childOrders) {
private List<Entry> newentrys;
private List<Machine> newMachines;
public BOMBuildResult(List<OrderMaterialRequirement> materialRequirements, List<Order> childOrders,List<Entry> newentrys,List<Machine> newMachines) {
this.materialRequirements = materialRequirements;
this.childOrders = childOrders;
this.newentrys=newentrys;
this.newMachines=newMachines;
}
public List<OrderMaterialRequirement> getMaterialRequirements() {
......@@ -24,4 +32,12 @@ public class BOMBuildResult {
public List<Order> getChildOrders() {
return childOrders;
}
public List<Entry> getNewEntrys() {
return newentrys;
}
public List<Machine> getNewMachines() {
return newMachines;
}
}
......@@ -59,6 +59,9 @@ public class Chromosome {
private List<Entry> allOperations;
private List<Order> orders;
private List<Machine> InitMachines;
private List<OrderMaterialRequirement> orderMaterials;
private List<GroupResult> OperatRel;
private double[] Objectives ; // 多目标值:[Makespan, TotalFlowTime, TotalChangeover, LoadStd, Delay]
......
......@@ -5,6 +5,7 @@ import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
......@@ -17,7 +18,12 @@ public class OrderMaterialRequirement {
private int operationId;
private String childorderId;
private String materialId;
private MaterialType materialType;
private String materialTypeName;
/**
* 物料类型
*/
private Long materialType;
/**
* 需求总数
......@@ -72,5 +78,10 @@ public class OrderMaterialRequirement {
/**
* 创建或使用的半成品订单ID
*/
private List<String> productOrderID;
private List<Integer> productOrderID=new ArrayList<>();
/**
* 检验周期
*/
private Long CkeckLeadTime;
}
......@@ -88,7 +88,7 @@ public class MaterialInfo implements Serializable {
private Long inspectDuration;
@TableField("purchase_duration")
private Long purchaseDuration;
private int purchaseDuration;
@TableField("first_lot")
private String firstLot;
......
......@@ -22,7 +22,7 @@ private String materialVersion;
private Long storeId;
private String storeCode;
private String storeName;
private BigDecimal total;
private double total;
private Integer measureUnit;
private BigDecimal totalLock;
private BigDecimal cost;
......
......@@ -13,5 +13,5 @@ public class StrategyScheduling {
private String content;
private int amplitude;
private boolean value;
private int sort;
}
\ No newline at end of file
......@@ -27,10 +27,12 @@ public class Entry {
*/
public int GroupId ;
public String OrderId ;
/**
* 原订单ID
*/
public String OrderId ;
public String SceneId ;
private Integer routingId;
private Long routingDetailId;
private Long taskSeq;
......@@ -107,7 +109,7 @@ public class Entry {
/// <summary>
/// 当前工序依赖的前置工序ID(半成品工序→成品工序)
/// </summary>
public List<String> DependentOnOrderIds = new ArrayList<>();
public List<Integer> DependentOnOrderIds =new ArrayList<>();
......
......@@ -16,6 +16,11 @@ public class Material {
*/
private String Id;
/**
* 物料名称
*/
private String code;
/**
* 物料名称
*/
......@@ -41,7 +46,15 @@ public class Material {
/**
* 物料类型
*/
private MaterialType MaterialType;
private Long MaterialType;
private String materialTypeName;
/**
* 检验周期
*/
private Long CkeckLeadTime;
@Override
public String toString() {
return "Material{" +
......
......@@ -40,7 +40,7 @@ public class Order {
private double actualPriority;
private String mainId;
/*使用这个半成品的成品工单*/
public List<String> FinishOrderId ;
public List<Integer> FinishOrderId ;
private double delayHours;//延迟时间
}
\ No newline at end of file
......@@ -6,6 +6,7 @@ import com.aps.entity.Algorithm.*;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.basic.*;
import com.aps.service.plan.MachineSchedulerService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
import java.util.stream.Collectors;
......@@ -14,6 +15,7 @@ import java.util.stream.Collectors;
* 作者:佟礼
* 时间:2025-11-21
*/
public class GeneticAlgorithm {
private final Random rnd = new Random();
private final List<Machine> machines;
......@@ -29,14 +31,21 @@ public class GeneticAlgorithm {
private ObjectiveWeights _objectiveWeights = new ObjectiveWeights();
private MaterialRequirementService materialRequirementService;
private List<OrderMaterialRequirement> orderMaterials;
public GeneticAlgorithm(GlobalParam globalParam,List<Machine> machines, List<Order> orders,
List<Material> materials, MachineSchedulerService machineScheduler,List<GroupResult> entryRel) {
List<Material> materials, MachineSchedulerService machineScheduler,List<GroupResult> entryRel,MaterialRequirementService _materialRequirementService) {
this.machines = machines;
this.orders = orders;
this.materials = materials;
this.machineScheduler = machineScheduler;
_GlobalParam=globalParam;
_entryRel=entryRel;
materialRequirementService=_materialRequirementService;
}
public void Init(double[] customWeights, boolean pureNSGAIIMode) {
......@@ -50,12 +59,14 @@ public class GeneticAlgorithm {
}
public Chromosome Run(ScheduleParams param, List<Entry> allOperations) {
if(_GlobalParam.isIsCheckBom()) {
materialRequirementService.init(materials, orders, allOperations, _entryRel, machineScheduler, machines);
orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(param.getBaseTime());
}
System.out.println("开始");
Initialization initialization = new Initialization(_GlobalParam,allOperations);
Initialization initialization = new Initialization(_GlobalParam,allOperations,orders);
GeneticOperations geneticOps = new GeneticOperations(_GlobalParam,allOperations,param);
......@@ -174,6 +185,7 @@ public class GeneticAlgorithm {
best.setBaseTime(param.getBaseTime());
best.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines));
best.setOrders(orders);
best.setOrderMaterials(orderMaterials);
best.setOperatRel(_entryRel);
// 步骤3:返回最优解
return best;
......@@ -181,20 +193,10 @@ public class GeneticAlgorithm {
}
private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population)
{
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler);
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,orderMaterials);
// population.parallelStream().forEach(chromosome -> {
// chromosome.setResult(new ArrayList<>());
//
// // 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
//
// decoder.decodeChromosomeWithCache(chromosome, globalOpList, allOperations);
// chromosome.setFitness(fitnessCalc.calculateFitness(chromosome));
// });
if(population!=null&&population.size()>0) {
population.forEach(chromosome -> {
population.parallelStream().forEach(chromosome -> {
chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
......
......@@ -4,6 +4,7 @@ import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.entity.DiscreteParameterDuration;
import com.aps.entity.ProdEquipment;
import com.aps.entity.Routingsupporting;
import com.aps.entity.basic.*;
import com.aps.service.DiscreteParameterDurationService;
import com.aps.service.DiscreteParameterMatrixService;
......@@ -11,6 +12,7 @@ import com.aps.service.plan.MachineSchedulerService;
import org.springframework.http.server.DelegatingServerHttpResponse;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
......@@ -37,18 +39,12 @@ public class GeneticDecoder {
private GlobalParam _globalParam;
private MachineCalculator machineCalculator;
private DiscreteParameterMatrixService discreteParameterMatrixService;
// 添加静态实例引用
private static DiscreteParameterMatrixService staticDiscreteParameterMatrixService;
private List<OrderMaterialRequirement> orderMaterials;
// 设置静态服务实例的方法
public static void setDiscreteParameterMatrixService(DiscreteParameterMatrixService service) {
staticDiscreteParameterMatrixService = service;
}
private DiscreteParameterMatrixService discreteParameterMatrixService;
public GeneticDecoder(GlobalParam globalParam,LocalDateTime baseTime, List<Machine> machines, List<Order> orders,
List<Material> materials, MachineSchedulerService machineScheduler) {
List<Material> materials, MachineSchedulerService machineScheduler, List<OrderMaterialRequirement> _orderMaterials) {
this.baseTime = baseTime;
this.machines = machines;
this.orders = orders;
......@@ -57,9 +53,14 @@ public class GeneticDecoder {
this.machineScheduler = machineScheduler;
_globalParam=globalParam;
machineCalculator=new MachineCalculator(baseTime,machines,machineScheduler);
orderMaterials=_orderMaterials;
// this.orderMaxID = orders.stream().mapToInt(Order::getId).max().orElse(0);
}
public Chromosome decodeChromosomeWithCache(Chromosome chromosome) {
_allOperations=chromosome.getAllOperations();
if(_globalParam.isIsCheckBom()) {
CreateNewOpSequence(chromosome);
}
// 1. 创建缓存键
String cacheKey = createCacheKey(chromosome);
......@@ -111,6 +112,97 @@ public class GeneticDecoder {
}
return chromosome;
}
private void CreateNewOpSequence(Chromosome chromosome)
{
List<Integer> finishedOrder = chromosome.getOrders().stream()
.filter(t-> t.getFinishOrderId()==null||t.getFinishOrderId().size()==0)
.map(Order::getId)
.distinct()
.collect(Collectors.toList());
List<Integer> oldSequence=chromosome.getOperationSequencing();
List<Integer> finalSequence = new ArrayList<>();
// 初始化两个结果数组
List<Integer> pfSequence = new ArrayList<>(); // 包含1/2的元素
Map<Integer, List<Integer>> sfSequence = new HashMap<>(); // 不包含1/2的元素
// 遍历原数组分类
for (int num : oldSequence) {
if (finishedOrder.contains(num)) {
pfSequence.add(num);
} else {
if(sfSequence.containsKey(num))
{
sfSequence.get(num).add(num);
}else {
sfSequence.computeIfAbsent(num, k -> new ArrayList<>()).add(num);
}
}
}
Map<Integer, Integer> orderProcessCounter=new HashMap<>();
for (int num : pfSequence) {
int scheduledCount=1;
if(orderProcessCounter.containsKey(num))
{
scheduledCount = orderProcessCounter.get(num)+1;
}
int scheduledCount1=scheduledCount;
Entry entry=_allOperations.stream()
.filter(t->t.GroupId==num&&t.getSequence()==scheduledCount1)
.findFirst().orElse(null);
if(entry!=null&&entry.getDependentOnOrderIds().size()>0)
{
for (int order : entry.getDependentOnOrderIds()) {
for (int num1 : sfSequence.get(order)){
InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence);
}
}
finalSequence.add(num);
}else {
finalSequence.add(num);
}
orderProcessCounter.put(num, scheduledCount);
}
}
private void InsertSimSequence(Map<Integer, Integer> orderProcessCounter,int orderid,List<Integer> finalSequence,Map<Integer, List<Integer>> sfSequence)
{
Random rnd = new Random();
int scheduledCount=1;
if(orderProcessCounter.containsKey(orderid))
{
scheduledCount = orderProcessCounter.get(orderid)+1;
}
int scheduledCount1=scheduledCount;
Entry entry=_allOperations.stream()
.filter(t->t.GroupId==orderid&&t.getSequence()==scheduledCount1)
.findFirst().orElse(null);
if(entry!=null&&entry.getDependentOnOrderIds().size()>0) {
for (int order : entry.getDependentOnOrderIds()) {
for (int num1 : sfSequence.get(order)) {
InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence);
}
}
finalSequence.add(orderid);
}else {
int insertPos = Math.max(0, finalSequence.size() - rnd.nextInt(2));
finalSequence.add(insertPos,orderid);
}
orderProcessCounter.put(orderid, scheduledCount);
}
/**
* 染色体解码为调度方案
*/
......@@ -224,14 +316,17 @@ public class GeneticDecoder {
// 上个离散参数
// String lastDiscreteParameter = machineState.get(machineId);
int bomtime = 0;
int bomtime = getOperationBOMTime(currentOp,chromosome);
prevtime = Math.max(prevtime, bomtime);
Machine machine = chromosome.getMachines().stream()
.filter(m -> m.getId() == machineId)
.findFirst()
.orElse(null);
if(machine==null)
{
int i=1+2;
}
// int changeoverTime =0; //(lastDiscreteParameter.isEmpty() ||
// lastDiscreteParameter.equals(currentOp.getDiscreteParameter())) ? 0 : 0;
......@@ -263,7 +358,8 @@ public class GeneticDecoder {
int preTime = machineOption.getPreTime();
int setupTime = calculateSetupTime(chromosome.getResult(), operation, machine, machineOption);
System.out.println(" 处理时间: " + processingTime + ", 后处理: " + teardownTime +
", 前处理: " + preTime + ", 换型: " + setupTime);
// 确定任务的最早开始时间(基于前一道工序的完整结束时间,包含后处理)
......@@ -292,25 +388,32 @@ public class GeneticDecoder {
machineAvailableTime += setupTime;
// 平滑模式:换型在非工作时间进行,不额外占用设备时间
System.out.println(" 平滑模式换型:在非工作时间进行,设备可用时间不变");
} else {
// 标准模式:换型需要额外占用设备时间
machineAvailableTime += setupTime;
System.out.println(" 标准模式换型:需要额外占用设备 " + setupTime + " 分钟");
}
}
earliestStartTime = Math.max(earliestStartTime, machineAvailableTime);
}
System.out.println(" 最终最早开始时间: " + earliestStartTime +
" (前序工序结束含后处理: " + prevOperationEndTime + ", 设备可用: " +
(lastGeneOnMachine != null ? lastGeneOnMachine.getEndTime() : 0) +
", 换型: " + setupTime + ")");
// 根据换型模式调整处理时间
// int processingTimeForScheduling;
if (_globalParam.is_smoothSetup()) {
// 平滑模式:只需要安排主处理时间
// processingTimeForScheduling = processingTimeTotal;
System.out.println(" 平滑模式:安排主处理时间 " + processingTime + " 分钟");
} else {
// 标准模式:需要安排主处理时间+换型时间
processingTimeTotal = processingTimeTotal + setupTime;
System.out.println(" 标准模式:安排主处理+" + setupTime + "分钟换型=" + processingTimeTotal + "分钟");
}
GAScheduleResult existingResult = chromosome.getResultOld().stream().filter(r-> r.getOperationId() == operation.Id).findFirst().orElse(null);
......@@ -347,6 +450,7 @@ public class GeneticDecoder {
.orElse(null);
if (conflictingGene != null) {
System.out.println(" ⚠️ 检测到时间冲突,重新调度");
int conflictSetupStartTime = conflictingGene.getEndTime();
int conflictSetupTime = calculateSetupTimeForConflict(chromosome.getResult(),operation , machine, machineOption, conflictingGene);
int conflictEarliestStartTime = conflictSetupStartTime + conflictSetupTime;
......@@ -365,6 +469,7 @@ public class GeneticDecoder {
.mapToInt(ScheduleResultDetail::getEndTime)
.max()
.orElse(0);
System.out.println(" 重新安排时间: " + ConvertTime(startTime) + " - " + ConvertTime(endTime));
}
}
......@@ -383,7 +488,6 @@ public class GeneticDecoder {
result.setOneTime(processingTime);
result.setQuantity(operation.getQuantity());
result.setTeardownTime(teardownTime);
if(existingResult!=null) {
result.setDesignatedStartTime(existingResult.getDesignatedStartTime());
......@@ -465,6 +569,54 @@ public class GeneticDecoder {
}
private int getOperationBOMTime(Entry currentOp, Chromosome chromosome) {
if(!_globalParam.isIsCheckBom())
{
return 0;
}
List<OrderMaterialRequirement> opboms = orderMaterials.stream()
.filter(t -> t.getOrderId().equals(currentOp.getOrderId()) && t.getOperationId() == currentOp.getId())
.collect(Collectors.toList());
int rawTime = 0, sfTime = 0;
if (opboms != null && !opboms.isEmpty()) {
// 计算RawTime
Optional<LocalDateTime> rawDateOpt = opboms.stream()
.filter(t -> t.getMaterialTypeName().equals("MP") )
.map(OrderMaterialRequirement::getUseTime)
.max(LocalDateTime::compareTo);
if (rawDateOpt.isPresent()) {
rawTime = (int) Duration.between(baseTime, rawDateOpt.get()).getSeconds();
}
// 计算SFTime
List<OrderMaterialRequirement> sfBoms = opboms.stream()
.filter(t -> !t.getMaterialTypeName().equals("MP")
&& t.getProductOrderID() != null && !t.getProductOrderID().isEmpty())
.collect(Collectors.toList());
if (!sfBoms.isEmpty()) {
for (OrderMaterialRequirement sf : sfBoms) {
for (int orderid : sf.getProductOrderID()) {
int sfTime1 = 0;
List<GAScheduleResult> result=chromosome.getResult();
List<GAScheduleResult> oe = result.stream()
.filter(t -> t.getGroupId() == orderid)
.collect(Collectors.toList());
if (!oe.isEmpty()) {
sfTime1 = oe.stream().mapToInt(GAScheduleResult::getEndTime).max().orElse(0)+(int) (sf.getCkeckLeadTime()*24*60);
sf.setUseTime(baseTime.plusSeconds(sfTime1));
}
sfTime = Math.max(sfTime, sfTime1);
}
}
}
}
return Math.max(rawTime, sfTime);
}
/**
* 计算在上一工序生产后什么时间可以开工
* @param details 工序详情列表
......@@ -655,6 +807,7 @@ public class GeneticDecoder {
.orElse(null);
if (lastGeneOnMachine == null) {
System.out.println("设备 " + machine.getId() + " 上无历史任务,换型时间为0");
return 0;
}
Entry prev= _allOperations.stream().
......@@ -666,15 +819,20 @@ public class GeneticDecoder {
//离散参数
// prev.getDiscreteParameter()
if (staticDiscreteParameterMatrixService != null) {
setupTime = (int) staticDiscreteParameterMatrixService.getDiscreteParameterMatrixValue(prev, operation);
} else {
// 添加兜底处理,避免空指针异常
setupTime = 0;
}
setupTime = (prev.getProductId() != operation.getProductId())
? (int) discreteParameterMatrixService.getDiscreteParameterMatrixValue(prev, operation)
: 0;
if (setupTime > 0) {
System.out.println("设备 " + machine.getId() + " 需要换型,因为产品从 " + prev.getProductId() + " 变更为 " + operation.getProductId());
}
}
return setupTime;
}
......@@ -688,7 +846,9 @@ public class GeneticDecoder {
setupTime = 0;
}
if (setupTime > 0) {
System.out.println("设备 " + machine.getId() + " 需要换型,因为产品从 " + conflictingGene.getProductId() + " 变更为 " + operation.getProductId());
}
return setupTime;
}
......
......@@ -6,6 +6,7 @@ import com.aps.entity.Algorithm.ScheduleParams;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import com.aps.entity.basic.MachineOption;
import com.aps.entity.basic.Order;
import java.util.*;
import java.util.stream.Collectors;
......@@ -19,9 +20,12 @@ public class Initialization {
private static List<Entry> allOperations;
private static GlobalParam _globalParam;
public Initialization(GlobalParam globalParam,List<Entry> allOperations) {
private static List<Order> orders;
public Initialization(GlobalParam globalParam,List<Entry> allOperations,List<Order> _orders) {
Initialization.allOperations = allOperations;
_globalParam= globalParam;
orders=_orders;
}
/**
* 预生成全局工序列表(按“订单0→订单1→…+订单内工序1→2→…”排序,分配GlobalOpId)
......@@ -44,32 +48,36 @@ public class Initialization {
* 生成初始种群
*/
public List<Chromosome> generateInitialPopulation(ScheduleParams param, List<GlobalOperationInfo> globalOpList) {
List<Chromosome> population = new ArrayList<>();
// 按比例生成不同类型个体(GS:40%, LS:40%, RS:20%)
int gsCount = (int) (param.getPopulationSize() * param.getGsRatio());
int lsCount = gsCount + (int) (param.getPopulationSize() * param.getLsRatio());
int lsCount =gsCount+ (int) (param.getPopulationSize() * param.getLsRatio());
int rsCount = param.getPopulationSize() - gsCount - lsCount;
int populationSize = param.getPopulationSize();
// 使用并行流生成所有染色体,然后收集到列表中,避免并发修改ArrayList的问题
List<Chromosome> population = IntStream.range(0, populationSize)
.parallel()
.mapToObj(i -> {
Chromosome chromo = new Chromosome();
int populationSize=param.getPopulationSize();
// 并行循环:对应 Parallel.For(0, PopulationSize, i => { ... })
IntStream.range(0, populationSize)
.parallel() // 开启并行
.forEach(i -> {
Chromosome chromo = new Chromosome(); // 初始化染色体
chromo.setOrders(orders);
// 全局选择(GS):按GlobalOpId顺序生成MachineSelection
if (i < gsCount) {
generateGSChromosome(chromo, globalOpList);
generateGSChromosome(chromo,globalOpList); // 对应 C# GenerateGSChromosome
} else if (i < lsCount) {
// 局部选择(LS):按GlobalOpId顺序生成MachineSelection(仅负载计算范围不同)
generateLSChromosome(chromo, globalOpList);
generateLSChromosome(chromo,globalOpList);
} else {
// 随机选择(RS):按GlobalOpId顺序生成MachineSelection(仅机器选择随机)
generateRSChromosome(chromo, globalOpList);
generateRSChromosome(chromo,globalOpList);
}
return chromo;
})
.collect(Collectors.toList());
population.add(chromo); // 赋值到数组,线程安全(数组索引唯一)
});
return population;
}
......@@ -109,6 +117,7 @@ public class Initialization {
.min(Comparator.comparingDouble(m ->machineLoad.getOrDefault(m.getMachineId(), (double)0) + m.getProcessingTime()))
.orElseThrow(() -> new NoSuchElementException("MachineOption not found for machine: " ));
OptionalInt index = IntStream.range(0, optionalMachines.size())
.filter(i -> minLoadMachine.getMachineId()==optionalMachines.get(i).getMachineId())
.findFirst();
......@@ -172,10 +181,6 @@ public class Initialization {
// 选择“当前订单内设备负载+加工时间”最小的机器
List<MachineOption> optionalMachines = op.getMachineOptions();
if (optionalMachines == null || optionalMachines.isEmpty()) {
throw new IllegalStateException("工序 " + op.getId() + " 没有可用的机器选项");
}
MachineOption minLoadMachine = optionalMachines.stream()
......
......@@ -11,6 +11,7 @@ import com.aps.mapper.RoutingSupportingReplaceMapper;
import com.aps.mapper.RoutingsupportingMapper;
import com.aps.service.*;
import com.aps.service.impl.LanuchServiceImpl;
import com.aps.service.plan.MachineSchedulerService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -34,13 +35,15 @@ public class MaterialRequirementService {
private List<Entry> _allOperations;
private List<Machine> _Machines;
private List<GroupResult> _entryRel;
private List<RoutingHeader> headers;
private List<Routingsupporting> routingsupportings;
private List<Routingsupporting> routingsupportings=new ArrayList<>();
private List<RoutingSupportingReplace> routingsupportingreplaces;
private List<RoutingSupportingReplace> routingsupportingreplaces=new ArrayList<>();
List<RoutingDetail> allRoutingDetails=new ArrayList<>();
List<RoutingDetailEquip> allroutingDetailEquips=new ArrayList<>();
......@@ -51,7 +54,7 @@ public class MaterialRequirementService {
RoutingDetailConnectService routingDetailConnectService;
private final List<Order> orders;
private List<Order> orders;
@Autowired
RoutingHeaderMapper routingHeaderMapper;
......@@ -68,26 +71,33 @@ public class MaterialRequirementService {
@Autowired
private RoutingDiscreteParamService _routingDiscreteParamService;
@Autowired
private LanuchService lanuchService;
private LocalDateTime baseTime ;
public MaterialRequirementService(List<Material> materials,List<Order> _orders,List<Entry> allOperations,List<GroupResult> entryRel)
private MachineSchedulerService machineScheduler;
public void init(List<Material> materials,List<Order> _orders,List<Entry> allOperations,List<GroupResult> entryRel,MachineSchedulerService _machineScheduler,List<Machine> machines)
{
this.orders = _orders;
orders = _orders;
_allOperations=allOperations;
_materials=materials;
_entryRel=entryRel;
machineScheduler=_machineScheduler;
_Machines=machines;
}
/**
* 构建多级BOM需求网络
* @return 所有物料需求列表
*/
private List<OrderMaterialRequirement> buildMultiLevelRequirementNetwork(LocalDateTime _baseTime) {
public List<OrderMaterialRequirement> buildMultiLevelRequirementNetwork(LocalDateTime _baseTime) {
baseTime=_baseTime;
List<OrderMaterialRequirement> allRequirements = new ArrayList<>();
List<Order> childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
List<Machine> _newMachines = new ArrayList<>();
List<Integer> routingIds = _allOperations.stream()
.map(Entry::getRoutingId)
.distinct()
......@@ -104,9 +114,17 @@ public class MaterialRequirementService {
.eq(Routingsupporting::getIsdeleted, 0);
routingsupportings = routingsupportingMapper.selectList(routingsupportingwrapper);
if(routingsupportings==null||routingsupportings.size()==0)
{
return null;
}
List<String> routingsupportingids = routingsupportings.stream()
.map(Routingsupporting::getStrId)
.distinct()
.collect(Collectors.toList());
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingIds)
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0);
routingsupportingreplaces = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
......@@ -121,15 +139,25 @@ public class MaterialRequirementService {
// 递归展开BOM层级(通过结果对象接收out参数数据)
BOMBuildResult result = buildOrderBOM(demand.getRoutingId(),"", demand.getOrderId(), demand.getOrderId(),
demand.getQuantity(), 0);
demand.getQuantity(), 0,demand);
allRequirements.addAll(result.getMaterialRequirements());
childorders.addAll(result.getChildOrders());
_newEntrys.addAll(result.getNewEntrys());
_newMachines.addAll(result.getNewMachines());
}
// 将子订单添加到全局订单列表
// if (_orders != null) {
// _orders.addAll(childorders);
// }
if (orders != null) {
orders.addAll(childorders);
// _allOperations.addAll(_newEntrys);
Set<Long> existIds = new HashSet<>();
_Machines.addAll(_newMachines.stream()
.filter(t->existIds.add(t.getId()))//HashSet.add() 方法:添加成功返回 true,重复返回 false;
.collect(Collectors.toList()));
}
return allRequirements;
}
......@@ -145,7 +173,7 @@ public class MaterialRequirementService {
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public BOMBuildResult buildOrderBOM(int parent, String materialID, String mainorderId,
String childorderId, double parentQuantity, int level) {
String childorderId, double parentQuantity, int level,Order forder) {
RoutingHeader routingHeaders= headers.stream()
.filter(t->t.getId()==parent|| t.getMaterialId().equals(materialID))
......@@ -160,11 +188,12 @@ public class MaterialRequirementService {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
List<Order> childorders2 = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
List<Machine> _newMachines = new ArrayList<>();
// 遍历产品的工序,递归构建工序BOM
List<Entry> Operations= _allOperations.stream()
.filter(t->t.getOrderId()==childorderId)
.filter(t->t.getOrderId().equals(childorderId))
.collect(Collectors.toList());
......@@ -174,52 +203,80 @@ public class MaterialRequirementService {
for (Entry operation : Operations) {
// 调用BuildOperationBOM方法(返回结果对象替代out参数)
BOMBuildResult operationResult = buildOperationBOM(mainorderId, childorderId,
parentQuantity, operation, level);
parentQuantity, operation, level,forder);
// // 合并物料需求和子订单
materialRequirements.addAll(operationResult.getMaterialRequirements());
childorders2.addAll(operationResult.getChildOrders());
_newEntrys.addAll(operationResult.getNewEntrys());
_newMachines.addAll(operationResult.getNewMachines());
}
}
// return new BOMBuildResult(materialRequirements, childorders2);
return null;
return new BOMBuildResult(materialRequirements, childorders2,_newEntrys,_newMachines);
}
private void CreateChild(Order order,String materialID)
private Map<Integer, Object> CreateChild(Order order,String materialID)
{
String sceneId="";
Long routingIds=0l;
List<Routingsupporting> routingsupportings1=new ArrayList<>();
List<RoutingSupportingReplace> routingsupportingreplaces1 =new ArrayList<>();
RoutingHeader headers1= headers.stream()
.filter(t->t.getMaterialId().equals(materialID))
.findFirst().orElse(null);
if(headers1==null) {
LambdaQueryWrapper<RoutingHeader> wrapper = new LambdaQueryWrapper<>();
wrapper.in(RoutingHeader::getMaterialId, materialID)
wrapper.eq(RoutingHeader::getMaterialId, materialID)
.eq(RoutingHeader::getIsDeleted, 0)
.eq(RoutingHeader::getApprovalStatus, 1); // 添加 is_deleted=0 过滤条件
RoutingHeader headers1 = routingHeaderMapper.selectOne(wrapper);
if(headers==null)
{
return;
}
headers1 = routingHeaderMapper.selectOne(wrapper);
if(headers!=null) {
headers.add(headers1);
Integer routingIds =headers1.getId();
routingIds=headers1.getId().longValue();
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds)
.eq(Routingsupporting::getIsdeleted, 0);
List<Routingsupporting> routingsupportings1 = routingsupportingMapper.selectList(routingsupportingwrapper);
routingsupportings1 = routingsupportingMapper.selectList(routingsupportingwrapper);
routingsupportings.addAll(routingsupportings1);
List<String> routingsupportingids = routingsupportings.stream()
.map(Routingsupporting::getStrId)
.distinct()
.collect(Collectors.toList());
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingIds)
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0);
List<RoutingSupportingReplace> routingsupportingreplaces1 = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
routingsupportingreplaces1 = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
routingsupportingreplaces.addAll(routingsupportingreplaces1);
}
}
else {
Long routingIds1=headers1.getId().longValue();
routingIds=headers1.getId().longValue();
routingsupportings1= routingsupportings.stream()
.filter(t->t.getRoutingHeaderId().equals(routingIds1))
.collect(Collectors.toList());
List<String> routingsupportingids = routingsupportings.stream()
.map(Routingsupporting::getStrId)
.distinct()
.collect(Collectors.toList());
routingsupportingreplaces1 =routingsupportingreplaces.stream()
.filter(t->routingsupportingids.contains(t.getStrsupid())).collect(Collectors.toList());
}
if(headers==null)
{
return null;
}
List<RoutingDetail> RoutingDetails= lanuchService.getRoutingDetails(headers1.getId());
List<RoutingDetailEquip> routingDetailEquips = lanuchService.getRoutingDetailEquip(headers1.getId(),headers1.getCode());
LanuchServiceImpl lanuchService=new LanuchServiceImpl();
List<RoutingDetail> RoutingDetails= lanuchService.getRoutingDetails(routingIds);
List<RoutingDetailEquip> routingDetailEquips = lanuchService.getRoutingDetailEquip(routingIds,headers1.getCode());
order.setRoutingId(headers1.getId());
ProdLaunchOrder prodOrderMain= convertToLaunchOrder(order,"");
List<ProdProcessExec> processExecList = RoutingDetails.stream()
......@@ -264,8 +321,18 @@ public class MaterialRequirementService {
Map<Integer, Object> list=_routingDataService.CreateEntry( sceneId, ProdEquipmentList, ProdLaunchOrders, routingDiscreteParams, ProdOrderProcesslist, processExecList,_entryRel );
List<Machine> machines= _routingDataService.InitCalendarToAllMachines(sceneId,ProdEquipmentList,machineScheduler);
if(list.get(1)!=null)
{
_allOperations.addAll((List<Entry>)list.get(1));
_entryRel=(List<GroupResult>)list.get(2);
}
Map<Integer, Object> rest=new HashMap<>();
rest.put(1,list.get(1));
rest.put(2,machines);
return rest;
}
private ProdLaunchOrder convertToLaunchOrder(Order order, String sceneId) {
......@@ -273,9 +340,9 @@ public class MaterialRequirementService {
ProdLaunchOrder launchOrder = new ProdLaunchOrder();
launchOrder.setOrderId(order.getOrderId());
launchOrder.setSceneId(sceneId);
launchOrder.setSerie("");
launchOrder.setSerie(order.getSerie());
launchOrder.setCreateUser("GA");
launchOrder.setMaterialCode("");
launchOrder.setMaterialCode(order.getMaterialCode());
// launchOrder.setStartDate(order.get);
launchOrder.setEndDate(order.getDueDate());
// launchOrder.setOrderPriority(order.getPrioritry());
......@@ -307,15 +374,16 @@ public class MaterialRequirementService {
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public BOMBuildResult buildOperationBOM(String orderId, String childorderId, double parentQuantity,
Entry operation, int level) {
Entry operation, int level,Order forder) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
List<Order> _childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>();
List<Machine> _newMachines = new ArrayList<>();
List<Routingsupporting> MaterialRequirements= routingsupportings.stream()
.filter(t->t.getRoutingDetailId()==operation.getRoutingDetailId())
.filter(t->t.getRoutingDetailId().equals(operation.getRoutingDetailId()))
.collect(Collectors.toList());
if (MaterialRequirements != null) {
if (MaterialRequirements != null&&MaterialRequirements.size()>0) {
for (Routingsupporting component : MaterialRequirements) {
OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement();
materialRequirements.add(orderMaterial);
......@@ -338,7 +406,9 @@ public class MaterialRequirementService {
}
orderMaterial.setMaterialType(material.getMaterialType());
orderMaterial.setMaterialTypeName(material.getMaterialTypeName());
orderMaterial.setMaterialId(material.getId());
orderMaterial.setCkeckLeadTime(material.getCkeckLeadTime());
// 扣减现有库存
double availableNow = material.getCurrentStock();
......@@ -382,7 +452,7 @@ public class MaterialRequirementService {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
if (material.getMaterialType() == MaterialType.RawMaterial) {
if (material.getMaterialTypeName().equals("MP") ) {
// 处理原材料采购时间
orderMaterial.setPurchaseStartTime(baseTime);
// 采购结束时间 = 采购开始时间 + 采购提前期(天)
......@@ -402,8 +472,8 @@ public class MaterialRequirementService {
if (order.getFinishOrderId() == null) {
order.setFinishOrderId(new ArrayList<>());
}
order.getFinishOrderId().add(orderId);
orderMaterial.getProductOrderID().add(order.getOrderId());
order.getFinishOrderId().add(forder.getId());
orderMaterial.getProductOrderID().add(forder.getId());
double useq = Math.min(needed, order.getSYQuantity());
needed -= useq;
......@@ -414,10 +484,12 @@ public class MaterialRequirementService {
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(0, material.getId(),
orderId, order.getOrderId(),
order.getQuantity(), l);
order.getQuantity(), l,order);
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
operation.getDependentOnOrderIds().add(order.getOrderId());
_newEntrys.addAll(childResult.getNewEntrys());
_newMachines.addAll(childResult.getNewMachines());
operation.getDependentOnOrderIds().add(order.getId());
}
if (needed <= 0) {
......@@ -437,20 +509,34 @@ public class MaterialRequirementService {
childorder.setOrderId(OrderId);
childorder.setMaterialId(material.getId());
childorder.setMaterialCode(material.getCode());
childorder.setOrderCode(material.getCode());
childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(orderId);
childorder.getFinishOrderId().add(forder.getId());
childorder.setSerie(forder.getSerie());
childorder.setStartDate(forder.getStartDate());
childorder.setDueDate(forder.getDueDate());
childorder.setPriority(forder.getPriority());
childorder.setActualPriority(forder.getActualPriority());
_childorders.add(childorder);
CreateChild(childorder,material.getId());
orderMaterial.getProductOrderID().add(OrderId);
operation.getDependentOnOrderIds().add(OrderId);
Map<Integer, Object> list= CreateChild(childorder,material.getId());
List<Entry> newentrys=(List<Entry>)list.get(1);
_newEntrys.addAll(newentrys);
_newMachines.addAll((List<Machine>)list.get(2));
orderMaterial.getProductOrderID().add(childorder.getId());
operation.getDependentOnOrderIds().add(childorder.getId());
// 递归构建BOM
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(0, material.getId(),
orderId, childorder.getOrderId(),
childorder.getQuantity(), l);
childorder.getQuantity(), l,childorder);
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
_newMachines.addAll(childResult.getNewMachines());
}
}
}
......@@ -473,6 +559,6 @@ public class MaterialRequirementService {
}
}
return new BOMBuildResult(materialRequirements, _childorders);
return new BOMBuildResult(materialRequirements, _childorders,_newEntrys,_newMachines);
}
}
......@@ -5,14 +5,15 @@ import com.aps.entity.Algorithm.DependencyType;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
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.entity.basic.*;
import com.aps.service.*;
import com.aps.service.plan.MachineSchedulerService;
import com.aps.service.plan.SceneService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
......@@ -46,6 +47,12 @@ public class RoutingDataService {
@Autowired
private DiscreteParameterMatrixService _discreteParameterMatrixService;
@Autowired
private ProdEquipSpecialCalService _prodEquipSpecialCalService;
@Autowired
private MesShiftWorkSchedService _MesShiftWorkSchedService;
public Map<Integer, Object> InitEntrys(String SceneId, List<ProdEquipment> ProdEquipments, List<Order> ProdLaunchOrders)
{
Map<Integer, Object> list=new HashMap<>();
......@@ -125,7 +132,7 @@ public class RoutingDataService {
// nodeInfo.getNewChildIds());
Entry entry = new Entry();
entry.setSceneId(SceneId);
entry.setId(nodeInfo.getGlobalSerial());
entry.setGroupId(i + 1);
entry.setSequence(nodeInfo.getGroupSerial());
......@@ -191,6 +198,7 @@ public class RoutingDataService {
if (order != null) {
entry.setProductId(order.getMaterialId());
entry.setPriority(order.getActualPriority());
order.setId(entry.getGroupId());
}
List<ProdEquipment> Equipments = ProdEquipments.stream()
.filter(t -> t.getExecId().equals(op.getExecId()))
......@@ -224,4 +232,154 @@ public class RoutingDataService {
return list;
}
public List<Machine> InitCalendarToAllMachines(String SceneId, List<ProdEquipment> ProdEquipments, MachineSchedulerService machineScheduler) {
// 按设备分组
List<Long> MachineIds = ProdEquipments.stream()
.map(ProdEquipment::getEquipId)
.distinct()
.sorted()
.collect(Collectors.toList());
List<Machine> machines=new ArrayList<>();
for (Long id : MachineIds) {
Machine machine=new Machine();
machine.setId(id);
machines.add(machine);
}
//节假日
// List<MesHoliday> holidays= _MesHolidayService.list();
LambdaQueryWrapper<ProdEquipSpecialCal> ProdEquipSpecialCalWrapper = new LambdaQueryWrapper<>();
ProdEquipSpecialCalWrapper.eq(ProdEquipSpecialCal::getSceneId, SceneId);
List<PlanResource> PlanResources= _PlanResourceService.lambdaQuery()
.eq(PlanResource::getIsdeleted,0)
.list();
List<ProdEquipSpecialCal> ProdEquipSpecialCals= _prodEquipSpecialCalService.list(ProdEquipSpecialCalWrapper);
List<MesShiftWorkSched> MesShiftWorkScheds= _MesShiftWorkSchedService.lambdaQuery()
.eq(MesShiftWorkSched::getIsdeleted,0).list();
if (machines == null) {
return null;
}
for (Machine machine : machines) {
// 确保维护窗口列表不为null
if (machine.getMaintenanceWindows() == null) {
machine.setMaintenanceWindows(new ArrayList<>());
}
List<ProdEquipSpecialCal> machineProdEquipSpecialCals = ProdEquipSpecialCals.stream()
.filter(t -> t.getEquipId() == machine.getId()&&t.getReferenceType()==1)
.collect(Collectors.toList());
List<Shift> shifts1=new ArrayList<>();
for (ProdEquipSpecialCal machineProdEquipSpecialCal : machineProdEquipSpecialCals) {
List<MesShiftWorkSched> ShiftWorkScheds = MesShiftWorkScheds.stream()
.filter(t -> (long) t.getWeekWorkSchedId() == machineProdEquipSpecialCal.getReferenceId())
.collect(Collectors.toList());
List<Shift> Shifts = mergeShiftData(ShiftWorkScheds);
for (Shift shift : Shifts) {
shift.setMachineId(machine.getId());
shift.setStartDate(machineProdEquipSpecialCal.getStartDate());
shift.setEndDate(machineProdEquipSpecialCal.getEndDate());
shifts1.add(shift);
}
}
List<PlanResource> PlanResources1 = PlanResources.stream()
.filter(t -> t.getReferenceId() == machine.getId())
.collect(Collectors.toList());
if(PlanResources1!=null&&PlanResources1.size()>0)
{
for (PlanResource PlanResource : PlanResources1) {
List<MesShiftWorkSched> ShiftWorkScheds = MesShiftWorkScheds.stream()
.filter(t -> (long) t.getWeekWorkSchedId() == PlanResource.getWorkSchedId())
.collect(Collectors.toList());
List<Shift> Shifts = mergeShiftData(ShiftWorkScheds);
for (Shift shift : Shifts) {
shift.setMachineId(machine.getId());
shift.setStartDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
shift.setEndDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
shifts1.add(shift);
}
}
}
machine.setShifts(shifts1);
List<ProdEquipSpecialCal> Holidays = ProdEquipSpecialCals.stream()
.filter(t -> t.getEquipId() == machine.getId()&&t.getReferenceType()==2)
.collect(Collectors.toList());
List<Holiday> Holidays1=new ArrayList<>();
for (ProdEquipSpecialCal machineProdEquipSpecialCal : Holidays) {
Holiday holiday=new Holiday();
holiday.setStart(machineProdEquipSpecialCal.getStartDate());
holiday.setEnd(machineProdEquipSpecialCal.getEndDate());
Holidays1.add(holiday);
}
machine.setHolidays(Holidays1);
}
// 4. 初始化机器时间线
for (Machine machine : machines) {
MachineTimeline timeline = machineScheduler.getOrCreateTimeline(machine);
machine.setAvailability(timeline.getSegments());
}
return machines;
}
/**
* 合并重复的ShiftData,将serialNumber收集为列表
* @param originalList 原始数据列表
* @return 合并后的MergedShiftData列表
*/
public static List<Shift> mergeShiftData(List<MesShiftWorkSched> originalList) {
// 按shiftStart和shiftEnd分组
Map<String, Shift> groupMap = new HashMap<>();
for (MesShiftWorkSched data : originalList) {
// 用shiftStart+shiftEnd作为分组key
String groupKey = data.getShiftStart().toString() + "_" + data.getShiftEnd().toString();
if (groupMap.containsKey(groupKey)) {
// 已存在分组:添加serialNumber到列表
Shift merged = groupMap.get(groupKey);
merged.getDays().add(data.getStartWeekDay());
} else {
// 新分组:创建MergedShiftData并初始化
Shift merged = new Shift();
merged.setStartTime(data.getShiftStart().toLocalTime());
merged.setEndTime(data.getShiftEnd().toLocalTime());
merged.setStatus(0);
// 初始化序号列表
Set<Integer> serials =new HashSet<>();
serials.add(data.getStartWeekDay());
merged.setDays(serials);
groupMap.put(groupKey, merged);
}
}
// 转换为列表返回
return new ArrayList<>(groupMap.values());
}
}
......@@ -53,7 +53,7 @@ public class ScheduleOperationService {
.indexOf(newMachineId) + 1;
if (machineOptionIndex == 0) {
throw new NoSuchElementException("不能移动到该设备");
throw new NoSuchElementException("Machine not found: " + newMachineId);
}
// 设置约束
......@@ -183,10 +183,8 @@ public class ScheduleOperationService {
od.setPrevOperationId(id);
OperationDependency.add(od);
}
if (entry != null) {
entry.setPrevEntryIds(OperationDependency);
}
}
if(nodeInfo.getNewChildIds()!=null)
{
List<OperationDependency> OperationDependency=new ArrayList<>();
......@@ -195,10 +193,8 @@ public class ScheduleOperationService {
od.setNextOperationId(id);
OperationDependency.add(od);
}
if (entry != null) {
entry.setNextEntryIds(OperationDependency);
}
}
GlobalOperationInfo info= chromosome.getGlobalOpList().stream()
.filter(t->t.getOp().getId()==entry.getId())
.findFirst()
......@@ -229,7 +225,7 @@ public class ScheduleOperationService {
od.setPrevOperationId(id);
OperationDependency.add(od);
}
newOp.setPrevEntryIds(OperationDependency);
entry.setPrevEntryIds(OperationDependency);
}
if(nodeInfo.getNewChildIds()!=null)
{
......@@ -239,7 +235,7 @@ public class ScheduleOperationService {
od.setNextOperationId(id);
OperationDependency.add(od);
}
newOp.setNextEntryIds(OperationDependency);
entry.setNextEntryIds(OperationDependency);
}
newOp.setQuantity(newids.get(nodeInfo.getOriginalId()));
newOp.setMainId(MainId);
......@@ -286,17 +282,6 @@ public class ScheduleOperationService {
.findFirst()
.orElseThrow(() -> new NoSuchElementException("Order not found: " + orderId));
double sum = Arrays.stream(splitCounts)
.filter(Objects::nonNull)
.mapToDouble(Double::doubleValue)
.sum();
if(sum!=order.getQuantity()){
throw new RuntimeException("订单数量拆分不正确");
}
int maxorderId =OperatRels.size() ;
int maxgroupId =maxorderId ;
......@@ -571,10 +556,8 @@ public class ScheduleOperationService {
od.setPrevOperationId(id);
OperationDependency.add(od);
}
if (entry != null) {
entry.setPrevEntryIds(OperationDependency);
}
}
if(node.getNewChildIds()!=null)
{
List<OperationDependency> OperationDependency=new ArrayList<>();
......@@ -583,10 +566,8 @@ public class ScheduleOperationService {
od.setNextOperationId(id);
OperationDependency.add(od);
}
if (entry != null) {
entry.setNextEntryIds(OperationDependency);
}
}
GlobalOperationInfo info= chromosome.getGlobalOpList().stream()
.filter(t->t.getOp().getId()==entry.getId())
.findFirst()
......@@ -657,7 +638,7 @@ public class ScheduleOperationService {
{
MachineSchedulerService machineScheduler = new MachineSchedulerService(baseTime);
GeneticDecoder decoder = new GeneticDecoder(globalParam,baseTime, chromosome.getInitMachines(),
chromosome.getOrders(), null, machineScheduler);
chromosome.getOrders(), null, machineScheduler,chromosome.getOrderMaterials());
chromosome.setMachines(chromosome.getInitMachines());
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult()));
......
package com.aps.service;
import com.aps.common.util.R;
import com.aps.entity.*;
import java.util.List;
import java.util.Map;
/**
* 设备日历服务接口
......@@ -32,4 +34,23 @@ public interface LanuchService {
R<String> exportPlan( String sceneId);
List<RoutingDetail> getRoutingDetails(Integer routingHeaderId);
List<RoutingDetailEquip> getRoutingDetailEquip(Integer routingHeaderId, String routingCode);
ProdProcessExec createProcessExec(ProdLaunchOrder prodOrderMain,
RoutingDetail detail,
String sceneId);
List<ProdEquipment> batchInsertEquipMent(
List<RoutingDetailEquip> routingDetailEquips,
String sceneId,List<ProdProcessExec> processExecList,Boolean isSave);
List<ProdOrderProcess> createProcessRelations(ProdLaunchOrder prodOrderMain, String sceneId, Map<Long, String> routingDetailIdToExecIdMap);
ProdOrderProcess createProcessRelation(ProdLaunchOrder prodOrderMain,
RoutingDetailConnect connection,
String sceneId,
Map<Long, String> routingDetailIdToExecIdMap);
}
\ No newline at end of file
......@@ -758,7 +758,7 @@ public class LanuchServiceImpl implements LanuchService {
◦ @return 工序关系列表
*/
private List<ProdOrderProcess> createProcessRelations(ProdLaunchOrder prodOrderMain, String sceneId, Map<Long, String> routingDetailIdToExecIdMap) {
public List<ProdOrderProcess> createProcessRelations(ProdLaunchOrder prodOrderMain, String sceneId, Map<Long, String> routingDetailIdToExecIdMap) {
LambdaQueryWrapper<RoutingDetailConnect> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(RoutingDetailConnect::getRoutingHeaderId, prodOrderMain.getRoutingId())
.eq(RoutingDetailConnect::getIsdeleted, 0)
......
......@@ -14,6 +14,7 @@ import com.aps.entity.Schedule.GenVO;
import com.aps.entity.Schedule.MachineVO;
import com.aps.entity.basic.*;
import com.aps.mapper.ConfigMapper;
import com.aps.mapper.MaterialInfoMapper;
import com.aps.service.*;
import com.aps.service.Algorithm.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
......@@ -22,7 +23,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
......@@ -89,15 +89,28 @@ public class PlanResultService {
@Autowired
private OrderSortService orderSortService;
@Autowired
private MaterialInfoService materialInfoService;
@Autowired
private MaterialInfoMapper materialInfoMapper;
private LocalDateTime baseTime = LocalDateTime.of(2025, 11, 1, 0, 0, 0);
@Autowired
private StockService stockService;
@PostConstruct
public void init() {
// 设置GeneticDecoder中的静态服务引用
GeneticDecoder.setDiscreteParameterMatrixService(_discreteParameterMatrixService);
}
@Autowired
private SjzPfWhStockService sjzPfWhStockService;
@Autowired
private PurchaseReceiptService purchaseReceiptService;
@Autowired
private ErpPurchaseOrderService erpPurchaseOrderService;
@Autowired
private MaterialRequirementService materialRequirementService;
private LocalDateTime baseTime = LocalDateTime.of(2025, 11, 1, 0, 0, 0);
public List<ScheduleChromosome> execute() {
try {
......@@ -270,7 +283,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
GlobalParam globalParam=new GlobalParam();
// 5. 执行调度算法
param.initAdaptiveParams(allOperations.size());
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,null); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,null,materialRequirementService); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
Chromosome Chromosomes =scheduler.Run(param,allOperations);
WriteScheduleSummary(Chromosomes);
ScheduleOperationService ScheduleOperation=new ScheduleOperationService();
......@@ -290,16 +303,13 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
ScheduleParams param = new ScheduleParams();
param.setBaseTime(LocalDateTime.of(2025, 11, 1, 0, 0, 0));
System.out.println("开始调度");
// 1. 读取数据
// List<Machine> machines = loadData("machines.json", Machine.class);
// List<Product> products = loadData("products.json", Product.class);
// List<Order> orders = loadData("orders.json", Order.class);
List<ProdEquipment> ProdEquipments= _prodEquipmentService.lambdaQuery()
.eq(ProdEquipment::getSceneId,SceneId)
.list();
......@@ -314,9 +324,13 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
// 3. 构建订单-工序数据
List<Order> orders=InitOrder(ProdLaunchOrders);
List<Material> Materials= InitMaterial();
Map<Integer,Object> list= InitEntrys(SceneId,ProdEquipments,orders);
List<Entry> entrys=(List<Entry>)list.get(1);
List<GroupResult> entryRel=(List<GroupResult>)list.get(2);
......@@ -326,7 +340,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
GlobalParam globalParam=InitGlobalParam();
// 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,entryRel); //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());
double[] customWeights = new double[] { 0.2, 0.1, 0.1, 0.1, 0.5 }; // 延迟时间权重提升到0.5
......@@ -404,8 +418,6 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
// WriteScheduleSummary(chromosome);
_sceneService.saveChromosomeToFile(chromosome, SceneId);
return chromosome;
}
......@@ -419,21 +431,6 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
// WriteScheduleSummary(chromosome);
ScheduleOperationService ScheduleOperation=new ScheduleOperationService();
List<GAScheduleResult> result = chromosome.getResult();
GAScheduleResult gaScheduleResult = result.stream()
.filter(r -> r.getOperationId() == opId).findFirst().orElse(null);
double sum = Arrays.stream(splitCounts)
.filter(Objects::nonNull)
.mapToDouble(Double::doubleValue)
.sum();
if (gaScheduleResult.getQuantity() != sum) {
throw new RuntimeException("拆分数量不正确");
}
ScheduleOperation.SpiltOperation(chromosome,opId,splitCounts, globalParam);
WriteScheduleSummary(chromosome);
......@@ -517,13 +514,12 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
public Chromosome schedule(String SceneId) {
public Chromosome schedule(String SceneId,LocalDateTime baseTime) {
try {
ScheduleParams param = new ScheduleParams();
// param.setBaseTime(baseTime);
param.setBaseTime(baseTime);
param.setBaseTime(LocalDateTime.of(2025, 11, 1, 0, 0, 0));
// 1. 读取数据
......@@ -557,7 +553,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
GlobalParam globalParam=InitGlobalParam();
// 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,entryRel); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,entryRel,materialRequirementService); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
param.initAdaptiveParams(entrys.size());
// double[] customWeights = new double[] { 0.2, 0.1, 0.1, 0.1, 0.5 }; // 延迟时间权重提升到0.5
......@@ -576,8 +572,6 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
return chromosomes;
} catch (Exception e) {
throw new RuntimeException("调度执行失败", e);
}
}
......@@ -687,113 +681,9 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
private List<Machine> InitCalendarToAllMachines(String SceneId,List<ProdEquipment> ProdEquipments,MachineSchedulerService machineScheduler) {
// 按设备分组
return _routingDataService.InitCalendarToAllMachines(SceneId,ProdEquipments,machineScheduler);
List<Long> MachineIds = ProdEquipments.stream()
.map(ProdEquipment::getEquipId)
.distinct()
.sorted()
.collect(Collectors.toList());
List<Machine> machines=new ArrayList<>();
for (Long id : MachineIds) {
Machine machine=new Machine();
machine.setId(id);
machines.add(machine);
}
//节假日
List<MesHoliday> holidays= _MesHolidayService.list();
LambdaQueryWrapper<ProdEquipSpecialCal> ProdEquipSpecialCalWrapper = new LambdaQueryWrapper<>();
ProdEquipSpecialCalWrapper.eq(ProdEquipSpecialCal::getSceneId, SceneId);
List<PlanResource> PlanResources= _PlanResourceService.lambdaQuery()
.eq(PlanResource::getIsdeleted,0)
.list();
List<ProdEquipSpecialCal> ProdEquipSpecialCals= _prodEquipSpecialCalService.list(ProdEquipSpecialCalWrapper);
List<MesShiftWorkSched> MesShiftWorkScheds= _MesShiftWorkSchedService.lambdaQuery()
.eq(MesShiftWorkSched::getIsdeleted,0).list();
if (machines == null) {
return null;
}
for (Machine machine : machines) {
// 确保维护窗口列表不为null
if (machine.getMaintenanceWindows() == null) {
machine.setMaintenanceWindows(new ArrayList<>());
}
List<ProdEquipSpecialCal> machineProdEquipSpecialCals = ProdEquipSpecialCals.stream()
.filter(t -> t.getEquipId() == machine.getId()&&t.getReferenceType()==1)
.collect(Collectors.toList());
List<Shift> shifts1=new ArrayList<>();
for (ProdEquipSpecialCal machineProdEquipSpecialCal : machineProdEquipSpecialCals) {
List<MesShiftWorkSched> ShiftWorkScheds = MesShiftWorkScheds.stream()
.filter(t -> (long) t.getWeekWorkSchedId() == machineProdEquipSpecialCal.getReferenceId())
.collect(Collectors.toList());
List<Shift> Shifts = mergeShiftData(ShiftWorkScheds);
for (Shift shift : Shifts) {
shift.setMachineId(machine.getId());
shift.setStartDate(machineProdEquipSpecialCal.getStartDate());
shift.setEndDate(machineProdEquipSpecialCal.getEndDate());
shifts1.add(shift);
}
}
List<PlanResource> PlanResources1 = PlanResources.stream()
.filter(t -> t.getReferenceId() == machine.getId())
.collect(Collectors.toList());
if(PlanResources1!=null&&PlanResources1.size()>0)
{
for (PlanResource PlanResource : PlanResources1) {
List<MesShiftWorkSched> ShiftWorkScheds = MesShiftWorkScheds.stream()
.filter(t -> (long) t.getWeekWorkSchedId() == PlanResource.getWorkSchedId())
.collect(Collectors.toList());
List<Shift> Shifts = mergeShiftData(ShiftWorkScheds);
for (Shift shift : Shifts) {
shift.setMachineId(machine.getId());
shift.setStartDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
shift.setEndDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
shifts1.add(shift);
}
}
}
machine.setShifts(shifts1);
List<ProdEquipSpecialCal> Holidays = ProdEquipSpecialCals.stream()
.filter(t -> t.getEquipId() == machine.getId()&&t.getReferenceType()==2)
.collect(Collectors.toList());
List<Holiday> Holidays1=new ArrayList<>();
for (ProdEquipSpecialCal machineProdEquipSpecialCal : Holidays) {
Holiday holiday=new Holiday();
holiday.setStart(machineProdEquipSpecialCal.getStartDate());
holiday.setEnd(machineProdEquipSpecialCal.getEndDate());
Holidays1.add(holiday);
}
machine.setHolidays(Holidays1);
}
// 4. 初始化机器时间线
for (Machine machine : machines) {
MachineTimeline timeline = machineScheduler.getOrCreateTimeline(machine);
machine.setAvailability(timeline.getSegments());
}
return machines;
}
......@@ -882,7 +772,7 @@ private GlobalParam InitGlobalParam()
List<StrategyScheduling> StrategySchedulings = _strategyRuleService.getForwardSchedulingByRuleId(strategyRules.getId());
Set<String> files = new HashSet<>();
if (StrategySchedulings != null) {
List<StrategyScheduling> selecteds = StrategySchedulings.stream().filter(t -> t.isValue() == true).collect(Collectors.toList());
List<StrategyScheduling> selecteds = StrategySchedulings.stream().filter(t -> t.isValue() == true).sorted(Comparator.comparingInt(StrategyScheduling::getSort) ).collect(Collectors.toList());
if (selecteds != null && selecteds.size() > 0) {
int i = 1;
for (StrategyScheduling strategy : selecteds) {
......@@ -997,49 +887,75 @@ private GlobalParam InitGlobalParam()
}
}
private Map<Integer, Object> InitEntrys(String SceneId,List<ProdEquipment> ProdEquipments,List<Order> ProdLaunchOrders)
private final Map<String, Object> CommonCache = new HashMap<>();
private List<Material> InitMaterial() {
List<Material> materials=new ArrayList<>();
// List<MaterialInfo> materiallist= materialInfoService.lambdaQuery()
// .eq(MaterialInfo::getIsdeleted,0)
// .list();
List<Material> cmaterials= (List<Material>)CommonCache.get("material");
if(cmaterials!=null)
{
return _routingDataService.InitEntrys(SceneId,ProdEquipments,ProdLaunchOrders);
return cmaterials;
}
LambdaQueryWrapper<MaterialInfo> MaterialInfoWrapper = new LambdaQueryWrapper<>();
MaterialInfoWrapper.eq(MaterialInfo::getIsdeleted,0);
/**
* 合并重复的ShiftData,将serialNumber收集为列表
* @param originalList 原始数据列表
* @return 合并后的MergedShiftData列表
*/
public static List<Shift> mergeShiftData(List<MesShiftWorkSched> originalList) {
// 按shiftStart和shiftEnd分组
Map<String, Shift> groupMap = new HashMap<>();
for (MesShiftWorkSched data : originalList) {
// 用shiftStart+shiftEnd作为分组key
String groupKey = data.getShiftStart().toString() + "_" + data.getShiftEnd().toString();
if (groupMap.containsKey(groupKey)) {
// 已存在分组:添加serialNumber到列表
Shift merged = groupMap.get(groupKey);
merged.getDays().add(data.getStartWeekDay());
} else {
// 新分组:创建MergedShiftData并初始化
Shift merged = new Shift();
merged.setStartTime(data.getShiftStart().toLocalTime());
merged.setEndTime(data.getShiftEnd().toLocalTime());
merged.setStatus(0);
// 初始化序号列表
Set<Integer> serials =new HashSet<>();
serials.add(data.getStartWeekDay());
merged.setDays(serials);
groupMap.put(groupKey, merged);
}
List<String> ids=new ArrayList<>();
ids.add("d0d0dd08-540d-e942-8ee9-96521072e6b9");
ids.add("cdd0dd08-1381-1348-8e53-8faeef45557d");
ids.add("cdd0dd08-5deb-5f48-81f9-1357e40dc546");
ids.add("cfd0dd08-c7b5-1a45-8126-b65108488443");
MaterialInfoWrapper.in(MaterialInfo::getId,ids);
List<MaterialInfo> materiallist= materialInfoMapper.selectList(MaterialInfoWrapper);
// List<ProdEquipSpecialCal> ProdEquipSpecialCals= _prodEquipSpecialCalService.list(ProdEquipSpecialCalWrapper);
List<Stock> Stocklist= stockService.lambdaQuery()
.eq(Stock::getIsdeleted,0)
.gt(Stock::getTotal,0)
.list();
materiallist.forEach(m -> {
Material material=new Material();
material.setId(m.getId());
material.setMaterialType(m.getMaterialType());
material.setMaterialTypeName(m.getMaterialTypeName());
material.setCkeckLeadTime(m.getInspectDuration());
material.setPurchaseLeadTime(m.getPurchaseDuration());
double stock= Stocklist.stream()
.filter(t->t.getMaterialId().equals(m.getId()))
.mapToDouble(Stock::getTotal)
.sum();
material.setCurrentStock(stock);
materials.add(material);
});
CommonCache.put("material",materials);
return materials;
}
// 转换为列表返回
return new ArrayList<>(groupMap.values());
private Map<Integer, Object> InitEntrys(String SceneId,List<ProdEquipment> ProdEquipments,List<Order> ProdLaunchOrders)
{
return _routingDataService.InitEntrys(SceneId,ProdEquipments,ProdLaunchOrders);
}
public GenVO convertGeneToGenVO(Gene gene, LocalDateTime baseTime) {
GenVO genVO = new GenVO();
genVO.setOrderId(String.valueOf(gene.getOrderId()));
......@@ -1096,7 +1012,6 @@ private GlobalParam InitGlobalParam()
Machine machine=new Machine();
machine.setId(id);
machines.add(machine);
machine.setCode(ProdEquipments.stream().filter(t -> t.getEquipId() == id).findFirst().get().getEquipCode());
}
//节假日
List<MesHoliday> holidays= _MesHolidayService.list();
......@@ -1144,27 +1059,6 @@ private GlobalParam InitGlobalParam()
}
}
// List<PlanResource> PlanResources1 = PlanResources.stream()
// .filter(t -> t.getReferenceId() == machine.getId())
// .collect(Collectors.toList());
// if(PlanResources1!=null&&PlanResources1.size()>0)
// {
// for (PlanResource PlanResource : PlanResources1) {
//
// List<MesShiftWorkSched> ShiftWorkScheds = MesShiftWorkScheds.stream()
// .filter(t -> (long) t.getWeekWorkSchedId() == PlanResource.getWorkSchedId())
// .collect(Collectors.toList());
// List<Shift> Shifts = mergeShiftData(ShiftWorkScheds);
// for (Shift shift : Shifts) {
//
// shift.setMachineId(machine.getId());
// shift.setStartDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
// shift.setEndDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
// shifts1.add(shift);
// }
// }
//
// }
......@@ -1220,228 +1114,41 @@ private GlobalParam InitGlobalParam()
}
/**
* 将 ScheduleChromosome 转换为 ResourceGanttVO 列表
* @param scheduleChromosome 调度结果
* @param machineList 机器列表
* @return 转换后的数据
* 合并重复的ShiftData,将serialNumber收集为列表
* @param originalList 原始数据列表
* @return 合并后的MergedShiftData列表
*/
public List<com.aps.entity.Gantt.ResourceGanttVO> convertToResourceGanttVO1(Chromosome scheduleChromosome, List<Machine> machineList) {
List<com.aps.entity.Gantt.ResourceGanttVO> resourceGanttVOList = new ArrayList<>();
List<Entry> allOperations = scheduleChromosome.getAllOperations();
// 遍历所有机器资源
if (machineList != null) {
for (int i = 0; i < machineList.size(); i++) {
Machine machine = machineList.get(i);
com.aps.entity.Gantt.ResourceGanttVO resourceGanttVO = new com.aps.entity.Gantt.ResourceGanttVO();
resourceGanttVO.setId(machine.getId());
resourceGanttVO.setName(machine.getId()+"号设备");
resourceGanttVO.setShift(convertToShiftVO(machine));
resourceGanttVO.setCode(machine.getCode());
// 转换任务列表
List<com.aps.entity.Gantt.TaskVO> taskVOList = new ArrayList<>();
if (scheduleChromosome.getResult() != null) {
// 筛选出属于当前设备的任务
List<GAScheduleResult> machineGenes = scheduleChromosome.getResult().stream()
.filter(gene -> gene.getMachineId()==(machine.getId()))
.collect(Collectors.toList());
// 按开始时间排序
machineGenes.sort((g1, g2) -> Integer.compare(g1.getStartTime(), g2.getStartTime()));
for (GAScheduleResult gene : machineGenes) {
Entry entry = allOperations.stream()
.filter(t -> t.getId() == gene.getOperationId()).findFirst().orElse(null);
com.aps.entity.Gantt.TaskVO taskVO = new com.aps.entity.Gantt.TaskVO();
taskVO.setId(String.valueOf(gene.getOperationId()));
taskVO.setPlanId(gene.getOrderId()); // 默认值
// taskVO.setProductType(0); // 默认值
// taskVO.setProductName("产品"+gene.getProductId());
taskVO.setProductId(gene.getProductId()); // 默认值
taskVO.setQuantity(gene.getQuantity());
taskVO.setStart(scheduleChromosome.getBaseTime().plusSeconds(gene.getStartTime()));
taskVO.setEnd(scheduleChromosome.getBaseTime().plusSeconds(gene.getEndTime()));
taskVO.setSetup(0); // 默认值
taskVO.setTeardown(gene.getTeardownTime()); // 默认值
taskVO.setEquipChange(gene.getChangeoverTime()); // 默认值
taskVO.setEquipCooling(0); // 默认值
taskVO.setEquipType(resourceGanttVO.getType());
taskVO.setEquipName(resourceGanttVO.getName());
taskVO.setLocked(gene.isIsLocked()); // 默认值
if (entry != null) {
taskVO.setSeq(Math.toIntExact(entry.getTaskSeq())); // 使用工序ID
taskVO.setSeqName(entry.getRoutingDetailName());
}
// taskVO.setDuration(calculateDuration(
// scheduleChromosome.getBaseTime().plusMinutes(gene.getStartTime()),
// scheduleChromosome.getBaseTime().plusMinutes(gene.getEndTime()))); // 计算持续时间
taskVO.setDuration(0); //
taskVO.setEquipId(machine.getId());
taskVO.setShopId(machine.getId());
taskVO.setShopName(resourceGanttVO.getShopName());
taskVO.setStatus(0); // 默认值
taskVO.setDetailId((long) gene.getStartTime()); // 将productId和operationID组合为detailId
taskVO.setHeaderId(gene.getEndTime()); // 默认值
// taskVO.setHeaderName("工艺"+gene.getProductId()); // 默认值
// taskVO.setSeq(gene.getSequenceId()); // 使用工序ID
// taskVO.setSeqName( "工序名称"+gene.getSequenceId());
taskVO.setProcessingTime(gene.getProcessingTime());
// taskVO.setAbsoluteStart(scheduleChromosome.getBaseTime().plusMinutes(gene.getStartTime()));
// taskVO.setAbsoluteEnd(scheduleChromosome.getBaseTime().plusMinutes(gene.getEndTime()));
taskVOList.add(taskVO);
// 调试:检查machine中的shifts状态
// if (machine.getShifts() != null) {
// for (Shift shift : machine.getShifts()) {
// System.out.println("Before setting shifts - Shift status: " + shift.getStatus());
// }
// }
taskVO.setAbsolutePreparationTime(gene.getTeardownTime());
}
}
public static List<Shift> mergeShiftData(List<MesShiftWorkSched> originalList) {
// 按shiftStart和shiftEnd分组
Map<String, Shift> groupMap = new HashMap<>();
resourceGanttVO.setList(taskVOList);
resourceGanttVOList.add(resourceGanttVO);
}
}
for (MesShiftWorkSched data : originalList) {
// 用shiftStart+shiftEnd作为分组key
String groupKey = data.getShiftStart().toString() + "_" + data.getShiftEnd().toString();
return resourceGanttVOList;
}
if (groupMap.containsKey(groupKey)) {
// 已存在分组:添加serialNumber到列表
Shift merged = groupMap.get(groupKey);
merged.getDays().add(data.getStartWeekDay());
} else {
// 新分组:创建MergedShiftData并初始化
Shift merged = new Shift();
/**
* 将 ScheduleChromosome 转换为 ProductGanttVO 列表
* @param scheduleChromosome 调度结果
* @return 转换后的数据
*/
public List<com.aps.entity.Gantt.ProductGanttVO> convertToProductGanttVO1(Chromosome scheduleChromosome) {
List<com.aps.entity.Gantt.ProductGanttVO> productGanttVOList = new ArrayList<>();
// 按产品ID和工单ID分组基因
if (scheduleChromosome.getResult() != null) {
// 按工单ID分组
scheduleChromosome.getResult().stream()
.collect(Collectors.groupingBy(GAScheduleResult::getOrderId))
.forEach((orderId, genes) -> {
if (!genes.isEmpty()) {
com.aps.entity.Gantt.ProductGanttVO productGanttVO = new com.aps.entity.Gantt.ProductGanttVO();
GAScheduleResult firstGene = genes.get(0);
productGanttVO.setId(firstGene.getOrderId());
productGanttVO.setProductName("产品"+firstGene.getProductId()); // 默认值,实际应从订单数据获取
productGanttVO.setProductType(0);
productGanttVO.setProductId(firstGene.getProductId());
// 计算总数量(假设同一批次)
productGanttVO.setQuantity(firstGene.getQuantity());
productGanttVO.setCode("编号"+firstGene.getProductId()); // 默认值
productGanttVO.setShopId(firstGene.getMachineId()); // 默认值
productGanttVO.setShopName(firstGene.getMachineId()+"号线"); // 默认值
productGanttVO.setStatus("已发布");
// productGanttVO.setHeaderId(firstGene.getProductId());
productGanttVO.setHeaderName("工艺"+firstGene.getProductId()); // 默认值
// 计算开始和结束时间
int minStartTime = genes.stream()
.mapToInt(GAScheduleResult::getStartTime)
.min()
.orElse(0);
int maxEndTime = genes.stream()
.mapToInt(GAScheduleResult::getEndTime)
.max()
.orElse(0);
productGanttVO.setStartDate(scheduleChromosome.getBaseTime().plusMinutes(minStartTime));
productGanttVO.setEndDate(scheduleChromosome.getBaseTime().plusMinutes(maxEndTime));
// 转换任务列表
List<com.aps.entity.Gantt.TaskVO> taskVOList = new ArrayList<>();
// // 按工序顺序排序
// genes.sort((g1, g2) -> Integer.compare(g1.getSequenceId(), g2.getSequenceId()));
for (int i = 0; i < genes.size(); i++) {
GAScheduleResult gene = genes.get(i);
com.aps.entity.Gantt.TaskVO taskVO = new com.aps.entity.Gantt.TaskVO();
taskVO.setId(String.valueOf(gene.getOperationId())); // 生成唯一ID
taskVO.setPlanId(String.valueOf(orderId));
taskVO.setProductType(0);
taskVO.setProductName("产品"+gene.getProductId());
taskVO.setProductId(String.valueOf(gene.getProductId()));
taskVO.setQuantity(gene.getQuantity());
taskVO.setStart(scheduleChromosome.getBaseTime().plusSeconds(gene.getStartTime()));
taskVO.setEnd(scheduleChromosome.getBaseTime().plusSeconds(gene.getEndTime()));
taskVO.setSetup(0); // 默认值
taskVO.setTeardown(gene.getTeardownTime()); // 默认值
taskVO.setEquipChange(gene.getChangeoverTime()); // 默认值
taskVO.setEquipCooling(0); // 默认值
// taskVO.setEquipType("PTT-" + (i+1) + "-" + gene.getOperationName().toUpperCase().substring(0, Math.min(3, gene.getOperationName().length())));
// taskVO.setEquipName(gene.getOperationName());
taskVO.setDuration(calculateDuration(
scheduleChromosome.getBaseTime().plusMinutes(gene.getStartTime()),
scheduleChromosome.getBaseTime().plusMinutes(gene.getEndTime())));
taskVO.setEquipId(gene.getMachineId()); // 生成设备ID
taskVO.setShopId(gene.getMachineId());
taskVO.setShopName(gene.getMachineId()+"车间");
taskVO.setStatus(0);
// taskVO.setDetailId((long) gene.getProductId() * 1000 + gene.getOperationId());
// taskVO.setHeaderId(gene.getProductId());
taskVO.setHeaderName("工艺"+gene.getProductId());
// taskVO.setSeq(gene.getSequenceId());
// taskVO.setSeqName("工序名称"+gene.getSequenceId());
// taskVO.setAbsoluteStart(scheduleChromosome.getBaseTime().plusMinutes(gene.getStartTime()));
// taskVO.setAbsoluteEnd(scheduleChromosome.getBaseTime().plusMinutes(gene.getEndTime()));
taskVOList.add(taskVO);
}
productGanttVO.setList(taskVOList);
productGanttVOList.add(productGanttVO);
}
});
}
merged.setStartTime(data.getShiftStart().toLocalTime());
merged.setEndTime(data.getShiftEnd().toLocalTime());
merged.setStatus(0);
return productGanttVOList;
// 初始化序号列表
Set<Integer> serials =new HashSet<>();
serials.add(data.getStartWeekDay());
merged.setDays(serials);
groupMap.put(groupKey, merged);
}
private ShiftVO convertToShiftVO(Machine machine) {
ShiftVO shiftVO= new ShiftVO();
shiftVO.setId(machine.getId());
shiftVO.setName(machine.getName());
shiftVO.setShifts(machine.getShifts());
shiftVO.setMaintenanceWindows(machine.getMaintenanceWindows());
// 注意:tasks 字段需要在其他地方设置,因为 Machine 类中没有任务信息
return shiftVO;
}
/**
* 计算任务持续时间(分钟)
* @param start 开始时间
* @param end 结束时间
* @return 持续时间(分钟)
*/
private Integer calculateDuration(LocalDateTime start, LocalDateTime end) {
if (start == null || end == null) {
return 0;
}
return Math.toIntExact(java.time.Duration.between(start, end).toMinutes());
// 转换为列表返回
return new ArrayList<>(groupMap.values());
}
}
\ No newline at end of file
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