Commit 83617e88 authored by Tong Li's avatar Tong Li

遗传算法-优化

parent e0ba6b7a
package com.aps.entity.Algorithm; package com.aps.entity.Algorithm;
import com.aps.entity.basic.Entry; import java.text.DecimalFormat;
import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date;
/** /**
* 作者:佟礼 遗传参数 * 自适应遗传算法参数类(支持根据工序数量动态调整)
* 时间:2025-11-21 * @author AutoGenerated
*/ */
@Data public class ScheduleParams {
public class ScheduleParams {
private LocalDateTime BaseTime ; // 当前基准时间 private LocalDateTime baseTime ; // 当前基准时间
// 基础参数(自适应调整的基准值)
private static final int MIN_POPULATION_SIZE = 20;
private static final int MAX_POPULATION_SIZE = 500;
private static final int MIN_MAX_ITERATIONS = 20;
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.05f;
private static final float MAX_MUTATION_PROB = 0.2f;
private static final int MIN_TOURNAMENT_SIZE = 3;
private static final int MAX_TOURNAMENT_SIZE = 7;
// 自适应调整后的参数(私有变量+公共访问方法)
private int populationSize;
private int maxIterations;
private float crossoverProb;
private float mutationProb;
private int tournamentSize;
/// <summary>
/// 精英保留计数
/// </summary>
private int elitismCount = 5;
/// <summary>
/// 全局选择占比
/// </summary>
private double gsRatio = 0.4; // 全局选择占比
/// <summary> /// <summary>
/// 交叉概率 /// 局部选择占比
/// </summary> /// </summary>
private double CrossoverProb = 0.8; private double lsRatio = 0.4; // 局部选择占比
/// <summary>
/// 随机选择占比
/// </summary>
private double rsRatio = 0.2; // 随机选择占比
// 自适应调整系数
private float populationSizeCoeff = 0.1f; // 种群大小对工序数的敏感系数
private float maxIterationsCoeff = 0.05f; // 迭代次数对工序数的敏感系数
private float crossoverProbCoeff = 0.0001f; // 交叉概率对工序数的敏感系数
private float mutationProbCoeff = 0.00005f; // 变异概率对工序数的敏感系数
private float tournamentSizeCoeff = 200f; // 锦标赛规模对工序数的敏感系数(分母越大越不敏感)
/// <summary> /// <summary>
/// 变异概率 /// 基准时间
/// </summary> /// </summary>
private double MutationProb = 0.1; // 变异概率 public LocalDateTime getBaseTime() {
return baseTime;
}
/// <summary> /// <summary>
/// 种群规模 /// 种群规模
/// </summary> /// </summary>
private int PopulationSize = 50; // 种群规模 public int getPopulationSize() {
return populationSize;
}
/// <summary> /// <summary>
/// 最大迭代次数 /// 最大迭代次数
/// </summary> /// </summary>
private int MaxIterations = 100; // 最大迭代次数 public int getMaxIterations() {
return maxIterations;
}
/// <summary> /// <summary>
/// 精英保留计数 /// 交叉概率
/// </summary> /// </summary>
private int ElitismCount = 5; public float getCrossoverProb() {
return crossoverProb;
}
/// <summary>
/// 变异概率
/// </summary>
public float getMutationProb() {
return mutationProb;
}
/// <summary>
/// 锦标赛规模
/// </summary>
public int getTournamentSize() {
return tournamentSize;
}
/// <summary>
/// 精英保留
/// </summary>
public int getElitismCount() {
return elitismCount;
}
/// <summary> /// <summary>
/// 全局选择占比 /// 全局选择占比
/// </summary> /// </summary>
private double GsRatio = 0.4; // 全局选择占比 public double getGsRatio() {
return gsRatio;
}
/// <summary> /// <summary>
/// 局部选择占比 /// 局部选择占比
/// </summary> /// </summary>
private double LsRatio = 0.4; // 局部选择占比 public double getLsRatio() {
return lsRatio;
}
/// <summary> /// <summary>
/// 随机选择占比 /// 随机选择占比
/// </summary> /// </summary>
private double RsRatio = 0.2; // 随机选择占比 public double getRsRatio() {
return rsRatio;
}
/// <summary>
/// 基准时间
/// </summary>
public void setBaseTime(LocalDateTime baseTime) {
this.baseTime = baseTime;
}
// Setter方法(调整系数)
public void setPopulationSizeCoeff(float populationSizeCoeff) {
this.populationSizeCoeff = populationSizeCoeff;
}
public void setMaxIterationsCoeff(float maxIterationsCoeff) {
this.maxIterationsCoeff = maxIterationsCoeff;
}
public void setCrossoverProbCoeff(float crossoverProbCoeff) {
this.crossoverProbCoeff = crossoverProbCoeff;
}
public void setMutationProbCoeff(float mutationProbCoeff) {
this.mutationProbCoeff = mutationProbCoeff;
}
public void setTournamentSizeCoeff(float tournamentSizeCoeff) {
this.tournamentSizeCoeff = tournamentSizeCoeff;
}
/**
* 根据总工序数初始化自适应参数(一次性调整)
* @param totalOps 总工序数
*/
public void initAdaptiveParams(int totalOps) {
// 1. 种群大小:50 ~ 500,随工序数线性增加
populationSize = (int) Math.max(MIN_POPULATION_SIZE,
Math.min(MAX_POPULATION_SIZE, MIN_POPULATION_SIZE + totalOps * populationSizeCoeff));
// 确保偶数(方便交叉)
if (populationSize % 2 != 0) {
populationSize += 1;
}
// 2. 最大迭代次数:50 ~ 200,随工序数线性减少
maxIterations = (int) Math.max(MIN_MAX_ITERATIONS,
Math.min(MAX_MAX_ITERATIONS, MAX_MAX_ITERATIONS - totalOps * maxIterationsCoeff));
// 3. 交叉概率:0.6 ~ 0.9,随工序数轻微减少
crossoverProb = Math.max(MIN_CROSSOVER_PROB,
Math.min(MAX_CROSSOVER_PROB, MAX_CROSSOVER_PROB - totalOps * crossoverProbCoeff));
// 4. 变异概率:0.05 ~ 0.2,随工序数轻微增加
mutationProb = Math.max(MIN_MUTATION_PROB,
Math.min(MAX_MUTATION_PROB, MIN_MUTATION_PROB + totalOps * mutationProbCoeff));
// 5. 锦标赛规模:3 ~ 7,随工序数阶梯式增加
tournamentSize = (int) Math.max(MIN_TOURNAMENT_SIZE,
Math.min(MAX_TOURNAMENT_SIZE, MIN_TOURNAMENT_SIZE + totalOps / tournamentSizeCoeff));
}
/**
* 迭代中动态微调参数(根据种群收敛情况)
* @param currentIter 当前迭代次数
* @param fitnessStd 当前种群适应度标准差(越小收敛越好)
*/
public void fineTuneParams(int currentIter, double fitnessStd) {
// 每10代微调一次,避免频繁调整
if (currentIter % 10 != 0) {
return;
}
// 适应度标准差阈值(可调整):小于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. 收敛过慢(适应度方差小):增加变异概率,降低交叉概率
if (fitnessStd < LOW_STD_THRESHOLD) {
mutationProb = Math.max(MIN_MUTATION_PROB,
Math.min(MAX_MUTATION_PROB, mutationProb + ADJUST_STEP * 0.5f));
crossoverProb = Math.max(MIN_CROSSOVER_PROB,
Math.min(MAX_CROSSOVER_PROB, crossoverProb - ADJUST_STEP * 0.3f));
System.out.println("迭代" + currentIter + ":收敛过慢,微调参数→变异概率:"
+ df.format(mutationProb) + ",交叉概率:" + df.format(crossoverProb));
}
// 2. 收敛过快(适应度方差大):降低变异概率,增加交叉概率
else if (fitnessStd > HIGH_STD_THRESHOLD) {
mutationProb = Math.max(MIN_MUTATION_PROB,
Math.min(MAX_MUTATION_PROB, mutationProb - ADJUST_STEP * 0.5f));
crossoverProb = Math.max(MIN_CROSSOVER_PROB,
Math.min(MAX_CROSSOVER_PROB, crossoverProb + ADJUST_STEP * 0.3f));
System.out.println("迭代" + currentIter + ":收敛过快,微调参数→变异概率:"
+ df.format(mutationProb) + ",交叉概率:" + df.format(crossoverProb));
}
// 3. 后期迭代(超过80%迭代次数):降低变异概率,稳定最优解
if (currentIter > maxIterations * 0.8f) {
mutationProb = Math.max(MIN_MUTATION_PROB,
Math.min(MAX_MUTATION_PROB, mutationProb * 0.8f));
System.out.println("迭代" + currentIter + ":后期迭代,微调参数→变异概率:"
+ df.format(mutationProb));
}
}
// 测试示例
public void test() {
ScheduleParams params = new ScheduleParams();
// 初始化参数(模拟1000道工序)
params.initAdaptiveParams(1000);
// 模拟迭代微调(第10代,适应度标准差0.04)
params.fineTuneParams(10, 0.04f);
// 模拟迭代微调(第80代,适应度标准差0.25)
params.fineTuneParams(80, 0.25f);
// 模拟迭代微调(第160代,适应度标准差0.1)
params.fineTuneParams(160, 0.1f);
}
} }
...@@ -2,6 +2,8 @@ package com.aps.service.Algorithm; ...@@ -2,6 +2,8 @@ package com.aps.service.Algorithm;
import com.aps.entity.Algorithm.Chromosome; import com.aps.entity.Algorithm.Chromosome;
import java.util.List;
/** /**
* 作者:佟礼 * 作者:佟礼
* 时间:2025-11-24 * 时间:2025-11-24
...@@ -28,4 +30,33 @@ public class FitnessCalculator { ...@@ -28,4 +30,33 @@ public class FitnessCalculator {
// 适应度值(越大越好) // 适应度值(越大越好)
return w1 * normMakespan + w2 * normFlowTime + w3 * normChangeover + w4 * normLoadStd + w5 * normDelay; return w1 * normMakespan + w2 * normFlowTime + w3 * normChangeover + w4 * normLoadStd + w5 * normDelay;
} }
/**
* 计算种群适应度标准差(用于参数微调)
* @param population 染色体种群数组
* @return 适应度标准差
*/
public double calculateFitnessStd(List<Chromosome> population) {
int popSize = population.size();
// 1. 计算平均适应度
double avgFitness = 0.0f;
for (Chromosome chromosome : population) {
avgFitness += chromosome.getFitness();
}
avgFitness /= popSize;
// 2. 计算每个个体与平均值的平方差之和
float sumSqDiff = 0.0f;
for (Chromosome chromosome : population) {
double diff = chromosome.getFitness() - avgFitness;
sumSqDiff += diff * diff;
}
// 3. 计算标准差
return (double) Math.sqrt(sumSqDiff / popSize);
}
} }
...@@ -26,6 +26,8 @@ public class GeneticAlgorithm { ...@@ -26,6 +26,8 @@ public class GeneticAlgorithm {
private static GlobalParam _GlobalParam; private static GlobalParam _GlobalParam;
private List<GroupResult> _entryRel; private List<GroupResult> _entryRel;
FitnessCalculator _fitnessCalculator = new FitnessCalculator();
public GeneticAlgorithm(GlobalParam globalParam,List<Machine> machines, List<Order> orders, public GeneticAlgorithm(GlobalParam globalParam,List<Machine> machines, List<Order> orders,
List<Material> materials, MachineSchedulerService machineScheduler,List<GroupResult> entryRel) { List<Material> materials, MachineSchedulerService machineScheduler,List<GroupResult> entryRel) {
this.machines = machines; this.machines = machines;
...@@ -40,7 +42,7 @@ public class GeneticAlgorithm { ...@@ -40,7 +42,7 @@ public class GeneticAlgorithm {
Initialization initialization = new Initialization(_GlobalParam,allOperations); Initialization initialization = new Initialization(_GlobalParam,allOperations);
GeneticOperations geneticOps = new GeneticOperations(_GlobalParam,allOperations); GeneticOperations geneticOps = new GeneticOperations(_GlobalParam,allOperations,param);
// 预生成全局工序列表(所有初始化方法共享同一顺序) // 预生成全局工序列表(所有初始化方法共享同一顺序)
List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList(); List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList();
...@@ -65,6 +67,12 @@ public class GeneticAlgorithm { ...@@ -65,6 +67,12 @@ public class GeneticAlgorithm {
// 解码并计算适应度 // 解码并计算适应度
// 计算种群适应度标准差,微调参数
double fitnessStd = _fitnessCalculator.calculateFitnessStd(population);
param.fineTuneParams(iter, fitnessStd);
// 检查终止条件(此处简化为迭代次数) // 检查终止条件(此处简化为迭代次数)
if (iter == param.getMaxIterations() - 1) { if (iter == param.getMaxIterations() - 1) {
break; break;
...@@ -145,7 +153,7 @@ public class GeneticAlgorithm { ...@@ -145,7 +153,7 @@ public class GeneticAlgorithm {
private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population) private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population)
{ {
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, 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<>()); // chromosome.setResult(new ArrayList<>());
...@@ -157,7 +165,7 @@ public class GeneticAlgorithm { ...@@ -157,7 +165,7 @@ public class GeneticAlgorithm {
// chromosome.setFitness(fitnessCalc.calculateFitness(chromosome)); // chromosome.setFitness(fitnessCalc.calculateFitness(chromosome));
// }); // });
if(population!=null&&population.size()>0) { if(population!=null&&population.size()>0) {
population.forEach(chromosome -> { population.parallelStream().forEach(chromosome -> {
chromosome.setResult(new ArrayList<>()); chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射 // 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
...@@ -167,7 +175,7 @@ public class GeneticAlgorithm { ...@@ -167,7 +175,7 @@ public class GeneticAlgorithm {
Chromosome chromosomen = decoder.decodeChromosomeWithCache(chromosome); Chromosome chromosomen = decoder.decodeChromosomeWithCache(chromosome);
if (chromosomen.getFitness() == 0) { if (chromosomen.getFitness() == 0) {
chromosomen.setFitness(fitnessCalc.calculateFitness(chromosomen)); chromosomen.setFitness(_fitnessCalculator.calculateFitness(chromosomen));
} }
}); });
} }
......
package com.aps.service.Algorithm; package com.aps.service.Algorithm;
import com.aps.common.util.ProductionDeepCopyUtil; import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.Chromosome; import com.aps.entity.Algorithm.*;
import com.aps.entity.Algorithm.GlobalOperationInfo;
import com.aps.entity.Algorithm.OperationSequencingWeight;
import com.aps.entity.Algorithm.Pair;
import com.aps.entity.basic.Entry; import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam; import com.aps.entity.basic.GlobalParam;
import com.aps.entity.basic.MachineOption; import com.aps.entity.basic.MachineOption;
...@@ -23,9 +20,12 @@ public class GeneticOperations { ...@@ -23,9 +20,12 @@ public class GeneticOperations {
private static GlobalParam _GlobalParam; private static GlobalParam _GlobalParam;
private static List<Entry> allOperations; private static List<Entry> allOperations;
public GeneticOperations(GlobalParam globalParam,List<Entry> allOperations) { private static ScheduleParams param;
public GeneticOperations(GlobalParam globalParam,List<Entry> _allOperations,ScheduleParams _param) {
_GlobalParam=globalParam; _GlobalParam=globalParam;
GeneticOperations.allOperations = allOperations; allOperations = _allOperations;
param=_param;
} }
/** /**
...@@ -60,7 +60,7 @@ public class GeneticOperations { ...@@ -60,7 +60,7 @@ public class GeneticOperations {
// 重载,使用默认锦标赛大小3 // 重载,使用默认锦标赛大小3
public List<Chromosome> tournamentSelection(List<Chromosome> population) { public List<Chromosome> tournamentSelection(List<Chromosome> population) {
return tournamentSelection(population, 3); return tournamentSelection(population, param.getTournamentSize());
} }
/** /**
......
...@@ -187,8 +187,7 @@ public class PlanResultService { ...@@ -187,8 +187,7 @@ public class PlanResultService {
} }
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(1);
param.setMaxIterations(2);
// List<MesHoliday> holidays= _MesHolidayService.list(); // List<MesHoliday> holidays= _MesHolidayService.list();
...@@ -246,6 +245,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0)); ...@@ -246,6 +245,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
} }
GlobalParam globalParam=new GlobalParam(); GlobalParam globalParam=new GlobalParam();
// 5. 执行调度算法 // 5. 执行调度算法
param.initAdaptiveParams(allOperations.size());
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,null); //new GeneticAlgorithm(products, machines, orders, machineScheduler); GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,null); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
Chromosome Chromosomes =scheduler.Run(param,allOperations); Chromosome Chromosomes =scheduler.Run(param,allOperations);
WriteScheduleSummary(Chromosomes); WriteScheduleSummary(Chromosomes);
...@@ -265,8 +265,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0)); ...@@ -265,8 +265,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
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.setMaxIterations(100);
// 1. 读取数据 // 1. 读取数据
...@@ -309,6 +308,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0)); ...@@ -309,6 +308,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
GlobalParam globalParam=new GlobalParam(); GlobalParam globalParam=new GlobalParam();
// 5. 执行调度算法 // 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,entryRel); //new GeneticAlgorithm(products, machines, orders, machineScheduler); GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,entryRel); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
param.initAdaptiveParams(entrys.size());
Chromosome chromosome =scheduler.Run(param,entrys); Chromosome chromosome =scheduler.Run(param,entrys);
_sceneService.saveChromosomeToFile(chromosome, SceneId); _sceneService.saveChromosomeToFile(chromosome, SceneId);
...@@ -479,8 +479,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0)); ...@@ -479,8 +479,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
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.setMaxIterations(100);
// 1. 读取数据 // 1. 读取数据
...@@ -523,6 +522,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0)); ...@@ -523,6 +522,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
GlobalParam globalParam=new GlobalParam(); GlobalParam globalParam=new GlobalParam();
// 5. 执行调度算法 // 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,entryRel); //new GeneticAlgorithm(products, machines, orders, machineScheduler); GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,null,machineScheduler,entryRel); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
param.initAdaptiveParams(entrys.size());
Chromosome chromosomes =scheduler.Run(param,entrys); Chromosome chromosomes =scheduler.Run(param,entrys);
chromosomes.setScenarioID(SceneId); chromosomes.setScenarioID(SceneId);
......
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