持续时间

离散参数
parent 9640e865
package com.aps.service; package com.aps.service;
import com.aps.entity.Algorithm.GAScheduleResult;
import com.aps.entity.DiscreteParameterDuration; import com.aps.entity.DiscreteParameterDuration;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.Machine;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/** /**
* <p> * <p>
* 服务类 * 服务类
...@@ -14,6 +19,8 @@ import com.baomidou.mybatisplus.extension.service.IService; ...@@ -14,6 +19,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
public interface DiscreteParameterDurationService extends IService<DiscreteParameterDuration> { public interface DiscreteParameterDurationService extends IService<DiscreteParameterDuration> {
double getDiscreteParameterMatrixValue(Long fistDetail, Long secondDetail); double calculateChangeoverTime(List<GAScheduleResult> existingGenes,
Entry operation,
Machine machine,
List<Entry> allOperations,int startTime);
} }
package com.aps.service.impl; package com.aps.service.impl;
import com.aps.entity.Algorithm.GAScheduleResult;
import com.aps.entity.DiscreteParameterDuration; import com.aps.entity.DiscreteParameterDuration;
import com.aps.entity.DiscreteParameterMatrix; import com.aps.entity.basic.Entry;
import com.aps.entity.RoutingDiscreteParam; import com.aps.entity.basic.Machine;
import com.aps.mapper.DiscreteParameterDurationMapper; import com.aps.mapper.DiscreteParameterDurationMapper;
import com.aps.service.DiscreteParameterDurationService; import com.aps.service.DiscreteParameterDurationService;
import com.aps.service.RoutingDiscreteParamService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author MyBatis-Plus
* @since 2025-12-05
*/
@Service @Service
public class DiscreteParameterDurationServiceImpl extends ServiceImpl<DiscreteParameterDurationMapper, DiscreteParameterDuration> implements DiscreteParameterDurationService { public class DiscreteParameterDurationServiceImpl extends ServiceImpl<DiscreteParameterDurationMapper, DiscreteParameterDuration> implements DiscreteParameterDurationService {
@Autowired
private RoutingDiscreteParamService _routingDiscreteParamService; /**
* 计算当前工序需要的换型时间
*/
@Override @Override
public double getDiscreteParameterMatrixValue(Long fistDetail, Long secondDetail) { public double calculateChangeoverTime(List<GAScheduleResult> existingGenes,
Entry operation,
Machine machine,
List<Entry> allOperations,
int startTime) {
if (existingGenes.isEmpty()) {
return 0.0;
}
// 获取当前工序的所有参数
List<ParameterPair> currentParams = getOperationParameters(operation);
if (currentParams.isEmpty()) {
return 0.0;
}
// 获取设备上最后一个任务
GAScheduleResult lastGene = existingGenes.stream()
.filter(g -> g.getMachineId() == machine.getId())
.max(Comparator.comparingInt(GAScheduleResult::getEndTime))
.orElse(null);
if (lastGene == null) {
return 0.0;
}
// 找到最后一个任务对应的Entry
Entry prev = allOperations.stream()
.filter(t -> t.getExecId().equals(lastGene.getExecId()))
.findFirst().orElse(null);
if (prev == null) {
return 0.0;
}
List<ParameterPair> lastParams = getOperationParameters(prev);
List<DiscreteParameterDuration> parameterDurations = this.lambdaQuery().list();
// 获取该设备上的所有任务(按开始时间排序)
List<GAScheduleResult> machineGenes = existingGenes.stream()
.filter(g -> g.getMachineId() == machine.getId())
.sorted(Comparator.comparingInt(GAScheduleResult::getStartTime))
.collect(Collectors.toList());
double maxChangeoverTime = 0.0;
for (ParameterPair currentParam : currentParams) {
double paramChangeoverTime = calculateChangeoverTimeForParameter(
currentParam, lastParams, machineGenes, parameterDurations, startTime, allOperations);
maxChangeoverTime = Math.max(maxChangeoverTime, paramChangeoverTime);
}
return maxChangeoverTime;
}
/**
* 为单个参数计算换型时间
*/
private double calculateChangeoverTimeForParameter(ParameterPair currentParam,
List<ParameterPair> lastParams,
List<GAScheduleResult> machineGenes,
List<DiscreteParameterDuration> parameterDurations,
int startTime, List<Entry> allOperations) {
// 查找相同参数的历史任务链(精确匹配groupid和parameterid)
List<GAScheduleResult> sameParamTaskChain = findSameParameterTaskChain(currentParam, machineGenes, allOperations);
if (sameParamTaskChain.isEmpty()) {
return 0.0;
}
// 分别计算四种规则的换型时间
double changeoverTime1 = calculateByWorkingDuration(currentParam, lastParams, sameParamTaskChain, parameterDurations, allOperations);
double changeoverTime2 = calculateByAbsoluteDuration(currentParam, lastParams, sameParamTaskChain, parameterDurations, startTime, allOperations);
double changeoverTime3 = calculateByMaxInterval(currentParam, lastParams, sameParamTaskChain, parameterDurations, startTime, allOperations);
double changeoverTime4 = calculateByOrderCount(currentParam, lastParams, sameParamTaskChain, parameterDurations, allOperations);
double changeoverTime5 = calculateByAccumulatedQuantity(currentParam, lastParams, sameParamTaskChain, parameterDurations, allOperations);
// 取五种规则中的最大值
return Math.max(Math.max(Math.max(changeoverTime1, changeoverTime2), Math.max(changeoverTime3, changeoverTime4)),
changeoverTime5);
}
/**
* 规则1:工作时间长检查(精确匹配参数)
*/
private double calculateByWorkingDuration(ParameterPair currentParam, List<ParameterPair> lastParams,
List<GAScheduleResult> sameParamChain,
List<DiscreteParameterDuration> parameterDurations,
List<Entry> allOperations) {
DiscreteParameterDuration config = findParameterConfig(currentParam, "WorkingDuration", parameterDurations);
if (config == null) {
return 0.0;
}
long maxWorkingSeconds = config.getMeasureduration().longValue();
// 从后往前找最近的换型点
int lastChangeoverIndex = findLastChangeoverIndex(sameParamChain);
// 计算从换型点之后的总工作时间(只计算精确匹配的任务)
long totalWorkingSeconds = 0;
for (int i = lastChangeoverIndex + 1; i < sameParamChain.size(); i++) {
GAScheduleResult task = sameParamChain.get(i);
// 验证任务参数是否精确匹配当前参数
if (isExactParameterMatch(task, currentParam, allOperations)) {
totalWorkingSeconds += (task.getEndTime() - task.getStartTime());
} else {
// 遇到不匹配的任务,停止累计(因为参数已变化)
break;
}
}
if (totalWorkingSeconds >= maxWorkingSeconds) {
return calculateMaxChangeoverDuration(lastParams, currentParam, parameterDurations);
}
return 0.0;
}
/**
* 规则2:绝对工作时间长检查(精确匹配参数)
*/
private double calculateByAbsoluteDuration(ParameterPair currentParam, List<ParameterPair> lastParams,
List<GAScheduleResult> sameParamChain,
List<DiscreteParameterDuration> parameterDurations,
int startTime, List<Entry> allOperations) {
DiscreteParameterDuration config = findParameterConfig(currentParam, "AbsoluteDuration", parameterDurations);
if (config == null) {
return 0.0;
}
if (sameParamChain.isEmpty()) {
return 0.0;
}
// 从后往前找最近的换型点
int lastChangeoverIndex = findLastChangeoverIndex(sameParamChain);
// 找到第一个精确匹配参数的任务
GAScheduleResult startTask = findFirstExactMatchTask(sameParamChain, currentParam, lastChangeoverIndex, allOperations);
if (startTask == null) {
return 0.0;
}
long absoluteDurationSeconds = calculateAbsoluteDuration(startTask, startTime);
long maxAbsoluteSeconds = config.getMeasureduration().longValue();
if (absoluteDurationSeconds >= maxAbsoluteSeconds) {
return calculateMaxChangeoverDuration(lastParams, currentParam, parameterDurations);
}
return 0.0;
}
/**
* 规则3:工作间隔时间检查(精确匹配参数)
*/
private double calculateByMaxInterval(ParameterPair currentParam, List<ParameterPair> lastParams,
List<GAScheduleResult> sameParamChain,
List<DiscreteParameterDuration> parameterDurations,
int startTime, List<Entry> allOperations) {
DiscreteParameterDuration config = findParameterConfig(currentParam, "MaxInterval", parameterDurations);
if (config == null) {
return 0.0;
}
if (sameParamChain.isEmpty()) {
return 0.0;
}
// 找到最后一个精确匹配参数的任务
GAScheduleResult lastTask = findLastExactMatchTask(sameParamChain, currentParam, allOperations);
if (lastTask == null) {
return 0.0;
}
List<RoutingDiscreteParam> firstParams = getRoutingParams(fistDetail); // 计算从上一个任务结束到当前开始时间的间隔
List<RoutingDiscreteParam> secondParams = getRoutingParams(secondDetail); long intervalSeconds = startTime - lastTask.getEndTime();
long maxIntervalSeconds = config.getMeasureduration().longValue();
findMatchingParams(firstParams, secondParams); if (intervalSeconds > maxIntervalSeconds) {
return calculateMaxChangeoverDuration(lastParams, currentParam, parameterDurations);
}
return 0.0;
}
/**
* 规则4:工单数量换型检查(精确匹配参数)
*/
private double calculateByOrderCount(ParameterPair currentParam, List<ParameterPair> lastParams,
List<GAScheduleResult> sameParamChain,
List<DiscreteParameterDuration> parameterDurations,
List<Entry> allOperations) {
DiscreteParameterDuration config = findParameterConfig(currentParam, "OrderCount", parameterDurations);
if (config == null) {
return 0.0;
}
// 获取配置的工单数量阈值
int maxOrderCount = config.getMeasureduration().intValue();
// 计算从最近换型点之后,精确匹配参数的任务数量
int orderCount = calculateOrderCountSinceLastChangeover(currentParam, sameParamChain, allOperations);
if (orderCount >= maxOrderCount) {
return calculateMaxChangeoverDuration(lastParams, currentParam, parameterDurations);
}
return 0; return 0.0;
} }
private List<RoutingDiscreteParam> findMatchingParams( /**
List<RoutingDiscreteParam> firstParams, * 查找相同参数的任务链(精确匹配groupid和parameterid)
List<RoutingDiscreteParam> secondParams) { */
private List<GAScheduleResult> findSameParameterTaskChain(ParameterPair targetParam,
List<GAScheduleResult> machineGenes,
List<Entry> allOperations) {
List<GAScheduleResult> sameParamChain = new ArrayList<>();
Set<String> secondGroupIds = secondParams.stream() // 从最新的任务开始往前找
.map(RoutingDiscreteParam::getGroupId) for (int i = machineGenes.size() - 1; i >= 0; i--) {
.filter(Objects::nonNull) GAScheduleResult gene = machineGenes.get(i);
.collect(Collectors.toSet());
return firstParams.stream() // 精确匹配:groupid和parameterid都必须相同
.filter(param -> param.getGroupId() != null && secondGroupIds.contains(param.getGroupId())) if (isExactParameterMatch(gene, targetParam, allOperations)) {
sameParamChain.add(0, gene); // 添加到开头保持时间顺序
// 如果这个任务有换型,停止追溯(换型后重新计算)
if (gene.getChangeoverTime() > 0) {
break;
}
} else {
break; // 遇到不同参数的任务,停止追溯
}
}
return sameParamChain;
}
/**
* 检查任务参数是否精确匹配目标参数
*/
private boolean isExactParameterMatch(GAScheduleResult task, ParameterPair targetParam, List<Entry> allOperations) {
List<ParameterPair> taskParams = getGeneParameters(task, allOperations);
return taskParams.stream()
.anyMatch(param -> param.getGroupId().equals(targetParam.getGroupId()) &&
param.getParameterId().equals(targetParam.getParameterId()));
}
/**
* 找到第一个精确匹配参数的任务
*/
private GAScheduleResult findFirstExactMatchTask(List<GAScheduleResult> sameParamChain,
ParameterPair targetParam,
int lastChangeoverIndex,
List<Entry> allOperations) {
for (int i = lastChangeoverIndex + 1; i < sameParamChain.size(); i++) {
GAScheduleResult task = sameParamChain.get(i);
if (isExactParameterMatch(task, targetParam, allOperations)) {
return task;
}
}
return null;
}
/**
* 找到最后一个精确匹配参数的任务
*/
private GAScheduleResult findLastExactMatchTask(List<GAScheduleResult> sameParamChain,
ParameterPair targetParam,
List<Entry> allOperations) {
for (int i = sameParamChain.size() - 1; i >= 0; i--) {
GAScheduleResult task = sameParamChain.get(i);
if (isExactParameterMatch(task, targetParam, allOperations)) {
return task;
}
}
return null;
}
/**
* 计算从最近换型点之后,精确匹配参数的任务数量
*/
private int calculateOrderCountSinceLastChangeover(ParameterPair targetParam,
List<GAScheduleResult> sameParamChain,
List<Entry> allOperations) {
// 从后往前找最近的换型点
int lastChangeoverIndex = findLastChangeoverIndex(sameParamChain);
int validOrderCount = 0;
// 从换型点之后开始统计
for (int i = lastChangeoverIndex + 1; i < sameParamChain.size(); i++) {
GAScheduleResult task = sameParamChain.get(i);
// 只统计精确匹配参数的任务
if (isExactParameterMatch(task, targetParam, allOperations)) {
validOrderCount++;
} else {
// 遇到不匹配的参数,停止计数(因为参数已变化)
break;
}
}
return validOrderCount;
}
/**
* 找到最近的换型点索引
*/
private int findLastChangeoverIndex(List<GAScheduleResult> taskChain) {
for (int i = taskChain.size() - 1; i >= 0; i--) {
if (taskChain.get(i).getChangeoverTime() > 0) {
return i;
}
}
return -1;
}
/**
* 计算绝对时间跨度
*/
private long calculateAbsoluteDuration(GAScheduleResult task, int startTime) {
return startTime - task.getStartTime();
}
/**
* 计算与所有历史参数的最大换型时间
*/
private double calculateMaxChangeoverDuration(List<ParameterPair> fromParams, ParameterPair toParam,
List<DiscreteParameterDuration> parameterDurations) {
if (fromParams.isEmpty()) {
return 0.0;
}
double maxChangeoverTime = 0.0;
for (ParameterPair fromParam : fromParams) {
if (fromParam.equals(toParam)) {
continue;
}
double changeoverTime = getChangeoverDuration(fromParam, toParam, parameterDurations);
maxChangeoverTime = Math.max(maxChangeoverTime, changeoverTime);
}
return maxChangeoverTime;
}
// 其他辅助方法保持不变...
private List<ParameterPair> getGeneParameters(GAScheduleResult gene, List<Entry> allOperations) {
Entry prev = allOperations.stream()
.filter(t -> t.getExecId().equals(gene.getExecId()))
.findFirst().orElse(null);
if (prev == null || prev.getDiscreteParameter() == null) {
return new ArrayList<>();
}
return prev.getDiscreteParameter().stream()
.map(param -> new ParameterPair(param.getGroupId(), param.getParameterId()))
.filter(pair -> pair.getGroupId() != null && pair.getParameterId() != null)
.collect(Collectors.toList());
}
private List<ParameterPair> getOperationParameters(Entry operation) {
if (operation == null || operation.getDiscreteParameter() == null) {
return new ArrayList<>();
}
return operation.getDiscreteParameter().stream()
.map(param -> new ParameterPair(param.getGroupId(), param.getParameterId()))
.filter(pair -> pair.getGroupId() != null && pair.getParameterId() != null)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
private List<RoutingDiscreteParam> getRoutingParams(Long detailId) { private DiscreteParameterDuration findParameterConfig(ParameterPair param, String configType,
return _routingDiscreteParamService.lambdaQuery() List<DiscreteParameterDuration> parameterDurations) {
.eq(RoutingDiscreteParam::getRoutingDetailId, detailId) return parameterDurations.stream()
.eq(RoutingDiscreteParam::getIsDeleted, 0) .filter(pd -> param.getGroupId().equals(pd.getGroupid()) &&
.list(); param.getParameterId().equals(pd.getParameterid()) &&
configType.equals(pd.getExp1()))
.findFirst()
.orElse(null);
}
private double getChangeoverDuration(ParameterPair fromParam, ParameterPair toParam,
List<DiscreteParameterDuration> parameterDurations) {
return parameterDurations.stream()
.filter(pd -> fromParam.getGroupId().equals(pd.getGroupid()) &&
fromParam.getParameterId().equals(pd.getParameterid()) &&
toParam.getParameterId().equals(pd.getExp2()))
.findFirst()
.map(pd -> pd.getMeasureduration().doubleValue())
.orElse(0.0);
} }
private double findMaxChangeOverTime(List<RoutingDiscreteParam> matchingParams,
List<RoutingDiscreteParam> secondParams) {
Set<String> groupIds = matchingParams.stream()
.map(RoutingDiscreteParam::getGroupId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
if (groupIds.isEmpty()) { /**
* 规则5:累计数量换型检查
* 例如:累计生产数量达到2500就需要换型
*/
private double calculateByAccumulatedQuantity(ParameterPair currentParam, List<ParameterPair> lastParams,
List<GAScheduleResult> sameParamChain,
List<DiscreteParameterDuration> parameterDurations,
List<Entry> allOperations) {
DiscreteParameterDuration config = findParameterConfig(currentParam, "AccumulatedQuantity", parameterDurations);
if (config == null) {
return 0.0; return 0.0;
} }
// 获取矩阵数据 // 获取配置的累计数量阈值
List<DiscreteParameterDuration> matrixData = getMatrixData(groupIds); double maxQuantity = config.getMeasureduration().doubleValue();
// // 按优先级查找匹配的矩阵记录 // 计算从最近换型点之后的累计数量
// List<DiscreteParameterMatrix> matchedMatrix = findMatchedMatrixByPriority( double accumulatedQuantity = calculateAccumulatedQuantitySinceLastChangeover(currentParam, sameParamChain, allOperations);
// matchingParams, secondParams, matrixData);
if (accumulatedQuantity >= maxQuantity) {
return calculateMaxChangeoverDuration(lastParams, currentParam, parameterDurations);
}
return 0.0; return 0.0;
} }
private List<DiscreteParameterDuration> getMatrixData(Set<String> groupIds) { /**
// 直接使用this调用,避免循环依赖 * 计算从最近换型点之后,精确匹配参数的累计数量
return this.lambdaQuery() */
.in(DiscreteParameterDuration::getGroupid, groupIds) private double calculateAccumulatedQuantitySinceLastChangeover(ParameterPair targetParam,
.eq(DiscreteParameterDuration::getIsdeleted, 0) List<GAScheduleResult> sameParamChain,
.list(); List<Entry> allOperations) {
// 从后往前找最近的换型点
int lastChangeoverIndex = findLastChangeoverIndex(sameParamChain);
double accumulatedQuantity = 0.0;
// 从换型点之后开始统计
for (int i = lastChangeoverIndex + 1; i < sameParamChain.size(); i++) {
GAScheduleResult task = sameParamChain.get(i);
// 只统计精确匹配参数的任务数量
if (isExactParameterMatch(task, targetParam, allOperations)) {
accumulatedQuantity += getTaskQuantity(task, allOperations);
} else {
// 遇到不匹配的参数,停止累计(因为参数已变化)
break;
}
}
return accumulatedQuantity;
} }
/**
* 获取任务的数量
*/
private double getTaskQuantity(GAScheduleResult task, List<Entry> allOperations) {
Entry entry = allOperations.stream()
.filter(t -> t.getExecId().equals(task.getExecId()))
.findFirst().orElse(null);
return entry != null ? entry.getQuantity() : 0.0;
}
/**
* 参数对封装类
*/
private static class ParameterPair {
private final String groupId;
private final String parameterId;
public ParameterPair(String groupId, String parameterId) {
this.groupId = groupId;
this.parameterId = parameterId;
}
public String getGroupId() { return groupId; }
public String getParameterId() { return parameterId; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ParameterPair that = (ParameterPair) o;
return Objects.equals(groupId, that.groupId) &&
Objects.equals(parameterId, that.parameterId);
}
} @Override
public int hashCode() {
return Objects.hash(groupId, parameterId);
}
@Override
public String toString() {
return groupId + ":" + parameterId;
}
}
}
\ 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