Commit f7bdf363 authored by Tong Li's avatar Tong Li

遗传算法

parent eee3a165
......@@ -106,9 +106,9 @@ public class ResourceGanttController {
@GetMapping("/getScene")
@Operation(summary = "获取所有场景ID", description = "获取所有场景ID")
public List<Chromosome> getScene() {
public Chromosome getScene() {
// 调用 PlanResultService 获取 ScheduleChromosome 列表
List<Chromosome> scheduleChromosomes = planResultService.execute1();
Chromosome scheduleChromosomes = planResultService.execute1();
// 提取所有场景ID
return scheduleChromosomes;
......@@ -116,9 +116,9 @@ public class ResourceGanttController {
@GetMapping("/getScene2")
@Operation(summary = "获取所有场景ID", description = "获取所有场景ID")
public List<Chromosome> getScene2() {
public Chromosome getScene2() {
// 调用 PlanResultService 获取 ScheduleChromosome 列表
List<Chromosome> scheduleChromosomes = planResultService.execute2("EAA26D85B5824B40A17554297B4EA32B");
Chromosome scheduleChromosomes = planResultService.execute2("B571EF6682DB463AB2977B1055A74112");
// 提取所有场景ID
return scheduleChromosomes;
......
......@@ -12,11 +12,18 @@ import java.util.List;
@Data
public class GAScheduleResult {
private int GroupId;
private int ProductId;
private int OperationId;
/**
* 工单ID
*/
public String ExecId ;
public String OrderId ;
private String productId;
private long MachineId;
private int StartTime; // 相对开始时间(分钟)
private int EndTime; // 相对结束时间(分钟)
private int StartTime; // 相对开始时间(秒)
private int EndTime; // 相对结束时间(秒)
private int teardownTime; //后处理
private double Quantity; // 批次大小(订单可拆分)
private List<ScheduleResultDetail> GeneDetails; // 时间详情
private double OneTime; // 单件工时
......
package com.aps.entity.Algorithm.IDAndChildID;
import java.util.List;
import java.util.Map;
/**
* 作者:佟礼
* 时间:2025-11-29
*/
// 存储分组结果:节点信息列表、新父子映射
// 存储分组结果:节点信息列表、原始ID(String)→全局序号映射
// 存储分组结果:节点信息列表、原始ID→全局序号映射
public class GroupResult {
private List<NodeInfo> nodeInfoList;
private Map<String, Integer> originalToGlobalSerial;
public GroupResult(List<NodeInfo> nodeInfoList, Map<String, Integer> originalToGlobalSerial) {
this.nodeInfoList = nodeInfoList;
this.originalToGlobalSerial = originalToGlobalSerial;
}
// getter
public List<NodeInfo> getNodeInfoList() { return nodeInfoList; }
public Map<String, Integer> getOriginalToGlobalSerial() { return originalToGlobalSerial; }
}
package com.aps.entity.Algorithm.IDAndChildID;
import lombok.Data;
import java.util.List;
/**
* 作者:佟礼
* 时间:2025-11-29
*/
// 存储节点信息:原ID、新序号、新父ID、新子ID列表
@Data
// 存储节点信息:原ID(String)、全局新序号、分组内序号、新父ID列表、新子ID列表
public class NodeInfo {
private String originalId; // 原始ID
private Integer globalSerial; // 全局新序号
private Integer groupSerial; // 分组内序号
private List<Integer> newParentIds; // 新父ID列表(基于全局序号)
private List<Integer> newChildIds; // 新子ID列表(基于全局序号)
public NodeInfo(String originalId, Integer globalSerial, Integer groupSerial, List<Integer> newParentIds, List<Integer> newChildIds) {
this.originalId = originalId;
this.globalSerial = globalSerial;
this.groupSerial = groupSerial;
this.newParentIds = newParentIds;
this.newChildIds = newChildIds;
}
@Override
public String toString() {
return originalId + ":" + globalSerial;
}
}
......@@ -29,6 +29,7 @@ public class Entry {
*/
public String OrderId ;
private String productId;
/**
* 工单ID
*/
......@@ -36,7 +37,7 @@ public class Entry {
/**
* 离散参数
*/
public String DiscreteParameter ;
public List<String> DiscreteParameter ;
/**
* 基因编号
*/
......@@ -58,6 +59,11 @@ public class Entry {
*/
public List<Integer> PrevEntryIds ;//前工序
/**
* 前工单ID
*/
public List<Integer> NextEntryIds ;//后工序
/**
* 是否可中断,间缝插针
*/
......
......@@ -11,15 +11,17 @@ public class GlobalParam {
/// <summary>
/// 是否可以打破优先级
/// </summary>
public static boolean IsBreakPriority = false;
private boolean IsBreakPriority = false;
/// <summary>
/// 是否多台设备
/// </summary>
public static boolean IsMultipleMachine = false;
private boolean IsMultipleMachine = false;
/// <summary>
/// 是否重叠
/// </summary>
public static boolean IsOverlap = false;
private boolean IsOverlap = false;
private boolean _smoothSetup = false; // 默认true,不占用设备时长
}
......@@ -11,11 +11,14 @@ import java.time.OffsetDateTime;
@Data
public class Order {
private int id;
private String OrderId;
private int productId;
private String materialId;
private double quantity = 100; // 100个
private double sYQuantity;
private OffsetDateTime dueDate;
private LocalDateTime dueDate;
private LocalDateTime orderCompletion;
private double tardiness;
private int priority;
......
......@@ -96,38 +96,38 @@ public class ScheduleChromosome {
private List<Order> calTardiness() {
tardiness = 0;
for (Order order : orders) {
final int orderId = order.getId();
List<Gene> orderGroups = genes.stream()
.filter(g -> g.getOrderId() == orderId)
.collect(Collectors.toList());
int orderCompletion = orderGroups.stream()
.mapToInt(Gene::getEndTime)
.max()
.orElse(0);
LocalDateTime orderCompletionTime = baseTime.plusMinutes(orderCompletion);
order.setOrderCompletion(orderCompletionTime);
order.setTardiness(0);
// 修复:统一时间类型
LocalDateTime dueDateTime = order.getDueDate().toLocalDateTime();
if (orderCompletionTime.isAfter(dueDateTime)) {
// 方法1:使用分钟计算再转换为小时(推荐)
long totalMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime);
double tardinessHours = totalMinutes / 60.0;
// 方法2:或者保持原有逻辑但使用统一的时间类型
// long diffHours = java.time.temporal.ChronoUnit.HOURS.between(dueDateTime, orderCompletionTime);
// long remainingMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime) % 60;
// double tardinessHours = diffHours + (double) remainingMinutes / 60;
order.setTardiness(tardinessHours);
tardiness += tardinessHours;
}
}
return orders;
// for (Order order : orders) {
// final int orderId = order.getId();
// List<Gene> orderGroups = genes.stream()
// .filter(g -> g.getOrderId() == orderId)
// .collect(Collectors.toList());
//
// int orderCompletion = orderGroups.stream()
// .mapToInt(Gene::getEndTime)
// .max()
// .orElse(0);
//
// LocalDateTime orderCompletionTime = baseTime.plusMinutes(orderCompletion);
// order.setOrderCompletion(orderCompletionTime);
// order.setTardiness(0);
//
// // 修复:统一时间类型
// LocalDateTime dueDateTime = order.getDueDate();
//
// if (orderCompletionTime.isAfter(dueDateTime)) {
// // 方法1:使用分钟计算再转换为小时(推荐)
// long totalMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime);
// double tardinessHours = totalMinutes / 60.0;
//
// // 方法2:或者保持原有逻辑但使用统一的时间类型
// // long diffHours = java.time.temporal.ChronoUnit.HOURS.between(dueDateTime, orderCompletionTime);
// // long remainingMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime) % 60;
// // double tardinessHours = diffHours + (double) remainingMinutes / 60;
//
// order.setTardiness(tardinessHours);
// tardiness += tardinessHours;
// }
// }
return null;
}
}
\ No newline at end of file
......@@ -6,10 +6,7 @@ import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.Algorithm.GlobalOperationInfo;
import com.aps.entity.Algorithm.Pair;
import com.aps.entity.Algorithm.ScheduleParams;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.Machine;
import com.aps.entity.basic.Material;
import com.aps.entity.basic.Order;
import com.aps.entity.basic.*;
import com.aps.service.plan.MachineSchedulerService;
import java.util.*;
......@@ -25,20 +22,22 @@ public class GeneticAlgorithm {
private final MachineSchedulerService machineScheduler;
private final List<Order> orders;
private final List<Material> materials;
private static GlobalParam _GlobalParam;
public GeneticAlgorithm(List<Machine> machines, List<Order> orders,
public GeneticAlgorithm(GlobalParam globalParam,List<Machine> machines, List<Order> orders,
List<Material> materials, MachineSchedulerService machineScheduler) {
this.machines = machines;
this.orders = orders;
this.materials = materials;
this.machineScheduler = machineScheduler;
_GlobalParam=globalParam;
}
public List<Chromosome> Run(ScheduleParams param, List<Entry> allOperations) {
public Chromosome Run(ScheduleParams param, List<Entry> allOperations) {
System.out.println("开始");
Initialization initialization = new Initialization(allOperations);
Initialization initialization = new Initialization(_GlobalParam,allOperations);
GeneticOperations geneticOps = new GeneticOperations(allOperations);
GeneticOperations geneticOps = new GeneticOperations(_GlobalParam,allOperations);
// 预生成全局工序列表(所有初始化方法共享同一顺序)
List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList();
......@@ -124,36 +123,43 @@ public class GeneticAlgorithm {
Iteration++;
}
if(Iteration>20)
if(Iteration>10)
{
break;
}
}
// 步骤3:返回最优解
return population.stream()
.sorted((c1, c2) -> Double.compare(c2.getFitness(), c1.getFitness()))
.limit(10)
.collect(Collectors.toList());
return best;
}
private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population)
{
GeneticDecoder decoder = new GeneticDecoder(param.getBaseTime(), machines, orders, materials, machineScheduler);
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler);
FitnessCalculator fitnessCalc = new FitnessCalculator();
population.parallelStream().forEach(chromosome -> {
// 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));
// });
population.forEach(chromosome -> {
chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
decoder.decodeChromosomeWithCache(chromosome, globalOpList, allOperations);
chromosome.setFitness(fitnessCalc.calculateFitness(chromosome));
Chromosome chromosomen= decoder.decodeChromosomeWithCache(chromosome, globalOpList, allOperations);
if(chromosomen.getFitness()==0) {
chromosomen.setFitness(fitnessCalc.calculateFitness(chromosomen));
}
});
}
}
......@@ -18,9 +18,13 @@ import java.util.stream.Collectors;
*/
public class GeneticOperations {
private final Random rnd = new Random();
private static GlobalParam _GlobalParam;
private static List<Entry> allOperations;
public GeneticOperations(List<Entry> allOperations) {
public GeneticOperations(GlobalParam globalParam,List<Entry> allOperations) {
_GlobalParam=globalParam;
GeneticOperations.allOperations = allOperations;
}
......@@ -225,7 +229,7 @@ public class GeneticOperations {
Random rnd = new Random();
List<OperationSequencingWeight> indexWeights = CommonCalculator.getOsw(os, allOperations);
if (!GlobalParam.IsBreakPriority) {
if (!_GlobalParam.isIsBreakPriority()) {
if (weight == 0) {
return indexWeights.get(rnd.nextInt(indexWeights.size()));
} else {
......
......@@ -17,9 +17,11 @@ import java.util.stream.IntStream;
*/
public class Initialization {
private static List<Entry> allOperations;
private static GlobalParam _globalParam;
public Initialization(List<Entry> allOperations) {
public Initialization(GlobalParam globalParam,List<Entry> allOperations) {
Initialization.allOperations = allOperations;
_globalParam= globalParam;
}
/**
* 预生成全局工序列表(按“订单0→订单1→…+订单内工序1→2→…”排序,分配GlobalOpId)
......@@ -257,7 +259,7 @@ int populationSize=param.getPopulationSize();
*/
private List<Integer> shuffleWithPriority(List<Integer> os) {
if (!GlobalParam.IsBreakPriority) {
if (!_globalParam.isIsBreakPriority()) {
return new ArrayList<>(os);
}
......
......@@ -4,6 +4,7 @@ import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.GAScheduleResult;
import com.aps.entity.Algorithm.ScheduleResultDetail;
import com.aps.entity.basic.*;
import com.aps.service.plan.AlgorithmScheduler8;
import com.aps.service.plan.MachineSchedulerService;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
......@@ -37,15 +38,15 @@ public class MachineCalculator {
* 获取机器下一个可用时间窗口(考虑班次约束)
*/
public List<ScheduleResultDetail> getNextAvailableTime(Machine machine, int proposedStartTime,
int prevtime, double processingTime,
int prevtime, int processingTime,
List<GAScheduleResult> existingTasks,
boolean isInterrupt, boolean istask,
boolean islockMachineTime) {
LocalDateTime startTime = baseTime.plus(proposedStartTime, ChronoUnit.MINUTES);
LocalDateTime startTime = baseTime.plus(proposedStartTime, ChronoUnit.SECONDS);
String prevtimestr = "";
if (prevtime > -1) {
prevtimestr = baseTime.plus(prevtime, ChronoUnit.MINUTES)
prevtimestr = baseTime.plus(prevtime, ChronoUnit.SECONDS)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
......@@ -55,54 +56,49 @@ public class MachineCalculator {
}
// 查找最早可用开始时间
private List<ScheduleResultDetail> findEarliestStart(Machine machine, double processingTime,
LocalDateTime currentTime, String prevtime,
List<GAScheduleResult> existingTasks,
boolean checkprevtime, boolean islockMachineTime) {
// 获取设备上已有任务
private List<ScheduleResultDetail> findEarliestStart(
Machine machine, int processingTime, LocalDateTime currentTime,
String prevtime, List<GAScheduleResult> existingTasks, boolean checkprevtime, boolean islockMachineTime
) {
List<GAScheduleResult> machineTasks = existingTasks.stream()
.filter(t -> t.getMachineId() == machine.getId())
.sorted(Comparator.comparingInt(GAScheduleResult::getStartTime))
.collect(Collectors.toList());
List<ScheduleResultDetail> times = new ArrayList<>();
TimeSegment slot =GetCurrentOrNextShift(machine, currentTime, prevtime, checkprevtime);
LocalDateTime startCandidate = slot.getStart().isAfter(
(prevtime.isEmpty() ? currentTime : LocalDateTime.parse(prevtime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
) ? slot.getStart() : (prevtime.isEmpty() ? currentTime : LocalDateTime.parse(prevtime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
TimeSegment slot = GetCurrentOrNextShift(machine, currentTime, prevtime, checkprevtime);
if (slot == null) return times;
LocalDateTime endCandidate = startCandidate.plus((long)processingTime, ChronoUnit.MINUTES);
LocalDateTime prevTimeDateTime = StringUtils.isEmpty(prevtime) ? null : LocalDateTime.parse(prevtime);
LocalDateTime startCandidate = slot.getStart().isAfter(prevTimeDateTime != null ? prevTimeDateTime : currentTime)
? slot.getStart()
: (prevTimeDateTime != null ? prevTimeDateTime : currentTime);
LocalDateTime endCandidate = startCandidate.plusSeconds(processingTime);
// 检查是否在可用时间段内
if (endCandidate.isAfter(slot.getEnd())) {
// 放不下,继续寻找后续可用时间
return CaldEarliestStart(machine, processingTime, currentTime, prevtime,
machineTasks, checkprevtime, islockMachineTime);
return CaldEarliestStart(machine, processingTime, currentTime, prevtime, machineTasks, checkprevtime,islockMachineTime);
} else {
ScheduleResultDetail time = new ScheduleResultDetail();
time.setKey(slot.getKey());
time.setStartTime((int) ChronoUnit.MINUTES.between(baseTime, startCandidate));
time.setEndTime((int) ChronoUnit.MINUTES.between(baseTime, endCandidate));
time.setStartTime((int) ChronoUnit.SECONDS.between(baseTime, startCandidate));
time.setEndTime((int) ChronoUnit.SECONDS.between(baseTime, endCandidate));
times.add(time);
if (islockMachineTime) {
if(islockMachineTime) {
RemoveMachineAvailable(machine, time);
}
return times;
}
}
private List<ScheduleResultDetail> CaldEarliestStart(
Machine machine, double processingTime, LocalDateTime currentTime,
Machine machine, int processingTime, LocalDateTime currentTime,
String prevtime, List<GAScheduleResult> machineTasks, boolean checkprevtime, boolean islockMachineTime
) {
double remainingTime = processingTime;
int remainingTime = processingTime;
LocalDateTime st = StringUtils.isEmpty(prevtime) ? currentTime : LocalDateTime.parse(prevtime);
LocalDateTime prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0, 0);
List<ScheduleResultDetail> times = new ArrayList<>();
......@@ -122,7 +118,7 @@ public class MachineCalculator {
LocalDateTime finalPrevEnd = prevEnd;
boolean hasTask = machineTasks.stream()
.anyMatch(t -> {
LocalDateTime taskStart = baseTime.plusMinutes(t.getStartTime());
LocalDateTime taskStart = baseTime.plusSeconds(t.getStartTime());
return taskStart.isAfter(finalPrevEnd) && taskStart.isBefore(shiftStart);
});
......@@ -158,29 +154,34 @@ public class MachineCalculator {
prevEnd = shiftEnd;
// 计算有效时间
LocalDateTime effectiveStart = st.isAfter(shiftStart) ? st : shiftStart;
long availableMinutes = ChronoUnit.MINUTES.between(effectiveStart, shiftEnd);
long availableSeconds = ChronoUnit.SECONDS.between(effectiveStart, shiftEnd);
// 处理当前班次
double processable = Math.min(remainingTime, (int) availableMinutes);
int processable = Math.min(remainingTime, (int) availableSeconds);
remainingTime -= processable;
currentTime = effectiveStart.plusMinutes((long)processable);
currentTime = effectiveStart.plusSeconds(processable);
// 添加时间详情
ScheduleResultDetail time = new ScheduleResultDetail();
time.setKey(shift.getKey());
time.setStartTime((int) ChronoUnit.MINUTES.between(baseTime, effectiveStart));
time.setEndTime((int) ChronoUnit.MINUTES.between(baseTime, currentTime));
time.setStartTime((int) ChronoUnit.SECONDS.between(baseTime, effectiveStart));
time.setEndTime((int) ChronoUnit.SECONDS.between(baseTime, currentTime));
times.add(time);
if (islockMachineTime) {
// 还原未使用的时间段
RemoveMachineAvailable(machine, time);
}
}
// 还原未使用的时间段
if (islockMachineTime) {
// 还原未使用的时间段
AddMachineAvailable(machine, oldTimes);
}
return times;
}
/**
* 获取设备当前或下一个有效班次
*/
......@@ -196,7 +197,7 @@ public class MachineCalculator {
if (start == null) {
// 生成新时间段
List<TimeSegment> timeSegments = machineScheduler.generateTimeSegment(machine, time);
List<TimeSegment> timeSegments = machineScheduler.generateTimeSegment(machine, time.plusDays(1));
machine.getAvailability().addAll(timeSegments);
// 更新设备时间线
......@@ -215,6 +216,8 @@ public class MachineCalculator {
return start;
}
private void RemoveMachineAvailable(Machine machine, ScheduleResultDetail geneDetails) {
List<TimeSegment> timeSegments = new ArrayList<>();
......@@ -226,11 +229,11 @@ public class MachineCalculator {
if (index > -1) {
TimeSegment targetSegment = machine.getAvailability().get(index);
LocalDateTime geneEndTime = baseTime.plusMinutes(geneDetails.getEndTime());
LocalDateTime geneEndTime = baseTime.plusSeconds(geneDetails.getEndTime());
if (targetSegment.getEnd().isAfter(geneEndTime)) {
TimeSegment usedSegment = new TimeSegment();
usedSegment.setStart(baseTime.plusMinutes(geneDetails.getStartTime()));
usedSegment.setStart(baseTime.plusSeconds(geneDetails.getStartTime()));
usedSegment.setEnd(geneEndTime);
usedSegment.setHoliday(false);
usedSegment.setKey(UUID.randomUUID().toString());
......
......@@ -9,6 +9,7 @@ import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.util.*;
import java.util.function.Function;
......@@ -35,7 +36,7 @@ public class OrderSortService {
registerFieldExtractor("dueDate", Order -> {
// 直接返回LocalDate,处理null情况
return Optional.ofNullable(Order.getDueDate())
.map(OffsetDateTime::toLocalDate)
.map(LocalDateTime::toLocalDate)
.orElse(null);
});
registerFieldExtractor("priority", Order::getPriority);
......
......@@ -324,7 +324,7 @@ public class AlgorithmScheduler6 {
LocalDateTime completionTime = chromosome.getBaseTime().plusMinutes(orderCompletion);
// 修复:正确处理OffsetDateTime到LocalDateTime的转换
LocalDateTime dueDateTime = order.getDueDate().toLocalDateTime();
LocalDateTime dueDateTime = order.getDueDate();
if (completionTime.isAfter(dueDateTime)) {
// 计算延迟小时数(修复时间计算)
......
......@@ -473,7 +473,7 @@ public class AlgorithmScheduler7 {
if (order != null) {
LocalDateTime completionTime = chromosome.getBaseTime().plusMinutes(orderCompletion);
LocalDateTime dueDateTime = order.getDueDate().toLocalDateTime();
LocalDateTime dueDateTime = order.getDueDate();
if (completionTime.isAfter(dueDateTime)) {
long totalMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, completionTime);
......
......@@ -94,7 +94,7 @@ public class AlgorithmScheduler8 {
// 为每个订单分配工序
for (Order order : _orders) {
Product product = _products.stream()
.filter(p -> p.getId() == order.getProductId())
.filter(p -> p.getId()==order.getProductId())
.findFirst()
.orElseThrow(() -> new NoSuchElementException("Product not found: " + order.getProductId()));
......@@ -322,7 +322,7 @@ public class AlgorithmScheduler8 {
// 创建基因
Gene gene = new Gene();
gene.setOrderId(order.getId());
// gene.setOrderId(order.getId());
gene.setProductId(order.getProductId());
gene.setOperationId(operation.getId());
gene.setMachineId(machine.getId());
......@@ -415,21 +415,21 @@ public class AlgorithmScheduler8 {
.mapToInt(Gene::getEndTime)
.max()
.orElse(0);
Order order = _orders.stream()
.filter(o -> o.getId() == group.getKey())
.findFirst()
.orElse(null);
if (order != null) {
LocalDateTime completionTime = chromosome.getBaseTime().plusMinutes(orderCompletion);
LocalDateTime dueDateTime = order.getDueDate().toLocalDateTime();
if (completionTime.isAfter(dueDateTime)) {
long hours = ChronoUnit.HOURS.between(dueDateTime, completionTime);
long minutes = ChronoUnit.MINUTES.between(dueDateTime, completionTime) % 60;
tardiness += hours + (double) minutes / 60;
}
}
// Order order = _orders.stream()
// .filter(o -> o.getId() == group.getKey())
// .findFirst()
// .orElse(null);
//
// if (order != null) {
// LocalDateTime completionTime = chromosome.getBaseTime().plusMinutes(orderCompletion);
// LocalDateTime dueDateTime = order.getDueDate();
//
// if (completionTime.isAfter(dueDateTime)) {
// long hours = ChronoUnit.HOURS.between(dueDateTime, completionTime);
// long minutes = ChronoUnit.MINUTES.between(dueDateTime, completionTime) % 60;
// tardiness += hours + (double) minutes / 60;
// }
// }
}
// 3. 总换型时间
......
......@@ -206,7 +206,12 @@ public class MachineSchedulerService {
&& s.getDays() != null
&& containsDay(s.getDays(), date.getDayOfWeek()))
.collect(Collectors.toList());
if(shifts==null||shifts.size()==0) {
shifts = machine.getShifts().stream()
.filter(s -> s.getDays() != null
&& containsDay(s.getDays(), date.getDayOfWeek()))
.collect(Collectors.toList());
}
for (Shift shift : shifts) {
LocalDateTime shiftStart = date.atTime(shift.getStartTime());
LocalDateTime shiftEnd = shift.getEndTime().isBefore(shift.getStartTime()) ?
......@@ -247,6 +252,12 @@ public class MachineSchedulerService {
}
private List<TimeSegment> mergeSegments(List<TimeSegment> segments) {
if(segments==null||segments.size()==0)
{
return null;
}
List<TimeSegment> maintenanceSegments = segments.stream()
.filter(t -> t.getType() == SegmentType.MAINTENANCE)
.collect(Collectors.toList());
......
......@@ -69,7 +69,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(OffsetDateTime.now().plusDays(i)); // 到期日递增
order.setTardiness(i * 0.5);
order.setCanSplit(i % 2 == 0);
order.setCanInterrupt(i % 3 == 0);
......
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