Commit 47286670 authored by Tong Li's avatar Tong Li

算法优化

parent e56eef9d
...@@ -23,7 +23,7 @@ public class Chromosome { ...@@ -23,7 +23,7 @@ public class Chromosome {
private String ID = UUID.randomUUID().toString(); private String ID = UUID.randomUUID().toString();
private String generateType;
private Integer version=0; private Integer version=0;
...@@ -117,6 +117,12 @@ public class Chromosome { ...@@ -117,6 +117,12 @@ public class Chromosome {
*/ */
private double[] WeightedObjectives;//越靠近1越优 private double[] WeightedObjectives;//越靠近1越优
private double WeightedObjective =0; // 加权目标值(用于自定义权重) private double WeightedObjective =0; // 加权目标值(用于自定义权重)
/// <summary>
/// 适应度值
/// </summary>
private double[] fitnessLevel;
/// <summary> /// <summary>
/// 适应度值 /// 适应度值
/// </summary> /// </summary>
......
...@@ -2,10 +2,7 @@ package com.aps.entity.basic; ...@@ -2,10 +2,7 @@ package com.aps.entity.basic;
import lombok.Data; import lombok.Data;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* 作者:佟礼 * 作者:佟礼
...@@ -81,6 +78,8 @@ public class GlobalParam { ...@@ -81,6 +78,8 @@ public class GlobalParam {
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_SETUP_TIME, true, 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_MACHINE_LOAD, false, 3, 0.1));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_TARDINESS, true, 1, 0.3)); objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_TARDINESS, true, 1, 0.3));
objectiveConfigs.sort(Comparator.comparing((ObjectiveConfig op) -> op.getLevel()));
} }
/// <summary> /// <summary>
...@@ -146,6 +145,8 @@ public class GlobalParam { ...@@ -146,6 +145,8 @@ public class GlobalParam {
/// </summary> /// </summary>
public void addObjectiveConfig(ObjectiveConfig config) { public void addObjectiveConfig(ObjectiveConfig config) {
objectiveConfigs.add(config); objectiveConfigs.add(config);
objectiveConfigs.sort(Comparator.comparing((ObjectiveConfig op) -> op.getLevel()));
} }
/// <summary> /// <summary>
...@@ -158,6 +159,8 @@ public class GlobalParam { ...@@ -158,6 +159,8 @@ public class GlobalParam {
return; return;
} }
} }
objectiveConfigs.sort(Comparator.comparing((ObjectiveConfig op) -> op.getLevel()));
} }
/// <summary> /// <summary>
......
...@@ -18,6 +18,11 @@ public class ObjectiveConfig { ...@@ -18,6 +18,11 @@ public class ObjectiveConfig {
*/ */
private boolean enabled; private boolean enabled;
/**
* 越小越好
*/
private boolean isMinimize;
/** /**
* 层级,层级越低优先级越高,1为最高 * 层级,层级越低优先级越高,1为最高
*/ */
...@@ -28,6 +33,11 @@ public class ObjectiveConfig { ...@@ -28,6 +33,11 @@ public class ObjectiveConfig {
*/ */
private double weight; private double weight;
/**
* 值
*/
private double val;
/** /**
* 构造函数 * 构造函数
*/ */
......
...@@ -2,7 +2,10 @@ package com.aps.service.Algorithm; ...@@ -2,7 +2,10 @@ package com.aps.service.Algorithm;
import com.aps.entity.Algorithm.Chromosome; import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.Algorithm.ObjectiveWeights; import com.aps.entity.Algorithm.ObjectiveWeights;
import com.aps.entity.basic.GlobalParam;
import com.aps.entity.basic.ObjectiveConfig;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
...@@ -10,6 +13,84 @@ import java.util.List; ...@@ -10,6 +13,84 @@ import java.util.List;
* 时间:2025-11-24 * 时间:2025-11-24
*/ */
public class FitnessCalculator { public class FitnessCalculator {
/**
* 多目标适应度计算(加权求和)
*/
public double[] calculateFitness(Chromosome chromosome, GlobalParam param) {
ArrayList<Double> list = new ArrayList<>();
double fitness=0;
int i=0;
int level=-1;
for (ObjectiveConfig config : param.getObjectiveConfigs()) {
if( config.isEnabled()) {
if(level==-1)
{
level=config.getLevel();
}else if(level!=config.getLevel())
{
list.add(fitness);
fitness=0;
level=config.getLevel();
}
double obj = chromosome.getObjectives()[i];
// 防御:处理负数(目标值应为非负,若为负则兜底为0)
obj = Math.max(0, obj);
//转化为0,1 越靠近1 越优
double val = 0;
if (config.isMinimize()) {
// ============================
// 最小化目标:越小越优 → 归一化后越大越优,越优
// ============================
//0/1+ 0 =0 min max 最优
//1/1+ 1 =0.5 min max 最优
//1/1+ 2 =0.33
//1/1+ 3 =0.25
val = 1.0 / (1.0 + obj);
} else {
// ============================
// 最大化目标:越大越优 → 反转成 越大越优
// ============================
// 1/1+ 1 = 0.5
// 2/1+ 2 = 0.66
// 3/1+ 3 = 0.75 max max 最优
val = obj / (1.0 + obj);
}
// 兜底:避免极端情况归一化值为0(最小设为1e-6)
// val = Math.max(val, 1e-6);
if (!param.isPureNSGAIIMode()) {
val = val * config.getWeight();
}
fitness += val;
i++;
}
}
list.add(fitness);
// 归一化(假设最大可能值,实际应根据问题规模调整)
// makespan = 10 → val = 1/11 = 0.09
// makespan = 20 → val = 1/21 = 0.045
// makespan = 100 → val = 1/101 = 0.009
// 值越大 归一化 后越小, 越大越好
//原目标(工期、延迟、负载)越小 → 生产越好
//原目标越小,归一化后 → f1、f2、f3 越大
// 方案 A:工期短、延迟小 → 很好
// makespan=10 → f1=1/(11)=0.09
// fitness ≈ 0.08
// 方案 B:工期长、延迟大 → 很差
// makespan=100 → f1=1/(101)=0.009
// fitness ≈ 0.01
// 适应度值(越大越好)
return list.stream().mapToDouble(Double::doubleValue).toArray();
}
/** /**
* 多目标适应度计算(加权求和) * 多目标适应度计算(加权求和)
*/ */
...@@ -29,11 +110,25 @@ public class FitnessCalculator { ...@@ -29,11 +110,25 @@ public class FitnessCalculator {
// 1/1+1 0.5 // 1/1+1 0.5
// 1/1+2 0.3 // 1/1+2 0.3
// 1/1+3 0.25 // 1/1+3 0.25
// 值越大 归一化 后越小
// makespan = 10 → val = 1/11 = 0.09
// makespan = 20 → val = 1/21 = 0.045
// makespan = 100 → val = 1/101 = 0.009
// 值越大 归一化 后越小, 越大越好
//原目标(工期、延迟、负载)越小 → 生产越好
//原目标越小,归一化后 → f1、f2、f3 越大
// 方案 A:工期短、延迟小 → 很好
// makespan=10 → f1=1/(11)=0.09
// fitness ≈ 0.08
// 方案 B:工期长、延迟大 → 很差
// makespan=100 → f1=1/(101)=0.009
// fitness ≈ 0.01
} }
// 适应度值(越大越好) // 适应度值(越大越好)
return fitness; return fitness;
} }
/** /**
* 计算种群适应度标准差(用于参数微调) * 计算种群适应度标准差(用于参数微调)
* @param population 染色体种群数组 * @param population 染色体种群数组
......
package com.aps.service.Algorithm; package com.aps.service.Algorithm;
import com.aps.common.util.DateTimeUtil; import com.aps.common.util.*;
import com.aps.common.util.DeepCopyUtil;
import com.aps.common.util.FileHelper;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*; import com.aps.entity.Algorithm.*;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult; import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.basic.*; import com.aps.entity.basic.*;
...@@ -51,19 +48,8 @@ public class GeneticAlgorithm { ...@@ -51,19 +48,8 @@ public class GeneticAlgorithm {
private String sceneId; private String sceneId;
private VariableNeighborhoodSearch _vns;
// 初始化算法实例
private HillClimbing _hillClimbing;
private SimulatedAnnealing _simulatedAnnealing;
private ParallelLocalSearch _parallelLocalSearch;
// 初始化算法实例
private TabuSearch _tabuSearch;
private TabuSearchWithSA _tabuSearchWithSA;
public GeneticAlgorithm(GlobalParam globalParam,List<Machine> machines, List<Order> orders, public GeneticAlgorithm(GlobalParam globalParam,List<Machine> machines, List<Order> orders,
List<Material> materials,List<String> _materialIds, MachineSchedulerService machineScheduler,List<GroupResult> entryRel,MaterialRequirementService _materialRequirementService,SceneService sceneService,String _sceneId) { List<Material> materials,List<String> _materialIds, MachineSchedulerService machineScheduler,List<GroupResult> entryRel,MaterialRequirementService _materialRequirementService,SceneService sceneService,String _sceneId) {
this.machines = machines; this.machines = machines;
this.orders = orders; this.orders = orders;
this.materials = materials; this.materials = materials;
...@@ -71,9 +57,9 @@ public class GeneticAlgorithm { ...@@ -71,9 +57,9 @@ public class GeneticAlgorithm {
_GlobalParam=globalParam; _GlobalParam=globalParam;
_entryRel=entryRel; _entryRel=entryRel;
materialRequirementService=_materialRequirementService; materialRequirementService=_materialRequirementService;
_sceneService=sceneService; _sceneService=sceneService;
sceneId=_sceneId; sceneId=_sceneId;
materialIds=_materialIds; materialIds=_materialIds;
} }
public void Init() { public void Init() {
...@@ -89,16 +75,6 @@ public class GeneticAlgorithm { ...@@ -89,16 +75,6 @@ public class GeneticAlgorithm {
throw new RuntimeException("没有待排产工单"); throw new RuntimeException("没有待排产工单");
} }
// if(materials!=null&&materials.size()>0) {
//
// materialRequirementService.init(materials, orders, allOperations, _entryRel, machineScheduler, machines,_GlobalParam);
//
// orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(param.getBaseTime());
// Set<Long> existIds = new HashSet<>();
// machines=machines.stream()
// .filter(t->existIds.add(t.getId()))//HashSet.add() 方法:添加成功返回 true,重复返回 false;
// .collect(Collectors.toList());
// }
LocalDateTime starttime=LocalDateTime.now(); LocalDateTime starttime=LocalDateTime.now();
FileHelper.writeLogFile("排产-----------开始-----------"+allOperations.get(0).getSceneId()); FileHelper.writeLogFile("排产-----------开始-----------"+allOperations.get(0).getSceneId());
...@@ -108,23 +84,11 @@ public class GeneticAlgorithm { ...@@ -108,23 +84,11 @@ public class GeneticAlgorithm {
// 预生成全局工序列表(所有初始化方法共享同一顺序) // 预生成全局工序列表(所有初始化方法共享同一顺序)
List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList(); List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList();
// 初始化变邻域搜索
_vns = new VariableNeighborhoodSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_hillClimbing = new HillClimbing(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_simulatedAnnealing = new SimulatedAnnealing(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_parallelLocalSearch = new ParallelLocalSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_tabuSearch = new TabuSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_tabuSearchWithSA = new TabuSearchWithSA(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
FileHelper.writeLogFile("初始化种群-----------开始-------"); FileHelper.writeLogFile("初始化种群-----------开始-------");
// 步骤1:初始化种群 // 步骤1:初始化种群
List<Chromosome> population = initialization.generateInitialPopulation(param, globalOpList); List<Chromosome> population = initialization.generateInitialPopulation(param, globalOpList);
// 步骤1:使用构造启发式算法生成初始种群
FileHelper.writeLogFile("构造启发式初始化-----------开始-------");
// List<Chromosome> population = initialization.generateHeuristicInitialPopulation(param, globalOpList);
FileHelper.writeLogFile("构造启发式初始化-----------结束-------");
population= chromosomeDistinct(population); population= chromosomeDistinct(population);
...@@ -133,31 +97,7 @@ public class GeneticAlgorithm { ...@@ -133,31 +97,7 @@ public class GeneticAlgorithm {
FileHelper.writeLogFile("初始化种群-----------结束-------"); FileHelper.writeLogFile("初始化种群-----------结束-------");
FileHelper.writeLogFile("初始化批量解码-----------开始-------"); FileHelper.writeLogFile("初始化批量解码-----------开始-------");
Chromosomedecode(param,allOperations,globalOpList,population); Chromosomedecode(param,allOperations,globalOpList,population);
FileHelper.writeLogFile("初始化批量解码-----------结束-------"); FileHelper.writeLogFile("初始化批量解码-----------结束-------");
// 步骤2:对初始种群进行爬山法局部优化
FileHelper.writeLogFile("爬山法局部优化-----------开始-------");
GeneticDecoder hillClimbingDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> optimizedPopulation = new ArrayList<>();
for (Chromosome chromosome : population) {
Chromosome optimized = _hillClimbing.search(chromosome, hillClimbingDecoder, param);
optimizedPopulation.add(optimized);
}
population = optimizedPopulation;
FileHelper.writeLogFile("爬山法局部优化-----------结束-------");
// 步骤2:对初始种群进行模拟退火+爬山法优化
FileHelper.writeLogFile("模拟退火+爬山法优化-----------开始-------");
GeneticDecoder saDecoder1 = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> saHcOptimized = new ArrayList<>();
for (Chromosome chromosome : population) {
Chromosome optimized = _simulatedAnnealing.searchWithHillClimbing(chromosome, saDecoder1, param);
saHcOptimized.add(optimized);
}
population = saHcOptimized;
FileHelper.writeLogFile("模拟退火+爬山法优化-----------结束-------");
List<List<Chromosome>> combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(population); List<List<Chromosome>> combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(population);
int ordercount = globalOpList.stream() int ordercount = globalOpList.stream()
.mapToInt(GlobalOperationInfo::getGroupId) .mapToInt(GlobalOperationInfo::getGroupId)
...@@ -174,11 +114,11 @@ public class GeneticAlgorithm { ...@@ -174,11 +114,11 @@ public class GeneticAlgorithm {
if(population.size()<param.getTournamentSize()) if(population.size()<param.getTournamentSize())
{ {
best.setBaseTime(param.getBaseTime()); best.setBaseTime(param.getBaseTime());
// best.setOrderMaterials(orderMaterials); // best.setOrderMaterials(orderMaterials);
best.setMaterialIds(materialIds); best.setMaterialIds(materialIds);
best.setMaterials(null); best.setMaterials(null);
best.setScenarioID(sceneId); best.setScenarioID(sceneId);
// best.setOperatRel(_entryRel); // best.setOperatRel(_entryRel);
if(best.getInitMachines()==null) if(best.getInitMachines()==null)
{ {
...@@ -209,7 +149,7 @@ public class GeneticAlgorithm { ...@@ -209,7 +149,7 @@ public class GeneticAlgorithm {
} }
FileHelper.writeLogFile("选择操作-----------开始-------"); FileHelper.writeLogFile("选择操作-----------开始-------");
// 选择前移除适应度为 0 或明显劣于当前最优解的个体,减少选择池规模: // 选择前移除适应度为 0 或明显劣于当前最优解的个体,减少选择池规模:
double minValidFitness = bestFitness * 0.5; // 保留最优解50%以上的个体 double minValidFitness = bestFitness * 0.5; // 保留最优解50%以上的个体
List<Chromosome> validPopulation = population.stream() List<Chromosome> validPopulation = population.stream()
.filter(c -> c.getFitness() >= minValidFitness) .filter(c -> c.getFitness() >= minValidFitness)
...@@ -218,57 +158,6 @@ public class GeneticAlgorithm { ...@@ -218,57 +158,6 @@ public class GeneticAlgorithm {
// 选择操作 // 选择操作
List<Chromosome> selected = geneticOps.tournamentSelection(validPopulation); List<Chromosome> selected = geneticOps.tournamentSelection(validPopulation);
FileHelper.writeLogFile("选择操作-----------结束-------"); FileHelper.writeLogFile("选择操作-----------结束-------");
// 变邻域搜索
FileHelper.writeLogFile("变邻域搜索-----------开始-------");
GeneticDecoder vnsDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> vnsImproved = _vns.search(selected, vnsDecoder, param);
selected.addAll(vnsImproved);
FileHelper.writeLogFile("变邻域搜索-----------结束-------");
// 模拟退火全局搜索
FileHelper.writeLogFile("模拟退火搜索-----------开始-------");
GeneticDecoder saDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> saImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
Chromosome saOptimized = _simulatedAnnealing.search(chromosome, saDecoder, param);
saImproved.add(saOptimized);
}
selected.addAll(saImproved);
FileHelper.writeLogFile("模拟退火搜索-----------结束-------");
// 爬山法局部优化
FileHelper.writeLogFile("爬山法局部优化-----------开始-------");
List<Chromosome> hcImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
Chromosome hcOptimized = _hillClimbing.search(chromosome, saDecoder, param);
hcImproved.add(hcOptimized);
}
selected.addAll(hcImproved);
FileHelper.writeLogFile("爬山法局部优化-----------结束-------");
// 多种局部搜索算法并行
FileHelper.writeLogFile("并行局部搜索-----------开始-------");
GeneticDecoder parallelDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> parallelImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
Chromosome parallelOptimized = _parallelLocalSearch.search(chromosome, parallelDecoder, param);
parallelImproved.add(parallelOptimized);
}
selected.addAll(parallelImproved);
FileHelper.writeLogFile("并行局部搜索-----------结束-------");
// 禁忌搜索+模拟退火
FileHelper.writeLogFile("禁忌搜索+模拟退火-----------开始-------");
GeneticDecoder tsDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> tsImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
Chromosome tsOptimized = _tabuSearchWithSA.search(chromosome, tsDecoder, param);
tsImproved.add(tsOptimized);
}
selected.addAll(tsImproved);
FileHelper.writeLogFile("禁忌搜索+模拟退火-----------结束-------");
// 交叉操作 // 交叉操作
FileHelper.writeLogFile("交叉操作-----------开始-------"); FileHelper.writeLogFile("交叉操作-----------开始-------");
...@@ -329,7 +218,7 @@ public class GeneticAlgorithm { ...@@ -329,7 +218,7 @@ public class GeneticAlgorithm {
newPopulation= chromosomeDistinct1(newPopulation); newPopulation= chromosomeDistinct1(newPopulation);
FileHelper.writeLogFile("非支配排序-----------开始-------"); FileHelper.writeLogFile("非支配排序-----------开始-------");
// 2.7 非支配排序 // 2.7 非支配排序
combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(newPopulation); combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(newPopulation);
FileHelper.writeLogFile("非支配排序-----------结束-------"); FileHelper.writeLogFile("非支配排序-----------结束-------");
// 2.8 选择下一代种群 // 2.8 选择下一代种群
population = _nsgaIIUtils.selectNextPopulation(combinedFronts, param.getPopulationSize()); population = _nsgaIIUtils.selectNextPopulation(combinedFronts, param.getPopulationSize());
...@@ -348,7 +237,7 @@ public class GeneticAlgorithm { ...@@ -348,7 +237,7 @@ public class GeneticAlgorithm {
Iteration++; Iteration++;
if (Iteration > 5) { if (Iteration > 5) {
// 当连续 5 代无最优解提升时,降低交叉概率(如从 0.8 降至 0.5)、提高变异概率(如从 0.1 升至 0.2) // 当连续 5 代无最优解提升时,降低交叉概率(如从 0.8 降至 0.5)、提高变异概率(如从 0.1 升至 0.2)
param.fineTuneParams(); param.fineTuneParams();
} }
} }
...@@ -356,8 +245,8 @@ public class GeneticAlgorithm { ...@@ -356,8 +245,8 @@ public class GeneticAlgorithm {
{ {
break; break;
} }
// 当种群适应度标准差小于阈值(如 0.001)时,说明种群已收敛,提前终止迭代 // 当种群适应度标准差小于阈值(如 0.001)时,说明种群已收敛,提前终止迭代
fitnessStd = _fitnessCalculator.calculateFitnessStd(population); fitnessStd = _fitnessCalculator.calculateFitnessStd(population);
if (fitnessStd < 0.001) { if (fitnessStd < 0.001) {
FileHelper.writeLogFile("种群已收敛,提前终止迭代"); FileHelper.writeLogFile("种群已收敛,提前终止迭代");
break; break;
...@@ -371,7 +260,7 @@ public class GeneticAlgorithm { ...@@ -371,7 +260,7 @@ public class GeneticAlgorithm {
best.setMaterialIds(materialIds); best.setMaterialIds(materialIds);
best.setMaterials(null); best.setMaterials(null);
best.setScenarioID(sceneId); best.setScenarioID(sceneId);
// best.setOperatRel(_entryRel); // best.setOperatRel(_entryRel);
if(best.getInitMachines()==null) if(best.getInitMachines()==null)
{ {
...@@ -389,14 +278,14 @@ public class GeneticAlgorithm { ...@@ -389,14 +278,14 @@ public class GeneticAlgorithm {
private Chromosome GetBest(List<List<Chromosome>> fronts,String msg) private Chromosome GetBest(List<List<Chromosome>> fronts,String msg)
{ {
// WriteKpis(fronts,msg); // WriteKpis(fronts,msg);
List<Chromosome> fChromosomes= fronts.get(0); List<Chromosome> fChromosomes= fronts.get(0);
fChromosomes.sort((c1, c2) -> { fChromosomes.sort((c1, c2) -> {
int rankCompare = Double.compare(c1.getCrowdingDistance(), c2.getCrowdingDistance()); int rankCompare = Double.compare(c1.getCrowdingDistance(), c2.getCrowdingDistance());
return rankCompare != 0 ? rankCompare : Double.compare(c1.getFitness(), c2.getFitness()); return rankCompare != 0 ? rankCompare : Double.compare(c1.getFitness(), c2.getFitness());
}); });
Chromosome best=fChromosomes.get(0); Chromosome best=fChromosomes.get(0);
// WriteKpi(best,"最大"); // WriteKpi(best,"最大");
return best; return best;
} }
private List<Chromosome> chromosomeDistinct(List<Chromosome> population) private List<Chromosome> chromosomeDistinct(List<Chromosome> population)
...@@ -404,7 +293,7 @@ public class GeneticAlgorithm { ...@@ -404,7 +293,7 @@ public class GeneticAlgorithm {
if(population==null) if(population==null)
{ {
FileHelper.writeLogFile(String.format("排产-----------方案数量---%d-------",0 )); FileHelper.writeLogFile(String.format("排产-----------方案数量---%d-------",0 ));
return population; return population;
} }
population = population.stream() population = population.stream()
.filter(chromosome -> chromosome != null && chromosome.getGeneStr() != null) .filter(chromosome -> chromosome != null && chromosome.getGeneStr() != null)
...@@ -429,17 +318,17 @@ return population; ...@@ -429,17 +318,17 @@ return population;
// List<Chromosome> population1 = population.stream().filter(t->t.getGeneStr()==null).collect(Collectors.toList()); // List<Chromosome> population1 = population.stream().filter(t->t.getGeneStr()==null).collect(Collectors.toList());
population = population.stream() population = population.stream()
.collect(Collectors.toMap( .collect(Collectors.toMap(
Chromosome::getGeneStr, // key:去重的字段(GeneStr) Chromosome::getGeneStr, // key:去重的字段(GeneStr)
u -> u, // value:Chromosome对象 u -> u, // value:Chromosome对象
(u1, u2) -> u1.getFitness() > u2.getFitness() ? u1 : u2 // 重复时保留第一个元素 (u1, u2) -> u1.getFitness() > u2.getFitness() ? u1 : u2 // 重复时保留第一个元素
)) ))
.values() // 获取去重后的 .values() // 获取去重后的
.stream() .stream()
.collect(Collectors.toList()); .collect(Collectors.toList());
return population; return population;
} }
...@@ -474,10 +363,10 @@ return population; ...@@ -474,10 +363,10 @@ return population;
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)
{ {
FileHelper.writeLogFile("解码---------------"+population.size() ); FileHelper.writeLogFile("解码---------------"+population.size() );
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,materialRequirementService, sceneId); GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,materialRequirementService, sceneId);
boolean ismore=false; boolean ismore=true;
if(ismore) { if(ismore) {
CompletableFuture.allOf(population.stream() CompletableFuture.allOf(population.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> decode(decoder, chromosome, param, allOperations, globalOpList), decodeExecutor)) .map(chromosome -> CompletableFuture.runAsync(() -> decode(decoder, chromosome, param, allOperations, globalOpList), decodeExecutor))
...@@ -497,10 +386,10 @@ return population; ...@@ -497,10 +386,10 @@ return population;
private void decode(GeneticDecoder decoder,Chromosome chromosome,ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList) { private void decode(GeneticDecoder decoder,Chromosome chromosome,ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList) {
if (chromosome==null){ if (chromosome==null){
System.out.println("chromosome==null"); System.out.println("chromosome==null");
return; return;
} }
chromosome.setResult(new CopyOnWriteArrayList<>()); chromosome.setResult(new CopyOnWriteArrayList<>());
...@@ -516,7 +405,16 @@ return population; ...@@ -516,7 +405,16 @@ return population;
//chromosome.setObjectiveWeights(_objectiveWeights); //chromosome.setObjectiveWeights(_objectiveWeights);
chromosome.setBaseTime(param.getBaseTime()); chromosome.setBaseTime(param.getBaseTime());
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝 // chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
// _sceneService.saveChromosomeToFile(chromosome, "12345679"); // _sceneService.saveChromosomeToFile(chromosome, "12345679");
// 加载锁定工单到ResultOld
List<GAScheduleResult> lockedOrders = GlobalCacheUtil.get("locked_orders_" + sceneId);
if (lockedOrders != null && !lockedOrders.isEmpty()) {
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(lockedOrders, GAScheduleResult.class));
FileHelper.writeLogFile("将 " + lockedOrders.size() + " 个锁定工单加载到初始种群中");
} else {
chromosome.setResultOld(new CopyOnWriteArrayList<>());
}
decoder.decodeChromosomeWithCache(chromosome); decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) { if (chromosome.getFitness() == 0) {
......
...@@ -21,9 +21,7 @@ import java.time.Duration; ...@@ -21,9 +21,7 @@ import java.time.Duration;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
...@@ -78,6 +76,36 @@ public class GeneticDecoder { ...@@ -78,6 +76,36 @@ public class GeneticDecoder {
// this.orderMaxID = orders.stream().mapToInt(Order::getId).max().orElse(0); // this.orderMaxID = orders.stream().mapToInt(Order::getId).max().orElse(0);
} }
private final ExecutorService decodeExecutor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors() - 1, // 核心线程数=CPU-1,无切换开销
Runtime.getRuntime().availableProcessors() - 1, // 最大线程数=核心数
0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(200), // 有界队列,避免内存溢出
new ThreadPoolExecutor.CallerRunsPolicy() // 任务满了主线程执行,不丢失任务
);
public void Chromosomedecode(List<Chromosome> population)
{
FileHelper.writeLogFile("解码---------------"+population.size() );
boolean ismore=false;
if(ismore) {
CompletableFuture.allOf(population.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> decodeChromosomeWithCache(chromosome), decodeExecutor))
.toArray(CompletableFuture[]::new))
.join();
} else {
if (population != null && population.size() > 0) {
population.forEach(chromosome -> {
decodeChromosomeWithCache( chromosome);
});
}
}
}
// public Chromosome decodeChromosomeWithCache(Chromosome chromosome) { // public Chromosome decodeChromosomeWithCache(Chromosome chromosome) {
// String cacheKey = createCacheKey(chromosome); // String cacheKey = createCacheKey(chromosome);
// // FileHelper.writeLogFile("解码-----------开始-------"+chromosome.getID()+":"+cacheKey ); // // FileHelper.writeLogFile("解码-----------开始-------"+chromosome.getID()+":"+cacheKey );
...@@ -345,18 +373,18 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -345,18 +373,18 @@ if(finishedOrder==null||finishedOrder.size()==0)
// //
// // 根据工序数量和CPU核心数决定是否使用内部并行 // // 根据工序数量和CPU核心数决定是否使用内部并行
if (operationCount > 500 && cpuCores > 4) { if (operationCount > 500 && cpuCores > 4) {
// 使用并行处理 // 使用设备并行处理
FileHelper.writeLogFile("使用并行处理 _s"); // FileHelper.writeLogFile("使用并行处理 _s");
parallelDecodeByMachine(chromosome); parallelDecodeByMachine(chromosome);
FileHelper.writeLogFile("使用并行处理 _e"); // FileHelper.writeLogFile("使用并行处理 _e");
} }
// else { else {
// 使用串行处理 // 使用串行处理
// FileHelper.writeLogFile("使用串行处理 _s"); // FileHelper.writeLogFile("使用串行处理 _s");
// serialDecode(chromosome); serialDecode(chromosome);
// FileHelper.writeLogFile("使用串行处理 _e"); // FileHelper.writeLogFile("使用串行处理 _e");
//} }
} }
/** /**
* 染色体解码为调度方案 * 染色体解码为调度方案
...@@ -555,6 +583,8 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -555,6 +583,8 @@ if(finishedOrder==null||finishedOrder.size()==0)
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache = new HashMap<>(); Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache = new HashMap<>();
Map<Long, Machine> machineIdMap = chromosome.getMachines().stream() Map<Long, Machine> machineIdMap = chromosome.getMachines().stream()
.collect(Collectors.toMap(Machine::getId, m -> m)); .collect(Collectors.toMap(Machine::getId, m -> m));
// 构建工序ID索引:opId -> Entry(O(1)查找)
Map<Integer, Entry> opIdIndex = buildOpIdIndex(chromosome);
for (GlobalOperationInfo globalOp : globalOpList) { for (GlobalOperationInfo globalOp : globalOpList) {
int globalOpId = globalOp.getGlobalOpId(); int globalOpId = globalOp.getGlobalOpId();
...@@ -590,7 +620,8 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -590,7 +620,8 @@ if(finishedOrder==null||finishedOrder.size()==0)
FileHelper.writeLogFile("预处理工序信息 _s"); FileHelper.writeLogFile("预处理工序信息 _s");
// 预处理工序信息 // 预处理工序信息
for (int opId : topologicalOrder) { for (int opId : topologicalOrder) {
Entry op = findOperationById(chromosome, opId); // Entry op = findOperationById(chromosome, opId);
Entry op = opIdIndex.get(opId);
if (op != null) { if (op != null) {
// 假设已经为工序分配了设备 // 假设已经为工序分配了设备
...@@ -610,7 +641,8 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -610,7 +641,8 @@ if(finishedOrder==null||finishedOrder.size()==0)
FileHelper.writeLogFile("并行处理 _s"); FileHelper.writeLogFile("并行处理 _s");
for (int opId : topologicalOrder) { for (int opId : topologicalOrder) {
// 获取当前工序的依赖 // 获取当前工序的依赖
Entry op = findOperationById(chromosome, opId); // Entry op = findOperationById(chromosome, opId);
Entry op = opIdIndex.get(opId);
List<Integer> dependencies = dependencyGraph.getOrDefault(opId, Collections.emptyList()); List<Integer> dependencies = dependencyGraph.getOrDefault(opId, Collections.emptyList());
// 等待所有依赖完成 // 等待所有依赖完成
...@@ -661,10 +693,8 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -661,10 +693,8 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 1. 获取工序处理顺序 // 1. 获取工序处理顺序
List<Integer> operationSequencing = chromosome.getOperationSequencing(); List<Integer> operationSequencing = chromosome.getOperationSequencing();
List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList(); List<GlobalOperationInfo> globalOpList = chromosome.getGlobalOpList();
List<Entry> allOperations=chromosome.getAllOperations(); List<Entry> allOperations = chromosome.getAllOperations();
// 2. 构建工序依赖图 // 2. 构建工序依赖图
...@@ -696,7 +726,7 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -696,7 +726,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 获取选择的设备ID和加工时间 // 获取选择的设备ID和加工时间
MachineOption selectedMachine = optionalMachines.get(machineSeq - 1); MachineOption selectedMachine = optionalMachines.get(machineSeq - 1);
OpMachine opMachine=new OpMachine(); OpMachine opMachine = new OpMachine();
opMachine.setGroupId(groupId); opMachine.setGroupId(groupId);
opMachine.setSequence(sequence); opMachine.setSequence(sequence);
opMachine.setMachineId(selectedMachine.getMachineId()); opMachine.setMachineId(selectedMachine.getMachineId());
...@@ -849,12 +879,12 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -849,12 +879,12 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 工序超过500的设备直接在主线程串行处理 // 工序超过500的设备直接在主线程串行处理
if (ops.size() > 500) { if (ops.size() > 500) {
// FileHelper.writeLogFile("设备 " + machineId + " 有 " + ops.size() + " 个工序,直接串行处理"); // FileHelper.writeLogFile("设备 " + machineId + " 有 " + ops.size() + " 个工序,直接串行处理");
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock,opMachineKeyMap,machineIdMap,machineTasksCache); processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock, opMachineKeyMap, machineIdMap, machineTasksCache);
} else { } else {
// 工序少的设备创建线程处理 // 工序少的设备创建线程处理
Thread thread = new Thread(() -> { Thread thread = new Thread(() -> {
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock,opMachineKeyMap,machineIdMap,machineTasksCache); processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock, opMachineKeyMap, machineIdMap, machineTasksCache);
}); });
thread.start(); thread.start();
threads.add(thread); threads.add(thread);
...@@ -870,14 +900,14 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -870,14 +900,14 @@ if(finishedOrder==null||finishedOrder.size()==0)
} }
} }
// 9. 等待所有设备处理完成 // 9. 等待所有设备处理完成
// CompletableFuture.allOf(allMachineFutures.toArray(new CompletableFuture[0])).join(); // CompletableFuture.allOf(allMachineFutures.toArray(new CompletableFuture[0])).join();
if(chromosome.getReOrderids()!=null&&chromosome.getReOrderids().size()>0) { if (chromosome.getReOrderids() != null && chromosome.getReOrderids().size() > 0) {
chromosome.getOperationSequencing().removeIf(t -> chromosome.getReOrderids().contains(t)); chromosome.getOperationSequencing().removeIf(t -> chromosome.getReOrderids().contains(t));
} }
calculateScheduleResult(chromosome); calculateScheduleResult(chromosome);
} }
/** /**
* 处理单个设备的工序 * 处理单个设备的工序
...@@ -1051,8 +1081,19 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -1051,8 +1081,19 @@ if(finishedOrder==null||finishedOrder.size()==0)
return result; return result;
} }
/**
* 构建工序ID索引:opId -> Entry(O(1)查找)
*/
private Map<Integer, Entry> buildOpIdIndex(Chromosome chromosome) {
Map<Integer, Entry> index = new HashMap<>();
for (Entry op : chromosome.getAllOperations()) {
index.put(op.getId(), op);
}
return index;
}
/** /**
* 根据工序ID查找工序 * 根据工序ID查找工序
*/ */
...@@ -2367,7 +2408,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2367,7 +2408,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
if(config.getName()==GlobalParam.OBJECTIVE_MAKESPAN) if(config.getName()==GlobalParam.OBJECTIVE_MAKESPAN)
{ {
// 1. 最早完工时间(最小化) // 1. 最早完工时间(最小化)
double makespan = chromosome.getResult().stream() double makespan = chromosome.getResult().stream()
.mapToInt(GAScheduleResult::getEndTime) .mapToInt(GAScheduleResult::getEndTime)
.max() .max()
.orElse(0); .orElse(0);
...@@ -2444,6 +2485,10 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2444,6 +2485,10 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
} }
chromosome.setObjectives(Objectives); chromosome.setObjectives(Objectives);
FitnessCalculator fitnessCalculator=new FitnessCalculator();
if (chromosome.getFitnessLevel()==null) {
chromosome.setFitnessLevel(fitnessCalculator.calculateFitness(chromosome, _globalParam));
}
} }
private double calculateTotalFlowTime(Chromosome chromosome) { private double calculateTotalFlowTime(Chromosome chromosome) {
......
...@@ -4,10 +4,12 @@ import com.aps.common.util.ProductionDeepCopyUtil; ...@@ -4,10 +4,12 @@ import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*; import com.aps.entity.Algorithm.*;
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 java.util.ArrayList; import java.util.*;
import java.util.List; import java.util.concurrent.CompletableFuture;
import java.util.Random; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/** /**
* 爬山法算法 * 爬山法算法
...@@ -28,39 +30,487 @@ public class HillClimbing { ...@@ -28,39 +30,487 @@ public class HillClimbing {
this.objectiveWeights = objectiveWeights; this.objectiveWeights = objectiveWeights;
} }
public Chromosome BatchSearchAll(List<Chromosome> population, GeneticDecoder decoder, ScheduleParams param) {
List<Chromosome> optimizedPopulation=new ArrayList<>();
for (Chromosome chromosome : population) {
Chromosome optimized = searchAll(chromosome, decoder, param);
optimizedPopulation.add(optimized);
}
int bestidx= Getbest(optimizedPopulation,null);
if(bestidx>-1) {
return optimizedPopulation.get(bestidx);
}
return null;
}
/** /**
* 爬山法搜索 * 穷举搜索
*/ */
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) { public Chromosome searchAll(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
boolean improved = true; // 按优先级分组工序
int iterations = 0; Map<Double, List<Entry>> priorityGroups = groupOperationsByPriority();
int maxIterations = 100;
// 按优先级从高到低处理
List<Double> sortedPriorities = new ArrayList<>(priorityGroups.keySet());
// 构建位置索引映射:groupId_sequence -> position
Map<String, Integer> positionIndex = buildPositionIndex(current);
Map<String, Integer> MachinePositionIndex = buildEntryMachinePositionIndex(current);
Map<String, Entry> Entrys = buildEntryKey(current);
// 构建位置到Entry的映射:position -> Entry
Map<Integer, Entry> entryIndex = buildEntryIndex(current,Entrys);
for (Double priority : sortedPriorities) {
List<Entry> priorityOps = priorityGroups.get(priority);
if (priorityOps.isEmpty()) {
continue;
}
// 根据当前优先级的工序数确定迭代次数和step
int priorityIterations = Math.max(5, priorityOps.size()/2);
// 200/10 =20
// 1
int step = Math.max(1, (int) Math.ceil(priorityOps.size() / 10.0));
// 200/20=10;
//
int stepCount = Math.max(1, (int) Math.ceil(priorityOps.size() / step));
Set<Integer> Groupid=new HashSet<>();
for (int pi = 0; pi < priorityIterations; pi++) {
// 随机取该优先级的工序
Entry randomOp = priorityOps.get(rnd.nextInt(priorityOps.size()));
if(Groupid.contains(randomOp.getGroupId()))
{
continue;
}
Groupid.add(randomOp.getGroupId());
// 从索引中快速查找位置(O(1)复杂度)
String key = randomOp.getGroupId() + "_" + randomOp.getSequence();
Integer opPos = positionIndex.get(key);
Integer maPos = MachinePositionIndex.get(key);
List<MachineOption> MachineOptions=randomOp.getMachineOptions();
if (opPos == null) {
continue;
}
List<Integer> os = current.getOperationSequencing();
// 生成多个候选方案
List<Chromosome> candidates = new ArrayList<>();
List<Chromosome> candidates1 = new ArrayList<>();
if(MachineOptions.size()>1) {
Chromosome machineChange = generateMachineChange(current, MachineOptions, maPos);
if (machineChange != null) {
candidates.add(machineChange);
candidates1.add(machineChange);
}
}
// 向左多次移动(step 1, 2, 3...)
for (int s = 1; s <= stepCount; s++) {
Entry leftOp = entryIndex.get(opPos - s * step);
if (leftOp != null&&randomOp.getGroupId()!=leftOp.getGroupId() && Math.abs(leftOp.getPriority() - priority) <= 0.001) {
while (improved && iterations < maxIterations) { Chromosome newChromosome = swapAtDistance(current, opPos, -s * step);
improved = false; candidates.add(newChromosome);
candidates1.add(newChromosome);
if(MachineOptions.size()>1) {
Chromosome machineChange = generateMachineChange(newChromosome, MachineOptions, maPos);
if (machineChange != null) {
candidates.add(machineChange);
candidates1.add(machineChange);
}
}
// 生成邻域解
List<Chromosome> neighbors = generateNeighbors(current);
// 评估所有邻域解 }else {
for (Chromosome neighbor : neighbors) { break;
decode(decoder, neighbor, param); }
if (isBetter(neighbor, best)) { if (candidates1.size() > 5) {
best = neighbor; batchDecode(decoder,candidates1);
current = neighbor; candidates1.clear();
improved = true; }
}
// 向右多次移动(step 1, 2, 3...)
for (int s = 1; s <= stepCount; s++) {
Entry rightOp = entryIndex.get(opPos + s * step);
if (rightOp != null && randomOp.getGroupId() != rightOp.getGroupId() && Math.abs(rightOp.getPriority() - priority) <= 0.001) {
Chromosome newChromosome = swapAtDistance(current, opPos, s * step);
candidates.add(newChromosome);
candidates1.add(newChromosome);
if(MachineOptions.size()>1) {
Chromosome machineChange = generateMachineChange(newChromosome, MachineOptions, maPos);
if (machineChange != null) {
candidates.add(machineChange);
candidates1.add(machineChange);
}
}
} else {
break;
}
if (candidates1.size() > 5) {
batchDecode(decoder,candidates1);
candidates1.clear();
}
}
// 限制最多5个方案并行
if (candidates1.size() > 0) {
batchDecode(decoder, candidates1);
}
if(candidates.size()== 0)
{
break;
}
int bestidx= Getbest(candidates,best);
if(bestidx>-1) {
best=candidates.get(bestidx);
current=best;
positionIndex = buildPositionIndex(current);
entryIndex = buildEntryIndex(current,Entrys);
}
}
} }
return best;
}
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
// 按优先级分组工序
Map<Double, List<Entry>> priorityGroups = groupOperationsByPriority();
// 按优先级从高到低处理
List<Double> sortedPriorities = new ArrayList<>(priorityGroups.keySet());
// 构建位置索引映射:groupId_sequence -> position
Map<String, Integer> positionIndex = buildPositionIndex(current);
Map<String, Integer> MachinePositionIndex = buildEntryMachinePositionIndex(current);
Map<String, Entry> Entrys = buildEntryKey(current);
// 构建位置到Entry的映射:position -> Entry
Map<Integer, Entry> entryIndex = buildEntryIndex(current,Entrys);
boolean improved = true;
for (Double priority : sortedPriorities) {
List<Entry> priorityOps = priorityGroups.get(priority);
if (priorityOps.isEmpty()) {
continue;
} }
iterations++; // 根据当前优先级的工序数确定迭代次数和step
int priorityIterations = Math.max(5, priorityOps.size()/2);
// 200/10 =20
// 1
int step = Math.max(1, (int) Math.ceil(priorityOps.size() / 10.0));
// 200/20=10;
//
int stepCount = Math.max(1, (int) Math.ceil(priorityOps.size() / step));
Set<Integer> Groupid=new HashSet<>();
for (int pi = 0; pi < priorityIterations; pi++) {
improved = false;
// 随机取该优先级的工序
Entry randomOp = priorityOps.get(rnd.nextInt(priorityOps.size()));
// 从索引中快速查找位置(O(1)复杂度)
String key = randomOp.getGroupId() + "_" + randomOp.getSequence();
Integer opPos = positionIndex.get(key);
Integer maPos = MachinePositionIndex.get(key);
List<MachineOption> MachineOptions=randomOp.getMachineOptions();
if (opPos == null) {
continue;
}
List<Integer> os = current.getOperationSequencing();
// 生成多个候选方案
List<Chromosome> candidates = new ArrayList<>();
if(MachineOptions.size()>1) {
Chromosome machineChange = generateMachineChange(current, MachineOptions, maPos);
if (machineChange != null) {
candidates.add(machineChange);
}
}
// 向左多次移动(step 1, 2, 3...)
for (int s = 1; s <= stepCount; s++) {
Entry leftOp = entryIndex.get(opPos - s * step);
if (leftOp != null&&randomOp.getGroupId()!=leftOp.getGroupId() && Math.abs(leftOp.getPriority() - priority) <= 0.001) {
Chromosome newChromosome = swapAtDistance(current, opPos, -s * step);
candidates.add(newChromosome);
if(MachineOptions.size()>1) {
Chromosome machineChange = generateMachineChange(newChromosome, MachineOptions, maPos);
if (machineChange != null) {
candidates.add(machineChange);
}
}
}else {
break;
}
if (candidates.size() > 5) {
batchDecode(decoder,candidates);
int bestidx= Getbest(candidates,best);
if(bestidx>-1)
{
best=candidates.get(bestidx);
current=best;
improved=true;
// 更新索引
positionIndex = buildPositionIndex(current);
entryIndex = buildEntryIndex(current,Entrys);
break;
}
candidates.clear();
}
}
if(improved)
{
break;
}
// 向右多次移动(step 1, 2, 3...)
for (int s = 1; s <= stepCount; s++) {
Entry rightOp = entryIndex.get(opPos + s * step);
if (rightOp != null && randomOp.getGroupId() != rightOp.getGroupId() && Math.abs(rightOp.getPriority() - priority) <= 0.001) {
Chromosome newChromosome = swapAtDistance(current, opPos, s * step);
candidates.add(newChromosome);
if(MachineOptions.size()>1) {
Chromosome machineChange = generateMachineChange(newChromosome, MachineOptions, maPos);
if (machineChange != null) {
candidates.add(machineChange);
}
}
} else {
break;
}
if (candidates.size() > 5) {
batchDecode(decoder,candidates);
int bestidx= Getbest(candidates,best);
if(bestidx>-1)
{
best=candidates.get(bestidx);
current=best;
// 更新索引
positionIndex = buildPositionIndex(current);
entryIndex = buildEntryIndex(current,Entrys);
improved=true;
break;
}
candidates.clear();
}
}
if(improved)
{
break;
}
if(candidates.size()== 0)
{
break;
}else {
batchDecode(decoder, candidates);
}
int bestidx= Getbest(candidates,best);
if(bestidx>-1)
{
best=candidates.get(bestidx);
current=best;
// 更新索引
positionIndex = buildPositionIndex(current);
entryIndex = buildEntryIndex(current,Entrys);
improved=true;
break;
}
}
} }
return best; return best;
} }
private int Getbest(List<Chromosome> candidates,Chromosome best) {
// 找出最佳候选方案
int bestidx = -1;
if(best==null)
{
best=candidates.get(0);
bestidx=0;
}
for (int i = 0; i < candidates.size(); i++) {
Chromosome candidate = candidates.get(i);
if (isBetter(candidate, best)) {
bestidx = i;
}
}
return bestidx;
}
/**
* 构建位置索引:groupId_sequence -> position
*/
private Map<String, Integer> buildPositionIndex(Chromosome chromosome) {
Map<String, Integer> index = new HashMap<>();
List<Integer> os = chromosome.getOperationSequencing();
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
for (int i = 0; i < os.size(); i++) {
int groupId = os.get(i);
int count = orderProcessCounter.getOrDefault(groupId, 0) + 1;
orderProcessCounter.put(groupId, count);
String key = groupId + "_" + count;
index.put(key, i);
}
return index;
}
/**
* 构建位置索引:groupId_sequence -> Machines position
*/
private Map<String, Integer> buildEntryMachinePositionIndex(Chromosome chromosome) {
Map<String, Integer> index = new HashMap<>();
List<GlobalOperationInfo> globalOpList = chromosome.getGlobalOpList();
for (int i = 0; i < globalOpList.size(); i++) {
GlobalOperationInfo globalOp= globalOpList.get(i);
Entry op= globalOp.getOp();
int groupId = op.getGroupId();
int count = op.getSequence();
String key = groupId + "_" + count;
index.put(key, i);
}
return index;
}
/**
* 构建Entry索引:position -> Entry
*/
private Map<Integer, Entry> buildEntryIndex(Chromosome chromosome,Map<String, Entry> entrys) {
Map<Integer, Entry> index = new HashMap<>();
List<Integer> os = chromosome.getOperationSequencing();
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
for (int i = 0; i < os.size(); i++) {
int groupId = os.get(i);
int count = orderProcessCounter.getOrDefault(groupId, 0) + 1;
orderProcessCounter.put(groupId, count);
String key = groupId + "_" + count;
Entry op=entrys.get(key);
if(op!=null)
{
index.put(i, op);
}
}
return index;
}
/**
* 构建Entry索引:op.getGroupId() + "_" + op.getSequence() -> Entry
*/
private Map<String, Entry> buildEntryKey(Chromosome chromosome) {
Map<String, Entry> index = new HashMap<>();
List<Entry> allOps = chromosome.getAllOperations();
for (Entry op : allOps) {
String key = op.getGroupId() + "_" + op.getSequence();
index.put(key, op);
}
return index;
}
/**
* 按优先级分组工序
*/
private Map<Double, List<Entry>> groupOperationsByPriority() {
Map<Double, List<Entry>> groups = new HashMap<>();
for (Entry op : allOperations) {
double priority = op.getPriority();
groups.computeIfAbsent(priority, k -> new ArrayList<>()).add(op);
}
return groups;
}
/**
* 将指定位置的工序与间隔distance的工序交换
* distance为负表示向左,为正表示向右
*/
private Chromosome swapAtDistance(Chromosome chromosome, int pos, int distance) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
int targetPos = pos + distance;
if (targetPos >= 0 && targetPos < os.size() && pos >= 0 && pos < os.size()) {
java.util.Collections.swap(os, pos, targetPos);
neighbor.setOperationSequencing(os);
}
return neighbor;
}
/** /**
* 生成邻域解 * 生成邻域解
*/ */
...@@ -167,21 +617,64 @@ public class HillClimbing { ...@@ -167,21 +617,64 @@ public class HillClimbing {
return neighbor; return neighbor;
} }
/**
* 生成机器选择邻域解
*/
private Chromosome generateMachineChange(Chromosome chromosome, List<MachineOption> MachineOptions, int idx) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> ms = neighbor.getMachineSelection();
if (!ms.isEmpty()) {
if (MachineOptions.size() > 1) {
int currentMachineSeq = ms.get(idx);
List<Integer> availableMachines = new ArrayList<>();
for (int i = 1; i <= MachineOptions.size(); i++) {
if (i != currentMachineSeq) {
availableMachines.add(i);
}
}
if (!availableMachines.isEmpty()) {
int newMachineSeq = availableMachines.get(rnd.nextInt(availableMachines.size()));
ms.set(idx, newMachineSeq);
neighbor.setMachineSelection(ms);
}
}
return null;
}
return neighbor;
}
private void batchDecode(GeneticDecoder decoder,List<Chromosome> chromosomes )
{
// 并行解码所有候选方案
decoder.Chromosomedecode(chromosomes);
}
/** /**
* 解码染色体 * 解码染色体
*/ */
private void decode(GeneticDecoder decoder, Chromosome chromosome, ScheduleParams param) { private void decode(GeneticDecoder decoder, Chromosome chromosome) {
chromosome.setResult(new java.util.concurrent.CopyOnWriteArrayList<>()); // chromosome.setResult(new java.util.concurrent.CopyOnWriteArrayList<>());
decoder.decodeChromosomeWithCache(chromosome); decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(fitnessCalculator.calculateFitness(chromosome, objectiveWeights));
}
} }
/** /**
* 比较两个染色体的优劣 * 比较两个染色体的优劣
*/ */
private boolean isBetter(Chromosome c1, Chromosome c2) { private boolean isBetter(Chromosome c1, Chromosome c2) {
return c1.getFitness() > c2.getFitness();
for (int i = 0; i < c1.getFitnessLevel().length; i++) {
double[] Fitness1 = c1.getFitnessLevel();
double[] Fitness2 = c2.getFitnessLevel();
if (Fitness1[i] > Fitness2[i]) {
return true;
}
}
return false;
} }
} }
\ No newline at end of file
package com.aps.service.Algorithm;
import com.aps.common.util.DateTimeUtil;
import com.aps.common.util.DeepCopyUtil;
import com.aps.common.util.FileHelper;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.basic.*;
import com.aps.service.plan.MachineSchedulerService;
import com.aps.service.plan.SceneService;
import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* 作者:佟礼
* 时间:2026-03-23
*/
public class HybridAlgorithm {
private final Random rnd = new Random();
private List<Machine> machines;
private final MachineSchedulerService machineScheduler;
private final List<Order> orders;
private final List<Material> materials;
private final List<String> materialIds;
private static GlobalParam _GlobalParam;
private List<GroupResult> _entryRel;
FitnessCalculator _fitnessCalculator = new FitnessCalculator();
private NSGAIIUtils _nsgaIIUtils = new NSGAIIUtils();
private ObjectiveWeights _objectiveWeights = new ObjectiveWeights();
private MaterialRequirementService materialRequirementService;
private List<OrderMaterialRequirement> orderMaterials;
private SceneService _sceneService;
private String sceneId;
private VariableNeighborhoodSearch _vns;
// 初始化算法实例
private HillClimbing _hillClimbing;
private SimulatedAnnealing _simulatedAnnealing;
private ParallelLocalSearch _parallelLocalSearch;
// 初始化算法实例
private TabuSearch _tabuSearch;
private TabuSearchWithSA _tabuSearchWithSA;
public HybridAlgorithm(GlobalParam globalParam,List<Machine> machines, List<Order> orders,
List<Material> materials,List<String> _materialIds, MachineSchedulerService machineScheduler,List<GroupResult> entryRel,MaterialRequirementService _materialRequirementService,SceneService sceneService,String _sceneId) {
this.machines = machines;
this.orders = orders;
this.materials = materials;
this.machineScheduler = machineScheduler;
_GlobalParam=globalParam;
_entryRel=entryRel;
materialRequirementService=_materialRequirementService;
_sceneService=sceneService;
sceneId=_sceneId;
materialIds=_materialIds;
}
public void Init() {
// 自定义权重配置
_nsgaIIUtils.init(_GlobalParam);
}
public Chromosome Run(ScheduleParams param, List<Entry> allOperations) {
if(allOperations==null||allOperations.size()==0)
{
throw new RuntimeException("没有待排产工单");
}
// if(materials!=null&&materials.size()>0) {
//
// materialRequirementService.init(materials, orders, allOperations, _entryRel, machineScheduler, machines,_GlobalParam);
//
// orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(param.getBaseTime());
// Set<Long> existIds = new HashSet<>();
// machines=machines.stream()
// .filter(t->existIds.add(t.getId()))//HashSet.add() 方法:添加成功返回 true,重复返回 false;
// .collect(Collectors.toList());
// }
LocalDateTime starttime=LocalDateTime.now();
FileHelper.writeLogFile("排产-----------开始-----------"+allOperations.get(0).getSceneId());
Initialization initialization = new Initialization(_GlobalParam,allOperations,orders,machines,_objectiveWeights);
GeneticOperations geneticOps = new GeneticOperations(_GlobalParam,allOperations,param);
int opcount=allOperations.size();
// 预生成全局工序列表(所有初始化方法共享同一顺序)
List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList();
// 初始化变邻域搜索
_vns = new VariableNeighborhoodSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_hillClimbing = new HillClimbing(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_simulatedAnnealing = new SimulatedAnnealing(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_parallelLocalSearch = new ParallelLocalSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_tabuSearch = new TabuSearch(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
_tabuSearchWithSA = new TabuSearchWithSA(_GlobalParam, allOperations, globalOpList, _fitnessCalculator, _objectiveWeights);
FileHelper.writeLogFile("初始化种群-----------开始-------");
// 步骤1:使用构造启发式算法生成初始种群
FileHelper.writeLogFile("构造启发式初始化-----------开始-------");
List<Chromosome> population = initialization.generateHeuristicInitialPopulation(param, globalOpList);
FileHelper.writeLogFile("构造启发式初始化-----------结束-------");
population= chromosomeDistinct(population);
FileHelper.writeLogFile("初始化种群-----------结束-------");
FileHelper.writeLogFile("初始化批量解码-----------开始-------");
Chromosomedecode(param,allOperations,globalOpList,population);
FileHelper.writeLogFile("初始化批量解码-----------结束-------");
// 按Objectives去重,减少重复方案
FileHelper.writeLogFile("按Objectives去重-----------开始-------" + population.size());
population = chromosomeDistinctByObjectives(population);
FileHelper.writeLogFile("按Objectives去重-----------结束-------" + population.size());
// 步骤2:对初始种群进行爬山法局部优化
if(population.size()<5||opcount<10 ) {
FileHelper.writeLogFile("爬山法局部优化-----------开始-------");
GeneticDecoder hillClimbingDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
Chromosome optimized = _hillClimbing.BatchSearchAll(population, hillClimbingDecoder, param);
FileHelper.writeLogFile("爬山法局部优化-----------结束-------");
return getBestChromosome(optimized, param.getBaseTime(), starttime);
}
// 步骤2:对初始种群进行模拟退火+爬山法优化
FileHelper.writeLogFile("模拟退火+爬山法优化-----------开始-------");
GeneticDecoder saDecoder1 = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> saHcOptimized = _simulatedAnnealing.batchSearch(population, saDecoder1, param);
population = saHcOptimized;
FileHelper.writeLogFile("模拟退火+爬山法优化-----------结束-------");
List<List<Chromosome>> combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(population);
int ordercount = globalOpList.stream()
.mapToInt(GlobalOperationInfo::getGroupId)
.max()
.orElse(0);
Chromosome best=GetBest(combinedFronts,"初始");
// best=fronts.get(0).stream()
// .max(Comparator.comparingDouble(Chromosome::getFitness))
// .orElse(null);
double bestFitness=best.getFitness();
if(population.size()<param.getTournamentSize())
{
return getBestChromosome(best, param.getBaseTime(), starttime);
}
int Iteration=0;
// 步骤2:迭代进化
FileHelper.writeLogFile("迭代进化-----------开始-------"+param.getMaxIterations());
for (int iter = 0; iter < param.getMaxIterations(); iter++) {
// 解码并计算适应度
FileHelper.writeLogFile("迭代进化------"+iter+"-----开始-------");
// 计算种群适应度标准差,微调参数
double fitnessStd = _fitnessCalculator.calculateFitnessStd(population);
param.fineTuneParams(iter, fitnessStd);
// 检查终止条件(此处简化为迭代次数)
if (iter == param.getMaxIterations() - 1) {
break;
}
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(validPopulation);
FileHelper.writeLogFile("选择操作-----------结束-------");
// 变邻域搜索
FileHelper.writeLogFile("变邻域搜索-----------开始-------");
GeneticDecoder vnsDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> vnsImproved = _vns.search(selected, vnsDecoder, param);
selected.addAll(vnsImproved);
FileHelper.writeLogFile("变邻域搜索-----------结束-------");
// 模拟退火全局搜索
FileHelper.writeLogFile("模拟退火搜索-----------开始-------");
GeneticDecoder saDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> saImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
// Chromosome saOptimized = _simulatedAnnealing.search(chromosome, saDecoder, param);
// saImproved.add(saOptimized);
}
selected.addAll(saImproved);
FileHelper.writeLogFile("模拟退火搜索-----------结束-------");
// 爬山法局部优化
FileHelper.writeLogFile("爬山法局部优化-----------开始-------");
List<Chromosome> hcImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
Chromosome hcOptimized = _hillClimbing.search(chromosome, saDecoder, param);
hcImproved.add(hcOptimized);
}
selected.addAll(hcImproved);
FileHelper.writeLogFile("爬山法局部优化-----------结束-------");
// 多种局部搜索算法并行
FileHelper.writeLogFile("并行局部搜索-----------开始-------");
GeneticDecoder parallelDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> parallelImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
Chromosome parallelOptimized = _parallelLocalSearch.search(chromosome, parallelDecoder, param);
parallelImproved.add(parallelOptimized);
}
selected.addAll(parallelImproved);
FileHelper.writeLogFile("并行局部搜索-----------结束-------");
// 禁忌搜索+模拟退火
FileHelper.writeLogFile("禁忌搜索+模拟退火-----------开始-------");
GeneticDecoder tsDecoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler, materialRequirementService, sceneId);
List<Chromosome> tsImproved = new ArrayList<>();
for (Chromosome chromosome : selected) {
Chromosome tsOptimized = _tabuSearchWithSA.search(chromosome, tsDecoder, param);
tsImproved.add(tsOptimized);
}
selected.addAll(tsImproved);
FileHelper.writeLogFile("禁忌搜索+模拟退火-----------结束-------");
// 交叉操作
FileHelper.writeLogFile("交叉操作-----------开始-------");
List<Chromosome> nextPopulation = new ArrayList<>();
for (int i = 0; i < selected.size(); i += 2) {
if (i + 1 >= selected.size()) {
selected.get(i).setID(UUID.randomUUID().toString());
nextPopulation.add(selected.get(i));
break;
}
Chromosome parent1 = selected.get(i);
Chromosome parent2 = selected.get(i + 1);
if (rnd.nextDouble() < param.getCrossoverProb()) {
// 假设PoxCrossover返回包含两个子染色体的数组
Pair<Chromosome, Chromosome> children = geneticOps.poxCrossover(parent1, parent2, ordercount);
nextPopulation.add(children.getFirst());
nextPopulation.add(children.getSecond());
} else {
nextPopulation.add(parent1);
nextPopulation.add(parent2);
}
}
FileHelper.writeLogFile("交叉操作-----------结束-------");
FileHelper.writeLogFile("变异操作-----------开始-------");
// 变异操作
List<Chromosome> nextPopulation1 = new ArrayList<>();
for (Chromosome chromosome : nextPopulation) {
if (rnd.nextDouble() < param.getMutationProb()) {
Chromosome chromosome1= ProductionDeepCopyUtil.deepCopy(chromosome,Chromosome.class);
chromosome1.setID(UUID.randomUUID().toString());
geneticOps.mutate(chromosome1, globalOpList);
nextPopulation1.add(chromosome1);
}
}
nextPopulation.addAll(nextPopulation1);
FileHelper.writeLogFile("变异操作-----------结束-------");
FileHelper.writeLogFile("变异批量解码-----------开始-------");
Chromosomedecode(param,allOperations,globalOpList,nextPopulation);
FileHelper.writeLogFile("变异批量解码-----------结束-------");
// // 精英保留
// 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<>();
//保留一定数量的上一代
List<Chromosome> populationcopy = _nsgaIIUtils.selectNextPopulation(combinedFronts, param.getPopulationSize()/5);
newPopulation.addAll(populationcopy);
newPopulation.addAll(nextPopulation);
newPopulation= chromosomeDistinct1(newPopulation);
FileHelper.writeLogFile("非支配排序-----------开始-------");
// 2.7 非支配排序
combinedFronts = _nsgaIIUtils.parallelFastNonDominatedSort(newPopulation);
FileHelper.writeLogFile("非支配排序-----------结束-------");
// 2.8 选择下一代种群
population = _nsgaIIUtils.selectNextPopulation(combinedFronts, param.getPopulationSize());
// 更新种群
// population = newPopulation.stream()
// .limit(param.getPopulationSize() )
// .collect(Collectors.toList());
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+"-----结束-------");
}
FileHelper.writeLogFile("迭代进化-----------结束-------");
best= getBestChromosome(best,param.getBaseTime(),starttime);
// 步骤3:返回最优解
return best;
}
private Chromosome getBestChromosome(Chromosome best,LocalDateTime BaseTime,LocalDateTime starttime)
{
best.setBaseTime(BaseTime);
// best.setOrderMaterials(orderMaterials);
best.setMaterialIds(materialIds);
best.setMaterials(null);
best.setScenarioID(sceneId);
// best.setOperatRel(_entryRel);
if(best.getInitMachines()==null)
{
best.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class));
}
LocalDateTime endtime=LocalDateTime.now();
FileHelper.writeLogFile(String.format("排产----------结束---%s----耗时%d----",sceneId, DateTimeUtil.diffDuration(starttime,endtime).getSeconds()) );
return best;
}
private Chromosome GetBest(List<List<Chromosome>> fronts,String msg)
{
// WriteKpis(fronts,msg);
List<Chromosome> fChromosomes= fronts.get(0);
fChromosomes.sort((c1, c2) -> {
int rankCompare = Double.compare(c1.getCrowdingDistance(), c2.getCrowdingDistance());
return rankCompare != 0 ? rankCompare : Double.compare(c1.getFitness(), c2.getFitness());
});
Chromosome best=fChromosomes.get(0);
// WriteKpi(best,"最大");
return best;
}
private List<Chromosome> chromosomeDistinct(List<Chromosome> population)
{
if(population==null)
{
FileHelper.writeLogFile(String.format("排产-----------方案数量---%d-------",0 ));
return population;
}
population = population.stream()
.filter(chromosome -> chromosome != null && chromosome.getGeneStr() != null)
.collect(Collectors.toMap(
Chromosome::getGeneStr, // key:去重的字段(GeneStr)
u -> u, // value:Chromosome对象
(u1, u2) -> u1 // 重复时保留第一个元素
))
.values() // 获取去重后的
.stream()
.collect(Collectors.toList());
return population;
}
/**
* 按Objectives去重,相同目标值的方案只保留一个(保留fitness最大的)
*/
private List<Chromosome> chromosomeDistinctByObjectives(List<Chromosome> population)
{
if(population==null || population.isEmpty())
{
return population;
}
// 使用Objectives数组的哈希值作为key
Map<String, Chromosome> objectivesMap = new HashMap<>();
for (Chromosome chromosome : population) {
if (chromosome == null || chromosome.getObjectives() == null) {
continue;
}
// 将Objectives数组转换为字符串作为key
String objectivesKey = Arrays.toString(chromosome.getObjectives());
Chromosome existing = objectivesMap.get(objectivesKey);
if (existing == null) {
// 第一次遇到这个Objectives,直接添加
objectivesMap.put(objectivesKey, chromosome);
} else {
// 已经存在,保留fitness更大的那个
if (chromosome.getFitness() > existing.getFitness()) {
objectivesMap.put(objectivesKey, chromosome);
}
}
}
return new ArrayList<>(objectivesMap.values());
}
private List<Chromosome> chromosomeDistinct1(List<Chromosome> population)
{
if(population==null)
{
FileHelper.writeLogFile(String.format("排产-----------方案数量---%d-------",0 ));
return population;
}
// List<Chromosome> population1 = population.stream().filter(t->t.getGeneStr()==null).collect(Collectors.toList());
population = population.stream()
.collect(Collectors.toMap(
Chromosome::getGeneStr, // key:去重的字段(GeneStr)
u -> u, // value:Chromosome对象
(u1, u2) -> u1.getFitness() > u2.getFitness() ? u1 : u2 // 重复时保留第一个元素
))
.values() // 获取去重后的
.stream()
.collect(Collectors.toList());
return population;
}
private void WriteKpis(List<List<Chromosome>> fronts,String index) {
for (int i=0;i<fronts.size();i++)
{
FileHelper.writeLogFile(String.format("KPI---%s--------%d----",index,i));
for (Chromosome chromosome:fronts.get(i)) {
WriteKpi(chromosome,"");
}
}
}
private void WriteKpi(Chromosome chromosome,String desc)
{
FileHelper.writeLogFile(String.format("KPI---%f----%f----%s----%s",chromosome.getWeightedObjective(),chromosome.getFitness(), chromosome.getID(),desc));
for (double d: chromosome.getObjectives()) {
FileHelper.writeLogFile(String.format(" KPI---%f-------",d));
}
}
//private ExecutorService decodeExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
private final ExecutorService decodeExecutor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors() - 1, // 核心线程数=CPU-1,无切换开销
Runtime.getRuntime().availableProcessors() - 1, // 最大线程数=核心数
0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(200), // 有界队列,避免内存溢出
new ThreadPoolExecutor.CallerRunsPolicy() // 任务满了主线程执行,不丢失任务
);
private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population)
{
FileHelper.writeLogFile("解码---------------"+population.size() );
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,materialRequirementService, sceneId);
boolean ismore=true;
if(ismore) {
CompletableFuture.allOf(population.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> decode(decoder, chromosome, param, allOperations, globalOpList), decodeExecutor))
.toArray(CompletableFuture[]::new))
.join();
} else {
if (population != null && population.size() > 0) {
population.forEach(chromosome -> {
decode(decoder, chromosome, param, allOperations, globalOpList);
});
}
}
}
private void decode(GeneticDecoder decoder,Chromosome chromosome,ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList) {
if (chromosome==null){
System.out.println("chromosome==null");
return;
}
chromosome.setResult(new CopyOnWriteArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setOrders(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(orders), Order.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setOperatRel(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(_entryRel), GroupResult.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setMaterials(ProductionDeepCopyUtil.deepCopyList(materials,Material.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(allOperations), Entry.class) ); // 简单拷贝,实际可能需要深拷贝
// chromosome.setGlobalOpList(ProductionDeepCopyUtil.deepCopyList(globalOpList, GlobalOperationInfo.class) ); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
chromosome.setBaseTime(param.getBaseTime());
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights));
}
}
}
...@@ -5,6 +5,7 @@ import com.aps.entity.Algorithm.Chromosome; ...@@ -5,6 +5,7 @@ import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.Algorithm.GlobalOperationInfo; import com.aps.entity.Algorithm.GlobalOperationInfo;
import com.aps.entity.Algorithm.ObjectiveWeights; import com.aps.entity.Algorithm.ObjectiveWeights;
import com.aps.entity.Algorithm.ScheduleParams; import com.aps.entity.Algorithm.ScheduleParams;
import com.aps.entity.RoutingDiscreteParam;
import com.aps.entity.basic.*; import com.aps.entity.basic.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;
...@@ -27,6 +28,8 @@ public class Initialization { ...@@ -27,6 +28,8 @@ public class Initialization {
private ObjectiveWeights _objectiveWeights = new ObjectiveWeights(); private ObjectiveWeights _objectiveWeights = new ObjectiveWeights();
private LocalDateTime baseTime ; // 当前基准时间
public Initialization() { public Initialization() {
} }
...@@ -38,6 +41,7 @@ public class Initialization { ...@@ -38,6 +41,7 @@ public class Initialization {
machines=_machines; machines=_machines;
_objectiveWeights= objectiveWeights; _objectiveWeights= objectiveWeights;
} }
/** /**
* 预生成全局工序列表(按“订单0→订单1→…+订单内工序1→2→…”排序,分配GlobalOpId) * 预生成全局工序列表(按“订单0→订单1→…+订单内工序1→2→…”排序,分配GlobalOpId)
*/ */
...@@ -342,14 +346,14 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -342,14 +346,14 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
public List<Chromosome> generateHeuristicInitialPopulation(ScheduleParams param, List<GlobalOperationInfo> globalOpList) { public List<Chromosome> generateHeuristicInitialPopulation(ScheduleParams param, List<GlobalOperationInfo> globalOpList) {
List<Chromosome> population = new ArrayList<>(); List<Chromosome> population = new ArrayList<>();
int populationSize = param.getPopulationSize(); int populationSize = param.getPopulationSize();
this.baseTime=param.getBaseTime();
// 按比例生成不同启发式规则的个体 // 按比例生成不同启发式规则的个体
int sptCount = (int) (populationSize * 0.2); int sptCount = (int) (populationSize * 0.2);
int lptCount = sptCount + (int) (populationSize * 0.2); int lptCount = sptCount + (int) (populationSize * 0.1);
int eddCount = lptCount + (int) (populationSize * 0.2); int eddCount = lptCount + (int) (populationSize * 0.2);
int crCount = eddCount + (int) (populationSize * 0.2); int crCount = eddCount + (int) (populationSize * 0.2);
int sstCount = populationSize - crCount; int sstCount = crCount + (int) (populationSize * 0.2);
int lsCount = populationSize - sstCount;
IntStream.range(0, populationSize) IntStream.range(0, populationSize)
.parallel() .parallel()
.forEach(i -> { .forEach(i -> {
...@@ -358,123 +362,216 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -358,123 +362,216 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
if (i < sptCount) { if (i < sptCount) {
// SPT规则 // SPT规则
generateSPTChromosome(chromo, globalOpList); chromo.setGenerateType("SPT");
generateChromosomeByType(chromo, 1);
} else if (i < lptCount) { } else if (i < lptCount) {
// LPT规则 // LPT规则
generateLPTChromosome(chromo, globalOpList); chromo.setGenerateType("LPT");
generateChromosomeByType(chromo, 2);
} else if (i < eddCount) { } else if (i < eddCount) {
// EDD规则 // EDD规则
generateEDDChromosome(chromo, globalOpList); chromo.setGenerateType("EDD");
generateChromosomeByType(chromo, 3);
} else if (i < crCount) { } else if (i < crCount) {
// CR规则 // CR规则
// generateCRChromosome(chromo, globalOpList); chromo.setGenerateType("CR");
} else { generateCRChromosome(chromo);
} else if (i < sstCount) {
// SST规则 // SST规则
// generateSSTChromosome(chromo, globalOpList); chromo.setGenerateType("SST");
generateSSTChromosome(chromo);
}else {
// 随机规则
chromo.setGenerateType("LS");
generateLsChromosome(chromo);
} }
population.add(chromo); population.add(chromo);
}); });
return population; return population;
} /** }
* 使用贪心算法生成染色体
/**
* SPT(最短加工时间)
*/ */
private Chromosome generateGreedyChromosome(Chromosome chromosome, List<GlobalOperationInfo> globalOpList) { private Chromosome generateChromosomeByType(Chromosome chromosome,int sortType) {
List<Integer> ms = new ArrayList<>(); List<Integer> ms = new ArrayList<>();
List<Integer> os = new ArrayList<>(); List<Integer> os = new ArrayList<>();
Map<Long, Double> machineLoad = new HashMap<>(); Map<Long, Double> machineLoad = new HashMap<>();
Map<Long, String> lastDiscreteParam = new HashMap<>(); Random rnd = new Random();
List<GlobalOperationInfo> globalOpList = new ArrayList<>();
// 按优先级排序工序
List<GlobalOperationInfo> sortedOps = new ArrayList<>(globalOpList);
sortedOps.sort((o1, o2) -> {
int priorityCompare = Double.compare(o2.getOp().getPriority(), o1.getOp().getPriority());
if (priorityCompare != 0) return priorityCompare;
// 同优先级按加工时间排序
return Double.compare(o1.getOp().getMachineOptions().get(0).getProcessingTime(),
o2.getOp().getMachineOptions().get(0).getProcessingTime());
});
for (GlobalOperationInfo globalOp : sortedOps) {
Entry op = globalOp.getOp();
int groupId = globalOp.getGroupId();
// 贪心选择机器:综合考虑负载、换型时间和加工时间 // 1 SPT(最短加工时间) 2 LPT(最长加工时间)
Map<Integer, LocalDateTime> dueDateMap = new HashMap<>();
for (Order order : orders) {
dueDateMap.put(order.getId(), order.getDueDate());
}
Map<Entry, Integer> randomIds = new HashMap<>();
List<Integer> indices = new ArrayList<>();
for (int i = 0; i < allOperations.size(); i++) {
indices.add(i);
}
Collections.shuffle(indices, rnd);
for (int i = 0; i < allOperations.size(); i++) {
randomIds.put(allOperations.get(i), indices.get(i));
}
boolean considerSequence = rnd.nextBoolean();
List<Entry> sortedOps = new ArrayList<>(allOperations);
if (sortType == 1 || sortType == 2) {
if (considerSequence) {
sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority())
.thenComparing(Entry::getSequence)
.thenComparing(op -> {
if (op.getMachineOptions() == null || op.getMachineOptions().isEmpty()) {
return sortType == 1 ? 0.0 : Double.MAX_VALUE; // 空值默认排最前/最后
}
double time = op.getMachineOptions().get(0).getProcessingTime() * op.getQuantity();
return sortType == 1 ? time : -time;
})
.thenComparing(randomIds::get));
}
else{
sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority())
.thenComparing(op -> {
if (op.getMachineOptions() == null || op.getMachineOptions().isEmpty()) {
return sortType == 1 ? 0.0 : Double.MAX_VALUE; // 空值默认排最前/最后
}
double time = op.getMachineOptions().get(0).getProcessingTime() * op.getQuantity();
return sortType == 1 ? time : -time;
})
.thenComparing(randomIds::get));
}
} else if (sortType == 3) {
if (considerSequence) {
sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority())
.thenComparing(Entry::getSequence)
.thenComparing(op -> dueDateMap.get(op.getGroupId()),
Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(randomIds::get));
}else {
sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority())
.thenComparing(op -> dueDateMap.get(op.getGroupId()),
Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(randomIds::get));
}
}
int globalOpId = 0;
// 为每个工序选择机器
for (Entry op : sortedOps) {
int groupId = op.getGroupId();
// 选择负载最小的机器
List<MachineOption> optionalMachines = op.getMachineOptions(); List<MachineOption> optionalMachines = op.getMachineOptions();
MachineOption bestMachine = optionalMachines.stream() double minLoad = optionalMachines.stream()
.min((m1, m2) -> { .mapToDouble(m -> machineLoad.getOrDefault(m.getMachineId(), 0.0) + m.getProcessingTime())
// 计算综合成本 .min()
double cost1 = calculateMachineCost(m1, machineLoad, lastDiscreteParam, op); .orElse(Double.MAX_VALUE);
double cost2 = calculateMachineCost(m2, machineLoad, lastDiscreteParam, op);
return Double.compare(cost1, cost2); // 找到所有负载最小的机器
}) List<MachineOption> minLoadMachines = optionalMachines.stream()
.orElseThrow(() -> new NoSuchElementException("MachineOption not found")); .filter(m -> machineLoad.getOrDefault(m.getMachineId(), 0.0) + m.getProcessingTime() == minLoad)
.collect(Collectors.toList());
// 随机选择一个负载最小的机器
MachineOption selectedMachine = minLoadMachines.get(rnd.nextInt(minLoadMachines.size()));
// 计算机器顺序号
OptionalInt index = IntStream.range(0, optionalMachines.size()) OptionalInt index = IntStream.range(0, optionalMachines.size())
.filter(i -> bestMachine.getMachineId() == optionalMachines.get(i).getMachineId()) .filter(i -> selectedMachine.getMachineId() == optionalMachines.get(i).getMachineId())
.findFirst(); .findFirst();
int machineSeq = index.orElse(0) + 1; int machineSeq = index.orElse(0) + 1;
ms.add(machineSeq); ms.add(machineSeq);
// 更新机器状态 // 更新负载
machineLoad.put(bestMachine.getMachineId(), machineLoad.put(selectedMachine.getMachineId(),
machineLoad.getOrDefault(bestMachine.getMachineId(), 0.0) + bestMachine.getProcessingTime()); machineLoad.getOrDefault(selectedMachine.getMachineId(), 0.0) + selectedMachine.getProcessingTime());
//lastDiscreteParam.put(bestMachine.getMachineId(), op.getDiscreteParameter());
os.add(groupId); os.add(groupId);
}
GlobalOperationInfo info = new GlobalOperationInfo();
info.setGlobalOpId(globalOpId);
info.setGroupId(op.getGroupId());
info.setSequence(op.getSequence());
info.setOp(op);
globalOpList.add(info);
globalOpId++;
}
chromosome.setGlobalOpList(globalOpList);
chromosome.setOperationSequencing(os); chromosome.setOperationSequencing(os);
chromosome.setMachineSelection(ms); chromosome.setMachineSelection(ms);
return chromosome; return chromosome;
} }
/** /**
* 计算机器综合成本 * CR(关键比率)规则:关键比率 = (截止日期 - 当前日期) / 剩余加工时间
* 比率越小,优先级越高
*/ */
private double calculateMachineCost(MachineOption machine, Map<Long, Double> machineLoad, private Chromosome generateCRChromosome(Chromosome chromosome) {
Map<Long, String> lastDiscreteParam, Entry op) {
double loadCost = machineLoad.getOrDefault(machine.getMachineId(), 0.0);
double processingCost = machine.getProcessingTime();
// 计算换型成本
double setupCost = 0;
String lastParam = lastDiscreteParam.get(machine.getMachineId());
if (lastParam != null && !lastParam.equals(op.getDiscreteParameter())) {
setupCost = op.getSetupTime().doubleValue();
}
// 综合成本:负载 + 加工时间 + 换型成本
return loadCost + processingCost + setupCost;
}
/**
* SPT(最短加工时间)
*/
private Chromosome generateSPTChromosome(Chromosome chromosome, List<GlobalOperationInfo> globalOpList) {
List<Integer> ms = new ArrayList<>(); List<Integer> ms = new ArrayList<>();
List<Integer> os = new ArrayList<>(); List<Integer> os = new ArrayList<>();
Map<Long, Double> machineLoad = new HashMap<>(); Map<Long, Double> machineLoad = new HashMap<>();
Random rnd = new Random(); Random rnd = new Random();
List<GlobalOperationInfo> globalOpList=new ArrayList<>();
Map<Integer, Order> orderMap = new HashMap<>();
for (Order order : orders) {
orderMap.put(order.getId(), order);
}
Map<Integer, Double> remainingProcessingTime = new HashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
double quantity = op.getQuantity();
double processTime = op.getMachineOptions().get(0).getProcessingTime()*quantity;
remainingProcessingTime.put(groupId, remainingProcessingTime.getOrDefault(groupId, 0.0) + processTime);
}
List<Entry> sortedOps = new ArrayList<>(allOperations);
Map<Entry, Integer> randomIds = new HashMap<>();
List<Integer> indices = new ArrayList<>();
for (int i = 0; i < allOperations.size(); i++) {
indices.add(i);
}
Collections.shuffle(indices, rnd);
for (int i = 0; i < allOperations.size(); i++) {
randomIds.put(allOperations.get(i), indices.get(i));
}
boolean considerSequence = rnd.nextBoolean();
if (considerSequence) {
sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority())
.thenComparing(Entry::getSequence)
.thenComparing(op -> {
Order order = orderMap.get(op.getGroupId());
return calculateCriticalRatio(order, remainingProcessingTime.getOrDefault(op.getGroupId(), 0.0));
})
.thenComparing(randomIds::get));
}else {
sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority())
.thenComparing(op -> {
Order order = orderMap.get(op.getGroupId());
return calculateCriticalRatio(order, remainingProcessingTime.getOrDefault(op.getGroupId(), 0.0));
})
.thenComparing(randomIds::get));
}
// 按加工时间排序工序,加工时间相同时随机排序
List<GlobalOperationInfo> sortedOps = new ArrayList<>(globalOpList);
sortedOps.sort((o1, o2) -> {
double time1 = o1.getOp().getMachineOptions().get(0).getProcessingTime();
double time2 = o2.getOp().getMachineOptions().get(0).getProcessingTime();
int timeCompare = Double.compare(time1, time2);
if (timeCompare != 0) {
return timeCompare;
}
// 加工时间相同时随机排序
return rnd.nextInt(2) * 2 - 1;
});
int globalOpId = 0;
// 为每个工序选择机器 // 为每个工序选择机器
for (GlobalOperationInfo globalOp : sortedOps) { for (Entry op : sortedOps) {
Entry op = globalOp.getOp();
int groupId = globalOp.getGroupId(); int groupId = op.getGroupId();
// 选择负载最小的机器 // 选择负载最小的机器
List<MachineOption> optionalMachines = op.getMachineOptions(); List<MachineOption> optionalMachines = op.getMachineOptions();
...@@ -502,94 +599,230 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -502,94 +599,230 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
machineLoad.getOrDefault(selectedMachine.getMachineId(), 0.0) + selectedMachine.getProcessingTime()); machineLoad.getOrDefault(selectedMachine.getMachineId(), 0.0) + selectedMachine.getProcessingTime());
os.add(groupId); os.add(groupId);
}
GlobalOperationInfo info = new GlobalOperationInfo();
info.setGlobalOpId(globalOpId);
info.setGroupId(op.getGroupId());
info.setSequence(op.getSequence());
info.setOp(op);
globalOpList.add(info);
globalOpId++;
}
chromosome.setGlobalOpList(globalOpList);
chromosome.setOperationSequencing(os); chromosome.setOperationSequencing(os);
chromosome.setMachineSelection(ms); chromosome.setMachineSelection(ms);
return chromosome; return chromosome;
} }
private double calculateCriticalRatio(Order order, double remainingTime) {
if (order == null || order.getDueDate() == null || remainingTime <= 0) {
return Double.MAX_VALUE;
}
long daysUntilDue = java.time.Duration.between(this.baseTime, order.getDueDate()).toDays();
if (daysUntilDue <= 0) {
return 0;
}
return (double) daysUntilDue / remainingTime;
}
/** /**
* EDD(最早截止日期) * SST(最短准备时间)规则:优先选择准备时间最短的工序
*/ */
private Chromosome generateEDDChromosome(Chromosome chromosome, List<GlobalOperationInfo> globalOpList) { private Chromosome generateSSTChromosome(Chromosome chromosome) {
List<Integer> ms = new ArrayList<>(); List<Integer> ms = new ArrayList<>();
List<Integer> os = new ArrayList<>(); List<Integer> os = new ArrayList<>();
Map<Long, Double> machineLoad = new HashMap<>(); Map<Long, Double> machineLoad = new HashMap<>();
Map<Long, List<RoutingDiscreteParam>> lastDiscreteParams = new HashMap<>();
Random rnd = new Random();
List<GlobalOperationInfo> globalOpList=new ArrayList<>();
// 按截止日期排序订单 List<Entry> sortedOps = new ArrayList<>(allOperations);
Map<Integer, LocalDateTime> orderDueDates = new HashMap<>(); Map<Entry, Integer> randomIds = new HashMap<>();
for (Order order : orders) { List<Integer> indices = new ArrayList<>();
orderDueDates.put(order.getId(), order.getDueDate()); for (int i = 0; i < allOperations.size(); i++) {
indices.add(i);
}
Collections.shuffle(indices, rnd);
for (int i = 0; i < allOperations.size(); i++) {
randomIds.put(allOperations.get(i), indices.get(i));
} }
List<GlobalOperationInfo> sortedOps = new ArrayList<>(globalOpList); sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority())
sortedOps.sort((o1, o2) -> { .thenComparing(op -> op.getProductId() != null ? op.getProductId() : "")
LocalDateTime due1 = orderDueDates.get(o1.getGroupId()); .thenComparing(op -> op.getMachineOptions().get(0).getProcessingTime() * op.getQuantity())
LocalDateTime due2 = orderDueDates.get(o2.getGroupId()); .thenComparing(randomIds::get));
if (due1 == null || due2 == null) return 0;
return due1.compareTo(due2);
});
// 为每个工序选择机器
for (GlobalOperationInfo globalOp : sortedOps) {
Entry op = globalOp.getOp();
int groupId = globalOp.getGroupId();
// 选择负载最小的机器 int globalOpId = 0;
for (Entry op : sortedOps) {
int groupId = op.getGroupId();
List<MachineOption> optionalMachines = op.getMachineOptions(); List<MachineOption> optionalMachines = op.getMachineOptions();
MachineOption minLoadMachine = optionalMachines.stream()
.min(Comparator.comparingDouble(m -> machineLoad.getOrDefault(m.getMachineId(), 0.0) + m.getProcessingTime())) MachineOption bestMachine = optionalMachines.stream()
.min((m1, m2) -> {
double cost1 = calculateSSTCost(m1, machineLoad, lastDiscreteParams, op);
double cost2 = calculateSSTCost(m2, machineLoad, lastDiscreteParams, op);
return Double.compare(cost1, cost2);
})
.orElseThrow(() -> new NoSuchElementException("MachineOption not found")); .orElseThrow(() -> new NoSuchElementException("MachineOption not found"));
OptionalInt index = IntStream.range(0, optionalMachines.size()) OptionalInt index = IntStream.range(0, optionalMachines.size())
.filter(i -> minLoadMachine.getMachineId() == optionalMachines.get(i).getMachineId()) .filter(i -> bestMachine.getMachineId() == optionalMachines.get(i).getMachineId())
.findFirst(); .findFirst();
int machineSeq = index.orElse(0) + 1; int machineSeq = index.orElse(0) + 1;
ms.add(machineSeq); ms.add(machineSeq);
// 更新负载 machineLoad.put(bestMachine.getMachineId(),
machineLoad.put(minLoadMachine.getMachineId(), machineLoad.getOrDefault(bestMachine.getMachineId(), 0.0) + bestMachine.getProcessingTime());
machineLoad.getOrDefault(minLoadMachine.getMachineId(), 0.0) + minLoadMachine.getProcessingTime()); if (op.getDiscreteParameter() != null && !op.getDiscreteParameter().isEmpty()) {
lastDiscreteParams.put(bestMachine.getMachineId(), op.getDiscreteParameter());
}
os.add(groupId); os.add(groupId);
}
GlobalOperationInfo info = new GlobalOperationInfo();
info.setGlobalOpId(globalOpId);
info.setGroupId(op.getGroupId());
info.setSequence(op.getSequence());
info.setOp(op);
globalOpList.add(info);
globalOpId++;
}
chromosome.setGlobalOpList(globalOpList);
chromosome.setOperationSequencing(os); chromosome.setOperationSequencing(os);
chromosome.setMachineSelection(ms); chromosome.setMachineSelection(ms);
return chromosome; return chromosome;
} }
private String getDiscreteParamsKey(Entry op) {
List<RoutingDiscreteParam> params = op.getDiscreteParameter();
if (params == null || params.isEmpty()) {
return "";
}
List<RoutingDiscreteParam> sortedParams = new ArrayList<>(params);
sortedParams.sort(Comparator.comparing(RoutingDiscreteParam::getParameterName));
StringBuilder sb = new StringBuilder();
for (RoutingDiscreteParam p : sortedParams) {
sb.append(p.getGroupName() != null ? p.getGroupName() : "")
.append("|")
.append(p.getParameterName() != null ? p.getParameterName() : "")
.append("|")
.append(";");
}
return sb.toString();
}
private double calculateSSTCost(MachineOption machine, Map<Long, Double> machineLoad,
Map<Long, List<RoutingDiscreteParam>> lastDiscreteParams, Entry op) {
double loadCost = machineLoad.getOrDefault(machine.getMachineId(), 0.0);
double processingCost = machine.getProcessingTime() * op.getQuantity();
double setupCost = 0;
List<RoutingDiscreteParam> lastParams = lastDiscreteParams.get(machine.getMachineId());
if (lastParams != null && op.getDiscreteParameter() != null) {
boolean needSetup = false;
for (RoutingDiscreteParam param : op.getDiscreteParameter()) {
boolean foundMatch = false;
for (RoutingDiscreteParam lastParam : lastParams) {
if (param.getGroupName().equals(lastParam.getGroupName())
&& param.getParameterName().equals(lastParam.getParameterName())) {
foundMatch = true;
break;
}
}
if (!foundMatch) {
needSetup = true;
break;
}
}
if (needSetup) {
setupCost = 3600;
}
}
return loadCost + processingCost + setupCost;
}
/** /**
* LPT(最长加工时间)启发式 * 随机
*/ */
private Chromosome generateLPTChromosome(Chromosome chromosome, List<GlobalOperationInfo> globalOpList) { private Chromosome generateLsChromosome(Chromosome chromosome) {
// 类似SPT,但排序顺序相反
List<Integer> ms = new ArrayList<>(); List<Integer> ms = new ArrayList<>();
List<Integer> os = new ArrayList<>(); List<Integer> os = new ArrayList<>();
Map<Long, Double> machineLoad = new HashMap<>(); Map<Long, Double> machineLoad = new HashMap<>();
Random rnd = new Random(); Random rnd = new Random();
List<GlobalOperationInfo> globalOpList = new ArrayList<>();
// 按加工时间排序工序,加工时间相同时随机排序 // 按加工时间排序工序,加工时间相同时随机排序
List<GlobalOperationInfo> sortedOps = new ArrayList<>(globalOpList); List<Entry> sortedOps = new ArrayList<>(allOperations);
sortedOps.sort((o1, o2) -> { Map<Entry, Integer> randomIds = new HashMap<>();
double time1 = o1.getOp().getMachineOptions().get(0).getProcessingTime(); List<Integer> indices = new ArrayList<>();
double time2 = o2.getOp().getMachineOptions().get(0).getProcessingTime(); for (int i = 0; i < allOperations.size(); i++) {
int timeCompare = Double.compare(time2, time1); // 注意这里是降序 indices.add(i);
if (timeCompare != 0) { }
return timeCompare; Collections.shuffle(indices, rnd);
} for (int i = 0; i < allOperations.size(); i++) {
// 加工时间相同时随机排序 randomIds.put(allOperations.get(i), indices.get(i));
return rnd.nextInt(2) * 2 - 1; }
}); sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority())
.thenComparing(randomIds::get));
int globalOpId = 0;
// 为每个工序选择机器
for (Entry op : sortedOps) {
int groupId = op.getGroupId();
// 选择负载最小的机器
List<MachineOption> optionalMachines = op.getMachineOptions();
double minLoad = optionalMachines.stream()
.mapToDouble(m -> machineLoad.getOrDefault(m.getMachineId(), 0.0) + m.getProcessingTime())
.min()
.orElse(Double.MAX_VALUE);
// 找到所有负载最小的机器
List<MachineOption> minLoadMachines = optionalMachines.stream()
.filter(m -> machineLoad.getOrDefault(m.getMachineId(), 0.0) + m.getProcessingTime() == minLoad)
.collect(Collectors.toList());
// 随机选择一个负载最小的机器
MachineOption selectedMachine = minLoadMachines.get(rnd.nextInt(minLoadMachines.size()));
OptionalInt index = IntStream.range(0, optionalMachines.size())
.filter(i -> selectedMachine.getMachineId() == optionalMachines.get(i).getMachineId())
.findFirst();
int machineSeq = index.orElse(0) + 1;
ms.add(machineSeq);
// 更新负载
machineLoad.put(selectedMachine.getMachineId(),
machineLoad.getOrDefault(selectedMachine.getMachineId(), 0.0) + selectedMachine.getProcessingTime());
os.add(groupId);
// 为每个工序选择机器(与SPT相同)
// ...
GlobalOperationInfo info = new GlobalOperationInfo();
info.setGlobalOpId(globalOpId);
info.setGroupId(op.getGroupId());
info.setSequence(op.getSequence());
info.setOp(op);
globalOpList.add(info);
globalOpId++;
}
chromosome.setGlobalOpList(globalOpList);
chromosome.setOperationSequencing(os); chromosome.setOperationSequencing(os);
chromosome.setMachineSelection(ms); chromosome.setMachineSelection(ms);
return chromosome; return chromosome;
} }
/** /**
* 按优先级加权打乱工序排序(高优先级订单的工序更可能靠前) * 按优先级加权打乱工序排序(高优先级订单的工序更可能靠前)
*/ */
......
...@@ -48,10 +48,10 @@ public class ParallelLocalSearch { ...@@ -48,10 +48,10 @@ public class ParallelLocalSearch {
}); });
// 添加模拟退火任务 // 添加模拟退火任务
tasks.add(() -> { // tasks.add(() -> {
SimulatedAnnealing sa = new SimulatedAnnealing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights); // SimulatedAnnealing sa = new SimulatedAnnealing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
return sa.search(chromosome, decoder, param); // return sa.search(chromosome, decoder, param);
}); // });
// 执行所有任务 // 执行所有任务
List<Chromosome> results = new ArrayList<>(); List<Chromosome> results = new ArrayList<>();
......
...@@ -5,9 +5,8 @@ import com.aps.entity.Algorithm.*; ...@@ -5,9 +5,8 @@ import com.aps.entity.Algorithm.*;
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 java.util.ArrayList; import java.util.*;
import java.util.List; import java.util.concurrent.*;
import java.util.Random;
/** /**
* 模拟退火算法 * 模拟退火算法
...@@ -27,167 +26,270 @@ public class SimulatedAnnealing { ...@@ -27,167 +26,270 @@ public class SimulatedAnnealing {
this.fitnessCalculator = fitnessCalculator; this.fitnessCalculator = fitnessCalculator;
this.objectiveWeights = objectiveWeights; this.objectiveWeights = objectiveWeights;
} }
private final ExecutorService decodeExecutor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors() - 1, // 核心线程数=CPU-1,无切换开销
Runtime.getRuntime().availableProcessors() - 1, // 最大线程数=核心数
0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(200), // 有界队列,避免内存溢出
new ThreadPoolExecutor.CallerRunsPolicy() // 任务满了主线程执行,不丢失任务
);
public List<Chromosome> batchSearch(List<Chromosome> chromosomes, GeneticDecoder decoder, ScheduleParams param) {
List<Chromosome> saHcOptimized=new ArrayList<>();
CompletableFuture.allOf(chromosomes.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> {
Chromosome optimized = searchWithHillClimbing(chromosome, decoder, param);
saHcOptimized.add(optimized);
}, decodeExecutor))
.toArray(CompletableFuture[]::new))
.join();
return saHcOptimized;
}
/** /**
* 模拟退火搜索 * 模拟退火搜索,当温度降低到一定程度后切换到爬山法
*/ * 流程:模拟退火迭代 → 随机生成新排产 → 按概率接受 → 降温 → 温度低时爬山法求精 → 输出最优
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) { */
public Chromosome searchWithHillClimbing(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
// 初始化温度 // 初始化解码
// decode(decoder, best, param);
// decode(decoder, current, param);
Map<String, Entry> Entrys = buildEntryKey(current);
// 初始化温度 - 优化速度:更快降温,更快切换到爬山法
double temperature = 100.0; double temperature = 100.0;
double coolingRate = 0.95; double coolingRate = 0.95;
int maxIterations = 1000; double temperatureThreshold = 1.0; // 提高阈值,更快切换到爬山法
int maxIterations = 300; // 减少最大迭代次数
int noImproveCount = 0;
int maxNoImprove = 50; // 连续50次没改进就提前停止
for (int i = 0; i < maxIterations; i++) { for (int i = 0; i < maxIterations; i++) {
// 生成邻域解 boolean improved = false;
Chromosome neighbor = generateNeighbor(current);
// 1. 随机生成新排产(邻域解)
Chromosome neighbor = generateNeighbor(current,Entrys);
// 解码并计算适应度 // 2. 解码并计算适应度(只解码neighbor,current已经解码过了)
decode(decoder, current, param);
decode(decoder, neighbor, param); decode(decoder, neighbor, param);
// 计算能量差 // 3. 计算能量差(fitness差)
double energyDifference = neighbor.getFitness() - current.getFitness(); double energyDifference = calculateEnergyDifference(neighbor, current);
// 接受新解的概率 // 4. 按概率接受新解
// - 更优:直接接受
// - 较差:概率接受(高温更容易接受)
if (energyDifference > 0 || rnd.nextDouble() < Math.exp(energyDifference / temperature)) { if (energyDifference > 0 || rnd.nextDouble() < Math.exp(energyDifference / temperature)) {
current = neighbor; current = neighbor;
// 更新全局最优
if (isBetter(current, best)) { if (isBetter(current, best)) {
best = current; best = ProductionDeepCopyUtil.deepCopy(current, Chromosome.class);
improved = true;
noImproveCount = 0;
} }
} }
// 降温 if (!improved) {
noImproveCount++;
}
// 5. 降温
temperature *= coolingRate; temperature *= coolingRate;
if (temperature < 0.1) {
break; // 6. 提前停止条件:温度低于阈值 或 连续多次没改进
if (temperature < temperatureThreshold || noImproveCount >= maxNoImprove) {
HillClimbing hillClimbing = new HillClimbing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
Chromosome refined = hillClimbing.search(best, decoder, param);
// 返回爬山法求精后的结果
return refined;
} }
} }
// 7. 输出全局最优排产
return best; return best;
} }
/** /**
* 模拟退火搜索,当温度降低到一定程度后切换到爬山法 * 计算能量差(基于fitnessLevel数组的比较)
*/ */
public Chromosome searchWithHillClimbing(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) { private double calculateEnergyDifference(Chromosome neighbor, Chromosome current) {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); double[] neighborFitness = neighbor.getFitnessLevel();
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); double[] currentFitness = current.getFitnessLevel();
// 初始化温度 // 计算加权能量差
double temperature = 100.0; double diff = 0;
double coolingRate = 0.95; for (int i = 0; i < neighborFitness.length; i++) {
double temperatureThreshold = 1.0; // 温度阈值 diff += (neighborFitness[i] - currentFitness[i]);
int maxIterations = 500; }
return diff;
}
/**
* 构建位置->Entry索引
*/
private Map<Integer, Entry> buildPositionToEntryIndex(Chromosome chromosome,Map<String, Entry> entrys) {
Map<Integer, Entry> index = new HashMap<>();
List<Integer> os = chromosome.getOperationSequencing();
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
for (int i = 0; i < maxIterations; i++) { for (int i = 0; i < os.size(); i++) {
// 生成邻域解 int groupId = os.get(i);
Chromosome neighbor = generateNeighbor(current); int count = orderProcessCounter.getOrDefault(groupId, 0) + 1;
orderProcessCounter.put(groupId, count);
// 解码并计算适应度 String key = groupId + "_" + count;
decode(decoder, current, param); Entry op = entrys.get(key);
decode(decoder, neighbor, param);
// 计算能量差 if (op != null) {
double energyDifference = neighbor.getFitness() - current.getFitness(); index.put(i, op);
// 接受新解的概率
if (energyDifference > 0 || rnd.nextDouble() < Math.exp(energyDifference / temperature)) {
current = neighbor;
if (isBetter(current, best)) {
best = current;
}
} }
}
return index;
}
/**
* 构建Entry索引:op.getGroupId() + "_" + op.getSequence() -> Entry
*/
private Map<String, Entry> buildEntryKey(Chromosome chromosome) {
Map<String, Entry> index = new HashMap<>();
// 降温 List<Entry> allOps = chromosome.getAllOperations();
temperature *= coolingRate;
// 当温度降低到阈值以下,切换到爬山法 for (Entry op : allOps) {
if (temperature < temperatureThreshold) { String key = op.getGroupId() + "_" + op.getSequence();
HillClimbing hillClimbing = new HillClimbing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
return hillClimbing.search(best, decoder, param); index.put(key, op);
}
} }
return best; return index;
} }
/** /**
* 生成邻域解 * 生成邻域解
*/ */
private Chromosome generateNeighbor(Chromosome chromosome) { private Chromosome generateNeighbor(Chromosome chromosome,Map<String, Entry> entrys) {
int neighborType = rnd.nextInt(4); int neighborType = rnd.nextInt(4);
switch (neighborType) { switch (neighborType) {
case 0: case 0:
return generateSwapNeighbor(chromosome); return generateSwapNeighbor(chromosome,entrys);
case 1: case 1:
return generateReverseNeighbor(chromosome); return generateReverseNeighbor(chromosome,entrys);
case 2: case 2:
return generateInsertNeighbor(chromosome); return generateInsertNeighbor(chromosome,entrys);
case 3: case 3:
return generateMachineChangeNeighbor(chromosome); return generateMachineChangeNeighbor(chromosome);
default: default:
return generateSwapNeighbor(chromosome); return generateSwapNeighbor(chromosome,entrys);
} }
} }
/** /**
* 生成交换邻域解 * 生成交换邻域解 - 只在相同优先级的工序之间交换
*/ */
private Chromosome generateSwapNeighbor(Chromosome chromosome) { private Chromosome generateSwapNeighbor(Chromosome chromosome,Map<String, Entry> entrys) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing(); List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) { if (os.size() >= 2) {
int idx1 = rnd.nextInt(os.size()); Map<Integer, Entry> positionIndex = buildPositionToEntryIndex(neighbor,entrys);
int idx2 = rnd.nextInt(os.size());
while (idx2 == idx1) { int maxAttempts = 50;
idx2 = rnd.nextInt(os.size()); for (int attempt = 0; attempt < maxAttempts; attempt++) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
if (idx1 == idx2) continue;
Entry op1 = positionIndex.get(idx1);
Entry op2 = positionIndex.get(idx2);
if (op1 != null && op2 != null) {
if (Math.abs(op1.getPriority() - op2.getPriority()) < 0.001) {
java.util.Collections.swap(os, idx1, idx2);
neighbor.setOperationSequencing(os);
break;
}
}
} }
java.util.Collections.swap(os, idx1, idx2);
neighbor.setOperationSequencing(os);
} }
return neighbor; return neighbor;
} }
/** /**
* 生成反转邻域解 * 生成反转邻域解 - 只反转相同优先级的连续工序
*/ */
private Chromosome generateReverseNeighbor(Chromosome chromosome) { private Chromosome generateReverseNeighbor(Chromosome chromosome,Map<String, Entry> entrys) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing(); List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) { if (os.size() >= 2) {
int start = rnd.nextInt(os.size()); Map<Integer, Entry> positionIndex = buildPositionToEntryIndex(neighbor,entrys);
int end = rnd.nextInt(os.size());
while (end <= start) { int maxAttempts = 50;
end = rnd.nextInt(os.size()); for (int attempt = 0; attempt < maxAttempts; attempt++) {
int start = rnd.nextInt(os.size());
int end = rnd.nextInt(os.size());
if (end <= start) continue;
Entry startOp = positionIndex.get(start);
if (startOp == null) continue;
double priority = startOp.getPriority();
boolean allSamePriority = true;
for (int i = start; i <= end; i++) {
Entry op = positionIndex.get(i);
if (op == null || Math.abs(op.getPriority() - priority) > 0.001) {
allSamePriority = false;
break;
}
}
if (allSamePriority) {
java.util.Collections.reverse(os.subList(start, end + 1));
neighbor.setOperationSequencing(os);
break;
}
} }
java.util.Collections.reverse(os.subList(start, end + 1));
neighbor.setOperationSequencing(os);
} }
return neighbor; return neighbor;
} }
/** /**
* 生成插入邻域解 * 生成插入邻域解 - 只插入到相同优先级的位置
*/ */
private Chromosome generateInsertNeighbor(Chromosome chromosome) { private Chromosome generateInsertNeighbor(Chromosome chromosome,Map<String, Entry> entrys) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing(); List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) { if (os.size() >= 2) {
int idx1 = rnd.nextInt(os.size()); Map<Integer, Entry> positionIndex = buildPositionToEntryIndex(neighbor,entrys);
int idx2 = rnd.nextInt(os.size());
while (idx2 == idx1) { int maxAttempts = 50;
idx2 = rnd.nextInt(os.size()); for (int attempt = 0; attempt < maxAttempts; attempt++) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
if (idx1 == idx2) continue;
Entry op1 = positionIndex.get(idx1);
Entry op2 = positionIndex.get(idx2);
if (op1 != null && op2 != null) {
if (Math.abs(op1.getPriority() - op2.getPriority()) < 0.001) {
int value = os.remove(idx1);
os.add(idx2, value);
neighbor.setOperationSequencing(os);
break;
}
}
} }
int value = os.remove(idx1);
os.add(idx2, value);
neighbor.setOperationSequencing(os);
} }
return neighbor; return neighbor;
} }
/** /**
* 生成机器选择邻域解 * 生成机器选择邻域解 - 不受优先级限制
*/ */
private Chromosome generateMachineChangeNeighbor(Chromosome chromosome) { private Chromosome generateMachineChangeNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
...@@ -220,7 +322,6 @@ public class SimulatedAnnealing { ...@@ -220,7 +322,6 @@ public class SimulatedAnnealing {
* 解码染色体 * 解码染色体
*/ */
private void decode(GeneticDecoder decoder, Chromosome chromosome, ScheduleParams param) { private void decode(GeneticDecoder decoder, Chromosome chromosome, ScheduleParams param) {
chromosome.setResult(new java.util.concurrent.CopyOnWriteArrayList<>());
decoder.decodeChromosomeWithCache(chromosome); decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) { if (chromosome.getFitness() == 0) {
chromosome.setFitness(fitnessCalculator.calculateFitness(chromosome, objectiveWeights)); chromosome.setFitness(fitnessCalculator.calculateFitness(chromosome, objectiveWeights));
...@@ -228,9 +329,16 @@ public class SimulatedAnnealing { ...@@ -228,9 +329,16 @@ public class SimulatedAnnealing {
} }
/** /**
* 比较两个染色体的优劣 * 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/ */
private boolean isBetter(Chromosome c1, Chromosome c2) { private boolean isBetter(Chromosome c1, Chromosome c2) {
return c1.getFitness() > c2.getFitness(); for (int i = 0; i < c1.getFitnessLevel().length; i++) {
double[] Fitness1 = c1.getFitnessLevel();
double[] Fitness2 = c2.getFitnessLevel();
if (Fitness1[i] > Fitness2[i]) {
return true;
}
}
return false;
} }
} }
\ No newline at end of file
...@@ -210,7 +210,7 @@ public class PlanResultService { ...@@ -210,7 +210,7 @@ public class PlanResultService {
.collect(Collectors.toList()); .collect(Collectors.toList());
globalParam.setPureNSGAIIMode(false); globalParam.setPureNSGAIIMode(false);
// 5. 执行调度算法 // 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,Materials1,materialIds,machineScheduler,entryRel,materialRequirementService,_sceneService,SceneId); //new GeneticAlgorithm(products, machines, orders, machineScheduler); HybridAlgorithm scheduler =new HybridAlgorithm(globalParam,machines,orders,Materials1,materialIds,machineScheduler,entryRel,materialRequirementService,_sceneService,SceneId); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
param.initAdaptiveParams(entrys.size()); param.initAdaptiveParams(entrys.size());
double[] customWeights = new double[] { 0.4, 0.1, 0.1, 0.1, 0.3 }; // 延迟时间权重提升到0.5 double[] customWeights = new double[] { 0.4, 0.1, 0.1, 0.1, 0.3 }; // 延迟时间权重提升到0.5
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间 //完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
......
...@@ -39,7 +39,9 @@ public class PlanResultServiceTest { ...@@ -39,7 +39,9 @@ public class PlanResultServiceTest {
// TestSortService sortService=new TestSortService(); // TestSortService sortService=new TestSortService();
// sortService.test1(); // sortService.test1();
// nsgaiiUtils.Test(); // nsgaiiUtils.Test();
planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4"); // planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4");//2000
planResultService.execute2("C8B533BD8944405B9A2F8823C575C204");//500
// planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");//20
// planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D"); // planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D");
// planResultService.execute2("92BB773E1E2447C99D8176C991D5C9D2"); // 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