Commit f30098ce authored by Tong Li's avatar Tong Li

目标kpi可配置

parent e9d075e2
......@@ -2,6 +2,11 @@ package com.aps.entity.basic;
import lombok.Data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 作者:佟礼
* 时间:2025-11-21
......@@ -43,4 +48,122 @@ public class GlobalParam {
private boolean _smoothChangeOver = true; // 默认true,设置时间 是否考虑换型时间
private boolean _smoothChangeOverInWeek = true; // 默认true,后台任务设置 休息时间是否换型
/**
* NSGA-II模式:true=纯帕累托(无视权重),false=加权帕累托
*/
private boolean pureNSGAIIMode = true;
/// <summary>
/// 目标值配置列表:包含目标值的名称、是否启用、层级和权重
/// </summary>
private List<ObjectiveConfig> objectiveConfigs = new ArrayList<>();
/// <summary>
/// 目标值名称常量
/// </summary>
public static final String OBJECTIVE_MAKESPAN = "makespan"; // 最早完工时间
public static final String OBJECTIVE_FLOW_TIME = "flowTime"; // 总流程时间
public static final String OBJECTIVE_SETUP_TIME = "setupTime"; // 总换型时间
public static final String OBJECTIVE_MACHINE_LOAD = "machineLoad"; // 机器负载均衡
public static final String OBJECTIVE_TARDINESS = "tardiness"; // 延迟时间
/// <summary>
/// 构造函数,初始化默认值
/// </summary>
public GlobalParam() {
// 初始化默认目标值配置
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_MAKESPAN, true, 1, 0.6));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_FLOW_TIME, false, 2, 0.1));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_SETUP_TIME, true, 2, 0.1));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_MACHINE_LOAD, false, 3, 0.1));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_TARDINESS, true, 1, 0.3));
}
/// <summary>
/// 获取目标值启用状态
/// </summary>
public Map<String, Boolean> getObjectiveEnabled() {
Map<String, Boolean> enabledMap = new HashMap<>();
for (ObjectiveConfig config : objectiveConfigs) {
enabledMap.put(config.getName(), config.isEnabled());
}
return enabledMap;
}
/// <summary>
/// 获取目标值层级
/// </summary>
public Map<String, Integer> getObjectiveLevels() {
Map<String, Integer> levelsMap = new HashMap<>();
for (ObjectiveConfig config : objectiveConfigs) {
levelsMap.put(config.getName(), config.getLevel());
}
return levelsMap;
}
/// <summary>
/// 获取目标值顺序
/// </summary>
public List<String> getObjectiveOrder() {
List<String> orderList = new ArrayList<>();
for (ObjectiveConfig config : objectiveConfigs) {
orderList.add(config.getName());
}
return orderList;
}
/// <summary>
/// 获取目标值权重
/// </summary>
public Map<String, Double> getObjectiveWeights() {
Map<String, Double> weightsMap = new HashMap<>();
for (ObjectiveConfig config : objectiveConfigs) {
if(config.isEnabled()) {
weightsMap.put(config.getName(), config.getWeight());
}
}
return weightsMap;
}
/// <summary>
/// 根据名称获取目标值配置
/// </summary>
public ObjectiveConfig getObjectiveConfig(String name) {
for (ObjectiveConfig config : objectiveConfigs) {
if (config.getName().equals(name)) {
return config;
}
}
return null;
}
/// <summary>
/// 添加目标值配置
/// </summary>
public void addObjectiveConfig(ObjectiveConfig config) {
objectiveConfigs.add(config);
}
/// <summary>
/// 更新目标值配置
/// </summary>
public void updateObjectiveConfig(String name, ObjectiveConfig config) {
for (int i = 0; i < objectiveConfigs.size(); i++) {
if (objectiveConfigs.get(i).getName().equals(name)) {
objectiveConfigs.set(i, config);
return;
}
}
}
/// <summary>
/// 移除目标值配置
/// </summary>
public void removeObjectiveConfig(String name) {
objectiveConfigs.removeIf(config -> config.getName().equals(name));
}
}
package com.aps.entity.basic;
import lombok.Data;
/**
* 目标值配置实体类
* 作者:佟礼
* 时间:2026-03-17
*/
@Data
public class ObjectiveConfig {
/**
* 目标值名称
*/
private String name;
/**
* 是否启用
*/
private boolean enabled;
/**
* 层级,层级越低优先级越高,1为最高
*/
private int level;
/**
* 权重
*/
private double weight;
/**
* 构造函数
*/
public ObjectiveConfig() {
}
/**
* 构造函数
*/
public ObjectiveConfig(String name, boolean enabled, int level, double weight) {
this.name = name;
this.enabled = enabled;
this.level = level;
this.weight = weight;
}
}
\ No newline at end of file
......@@ -65,14 +65,10 @@ public class GeneticAlgorithm {
materialIds=_materialIds;
}
public void Init(double[] customWeights, boolean pureNSGAIIMode) {
public void Init() {
// 自定义权重配置
if (customWeights != null && customWeights.length == 5)
{
_objectiveWeights.setWeights(customWeights);
_objectiveWeights.setPureNSGAIIMode(pureNSGAIIMode);
}
_nsgaIIUtils.init(_objectiveWeights);
_nsgaIIUtils.init(_GlobalParam);
}
public Chromosome Run(ScheduleParams param, List<Entry> allOperations) {
......
......@@ -1759,73 +1759,91 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
private void calculateScheduleResult(Chromosome chromosome) {
// 1. 最早完工时间(最小化)
double makespan = chromosome.getResult().stream()
.mapToInt(GAScheduleResult::getEndTime)
.max()
.orElse(0);
// 2. 交付期满足情况(最小化延迟)
double tardiness = 0;
Map<Integer, List<GAScheduleResult>> orderGroups = chromosome.getResult().stream()
.collect(Collectors.groupingBy(GAScheduleResult::getGroupId));
for (Map.Entry<Integer, List<GAScheduleResult>> group : orderGroups.entrySet()) {
int groupId = group.getKey();
int orderCompletion = group.getValue().stream()
.mapToInt(GAScheduleResult::getEndTime)
.max()
.orElse(0);
List<String> orderIds = group.getValue().stream()
.map(GAScheduleResult::getOrderId)
.distinct()
.sorted()
.collect(Collectors.toList());
Order order = chromosome.getOrders().stream()
.filter(t->orderIds.contains(t.getOrderId()))
.max(Comparator.comparing(Order::getDueDate))
.orElse(null);
if(order.isNewCreate())
{continue;}
LocalDateTime dueDateTime=order.getDueDate();
LocalDateTime completionTime =baseTime.plusSeconds(orderCompletion);
if (completionTime.isAfter(dueDateTime)) {
// 计算延迟小时数(修复时间计算)
long hours = ChronoUnit.HOURS.between(dueDateTime, completionTime);
long minutes = ChronoUnit.MINUTES.between(dueDateTime, completionTime) % 60;
tardiness += hours*60 + (double) minutes ;
}
double[] Objectives=new double[_globalParam.getObjectiveWeights().size()];
int i=0;
for (ObjectiveConfig config : _globalParam.getObjectiveConfigs()) {
if( config.isEnabled())
{
if(config.getName()==GlobalParam.OBJECTIVE_MAKESPAN)
{
// 1. 最早完工时间(最小化)
double makespan = chromosome.getResult().stream()
.mapToInt(GAScheduleResult::getEndTime)
.max()
.orElse(0);
Objectives[i]=makespan;
chromosome.setMakespan(makespan);
}
if(config.getName()==GlobalParam.OBJECTIVE_TARDINESS)
{
// 2. 交付期满足情况(最小化延迟)
double tardiness = 0;
Map<Integer, List<GAScheduleResult>> orderGroups = chromosome.getResult().stream()
.collect(Collectors.groupingBy(GAScheduleResult::getGroupId));
for (Map.Entry<Integer, List<GAScheduleResult>> group : orderGroups.entrySet()) {
int groupId = group.getKey();
int orderCompletion = group.getValue().stream()
.mapToInt(GAScheduleResult::getEndTime)
.max()
.orElse(0);
List<String> orderIds = group.getValue().stream()
.map(GAScheduleResult::getOrderId)
.distinct()
.sorted()
.collect(Collectors.toList());
Order order = chromosome.getOrders().stream()
.filter(t->orderIds.contains(t.getOrderId()))
.max(Comparator.comparing(Order::getDueDate))
.orElse(null);
if(order.isNewCreate())
{continue;}
LocalDateTime dueDateTime=order.getDueDate();
LocalDateTime completionTime =baseTime.plusSeconds(orderCompletion);
if (completionTime.isAfter(dueDateTime)) {
// 计算延迟小时数(修复时间计算)
long hours = ChronoUnit.HOURS.between(dueDateTime, completionTime);
long minutes = ChronoUnit.MINUTES.between(dueDateTime, completionTime) % 60;
tardiness += hours*60 + (double) minutes ;
}
}
Objectives[i]=tardiness;
chromosome.setDelayTime(tardiness);
}
if(config.getName()==GlobalParam.OBJECTIVE_SETUP_TIME)
{
// 3. 最小总换型时间
double totalSetupTime = calculateTotalSetupTime(chromosome);
chromosome.setTotalChangeoverTime(totalSetupTime);
Objectives[i]=totalSetupTime;
}
if(config.getName()==GlobalParam.OBJECTIVE_FLOW_TIME)
{
// 4. 最小化总流程时间 所有工序加工时间的总和
double totalFlowTime = calculateTotalFlowTime(chromosome);
chromosome.setTotalFlowTime(totalFlowTime);
Objectives[i]=totalFlowTime;
}
if(config.getName()==GlobalParam.OBJECTIVE_MACHINE_LOAD)
{
// 5. 机器负载均衡
double machineLoadBalance = calculateMachineLoadBalance(chromosome);
chromosome.setMachineLoadStd(machineLoadBalance);
Objectives[i]=machineLoadBalance;
}
i++;
}
}
// 3. 最小总换型时间
double totalSetupTime = calculateTotalSetupTime(chromosome);
// 4. 最小化总流程时间 所有工序加工时间的总和
double totalFlowTime = calculateTotalFlowTime(chromosome);
// 5. 机器负载均衡
double machineLoadBalance = calculateMachineLoadBalance(chromosome);
// 存储各目标值
chromosome.setMakespan(makespan);
chromosome.setTotalFlowTime(totalFlowTime);
chromosome.setTotalChangeoverTime(totalSetupTime);
chromosome.setMachineLoadStd(machineLoadBalance);
chromosome.setDelayTime(tardiness);
double[] Objectives=new double[5];
Objectives[0] = makespan;
Objectives[1] = totalFlowTime;
Objectives[2] = totalSetupTime;
Objectives[3] = machineLoadBalance;
Objectives[4] = tardiness;
chromosome.setObjectives(Objectives);
}
......
......@@ -3,14 +3,12 @@ package com.aps.service.Algorithm;
import com.aps.common.util.FileHelper;
import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.Algorithm.ObjectiveWeights;
import com.aps.entity.basic.GlobalParam;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
......@@ -19,31 +17,56 @@ import java.util.stream.IntStream;
public class NSGAIIUtils {
private ObjectiveWeights objectiveWeights;
private int taskCount; // 并行任务数(默认=CPU核心数)
private GlobalParam globalParam; // 全局参数配置
// true 越小越好
private boolean[] isMinimize = {true, true, true, true, true};
public void init(ObjectiveWeights weights, int taskCount,boolean[] isMinimize) {
this.objectiveWeights = (weights != null) ? weights : new ObjectiveWeights();
this.taskCount = (taskCount > 0) ? taskCount : Runtime.getRuntime().availableProcessors()-1;
this.isMinimize=isMinimize;
}
/**
* 初始化(设置权重和并行任务数)
*/
public void init(ObjectiveWeights weights, int taskCount) {
this.objectiveWeights = (weights != null) ? weights : new ObjectiveWeights();
public void init(GlobalParam globalParam, int taskCount) {
this.globalParam = globalParam;
this.objectiveWeights = (globalParam.getObjectiveWeights() != null) ? buildObjectiveWeightsFromGlobalParam() : new ObjectiveWeights();
this.taskCount = (taskCount > 0) ? taskCount : Runtime.getRuntime().availableProcessors()-1;
}
/**
* 重载初始化方法(默认任务数)
*/
public void init(ObjectiveWeights weights) {
init(weights, 0);
public void init(GlobalParam globalParam) {
init(globalParam, 0);
}
/**
* 从 globalParam 构建 ObjectiveWeights
*/
private ObjectiveWeights buildObjectiveWeightsFromGlobalParam() {
ObjectiveWeights weights = new ObjectiveWeights();
// 设置 pureNSGAIIMode
if (globalParam != null) {
weights.setPureNSGAIIMode(globalParam.isPureNSGAIIMode());
// 按照固定顺序构建权重数组
Map<String, Double> objectiveWeights = globalParam.getObjectiveWeights();
double[] weightsArray = new double[objectiveWeights.size()];
int i=0;
for (Double weight : objectiveWeights.values()) {
weightsArray[i]= weight;
i++;
}
weights.setWeights(weightsArray);
}
return weights;
}
/**
* 并行快速非支配排序(大规模种群提速50%+)
......@@ -65,57 +88,75 @@ public class NSGAIIUtils {
// 步骤2:拆分种群为多个块,并行计算支配关系
List<List<Chromosome>> chunks = splitPopulation(population, chunkCount);
Map<Chromosome, List<Chromosome>> dominanceMatrix = new HashMap<>();
Map<Chromosome, Integer> dominatedCount = new HashMap<>();
// Map<Chromosome, List<Chromosome>> dominanceMatrix = new HashMap<>();
// Map<Chromosome, Integer> dominatedCount = new HashMap<>();
ConcurrentHashMap<Chromosome, ConcurrentLinkedQueue<Chromosome>> dominanceMatrix = new ConcurrentHashMap<>();
ConcurrentHashMap<Chromosome, AtomicInteger> dominatedCount = new ConcurrentHashMap<>();
for (Chromosome chromo : population) {
dominanceMatrix.put(chromo, new ArrayList<>());
dominatedCount.put(chromo, 0);
// dominanceMatrix.put(chromo, new ArrayList<>());
// dominatedCount.put(chromo, 0);
dominanceMatrix.putIfAbsent(chromo, new ConcurrentLinkedQueue<>());
dominatedCount.putIfAbsent(chromo, new AtomicInteger(0));
}
ExecutorService executor = Executors.newFixedThreadPool(chunkCount);
try {
List<Future<?>> futures = new ArrayList<>(); // 存储任务Future,确保全量等待
for (List<Chromosome> chunk : chunks) {
futures.add(executor.submit(() -> {
for (Chromosome p : chunk) {
for (Chromosome q : population) {
if (p == q) continue;
if (dominates(p, q)) {
synchronized (dominanceMatrix.get(p)) { // 细粒度锁
dominanceMatrix.get(p).add(q);
}
} else if (dominates(q, p)) {
synchronized (dominatedCount) {
dominatedCount.put(p, dominatedCount.get(p) + 1);
}
}
}
// ExecutorService executor = Executors.newFixedThreadPool(chunkCount);
// try {
// List<Future<?>> futures = new ArrayList<>(); // 存储任务Future,确保全量等待
// for (List<Chromosome> chunk : chunks) {
// futures.add(executor.submit(() -> {
// for (Chromosome p : chunk) {
// for (Chromosome q : population) {
// if (p == q) continue;
// if (dominates(p, q)) {
// synchronized (dominanceMatrix.get(p)) { // 细粒度锁
// dominanceMatrix.get(p).add(q);
// }
// } else if (dominates(q, p)) {
// synchronized (dominatedCount) {
// dominatedCount.put(p, dominatedCount.get(p) + 1);
// }
// }
// }
// }
// }));
// }
//
// // 核心修复2:等待所有任务完成,避免提前终止导致的计算不完整
// for (Future<?> future : futures) {
// try {
// future.get(); // 等待单个任务完成,抛出异常则终止
// } catch (ExecutionException e) {
// throw new RuntimeException("并行计算支配关系失败", e.getCause());
// }
// }
//
// executor.shutdown();
//
// }catch (InterruptedException e) {
// Thread.currentThread().interrupt();
// throw new RuntimeException("并行计算支配关系中断", e);
// } finally {
// if (!executor.isShutdown()) {
// executor.shutdownNow(); // 确保线程池关闭
// }
// }
// 并行计算支配关系
chunks.parallelStream().forEach(chunk -> {
for (Chromosome p : chunk) {
for (Chromosome q : population) {
if (p == q) continue;
if (dominates(p, q)) {
dominanceMatrix.get(p).add(q);
} else if (dominates(q, p)) {
dominatedCount.get(p).incrementAndGet();
}
}));
}
// 核心修复2:等待所有任务完成,避免提前终止导致的计算不完整
for (Future<?> future : futures) {
try {
future.get(); // 等待单个任务完成,抛出异常则终止
} catch (ExecutionException e) {
throw new RuntimeException("并行计算支配关系失败", e.getCause());
}
}
executor.shutdown();
}catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("并行计算支配关系中断", e);
} finally {
if (!executor.isShutdown()) {
executor.shutdownNow(); // 确保线程池关闭
}
}
});
// 生成前沿
// 染色体 -> 数组下标的映射表
......@@ -124,6 +165,7 @@ public class NSGAIIUtils {
// 新增:支配矩阵数组化 - 每个p的下标,对应一个存储q下标的List
List<List<Integer>> dominanceMatrixArr = new ArrayList<>(popSize);
// ======== 修复空指针的核心行:循环popSize次,给每个索引塞一个空的ArrayList ========
//初始化每个位置的空列表
for (int idx = 0; idx < popSize; idx++) {
dominanceMatrixArr.add(new ArrayList<>()); // 必须加这行,初始化每个位置的空列表
Chromosome c = population.get(idx);
......@@ -133,16 +175,28 @@ public class NSGAIIUtils {
for (int idx = 0; idx < popSize; idx++) {
Chromosome c = population.get(idx);
dominatedCounts[idx] = dominatedCount.get(c);
// 把HashMap的支配列表,转成q的下标列表,存入数组
List<Chromosome> qList = dominanceMatrix.get(c);
List<Integer> qIdxList = dominanceMatrixArr.get(idx); // 此时get(idx)绝对非空!
for (Chromosome q : qList) {
// dominatedCounts[idx] = dominatedCount.get(c);
// // 把HashMap的支配列表,转成q的下标列表,存入数组
// List<Chromosome> qList = dominanceMatrix.get(c);
// List<Integer> qIdxList = dominanceMatrixArr.get(idx); // 此时get(idx)绝对非空!
// for (Chromosome q : qList) {
// Integer qIdx = chromosomeIndexMap.get(q);
// if(qIdx != null){ // 额外兜底:防止q是null导致的空指针
// qIdxList.add(qIdx);
// }
// }
dominatedCounts[idx] = dominatedCount.get(c).get();
// 把ConcurrentHashMap的支配队列,转成q的下标列表,存入数组
ConcurrentLinkedQueue<Chromosome> qQueue = dominanceMatrix.get(c);
List<Integer> qIdxList = dominanceMatrixArr.get(idx);
for (Chromosome q : qQueue) {
Integer qIdx = chromosomeIndexMap.get(q);
if(qIdx != null){ // 额外兜底:防止q是null导致的空指针
qIdxList.add(qIdx);
}
}
}
// ========== 初始化前沿列表,必须先添加F1(第一个前沿) ==========
......@@ -150,7 +204,9 @@ public class NSGAIIUtils {
// 遍历种群,找到所有被支配数=0的个体 → 这就是F1,绝对不被任何个体支配的最优解
for (Chromosome chromosome : population) {
if (chromosome == null) continue;
int count = dominatedCount.getOrDefault(chromosome, 0);
// int count = dominatedCount.getOrDefault(chromosome, 0);
int count = dominatedCount.getOrDefault(chromosome, new AtomicInteger(0)).get();
if (count == 0) {
firstFront.add(chromosome);
}
......@@ -375,22 +431,22 @@ public class NSGAIIUtils {
*/
private void preprocessObjectives(List<Chromosome> population) {
int kpisize = population.get(0).getObjectives().length;
int kpiSize = population.get(0).getObjectives().length;
// 计算每个目标的最大/最小值
double[] minValues = new double[kpisize];
double[] maxValues = new double[kpisize];
double[] minValues = new double[kpiSize];
double[] maxValues = new double[kpiSize];
// for (int i = 0; i < kpisize; i++) {
// final int idx = i;
// minValues[i] = population.stream().mapToDouble(c -> c.getObjectives()[idx]).min().orElse(0);
// maxValues[i] = population.stream().mapToDouble(c -> c.getObjectives()[idx]).max().orElse(0);
// }
for (int i = 0; i < kpisize; i++) {
for (int i = 0; i < kpiSize; i++) {
minValues[i] = Double.MAX_VALUE;
maxValues[i] = Double.MIN_VALUE;
}
for (Chromosome chromo : population) {
double[] obj = chromo.getObjectives();
for (int i = 0; i < kpisize; i++) {
for (int i = 0; i < kpiSize; i++) {
minValues[i] = Math.min(minValues[i], obj[i]);
maxValues[i] = Math.max(maxValues[i], obj[i]);
}
......@@ -400,6 +456,7 @@ public class NSGAIIUtils {
population.parallelStream().forEach(chromo -> {
double[] normalized = objectiveWeights.normalizeObjectives(chromo.getObjectives(), minValues, maxValues,this.isMinimize);
chromo.setMaxObjectives(maxValues);
chromo.setMinObjectives(minValues);
chromo.setWeightedObjectives(normalized);
......@@ -434,6 +491,11 @@ public class NSGAIIUtils {
// 纯NSGA-II模式:标准帕累托支配
double[] pObjectives = p.getWeightedObjectives();
double[] qObjectives = q.getWeightedObjectives();
// 如果启用了目标层级,则使用层级排序
// if (globalParam != null && globalParam.getObjectiveLevels() != null) {
// return dominatesWithLevels(p, q, pObjectives, qObjectives);
// }
if (objectiveWeights.isPureNSGAIIMode()) {
boolean hasBetter = false; // 是否至少有一个目标更优
boolean hasWorse = false; // 是否有任何一个目标更差
......@@ -478,6 +540,74 @@ public class NSGAIIUtils {
return hasBetterScore && hasAtLeastOneNotWorse;
}
}
/**
* 基于目标层级的支配关系判断
*/
private boolean dominatesWithLevels(Chromosome p, Chromosome q, double[] pObjectives, double[] qObjectives) {
// 获取启用的目标及其层级
Map<String, Integer> objectiveLevels = globalParam.getObjectiveLevels();
List<String> objectiveOrder = globalParam.getObjectiveOrder();
List<String> enabledObjectives = new ArrayList<>();
Map<String, Integer> levelMap = new HashMap<>();
// 构建启用的目标列表和层级映射
int objIndex = 0;
for (String objectiveName : objectiveOrder) {
if (globalParam.getObjectiveEnabled().getOrDefault(objectiveName, true)) {
enabledObjectives.add(objectiveName);
levelMap.put(objectiveName, objectiveLevels.getOrDefault(objectiveName, 1));
objIndex++;
}
}
// 按层级从低到高排序,层级越低优先级越高
List<Integer> sortedLevels = new ArrayList<>(new HashSet<>(levelMap.values()));
sortedLevels.sort(Comparator.naturalOrder());
// 遍历每个层级
for (int level : sortedLevels) {
// 获取当前层级的所有目标名称
List<String> levelObjectives = new ArrayList<>();
for (Map.Entry<String, Integer> entry : levelMap.entrySet()) {
if (entry.getValue() == level) {
levelObjectives.add(entry.getKey());
}
}
// 比较当前层级的目标值
boolean hasBetter = false;
boolean hasWorse = false;
for (String objectiveName : levelObjectives) {
int objIdx = enabledObjectives.indexOf(objectiveName);
if (objIdx < 0 || objIdx >= pObjectives.length || objIdx >= qObjectives.length) {
continue;
}
double thisObj = pObjectives[objIdx];
double otherObj = qObjectives[objIdx];
// 目标越大越好:当前解 > 另一个解 → 更优
if (thisObj > otherObj) {
hasBetter = true;
}
// 当前解 < 另一个解 → 更差
else if (thisObj < otherObj) {
hasWorse = true;
}
}
// 如果当前层级有差异,则根据差异判断支配关系
if (hasBetter && !hasWorse) {
return true;
} else if (hasWorse) {
return false;
}
// 如果当前层级无差异,则继续比较下一层级
}
// 所有层级都无差异,不支配
return false;
}
/**
* 并行计算拥挤距离
......@@ -547,6 +677,16 @@ public class NSGAIIUtils {
}
return Math.sqrt(sum); // 开平方得到欧氏距离
}
// 考虑使用标准化欧氏距离
private double calculateNormalizedEuclideanDistance(double[] objectives, double[] idealPoint, double[] maxValues, double[] minValues) {
double sum = 0.0;
for (int i = 0; i < objectives.length; i++) {
double range = maxValues[i] - minValues[i];
double normalizedDiff = range > 0 ? (objectives[i] - idealPoint[i]) / range : 0;
sum += normalizedDiff * normalizedDiff;
}
return Math.sqrt(sum);
}
/**
* 选择下一代种群(兼容并行计算)
......@@ -576,11 +716,11 @@ public class NSGAIIUtils {
public void Test() {
ObjectiveWeights weights = new ObjectiveWeights();
double[] weightvs = new double[] { 0.5, 0.5 };
weights.setWeights(weightvs);
weights.setPureNSGAIIMode(false);
init(weights);
GlobalParam globalParam1 = new GlobalParam();
globalParam1.setPureNSGAIIMode(false);
init(globalParam1);
List<Chromosome> chromosomeList = new ArrayList<>();
Chromosome chromosome1 = new Chromosome();
chromosome1.setID("A");
......
......@@ -208,13 +208,14 @@ public class PlanResultService {
.map(Material::getId)
.distinct()
.collect(Collectors.toList());
globalParam.setPureNSGAIIMode(false);
// 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,Materials1,materialIds,machineScheduler,entryRel,materialRequirementService,_sceneService,SceneId); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
param.initAdaptiveParams(entrys.size());
double[] customWeights = new double[] { 0.4, 0.1, 0.1, 0.1, 0.3 }; // 延迟时间权重提升到0.5
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
scheduler.Init(customWeights,false);
scheduler.Init();
// scheduler.Init(customWeights,false);
Chromosome chromosome =scheduler.Run(param,entrys);
KpiCalculator kpiCalculator=new KpiCalculator(chromosome);
......@@ -770,7 +771,8 @@ public class PlanResultService {
param.initAdaptiveParams(entrys.size());
double[] customWeights = new double[] { 0.4, 0.1, 0.1, 0.1, 0.3 }; // 延迟时间权重提升到0.5
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
scheduler.Init(customWeights,false);
// scheduler.Init(customWeights,false);
scheduler.Init();
Chromosome chromosomes =scheduler.Run(param,entrys);
KpiCalculator kpiCalculator=new KpiCalculator(chromosomes);
kpiCalculator.calculatekpi();
......
package com.aps.demo;
import com.aps.service.Algorithm.NSGAIIUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
/**
* 作者:佟礼
* 时间:2026-03-17
*/
@SpringBootTest
public class NSGAIIUtilsTest {
private NSGAIIUtils _nsgaIIUtils = new NSGAIIUtils();
@Test
public void test() {
_nsgaIIUtils.Test();
}
}
......@@ -39,7 +39,7 @@ public class PlanResultServiceTest {
// TestSortService sortService=new TestSortService();
// sortService.test1();
// nsgaiiUtils.Test();
planResultService.execute2("5475E00B844847ACB6DC20227967BA2F");
planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");
// planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D");
// planResultService.execute2("92BB773E1E2447C99D8176C991D5C9D2");
......
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