Commit 8447ab72 authored by Tong Li's avatar Tong Li

遗传算法-NSGA-II

parent 2c399e24
......@@ -60,6 +60,11 @@ public class Chromosome {
private List<Order> orders;
private List<Machine> InitMachines;
private List<GroupResult> OperatRel;
private double[] Objectives ; // 多目标值:[Makespan, TotalFlowTime, TotalChangeover, LoadStd, Delay]
private int Rank; // 非支配排序等级(1最优)
private double CrowdingDistance =0; // 拥挤距离
private double WeightedObjective =0; // 加权目标值(用于自定义权重)
/// <summary>
/// 适应度值
/// </summary>
......
package com.aps.entity.Algorithm;
/**
* 作者:佟礼
* 时间:2025-12-09
* 多目标权重配置
*/
public class ObjectiveWeights {
/**
* 目标权重(默认值:[0.3, 0.2, 0.15, 0.2, 0.15])
* 对应:完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
*/
private double[] weights = new double[] { 0.3, 0.2, 0.15, 0.2, 0.15 };
/**
* NSGA-II模式:true=纯帕累托(无视权重),false=加权帕累托
*/
private boolean pureNSGAIIMode = true;
// Getter and Setter for weights
public double[] getWeights() {
return weights;
}
public void setWeights(double[] weights) {
this.weights = weights;
}
// Getter and Setter for pureNSGAIIMode
public boolean isPureNSGAIIMode() {
return pureNSGAIIMode;
}
public void setPureNSGAIIMode(boolean pureNSGAIIMode) {
this.pureNSGAIIMode = pureNSGAIIMode;
}
/**
* 归一化目标值(消除量纲影响)
*/
public double[] normalizeObjectives(double[] objectives, double[] minValues, double[] maxValues) {
double[] normalized = new double[objectives.length];
if(minValues==null||minValues.length==0)
{
for (int i = 0; i < objectives.length; i++) {
normalized[i]= 1/ (1 +(double) objectives[i]);
}
}else {
for (int i = 0; i < objectives.length; i++) {
if (maxValues[i] - minValues[i] == 0)
normalized[i] = 0;
else
normalized[i] = (objectives[i] - minValues[i]) / (maxValues[i] - minValues[i]);
}
}
return normalized;
}
/**
* 计算加权目标值
*/
public double calculateWeightedObjective(double[] normalizedObjectives) {
double sum = 0;
for (int i = 0; i < normalizedObjectives.length; i++)
sum += normalizedObjectives[i] * weights[i];
return sum;
}
/**
* 计算加权目标值
*/
public double calculateObjective(double[] normalizedObjectives) {
double sum = 0;
for (int i = 0; i < normalizedObjectives.length; i++)
sum += normalizedObjectives[i];
return sum;
}
}
......@@ -48,7 +48,7 @@ public class FitnessCalculator {
// 2. 计算每个个体与平均值的平方差之和
float sumSqDiff = 0.0f;
for (Chromosome chromosome : population) {
double diff = chromosome.getFitness() - avgFitness;
double diff = chromosome.getWeightedObjective() - avgFitness;
sumSqDiff += diff * diff;
}
......
......@@ -2,11 +2,8 @@ package com.aps.service.Algorithm;
import com.aps.common.util.DeepCopyUtil;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.Algorithm.GlobalOperationInfo;
import com.aps.entity.Algorithm.*;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.Algorithm.Pair;
import com.aps.entity.Algorithm.ScheduleParams;
import com.aps.entity.basic.*;
import com.aps.service.plan.MachineSchedulerService;
......@@ -28,6 +25,10 @@ public class GeneticAlgorithm {
FitnessCalculator _fitnessCalculator = new FitnessCalculator();
private NSGAIIUtils _nsgaIIUtils = new NSGAIIUtils();
private ObjectiveWeights _objectiveWeights = new ObjectiveWeights();
public GeneticAlgorithm(GlobalParam globalParam,List<Machine> machines, List<Order> orders,
List<Material> materials, MachineSchedulerService machineScheduler,List<GroupResult> entryRel) {
this.machines = machines;
......@@ -37,7 +38,21 @@ public class GeneticAlgorithm {
_GlobalParam=globalParam;
_entryRel=entryRel;
}
public void Init(double[] customWeights, boolean pureNSGAIIMode) {
// 自定义权重配置
if (customWeights != null && customWeights.length == 5)
{
_objectiveWeights.setWeights(customWeights);
_objectiveWeights.setPureNSGAIIMode(pureNSGAIIMode);
}
_nsgaIIUtils.init(_objectiveWeights);
}
public Chromosome Run(ScheduleParams param, List<Entry> allOperations) {
System.out.println("开始");
Initialization initialization = new Initialization(_GlobalParam,allOperations);
......@@ -51,15 +66,22 @@ public class GeneticAlgorithm {
List<Chromosome> population = initialization.generateInitialPopulation(param, globalOpList);
Chromosomedecode(param,allOperations,globalOpList,population);
List<List<Chromosome>> fronts = _nsgaIIUtils.parallelFastNonDominatedSort(population);
int ordercount = globalOpList.stream()
.mapToInt(GlobalOperationInfo::getGroupId)
.max()
.orElse(0);
Chromosome best=new Chromosome();
best= population.stream()
.max(Comparator.comparingDouble(Chromosome::getFitness))
// best=fronts.get(0).stream()
// .max(Comparator.comparingDouble(Chromosome::getFitness))
// .orElse(null);
best = fronts.get(0).stream()
.sorted((c1, c2) -> Double.compare(c2.getWeightedObjective(), c1.getWeightedObjective()))
.findFirst()
.orElse(null);
double bestFitness=0;
int Iteration=0;
// 步骤2:迭代进化
......@@ -108,31 +130,38 @@ public class GeneticAlgorithm {
geneticOps.mutate(chromosome, globalOpList);
}
}
// 精英保留
List<Chromosome> population1 = population.stream()
.sorted((c1, c2) -> Double.compare(c2.getFitness(), c1.getFitness()))
.collect(Collectors.toList()); // 降序排序
List<Chromosome> elites = population1.subList(0, param.getElitismCount());
Chromosomedecode(param,allOperations,globalOpList,nextPopulation);
// // 精英保留
// List<Chromosome> population1 = population.stream()
// .sorted((c1, c2) -> Double.compare(c2.getFitness(), c1.getFitness()))
// .collect(Collectors.toList()); // 降序排序
//
//
// List<Chromosome> elites = population1.subList(0, param.getElitismCount());
List<Chromosome> newPopulation = new ArrayList<>();
newPopulation.addAll(elites);
newPopulation.addAll(population);
newPopulation.addAll(nextPopulation);
// 2.7 非支配排序
List<List<Chromosome>> combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(newPopulation);
// 2.8 选择下一代种群
population = _nsgaIIUtils.selectNextPopulation(combinedFronts, param.getPopulationSize());
// 更新种群
population = newPopulation.stream()
.limit(param.getPopulationSize() )
.collect(Collectors.toList());
// population = newPopulation.stream()
// .limit(param.getPopulationSize() )
// .collect(Collectors.toList());
Chromosomedecode(param,allOperations,globalOpList,population);
best= population.stream()
.max(Comparator.comparingDouble(Chromosome::getFitness))
fronts = _nsgaIIUtils.parallelFastNonDominatedSort(population);
best = fronts.get(0).stream()
.sorted((c1, c2) -> Double.compare(c2.getWeightedObjective(), c1.getWeightedObjective()))
.findFirst()
.orElse(null);
if(bestFitness<best.getFitness())
if(bestFitness<best.getWeightedObjective())
{
bestFitness=best.getFitness();
bestFitness=best.getWeightedObjective();
}else {
Iteration++;
......@@ -174,10 +203,12 @@ public class GeneticAlgorithm {
chromosome.setGlobalOpList(globalOpList); // 简单拷贝,实际可能需要深拷贝
Chromosome chromosomen = decoder.decodeChromosomeWithCache(chromosome);
if (chromosomen.getFitness() == 0) {
chromosomen.setFitness(_fitnessCalculator.calculateFitness(chromosomen));
}
// if (chromosomen.getFitness() == 0) {
// chromosomen.setFitness(_fitnessCalculator.calculateFitness(chromosomen));
// }
});
}
}
......
......@@ -756,12 +756,12 @@ public class GeneticDecoder {
chromosome.setMachineLoadStd(machineLoadBalance);
chromosome.setDelayTime(tardiness);
// 加权求和作为适应度(权重可根据需求调整)
// chromosome.setFitness(0.4 * (1.0 / (1 + makespan)) +
// 0.3 * (1.0 / (1 + tardiness)) +
// 0.1 * (1.0 / (1 + totalSetupTime)) +
// 0.1 * (1.0 / (1 + totalFlowTime)) +
// 0.1 * machineLoadBalance);
double[] Objectives=new double[5];
Objectives[0] = makespan;
Objectives[1] = totalFlowTime;
Objectives[2] = totalSetupTime;
Objectives[3] = machineLoadBalance;
Objectives[4] = tardiness;
}
private double calculateTotalFlowTime(Chromosome chromosome) {
......
......@@ -47,12 +47,22 @@ public class GeneticOperations {
if (tournamentSize < candidates.size()) {
candidates = candidates.subList(0, tournamentSize);
}
// 步骤4: 从参与者中选择适应度最高的个体
// Chromosome best = candidates.stream()
// .max(Comparator.comparingDouble(Chromosome::getFitness))
// .orElseThrow(() -> new IllegalStateException("候选列表为空,无法选择最佳个体。"));
// // 复制个体(假设Chromosome有复制方法或通过构造函数复制)
Chromosome best = candidates.stream()
.max(Comparator.comparingDouble(Chromosome::getFitness))
.orElseThrow(() -> new IllegalStateException("候选列表为空,无法选择最佳个体。"));
// 复制个体(假设Chromosome有复制方法或通过构造函数复制)
// 第一步:按Rank升序排序(与OrderBy对应)
.sorted(Comparator.comparingInt(Chromosome::getRank)
// 第二步:按拥挤距离降序排序(与ThenByDescending对应)
.thenComparing(Comparator.comparingDouble(Chromosome::getCrowdingDistance).reversed()))
// 取第一个元素(与First()对应)
.findFirst()
// 处理空列表情况(避免NoSuchElementException)
.orElse(null);
selected.add(ProductionDeepCopyUtil.deepCopy(best));
}
return selected;
......
This diff is collapsed.
......@@ -23,6 +23,9 @@ import java.util.stream.IntStream;
* 时间:2025-11-30
*/
public class ScheduleOperationService {
/**
* 移动工序方法
* @param chromosome 染色体对象
......@@ -647,10 +650,20 @@ public class ScheduleOperationService {
decoder.decode(chromosome);
if(chromosome.getFitness()==0) {
FitnessCalculator fitnessCalc = new FitnessCalculator();
chromosome.setFitness(fitnessCalc.calculateFitness(chromosome));
}
// if(chromosome.getWeightedObjective()==0) {
//
// double[] normalized = objectiveWeights.normalizeObjectives(chromosome.getObjectives(), null, null);
// if (objectiveWeights.isPureNSGAIIMode()) {
// chromosome.setWeightedObjective(objectiveWeights.calculateObjective(normalized));
// } else {
// chromosome.setWeightedObjective(objectiveWeights.calculateWeightedObjective(normalized));
// }
// }
// if(chromosome.getFitness()==0) {
// FitnessCalculator fitnessCalc = new FitnessCalculator();
// chromosome.setFitness(fitnessCalc.calculateFitness(chromosome));
// }
}
}
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