Commit 2c769406 authored by Tong Li's avatar Tong Li

遗传算法

parent 2fe0847f
package com.aps.entity.Algorithm; package com.aps.entity.Algorithm;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.Machine; import com.aps.entity.basic.Machine;
import com.aps.entity.basic.Order;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
...@@ -27,6 +29,7 @@ public class Chromosome { ...@@ -27,6 +29,7 @@ public class Chromosome {
private String MachineStr; private String MachineStr;
public String getMachineStr() { public String getMachineStr() {
if(MachineSelection==null) return "";
return MachineSelection.stream() return MachineSelection.stream()
.map(String::valueOf) // 将每个 Integer 转换为 String .map(String::valueOf) // 将每个 Integer 转换为 String
.collect(Collectors.joining(",")); .collect(Collectors.joining(","));
...@@ -43,11 +46,16 @@ public class Chromosome { ...@@ -43,11 +46,16 @@ public class Chromosome {
private String OperationStr; private String OperationStr;
public String getOperationStr() { public String getOperationStr() {
if(OperationSequencing==null) return "";
return OperationSequencing.stream() return OperationSequencing.stream()
.map(String::valueOf) // 将每个 Integer 转换为 String .map(String::valueOf) // 将每个 Integer 转换为 String
.collect(Collectors.joining("|")); .collect(Collectors.joining("|"));
}; };
private List<GlobalOperationInfo> globalOpList;
private List<Entry> allOperations;
private List<Order> orders;
private List<Machine> InitMachines;
/// <summary> /// <summary>
/// 适应度值 /// 适应度值
/// </summary> /// </summary>
......
...@@ -26,6 +26,8 @@ public class GAScheduleResult { ...@@ -26,6 +26,8 @@ public class GAScheduleResult {
private int teardownTime; //后处理 private int teardownTime; //后处理
private double Quantity; // 批次大小(订单可拆分) private double Quantity; // 批次大小(订单可拆分)
private List<ScheduleResultDetail> GeneDetails; // 时间详情 private List<ScheduleResultDetail> GeneDetails; // 时间详情
private int designatedStartTime = -1; // 设计开始时间(默认-1)
private int forcedMachineId = -1; // 强制分配的设备ID(-1表示无强制)
private double OneTime; // 单件工时 private double OneTime; // 单件工时
private double ProcessingTime; // 绝对处理时间(分钟) private double ProcessingTime; // 绝对处理时间(分钟)
private int ChangeoverTime; private int ChangeoverTime;
......
...@@ -52,6 +52,9 @@ public class GeneticAlgorithm { ...@@ -52,6 +52,9 @@ public class GeneticAlgorithm {
.max() .max()
.orElse(0); .orElse(0);
Chromosome best=new Chromosome(); Chromosome best=new Chromosome();
best= population.stream()
.max(Comparator.comparingDouble(Chromosome::getFitness))
.orElse(null);
double bestFitness=0; double bestFitness=0;
int Iteration=0; int Iteration=0;
// 步骤2:迭代进化 // 步骤2:迭代进化
...@@ -129,6 +132,8 @@ public class GeneticAlgorithm { ...@@ -129,6 +132,8 @@ public class GeneticAlgorithm {
} }
} }
best.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines));
best.setOrders(orders);
// 步骤3:返回最优解 // 步骤3:返回最优解
return best; return best;
...@@ -153,8 +158,10 @@ public class GeneticAlgorithm { ...@@ -153,8 +158,10 @@ public class GeneticAlgorithm {
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射 // 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝 chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(allOperations); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝
Chromosome chromosomen= decoder.decodeChromosomeWithCache(chromosome, globalOpList, allOperations); Chromosome chromosomen= decoder.decodeChromosomeWithCache(chromosome);
if(chromosomen.getFitness()==0) { if(chromosomen.getFitness()==0) {
chromosomen.setFitness(fitnessCalc.calculateFitness(chromosomen)); chromosomen.setFitness(fitnessCalc.calculateFitness(chromosomen));
} }
......
...@@ -42,9 +42,8 @@ public class GeneticDecoder { ...@@ -42,9 +42,8 @@ public class GeneticDecoder {
_globalParam=globalParam; _globalParam=globalParam;
// this.orderMaxID = orders.stream().mapToInt(Order::getId).max().orElse(0); // this.orderMaxID = orders.stream().mapToInt(Order::getId).max().orElse(0);
} }
public Chromosome decodeChromosomeWithCache(Chromosome chromosome, List<GlobalOperationInfo> globalOpList, public Chromosome decodeChromosomeWithCache(Chromosome chromosome) {
List<Entry> allOperations) {
_allOperations=allOperations;
// 1. 创建缓存键 // 1. 创建缓存键
String cacheKey = createCacheKey(chromosome); String cacheKey = createCacheKey(chromosome);
...@@ -64,8 +63,7 @@ public class GeneticDecoder { ...@@ -64,8 +63,7 @@ public class GeneticDecoder {
cacheLock.unlock(); // 确保锁释放 cacheLock.unlock(); // 确保锁释放
} }
// 3. 缓存未命中:执行解码逻辑 // 3. 缓存未命中:执行解码逻辑
decode(chromosome, globalOpList, decode(chromosome);
allOperations);
// 4. 将解码结果存入缓存(加锁保证线程安全) // 4. 将解码结果存入缓存(加锁保证线程安全)
cacheLock.lock(); cacheLock.lock();
...@@ -93,8 +91,11 @@ public class GeneticDecoder { ...@@ -93,8 +91,11 @@ public class GeneticDecoder {
/** /**
* 染色体解码为调度方案 * 染色体解码为调度方案
*/ */
public void decode(Chromosome chromosome, List<GlobalOperationInfo> globalOpList, public void decode(Chromosome chromosome) {
List<Entry> allOperations) {
List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList();
List<Entry> allOperations=chromosome.getAllOperations();
_allOperations=chromosome.getAllOperations();
Map<Integer, GlobalOperationInfo> globalOpMap = globalOpList.stream() Map<Integer, GlobalOperationInfo> globalOpMap = globalOpList.stream()
.collect(Collectors.toMap(GlobalOperationInfo::getGlobalOpId, g -> g)); .collect(Collectors.toMap(GlobalOperationInfo::getGlobalOpId, g -> g));
...@@ -345,7 +346,7 @@ public class GeneticDecoder { ...@@ -345,7 +346,7 @@ public class GeneticDecoder {
result.setQuantity(operation.getQuantity()); result.setQuantity(operation.getQuantity());
result.setStartTime(startTime); result.setStartTime(startTime);
result.setEndTime(endTime); result.setEndTime(endTime);
result.setEndTime(teardownTime); result.setTeardownTime(teardownTime);
result.setOneTime(processingTime); result.setOneTime(processingTime);
result.setProcessingTime(processingTimeTotal); result.setProcessingTime(processingTimeTotal);
......
...@@ -55,6 +55,8 @@ int populationSize=param.getPopulationSize(); ...@@ -55,6 +55,8 @@ int populationSize=param.getPopulationSize();
.parallel() // 开启并行 .parallel() // 开启并行
.forEach(i -> { .forEach(i -> {
Chromosome chromo = new Chromosome(); // 初始化染色体 Chromosome chromo = new Chromosome(); // 初始化染色体
// 全局选择(GS):按GlobalOpId顺序生成MachineSelection // 全局选择(GS):按GlobalOpId顺序生成MachineSelection
if (i < gsCount) { if (i < gsCount) {
generateGSChromosome(chromo,globalOpList); // 对应 C# GenerateGSChromosome generateGSChromosome(chromo,globalOpList); // 对应 C# GenerateGSChromosome
......
package com.aps.service.Algorithm;
import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.Algorithm.GAScheduleResult;
import com.aps.entity.Algorithm.GlobalOperationInfo;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import com.aps.entity.basic.MachineOption;
import com.aps.service.plan.MachineSchedulerService;
import javax.xml.transform.Result;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;
/**
* 作者:佟礼
* 时间:2025-11-30
*/
public class ScheduleOperationService {
/**
* 移动工序方法
* @param chromosome 染色体对象
* @param opId 工序ID
* @param newStartTime 新开始时间
* @param newMachineId 新设备ID
* @param baseTime 基准时间
*/
public void moveOperation(Chromosome chromosome, int opId, int newStartTime,
int newMachineId, LocalDateTime baseTime, GlobalParam globalParam) {
List<Entry> allOperations=chromosome.getAllOperations();
// 获取目标结果和工序
GAScheduleResult targetResult = chromosome.getResult().stream()
.filter(r -> r.getOperationId() == opId)
.findFirst()
.orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));
Entry targetOp = allOperations.stream()
.filter(o -> o.getId() == opId)
.findFirst()
.orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));
// 设置约束
targetResult.setDesignatedStartTime(newStartTime);
targetResult.setForcedMachineId(newMachineId);
// 更新设备选择序列
int globalOpIndex = chromosome.getGlobalOpList().stream()
.filter(g -> g.getOp().getId() == opId)
.findFirst()
.map(GlobalOperationInfo::getGlobalOpId)
.orElseThrow(() -> new NoSuchElementException("Global operation not found: " + opId));
int machineOptionIndex = targetOp.getMachineOptions().stream()
.map(MachineOption::getMachineId)
.collect(Collectors.toList())
.indexOf(newMachineId) + 1;
chromosome.getMachineSelection().set(globalOpIndex, machineOptionIndex);
// 生成新的工序顺序
Map<Integer, Integer> opTimeMap = chromosome.getResult().stream()
.collect(Collectors.toMap(
GAScheduleResult::getOperationId,
r -> r.getOperationId() == opId ? newStartTime : r.getStartTime()
));
List<Integer> operationSequencing = allOperations.stream()
.sorted((op1, op2) -> {
int time1 = opTimeMap.getOrDefault(op1.getId(), Integer.MAX_VALUE);
int time2 = opTimeMap.getOrDefault(op2.getId(), Integer.MAX_VALUE);
if (time1 != time2) {
return Integer.compare(time1, time2);
} else {
return Integer.compare(op1.getSequence(), op2.getSequence());
}
})
.map(Entry::getGroupId)
.collect(Collectors.toList());
chromosome.setOperationSequencing(operationSequencing);
// 优化解码
MachineSchedulerService machineScheduler = new MachineSchedulerService(baseTime);
GeneticDecoder decoder = new GeneticDecoder(globalParam,baseTime, chromosome.getInitMachines(),
chromosome.getOrders(), null, machineScheduler);
decoder.decode(chromosome);
if(chromosome.getFitness()==0) {
FitnessCalculator fitnessCalc = new FitnessCalculator();
chromosome.setFitness(fitnessCalc.calculateFitness(chromosome));
}
}
}
package com.aps.service.Algorithm;
/**
* 作者:佟礼
* 时间:2025-11-30
*/
public class ScheduleUpdater {
}
...@@ -18,6 +18,7 @@ import com.aps.entity.basic.*; ...@@ -18,6 +18,7 @@ import com.aps.entity.basic.*;
import com.aps.service.*; import com.aps.service.*;
import com.aps.service.Algorithm.GeneticAlgorithm; import com.aps.service.Algorithm.GeneticAlgorithm;
import com.aps.service.Algorithm.IdGroupingWithDualSerial; import com.aps.service.Algorithm.IdGroupingWithDualSerial;
import com.aps.service.Algorithm.ScheduleOperationService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -26,6 +27,7 @@ import java.io.IOException; ...@@ -26,6 +27,7 @@ import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -222,7 +224,9 @@ public class PlanResultService { ...@@ -222,7 +224,9 @@ public class PlanResultService {
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler); //new GeneticAlgorithm(products, machines, orders, machineScheduler); GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
Chromosome Chromosomes =scheduler.Run(param,allOperations); Chromosome Chromosomes =scheduler.Run(param,allOperations);
ScheduleOperationService ScheduleOperation=new ScheduleOperationService();
LocalDateTime ds= LocalDateTime.of(2025, 12, 7, 23, 59);
ScheduleOperation.moveOperation(Chromosomes,3, (int)ChronoUnit.SECONDS.between(param.getBaseTime(), ds),2,param.getBaseTime(), globalParam);
//Chromosomes.forEach(this::WriteScheduleSummary); //Chromosomes.forEach(this::WriteScheduleSummary);
return Chromosomes; return Chromosomes;
...@@ -236,8 +240,8 @@ public class PlanResultService { ...@@ -236,8 +240,8 @@ public class PlanResultService {
try { try {
ScheduleParams param = new ScheduleParams(); ScheduleParams param = new ScheduleParams();
param.setBaseTime(LocalDateTime.of(2025, 11, 1, 0, 0, 0)); param.setBaseTime(LocalDateTime.of(2025, 11, 1, 0, 0, 0));
param.setPopulationSize(50); param.setPopulationSize(1);
param.setMaxIterations(100); param.setMaxIterations(1);
// 1. 读取数据 // 1. 读取数据
......
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