Commit e90e9ad9 authored by Tong Li's avatar Tong Li

Merge remote-tracking branch 'origin/master' into tl

parents 30d0470a e44843a1
......@@ -31,3 +31,4 @@ build/
### VS Code ###
.vscode/
/src/main/resources/application.yml
......@@ -36,7 +36,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleIllegalArgumentException(IllegalArgumentException e) {
log.debug("参数校验失败: {}", e.getMessage());
log.error("参数校验失败:", e);
return R.failed(500, e.getMessage());
}
......@@ -46,7 +46,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(SceneGenerationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleSceneGenerationException(SceneGenerationException e) {
log.debug("场景生成异常: {}", e.getMessage());
log.error("场景生成异常:", e);
return R.failed(500, e.getMessage());
}
......@@ -56,7 +56,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public R<Void> handleRuntimeException(RuntimeException e) {
log.debug("运行时异常: {}", e.getMessage());
log.error("运行时异常:", e);
return R.failed(500, e.getMessage());
}
......@@ -66,7 +66,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(BindingException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public R<Void> handleBindingException(BindingException e) {
log.debug("MyBatis绑定异常: {}", e.getMessage());
log.error("MyBatis绑定异常:", e);
return R.failed(500, "数据绑定异常: " + e.getMessage());
}
......@@ -76,7 +76,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(MyBatisSystemException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public R<Void> handleMyBatisSystemException(MyBatisSystemException e) {
log.debug("MyBatis系统异常: {}", e.getMessage());
log.error("MyBatis系统异常:", e);
Throwable cause = e.getCause();
if (cause != null && cause.getMessage().contains("ORA-17004")) {
return R.failed(500, "数据库列类型无效,请检查查询参数是否正确");
......@@ -90,7 +90,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(SQLException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public R<Void> handleSQLException(SQLException e) {
log.debug("SQL异常: {}", e.getMessage());
log.error("SQL异常:", e);
return R.failed(500, "数据库访问异常: " + e.getMessage());
}
......@@ -100,7 +100,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(DataAccessException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public R<Void> handleDataAccessException(DataAccessException e) {
log.debug("数据访问异常: {}", e.getMessage());
log.error("数据访问异常:", e);
return R.failed(500, "数据访问异常: " + e.getMessage());
}
......@@ -110,7 +110,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
log.debug("参数验证异常: {}", e.getMessage());
log.error("参数验证异常:", e);
FieldError fieldError = e.getBindingResult().getFieldError();
if (fieldError != null) {
return R.failed(400, Objects.requireNonNull(fieldError.getDefaultMessage()));
......@@ -124,7 +124,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleBindException(BindException e) {
log.debug("参数绑定异常: {}", e.getMessage());
log.error("参数绑定异常:", e);
FieldError fieldError = e.getBindingResult().getFieldError();
if (fieldError != null) {
return R.failed(500, Objects.requireNonNull(fieldError.getDefaultMessage()));
......@@ -138,7 +138,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
log.debug("请求参数缺失: {}", e.getMessage());
log.error("请求参数缺失:", e);
return R.failed(500, "缺少必要参数: " + e.getParameterName());
}
......@@ -148,7 +148,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) {
log.debug("参数类型不匹配: {}", e.getMessage());
log.error("参数类型不匹配:", e);
return R.failed(500, "参数类型不匹配: " + e.getName());
}
......@@ -158,7 +158,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R<Void> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
log.debug("HTTP消息不可读: {}", e.getMessage());
log.error("HTTP消息不可读:", e);
return R.failed(500, "请求体格式错误");
}
......@@ -168,7 +168,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
public R<Void> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
log.debug("HTTP请求方法不支持: {}", e.getMessage());
log.error("HTTP请求方法不支持:", e);
return R.failed(405, "请求方法不支持: " + e.getMethod());
}
......@@ -178,7 +178,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
public R<Void> handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {
log.debug("HTTP媒体类型不支持: {}", e.getMessage());
log.error("HTTP媒体类型不支持:", e);
return R.failed(415, "媒体类型不支持: " + e.getContentType());
}
......@@ -188,7 +188,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public R<Void> handleNoHandlerFoundException(NoHandlerFoundException e) {
log.debug("404异常: {}", e.getMessage());
log.error("404异常:", e);
return R.failed(404, "请求的资源不存在: " + e.getRequestURL());
}
......@@ -198,7 +198,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public R<Void> handleException(Exception e) {
log.debug("未知异常: {}", e.getMessage());
log.error("未知异常:", e);
return R.failed(500, "系统异常,请联系管理员");
}
}
\ No newline at end of file
......@@ -5,6 +5,7 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 生产环境可用的深拷贝工具类
......@@ -109,4 +110,21 @@ public class ProductionDeepCopyUtil {
throw new RuntimeException("列表深拷贝失败", e);
}
}
public static <T> CopyOnWriteArrayList<T> deepCopyList(CopyOnWriteArrayList<T> source, Class<T> elementType) {
if (source == null) {
return new CopyOnWriteArrayList<>();
}
try {
String json = objectMapper.writeValueAsString(source);
return objectMapper.readValue(json,
objectMapper.getTypeFactory().constructCollectionType(CopyOnWriteArrayList.class, elementType));
} catch (Exception e) {
throw new RuntimeException("列表深拷贝失败", e);
}
}
}
\ No newline at end of file
......@@ -167,14 +167,14 @@ public class SwaggerMapParamConfig {
));
break;
case "operationedit":
case "operationEdit":
properties.put("sceneId", new StringSchema().description("场景ID").example("B571EF6682DB463AB2977B1055A74112"));
properties.put("operation", new StringSchema().description("操作对象"));
properties.put("entry", new StringSchema().description("操作对象"));
examples.put("编辑操作示例", createExample(
"编辑指定的操作",
"{\n" +
" \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
" \"operation\": {}\n" +
" \"entry\": {}\n" +
"}"
));
break;
......
package com.aps.controller.gantt;
import cn.hutool.core.bean.BeanUtil;
import com.aps.common.util.NumberUtils;
import com.aps.common.util.ParamValidator;
import com.aps.common.util.R;
......@@ -146,11 +147,31 @@ public class ResourceGanttController {
}
@GetMapping("/SyncMachines")
@Operation(summary = "更新设备信息缓存", description = "更新设备信息缓存")
public void SyncMachines() {
// 调用 PlanResultService 获取 ScheduleChromosome 列表
planResultService.InitCalendarToAllMachines();
@PostMapping("/editOrder")
@Operation(summary = "修改订单", description = "编辑场景中的订单信息",
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "编辑订单参数",
content = @io.swagger.v3.oas.annotations.media.Content(
mediaType = "application/json",
examples = @io.swagger.v3.oas.annotations.media.ExampleObject(
name = "编辑订单示例",
value = "{\n \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n \"order\": { }\n}"
)
)
)
)
public R<Chromosome> editOrder(@RequestBody Map<String, Object> params) {
log.info("editOrder 请求参数: {}", params);
String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
ParamValidator.validateSceneExists(sceneService, sceneId);
// 使用BeanUtil转换LinkedHashMap为Order对象
Order order = BeanUtil.toBean(params.get("order"), Order.class);
Chromosome result = planResultService.EditOrder(sceneId, order);
return R.ok(result);
}
......@@ -231,17 +252,16 @@ public class ResourceGanttController {
@PostMapping("/operationedit")
@PostMapping("/operationEdit")
@Operation(summary = "修改工单", description = "修改工单")
public R<Chromosome> operationedit(@RequestBody Map<String, Object> params) {
log.info("operationedit 请求参数: {}", params);
public R<Chromosome> operationEdit(@RequestBody Map<String, Object> params) {
log.info("operationEdit 请求参数: {}", params);
String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
ParamValidator.validateSceneExists(sceneService, sceneId);
// 处理Entry对象
Entry entry = (Entry) params.get("operation");
// 使用BeanUtil转换LinkedHashMap为Entry对象
Entry entry = BeanUtil.toBean(params.get("entry"), Entry.class);
Chromosome result = planResultService.EditOperation(sceneId, entry);
return R.ok(result);
......
......@@ -12,6 +12,7 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
/**
......@@ -113,7 +114,7 @@ public class Chromosome {
/// <summary>
/// 解码后的调度结果
/// </summary>
private List<GAScheduleResult> ResultOld=new ArrayList<>();
private List<GAScheduleResult> ResultOld=new CopyOnWriteArrayList<>();
/// <summary>
/// 最早完工时间
......
......@@ -140,4 +140,7 @@ public class Entry {
private BigDecimal runtime;//持续时间
private BigDecimal singleOut;//单件产出
private double changeLineTime;//换模时间
private BigDecimal setupTime;
private int constTime;
}
......@@ -5,6 +5,7 @@ import lombok.Data;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
@Data
......@@ -15,7 +16,7 @@ public class Machine {
private double totalTaskTime=0;
private List<Shift> shifts;
private List<MaintenanceWindow> maintenanceWindows;
private List<TimeSegment> availability;
private CopyOnWriteArrayList<TimeSegment> availability;
private String code;
private List<Holiday> holidays;
......@@ -30,7 +31,7 @@ public class Machine {
public Machine() {
this.shifts = new ArrayList<>();
this.maintenanceWindows = new ArrayList<>();
this.availability = new ArrayList<>();
this.availability = new CopyOnWriteArrayList<>();
}
public Machine(int id, String name) {
......
......@@ -4,17 +4,18 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
public class MachineTimeline {
private Long machineId;
private List<TimeSegment> segments;
private CopyOnWriteArrayList<TimeSegment> segments;
private LocalDateTime validFrom;
private LocalDateTime validTo;
private LocalDateTime lastUpdated;
private int version = 1;
public MachineTimeline() {
this.segments = new ArrayList<>();
this.segments = new CopyOnWriteArrayList<>();
}
// Getters and Setters
......@@ -26,11 +27,11 @@ public class MachineTimeline {
this.machineId = machineId;
}
public List<TimeSegment> getSegments() {
public CopyOnWriteArrayList<TimeSegment> getSegments() {
return segments;
}
public void setSegments(List<TimeSegment> segments) {
public void setSegments(CopyOnWriteArrayList<TimeSegment> segments) {
this.segments = segments;
}
......
......@@ -14,6 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
......@@ -335,6 +336,8 @@ public class GeneticAlgorithm {
.join();
if(1==2) {
if (population != null && population.size() > 0) {
population.parallelStream().forEach(chromosome -> {
......@@ -345,19 +348,27 @@ public class GeneticAlgorithm {
}
}
}
private void decode(GeneticDecoder decoder,Chromosome chromosome,ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList) {
chromosome.setResult(new ArrayList<>());
if (chromosome==null){
System.out.println("chromosome==null");
}
chromosome.setResult(new CopyOnWriteArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(allOperations); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
chromosome.setBaseTime(param.getBaseTime());
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
......
......@@ -141,10 +141,13 @@ public class KpiCalculator {
*/
private void calculateMachine() {
// 按设备ID分组工序列表(对应C# GroupBy + ToList)
// 按设备ID分组工序列表(对应C# GroupBy + ToList)- Java 8兼容方式,处理null键
List<GAScheduleResult> list= chromosome.getResult() ;
Map<Long, List<GAScheduleResult>> machineTasks = list.stream()
.collect(Collectors.groupingBy(GAScheduleResult::getMachineId));
Map<Long, List<GAScheduleResult>> machineTasks = new HashMap<>();
list.forEach(result -> {
Long machineId = result.getMachineId();
machineTasks.computeIfAbsent(machineId, k -> new ArrayList<>()).add(result);
});
// 计划工作时间:最后一个任务结束时间 - 第一个任务开始时间
int firstTaskStart = list.stream()
......@@ -202,9 +205,12 @@ public class KpiCalculator {
*/
private void calculateOrder() {
List<GAScheduleResult> list= chromosome.getResult();
// 按GroupId(订单ID)分组 - 对应C#的GroupBy
Map<String, List<GAScheduleResult>> orderGroups = list.stream()
.collect(Collectors.groupingBy(GAScheduleResult::getOrderId));
// 按GroupId(订单ID)分组 - Java 8兼容方式,处理null键
Map<String, List<GAScheduleResult>> orderGroups = new HashMap<>();
list.forEach(result -> {
String orderId = result.getOrderId();
orderGroups.computeIfAbsent(orderId, k -> new ArrayList<>()).add(result);
});
for (Map.Entry<String, List<GAScheduleResult>> entry : orderGroups.entrySet()) {
String orderId = entry.getKey();
......
......@@ -179,9 +179,12 @@ public class OrderSortService {
return;
}
// 1. 按当前条件分组
Map<Object, List<Order>> groups = orders.stream()
.collect(Collectors.groupingBy(keyExtractor));
// 1. 按当前条件分组 处理null键
Map<Object, List<Order>> groups = new HashMap<>();
orders.forEach(order -> {
Object key = keyExtractor.apply(order);
groups.computeIfAbsent(key, k -> new ArrayList<>()).add(order);
});
// 2. 对分组键排序(关键:按条件配置的方向排序)
List<Object> sortedKeys = getSortedKeys(groups, currentCondition);
......
......@@ -213,6 +213,8 @@ public class RoutingDataService {
entry.setEquipTypeCode(op.getEquipTypeCode());
entry.setRuntime(op.getRuntime());
entry.setSingleOut(op.getSingleOut());
entry.setSetupTime(op.getSetupTime());
entry.setConstTime(op.getConstTime());
entry.setOrderId(op.getOrderId());
entry.setOrderCode(op.getOrderCode());
entry.setQuantity(op.getPlanQty());
......
......@@ -14,6 +14,7 @@ import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
......@@ -50,7 +51,7 @@ public class MachineSchedulerService {
// 创建新时间线(60天范围)
MachineTimeline newTimeline = generateTimeline(machine);
newTimeline.setSegments(mergeSegments(newTimeline.getSegments()));
// newTimeline.setSegments(mergeSegments(newTimeline.getSegments()));
timelineCache.put(machineId, newTimeline);
return newTimeline;
......@@ -66,14 +67,14 @@ public class MachineSchedulerService {
LocalDate currentDate = currentTime.toLocalDate();
LocalDate endDate = currentTime.plusDays(200).toLocalDate();
List<TimeSegment> allSegments = new ArrayList<>();
CopyOnWriteArrayList<TimeSegment> allSegments = new CopyOnWriteArrayList<>();
while (!currentDate.isAfter(endDate)) {
// 检查是否在假期内
boolean isHolidayPeriod = isHoliday(machine,currentDate);
// 生成当日时间段
List<TimeSegment> daySegments = calculateDaySegments(machine, currentDate, isHolidayPeriod);
CopyOnWriteArrayList<TimeSegment> daySegments = calculateDaySegments(machine, currentDate, isHolidayPeriod);
allSegments.addAll(daySegments);
// 跳到下一天
......@@ -101,7 +102,7 @@ public class MachineSchedulerService {
}
if(maintenanceWindow.getStartTime().isBefore(currentTime)&&maintenanceWindow.getEndTime().isAfter(maxEnd))
{
timeline.setSegments(new ArrayList<>());
timeline.setSegments(new CopyOnWriteArrayList<>());
currentTime=maintenanceWindow.getEndTime();
timeline= generateTimeline(machine);
break;
......@@ -115,7 +116,7 @@ public class MachineSchedulerService {
return timeline;
}
public List<TimeSegment> generateTimeSegment(Machine machine, LocalDateTime currentTime,int days) {
public CopyOnWriteArrayList<TimeSegment> generateTimeSegment(Machine machine, LocalDateTime currentTime,int days) {
if(days==0)
{
days=200;
......@@ -138,7 +139,7 @@ try {
timeline.setValidFrom(currentTime);
timeline.setValidTo(currentTime.plusDays(days));
timeline.setLastUpdated(LocalDateTime.now());
timeline.setSegments(new ArrayList<>());
timeline.setSegments(new CopyOnWriteArrayList<>());
} else {
if(currentTime==null)
{
......@@ -146,9 +147,9 @@ try {
}
if (timeline.getValidTo().compareTo(currentTime) > 0) {
LocalDateTime currentTime1=currentTime;
List<TimeSegment> timeSegments= timeline.getSegments().stream()
CopyOnWriteArrayList<TimeSegment> timeSegments= timeline.getSegments().stream()
.filter(t->t.getStart().isAfter(currentTime1)||t.getStart().isBefore(currentTime1))
.collect(Collectors.toList());
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
return ProductionDeepCopyUtil.deepCopyList(timeSegments,TimeSegment.class);
} else {
......@@ -163,7 +164,7 @@ try {
LocalDate currentDate = currentTime.toLocalDate();
LocalDate endDate = currentTime.plusDays(days).toLocalDate();
List<TimeSegment> segments = new ArrayList<>();
CopyOnWriteArrayList<TimeSegment> segments = new CopyOnWriteArrayList<>();
while (!currentDate.isAfter(endDate)) {
// 检查是否在假期内
......@@ -235,7 +236,7 @@ try {
machine.getAvailability().addAll(newSegments);
// 合并片段(去重+排序),并重新赋值给设备的可用片段列表,对应C#的 machine.Availability = MergeSegments(...)
List<TimeSegment> mergedSegments = mergeSegments(machine.getAvailability());
CopyOnWriteArrayList<TimeSegment> mergedSegments = mergeSegments(machine.getAvailability());
machine.setAvailability(mergedSegments);
}
......@@ -259,8 +260,8 @@ try {
return false;
}
private List<TimeSegment> calculateDaySegments(Machine machine, LocalDate date, boolean isHoliday) {
List<TimeSegment> segments = new ArrayList<>();
private CopyOnWriteArrayList<TimeSegment> calculateDaySegments(Machine machine, LocalDate date, boolean isHoliday) {
CopyOnWriteArrayList<TimeSegment> segments = new CopyOnWriteArrayList<>();
if (isHoliday) {
// 假期:只处理特定日期的班次
......@@ -358,29 +359,29 @@ if(shifts==null||shifts.size()==0) {
return shiftDays.contains(targetDayValue);
}
private List<TimeSegment> mergeSegments(List<TimeSegment> segments1) {
private CopyOnWriteArrayList<TimeSegment> mergeSegments(CopyOnWriteArrayList<TimeSegment> segments1) {
List<TimeSegment> segments= ProductionDeepCopyUtil.deepCopyList(segments1,TimeSegment.class);
CopyOnWriteArrayList<TimeSegment> segments= ProductionDeepCopyUtil.deepCopyList(segments1,TimeSegment.class);
if(segments==null||segments.size()==0)
{
return null;
}
List<TimeSegment> maintenanceSegments1 = segments.stream()
CopyOnWriteArrayList<TimeSegment> maintenanceSegments1 = segments.stream()
.filter(t ->t.getType()==null)
.collect(Collectors.toList());
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
if(maintenanceSegments1.size()>0)
{
int i=0;
}
List<TimeSegment> maintenanceSegments = segments.stream()
CopyOnWriteArrayList<TimeSegment> maintenanceSegments = segments.stream()
.filter(t ->t.getType()!=null&& t.getType() == SegmentType.MAINTENANCE)
.collect(Collectors.toList());
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
List<TimeSegment> otherSegments = segments.stream()
CopyOnWriteArrayList<TimeSegment> otherSegments = segments.stream()
.filter(t ->t.getType()!=null&& t.getType() != SegmentType.MAINTENANCE)
.collect(Collectors.toList());
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
// 按开始时间排序
otherSegments.sort(Comparator.comparing(TimeSegment::getStart));
......@@ -399,7 +400,7 @@ if(shifts==null||shifts.size()==0) {
}
}
List<TimeSegment> result = new ArrayList<>(merged);
CopyOnWriteArrayList<TimeSegment> result = new CopyOnWriteArrayList<>(merged);
result.addAll(maintenanceSegments);
// 按开始时间排序
......@@ -433,7 +434,7 @@ if(shifts==null||shifts.size()==0) {
}
}
List<MaintenanceWindow> result = new ArrayList<>(merged);
List<MaintenanceWindow> result = new CopyOnWriteArrayList<>(merged);
// 按开始时间排序
result.sort(Comparator.comparing(MaintenanceWindow::getStartTime));
......
......@@ -120,69 +120,7 @@ public class PlanResultService {
private LocalDateTime baseTime = LocalDateTime.of(2025, 11, 1, 0, 0, 0);
public List<ScheduleChromosome> execute() {
try {
// 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);
// 设置机器信息到班次中
for (Machine machine : machines) {
if (machine.getShifts() != null) {
for (Shift shift : machine.getShifts()) {
shift.setMachineId(machine.getId());
shift.setMachineName(machine.getName());
}
}
// 调试:打印机器和班次信息
System.out.println("Machine: " + machine.getId() + ", Name: " + machine.getName());
if (machine.getShifts() != null) {
for (Shift shift : machine.getShifts()) {
System.out.println(" Shift: " + shift.getStartTime() + " - " + shift.getEndTime() +
", Status: " + shift.getStatus() +
", MachineId: " + shift.getMachineId() +
", MachineName: " + shift.getMachineName());
}
}
}
// 创建节假日
List<Holiday> holidays = Arrays.asList(
new Holiday(LocalDateTime.of(2025, 10, 1, 0, 0),
LocalDateTime.of(2025, 10, 7, 23, 59))
);
// 将节假日添加到所有设备中
addHolidaysToAllMachines(machines, holidays);
// 3. 创建调度服务
MachineSchedulerService machineScheduler = new MachineSchedulerService(
holidays, LocalDateTime.of(2025, 10, 1, 0, 0, 0));
// 4. 初始化机器时间线
for (Machine machine : machines) {
MachineTimeline timeline = machineScheduler.getOrCreateTimeline(machine);
machine.setAvailability(timeline.getSegments());
}
// 5. 执行调度算法
AlgorithmScheduler7 scheduler = new AlgorithmScheduler7(products, machines, orders, machineScheduler);
List<ScheduleChromosome> scheduleChromosomes = scheduler.RunAll();
// 对调度结果按照 fitness 由高到低排序
scheduleChromosomes.sort((c1, c2) -> Double.compare(c2.getFitness(), c1.getFitness()));
// 为每个 ScheduleChromosome 分配场景ID(基于排序后的位置)
for (int i = 0; i < scheduleChromosomes.size(); i++) {
scheduleChromosomes.get(i).setSceneId(i + 1); // 场景ID从1开始
}
return scheduleChromosomes;
} catch (Exception e) {
throw new RuntimeException("调度执行失败", e);
}
return null;
}
......@@ -388,31 +326,93 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
public Chromosome EditOperation(String SceneId,Entry operation) {
Chromosome chromosome= _sceneService.loadChromosomeFromFile(SceneId);
public Chromosome EditOperation(String SceneId, Entry operation) {
Chromosome chromosome = _sceneService.loadChromosomeFromFile(SceneId);
if (chromosome == null || chromosome.getAllOperations() == null) {
return chromosome; // 直接返回,空值由上层处理
return chromosome;
}
List<Entry> operations = chromosome.getAllOperations();
// 直接查找匹配元素的索引(避免先找元素再查索引的冗余)
int position = IntStream.range(0, operations.size())
.filter(i -> {
Entry t = operations.get(i);
return t.getId()==operation.getId();
})
.filter(i -> operations.get(i).getId() == operation.getId())
.findFirst()
.orElse(-1);
// 索引有效时替换
if (position != -1) {
operations.set(position, operation);
Entry oldEntry = operations.set(position, operation);
List<GlobalOperationInfo> globalOpList = chromosome.getGlobalOpList();
if (globalOpList != null) {
globalOpList.stream()
.filter(opInfo -> opInfo.getOp() == oldEntry)
.forEach(opInfo -> opInfo.setOp(operation));
}
}
ScheduleOperationService ScheduleOperation=new ScheduleOperationService();
GlobalParam globalParam=new GlobalParam();
ScheduleOperation.redecode(chromosome,chromosome.getBaseTime(), globalParam);
return chromosome;
return redecodeChromosome(chromosome);
}
public Chromosome EditOrder(String SceneId, Order order) {
Chromosome chromosome = _sceneService.loadChromosomeFromFile(SceneId);
if (chromosome == null || chromosome.getOrders() == null) {
return chromosome;
}
List<Order> orders = chromosome.getOrders();
int position = IntStream.range(0, orders.size())
.filter(i -> orders.get(i).getId() == order.getId())
.findFirst()
.orElse(-1);
if (position != -1) {
orders.set(position, order);
}
orderSortService.initializeFieldExtractors();
OrderSortRule rule = createMultiConditionRule(orders);
orderSortService.assignPriority(orders, rule);
updateOrderRelatedEntries(chromosome, order);
return redecodeChromosome(chromosome);
}
/**
* 更新订单相关的所有Entry的数量和优先级
*/
private void updateOrderRelatedEntries(Chromosome chromosome, Order order) {
// 更新所有操作中的Entry
List<Entry> allOperations = chromosome.getAllOperations();
if (allOperations != null) {
allOperations.stream()
.filter(entry -> entry.getOrderId() != null && entry.getOrderId().equals(order.getOrderId()))
.forEach(entry -> {
entry.setQuantity(order.getQuantity());
entry.setPriority(order.getActualPriority());
});
}
// 更新GlobalOperationInfo中的Entry
List<GlobalOperationInfo> globalOpList = chromosome.getGlobalOpList();
if (globalOpList != null) {
globalOpList.stream()
.map(GlobalOperationInfo::getOp)
.filter(entry -> entry != null && entry.getOrderId() != null && entry.getOrderId().equals(order.getOrderId()))
.forEach(entry -> {
entry.setQuantity(order.getQuantity());
entry.setPriority(order.getActualPriority());
});
}
}
/**
* 重新解码染色体
*/
private Chromosome redecodeChromosome(Chromosome chromosome) {
GlobalParam globalParam = new GlobalParam();
ScheduleOperationService scheduleOperation = new ScheduleOperationService();
scheduleOperation.redecode(chromosome, chromosome.getBaseTime(), globalParam);
return chromosome;
}
public Chromosome ChangeBaseTime(String SceneId,LocalDateTime BaseTime) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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