Commit 4148b970 authored by DESKTOP-VKRD9QF\Administration's avatar DESKTOP-VKRD9QF\Administration

Merge branch 'master' of http://39.100.78.207:1213/tongli/hyh.apsj

# Conflicts:
#	src/test/java/com/aps/demo/PlanResultServiceTest.java
parents a7c9d3a4 f081f29e
......@@ -20,8 +20,8 @@ public class ScheduleParams {
private static final int MAX_MAX_ITERATIONS = 200;
private static final float MIN_CROSSOVER_PROB = 0.6f;
private static final float MAX_CROSSOVER_PROB = 0.9f;
private static final float MIN_MUTATION_PROB = 0.3f;
private static final float MAX_MUTATION_PROB = 0.7f;
private static final float MIN_MUTATION_PROB = 0.2f;
private static final float MAX_MUTATION_PROB = 0.5f;
private static final int MIN_TOURNAMENT_SIZE = 3;
private static final int MAX_TOURNAMENT_SIZE = 7;
......@@ -81,6 +81,13 @@ public class ScheduleParams {
return maxIterations;
}
/// <summary>
/// 交叉概率
/// </summary>
public float setCrossoverProb(float crossoverProb) {
return this.crossoverProb=crossoverProb;
}
/// <summary>
/// 交叉概率
/// </summary>
......@@ -235,6 +242,26 @@ public class ScheduleParams {
}
}
public void fineTuneParams() {
// 适应度标准差阈值(可调整):小于0.05视为收敛过慢,大于0.2视为收敛过快
final float LOW_STD_THRESHOLD = 0.05f;
final float HIGH_STD_THRESHOLD = 0.2f;
final float ADJUST_STEP = 0.05f; // 调整步长
DecimalFormat df = new DecimalFormat("#.000");
// 1. 收敛过慢(适应度方差小):增加变异概率,降低交叉概率
mutationProb = Math.max(MIN_MUTATION_PROB,
Math.min(MAX_MUTATION_PROB, mutationProb + 0.05f));
crossoverProb = Math.max(MIN_CROSSOVER_PROB,
Math.min(MAX_CROSSOVER_PROB, crossoverProb - 0.1f));
}
// 测试示例
public void test() {
ScheduleParams params = new ScheduleParams();
......
package com.aps.entity.Algorithm;
import com.aps.entity.basic.TimeSegment;
import lombok.Data;
import java.util.List;
/**
* 作者:佟礼
* 时间:2025-11-21
......@@ -14,6 +17,9 @@ public class ScheduleResultDetail {
private double OneTime; // 单件工时
private double Quantity; // 时间段
private List<TimeSegment> usedSegment;
// Key 的 getter/setter
public String getKey() {
return Key;
......
......@@ -13,6 +13,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
/**
......@@ -98,7 +101,7 @@ public class GeneticAlgorithm {
List<Chromosome> population = initialization.generateInitialPopulation(param, globalOpList);
//population= chromosomeDistinct(population);
population= chromosomeDistinct(population);
......@@ -137,8 +140,14 @@ public class GeneticAlgorithm {
}
FileHelper.writeLogFile("选择操作-----------开始-------");
// 选择前移除适应度为 0 或明显劣于当前最优解的个体,减少选择池规模:
double minValidFitness = bestFitness * 0.5; // 保留最优解50%以上的个体
List<Chromosome> validPopulation = population.stream()
.filter(c -> c.getFitness() >= minValidFitness)
.collect(Collectors.toList());
// 选择操作
List<Chromosome> selected = geneticOps.tournamentSelection(population);
List<Chromosome> selected = geneticOps.tournamentSelection(validPopulation);
FileHelper.writeLogFile("选择操作-----------结束-------");
// 交叉操作
FileHelper.writeLogFile("交叉操作-----------开始-------");
......@@ -178,7 +187,7 @@ public class GeneticAlgorithm {
FileHelper.writeLogFile("变异批量解码-----------开始-------");
nextPopulation= chromosomeDistinct(nextPopulation);
Chromosomedecode(param,allOperations,globalOpList,nextPopulation);
FileHelper.writeLogFile("变异批量解码-----------结束-------");
// // 精英保留
......@@ -192,7 +201,7 @@ public class GeneticAlgorithm {
List<Chromosome> newPopulation = new ArrayList<>();
newPopulation.addAll(population);
newPopulation.addAll(nextPopulation);
newPopulation= chromosomeDistinct(newPopulation);
newPopulation= chromosomeDistinct1(newPopulation);
FileHelper.writeLogFile("非支配排序-----------开始-------");
// 2.7 非支配排序
List<List<Chromosome>> combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(newPopulation);
......@@ -208,19 +217,26 @@ public class GeneticAlgorithm {
best= GetBest(combinedFronts,String.valueOf(iter));
if(bestFitness<best.getFitness())
{
bestFitness=best.getFitness();
Iteration=1;
}else {
Iteration++;
if (Iteration > 5) {
// 当连续 5 代无最优解提升时,降低交叉概率(如从 0.8 降至 0.5)、提高变异概率(如从 0.1 升至 0.2)
param.fineTuneParams();
}
}
if(Iteration>10)
{
break;
}
// 当种群适应度标准差小于阈值(如 0.001)时,说明种群已收敛,提前终止迭代
fitnessStd = _fitnessCalculator.calculateFitnessStd(population);
if (fitnessStd < 0.001) {
FileHelper.writeLogFile("种群已收敛,提前终止迭代");
break;
}
FileHelper.writeLogFile("迭代进化------"+iter+"-----结束-------");
}
......@@ -256,21 +272,34 @@ public class GeneticAlgorithm {
// WriteKpi(best,"最大");
return best;
}
private List<Chromosome> chromosomeDistinct(List<Chromosome> population)
{
if(orders.size()<10)
{
population = population.stream()
.collect(Collectors.toMap(
Chromosome::getGeneStr, // key:去重的字段(GeneStr)
u -> u, // value:Chromosome对象
(u1, u2) -> u1 // 重复时保留第一个元素
))
.values() // 获取去重后的
.stream()
.collect(Collectors.toList());
return population;
}
private List<Chromosome> chromosomeDistinct1(List<Chromosome> population)
{
population = population.stream()
.collect(Collectors.toMap(
Chromosome::getGeneStr, // key:去重的字段(GeneStr)
u -> u, // value:Chromosome对象
(u1, u2) -> u1 // 重复时保留第一个元素
(u1, u2) -> u1.getFitness() > u2.getFitness() ? u1 : u2 // 重复时保留第一个元素
))
.values() // 获取去重后的
.stream()
.collect(Collectors.toList());
}
return population;
}
......@@ -292,6 +321,7 @@ public class GeneticAlgorithm {
FileHelper.writeLogFile(String.format(" KPI---%f-------",d));
}
}
private ExecutorService decodeExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population)
{
......@@ -299,26 +329,51 @@ public class GeneticAlgorithm {
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,orderMaterials);
if(population!=null&&population.size()>0) {
population.parallelStream().forEach(chromosome -> {
chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(allOperations); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
chromosome.setBaseTime(param.getBaseTime());
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome,_objectiveWeights));
}
});
CompletableFuture.allOf(population.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> decode(decoder,chromosome,param,allOperations,globalOpList), decodeExecutor))
.toArray(CompletableFuture[]::new))
.join();
if(1==2) {
if (population != null && population.size() > 0) {
population.parallelStream().forEach(chromosome -> {
chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(allOperations); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
chromosome.setBaseTime(param.getBaseTime());
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights));
}
});
}
}
}
private void decode(GeneticDecoder decoder,Chromosome chromosome,ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList) {
chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(allOperations); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
chromosome.setBaseTime(param.getBaseTime());
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights));
}
}
......
......@@ -374,6 +374,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
int teardownTime = machineOption.getTeardownTime();
int preTime = machineOption.getPreTime();
int setupTime = calculateSetupTime(chromosome.getResult(), operation, machine, machineOption);
......
......@@ -33,11 +33,80 @@ public class GeneticOperations {
* 锦标赛选择
*/
public List<Chromosome> tournamentSelection(List<Chromosome> population, int tournamentSize) {
// 前置边界校验(避免NPE和无效计算)
if (population == null || population.isEmpty()) {
return new ArrayList<>();
}
int populationSize = population.size();
// 预计算需要选中的个体数量,避免动态判断
int needSelectCount = populationSize - Math.max(1, Math.min(tournamentSize, populationSize));
List<Chromosome> selected = new ArrayList<>(needSelectCount); // 预初始化容量
// 边界值处理:锦标赛规模不能超过种群规模,且至少为1
int effectiveTournamentSize = Math.max(1, Math.min(tournamentSize, populationSize));
List<Chromosome> selectedtemp = new ArrayList<>(needSelectCount); // 预初始化容量
// 预生成随机索引,减少Random对象创建开销
Random random = this.rnd;
// 固定次数循环,替代动态终止条件
for (int selectIdx = 0; selectIdx < needSelectCount; selectIdx++) {
// 优化1:Fisher-Yates抽样(无重复、无冲突,比HashSet高效)
List<Integer> indices = new ArrayList<>(populationSize);
for (int i = 0; i < populationSize; i++) {
indices.add(i);
}
// 仅打乱前effectiveTournamentSize个索引,减少计算量
for (int i = 0; i < effectiveTournamentSize; i++) {
int swapIdx = i + random.nextInt(populationSize - i);
Collections.swap(indices, i, swapIdx);
}
Chromosome bestCandidate=null;
for (int i = 0; i < effectiveTournamentSize; i++) {
int idx = indices.get(i);
Chromosome curr= population.get(idx);
if(bestCandidate!=null)
{
int rankCompare = Integer.compare(curr.getRank(), bestCandidate.getRank());
if(rankCompare==0)
{
int crowdingCompare = Double.compare(curr.getCrowdingDistance(), bestCandidate.getCrowdingDistance());
if(crowdingCompare<0)
{
bestCandidate=curr;
}
}else {
if(rankCompare<0)
{
bestCandidate=curr;
}
}
}else {
bestCandidate=curr;
}
}
if (bestCandidate != null) {
selected.add(bestCandidate);
}
}
return selected;// ProductionDeepCopyUtil.deepCopyList(selected, Chromosome.class);
}
/**
* 锦标赛选择
*/
public List<Chromosome> tournamentSelection1(List<Chromosome> population, int tournamentSize) {
int populationSize = population.size();
List<Chromosome> selected = new ArrayList<>(); // 预初始化容量
// 边界值处理:锦标赛规模不能超过种群规模,且至少为1
int effectiveTournamentSize = Math.max(1, Math.min(tournamentSize, populationSize));
while (selected.size() < populationSize-tournamentSize) {
// 优化1:不复制整个种群,直接随机抽取有效锦标赛规模的个体,避免大量内存拷贝和shuffle开销
......@@ -46,9 +115,9 @@ public class GeneticOperations {
List<Chromosome> chromosomes=population.subList(0, endIndex);
chromosomes.sort((c1, c2) -> {
int rankCompare = Integer.compare(c1.getRank(), c2.getRank());
return rankCompare != 0 ? rankCompare : Double.compare(c1.getCrowdingDistance(), c2.getCrowdingDistance());
});
int rankCompare = Integer.compare(c1.getRank(), c2.getRank());
return rankCompare != 0 ? rankCompare : Double.compare(c1.getCrowdingDistance(), c2.getCrowdingDistance());
});
Chromosome bestCandidate = chromosomes.get(0);
......@@ -60,6 +129,7 @@ public class GeneticOperations {
return selected;
}
// 重载,使用默认锦标赛大小3
public List<Chromosome> tournamentSelection(List<Chromosome> population) {
return tournamentSelection(population, param.getTournamentSize());
......@@ -259,8 +329,8 @@ public class GeneticOperations {
.findFirst().orElse(0);
int machineSeq = chromosome.getMachineSelection().get(pos);
List<Integer> MachineSelections= chromosome.getMachineSelection();
int machineSeq = MachineSelections.get(pos);
// 选择当前所选设备外最短加工时间的机器
......@@ -274,7 +344,8 @@ public class GeneticOperations {
.orElse(currentMachine); // 如果没有其他机器,保持当前
machineSeq = optionalMachines.indexOf(minLoadMachine) + 1;
chromosome.getMachineSelection().set(pos, machineSeq);
MachineSelections.set(pos, machineSeq);
chromosome.setMachineSelection(MachineSelections);
i++;
}
......@@ -298,6 +369,7 @@ public class GeneticOperations {
// 交换位置
List<Integer> os = chromosome.getOperationSequencing();
Collections.swap(os, idx1, idx2);
chromosome.setOperationSequencing(os);
} else {
// 反转:仅对高优先级工序集中的子序列反转
OperationSequencingWeight osStart = selectHighPriorityIndex(chromosome.getOperationSequencing(), 0);
......@@ -318,6 +390,7 @@ public class GeneticOperations {
int pos2 = end - i;
Collections.swap(os, pos1, pos2);
}
chromosome.setOperationSequencing(os);
}
}
......
......@@ -668,7 +668,7 @@ public class IdGroupingWithDualSerial {
nodeInfo.getNewParentIds().isEmpty() ? "无" : nodeInfo.getNewParentIds(),
nodeInfo.getNewChildIds());
}
System.out.println("------------------------");
// System.out.println("------------------------");
}
}
}
......@@ -65,7 +65,7 @@ int populationSize=param.getPopulationSize();
.forEach(i -> {
Chromosome chromo = new Chromosome(); // 初始化染色体
// chromo.setObjectiveWeights(_objectiveWeights);
chromo.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines));
// chromo.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines));
chromo.setOrders(orders);
// 全局选择(GS):按GlobalOpId顺序生成MachineSelection
if (i < gsCount) {
......
......@@ -272,9 +272,8 @@ public class RoutingDataService {
entrys.add(entry);
}
// 输出每个节点的详细信息
System.out.println("------------------------");
}
list.put(1,entrys);
list.put(2,results);
......
......@@ -928,13 +928,13 @@ Integer newMachineId1=newMachineId.intValue();
GeneticDecoder decoder = new GeneticDecoder(globalParam,baseTime, chromosome.getMachines(),
chromosome.getOrders(), null, machineScheduler,chromosome.getOrderMaterials());
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult()));
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult(),GAScheduleResult.class));
chromosome.getResult().clear();
List<GAScheduleResult> Resultlock= chromosome.getResult().stream()
.filter(o -> o.isIsLocked() == true)
.collect(Collectors.toList());
chromosome.setResult(ProductionDeepCopyUtil.deepCopyList(Resultlock));
chromosome.setResult(ProductionDeepCopyUtil.deepCopyList(Resultlock,GAScheduleResult.class));
decoder.decode(chromosome);
......
......@@ -98,7 +98,8 @@ public class PlanResultService {
@Autowired
private MaterialInfoMapper materialInfoMapper;
@Autowired
private MaterialPurchaseMapper materialPurchaseMapper;
@Autowired
private StockMapper stockMapper;
......@@ -1139,14 +1140,19 @@ private GlobalParam InitGlobalParam()
public List<Material> getMaterials(){
List<Material> materials=new ArrayList<>();
System.out.println("开始初始化物料数据");
LambdaQueryWrapper<MaterialInfo> MaterialInfoWrapper = new LambdaQueryWrapper<>();
MaterialInfoWrapper.eq(MaterialInfo::getIsdeleted,0);
List<MaterialInfo> materiallist=materialInfoMapper.selectList(MaterialInfoWrapper);
LambdaQueryWrapper<MaterialPurchase> materialPurchaseWrapper= new LambdaQueryWrapper<>();
materialPurchaseWrapper.eq(MaterialPurchase::getIsdeleted,0);
List<MaterialPurchase> MaterialPurchaselist=materialPurchaseMapper.selectList(materialPurchaseWrapper);
System.out.println("开始初始化物料数据");
LambdaQueryWrapper<Stock> StockWrapper = new LambdaQueryWrapper<>();
StockWrapper.eq(Stock::getIsdeleted,0);
......
......@@ -39,7 +39,7 @@ public class PlanResultServiceTest {
// nsgaiiUtils.Test();
//planResultService.execute2("C5FB5EF2A7334A0A92F826F4937E1008");
// planResultService.execute2("726D4C1A712B4B1393175BD44B775B66");
planResultService.execute2("E81EE93EFA564CEB8594C61CAEEBCD53");
planResultService.execute2("BCA6FA43FFA444D3952CF8F6E1EA291B");
// LocalDateTime t= LocalDateTime.of(2025, 11, 15, 6, 51, 11);
// List<Integer> opids=new ArrayList<>();
// opids.add(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