Commit f2a1529b authored by Tong Li's avatar Tong Li

Merge remote-tracking branch 'origin/tl'

parents bb00017a f1998b61
......@@ -32,6 +32,11 @@ public class Chromosome {
/// </summary>
private List<Integer> machineSelection;
// 缓存标记
private transient boolean machineStrDirty = true;
private transient boolean operationStrDirty = true;
private transient boolean geneStrDirty = true;
/// <summary>
/// 工序排序部分(工件/订单ID)
/// </summary>
......@@ -43,32 +48,53 @@ public class Chromosome {
private String geneStr;
public String getGeneStr() {
geneStr=getMachineStr()+"_"+getOperationStr();
return geneStr;
if (geneStrDirty || machineStrDirty || operationStrDirty) {
geneStr = getMachineStr() + "_" + getOperationStr();
geneStrDirty = false;
}
return geneStr;
}
private Integer gsOrls=0;
public String getMachineStr() {
machineStr= Optional.ofNullable(machineSelection)
.orElse(Collections.emptyList())
.stream()
.map(String::valueOf) // Integer转String
.collect(Collectors.joining(","));
return machineStr;
if (machineStrDirty) {
machineStr = Optional.ofNullable(machineSelection)
.orElse(Collections.emptyList())
.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
machineStrDirty = false;
geneStrDirty = true;
}
return machineStr;
}
public String getOperationStr() {
if (operationStrDirty) {
operationStr = Optional.ofNullable(operationSequencing)
.orElse(Collections.emptyList())
.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
operationStrDirty = false;
geneStrDirty = true;
}
return operationStr;
}
// 重写 setter 方法,在设置时标记为脏
public void setMachineSelection(List<Integer> machineSelection) {
this.machineSelection = machineSelection;
this.machineStrDirty = true;
this.geneStrDirty = true;
}
operationStr= Optional.ofNullable(operationSequencing)
.orElse(Collections.emptyList())
.stream()
.map(String::valueOf) // Integer转String
.collect(Collectors.joining(","));
return operationStr;
public void setOperationSequencing(List<Integer> operationSequencing) {
this.operationSequencing = operationSequencing;
this.operationStrDirty = true;
this.geneStrDirty = true;
}
......@@ -105,7 +131,7 @@ public class Chromosome {
private List<String> materialIds;
/*
* 最早完工时间(最小化) 最小化总加工时间 最小总换型时间
* 最早完工时间(最小化) 最小化总加工时间 最小总换型时间
*/
private double[] Objectives ; // 多目标值:[Makespan, TotalFlowTime, TotalChangeover, LoadStd, Delay]
private double[] MaxObjectives ; //
......@@ -113,8 +139,8 @@ public class Chromosome {
private int Rank; // 非支配排序等级(1最优)
private double CrowdingDistance =0; // 拥挤距离 越小越优
/*
*(Objectives - min) / (max - min);
*/
*(Objectives - min) / (max - min);
*/
private double[] WeightedObjectives;//越靠近1越优
private double WeightedObjective =0; // 加权目标值(用于自定义权重)
......
......@@ -15,7 +15,7 @@ public class ScheduleParams {
// 基础参数(自适应调整的基准值)
private static final int MIN_POPULATION_SIZE = 10;
private static final int MAX_POPULATION_SIZE = 50;
private static final int MAX_POPULATION_SIZE = 20;
private static final int MIN_MAX_ITERATIONS = 50;
private static final int MAX_MAX_ITERATIONS = 100;
private static final float MIN_CROSSOVER_PROB = 0.6f;
......@@ -172,10 +172,14 @@ public class ScheduleParams {
// 1. 种群大小:50 ~ 500,随工序数线性增加
populationSize = (int) Math.max(MIN_POPULATION_SIZE,
Math.min(MAX_POPULATION_SIZE, MIN_POPULATION_SIZE + totalOps * populationSizeCoeff));
int maxthead= Runtime.getRuntime().availableProcessors() - 1;
populationSize= populationSize / maxthead*maxthead;
// 确保偶数(方便交叉)
if (populationSize % 2 != 0) {
populationSize += 1;
}
// if (populationSize % 2 != 0) {
// populationSize += 1;
// }
// 2. 最大迭代次数:50 ~ 200,随工序数线性减少
maxIterations = (int) Math.max(MIN_MAX_ITERATIONS,
......
......@@ -73,11 +73,11 @@ public class GlobalParam {
public GlobalParam() {
// 初始化默认目标值配置
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_MAKESPAN, true, 1, 0.6));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_FLOW_TIME, false, 2, 0.1));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_MAKESPAN, true, 1, 0.3));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_FLOW_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_TARDINESS, true, 1, 0.3));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_MACHINE_LOAD, true, 1, 0.1));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_TARDINESS, true, 1, 0.6));
objectiveConfigs.sort(Comparator.comparing((ObjectiveConfig op) -> op.getLevel()));
}
......
package com.aps.entity.basic;
/**
* 作者:佟礼
* 时间:2026-04-09
*/
public class KpiTargetConfig {
}
......@@ -156,6 +156,11 @@ public class Order {
* 是否新创建,默认值:false
*/
private boolean newCreate = false;
/**
* 是否新创建半成品,默认值:false
*/
private boolean newSfCreate = false;
/**
* 是否创建BOM,默认值:false
......
......@@ -21,8 +21,10 @@ public class FitnessCalculator {
ArrayList<Double> list = new ArrayList<>();
double fitness=0;
double total=0;
int i=0;
int level=-1;
double[] weightedObjectives=new double[chromosome.getObjectives().length];
for (ObjectiveConfig config : param.getObjectiveConfigs()) {
if( config.isEnabled()) {
......@@ -65,7 +67,9 @@ public class FitnessCalculator {
if (!param.isPureNSGAIIMode()) {
val = val * config.getWeight();
}
weightedObjectives[i]=val;
fitness += val;
total+=val;
i++;
}
}
......@@ -87,6 +91,8 @@ public class FitnessCalculator {
// fitness ≈ 0.01
// 适应度值(越大越好)
chromosome.setFitness(total);
chromosome.setWeightedObjectives(weightedObjectives);
return list.stream().mapToDouble(Double::doubleValue).toArray();
}
......@@ -147,7 +153,7 @@ public class FitnessCalculator {
// 2. 计算每个个体与平均值的平方差之和
float sumSqDiff = 0.0f;
for (Chromosome chromosome : population) {
double diff = chromosome.getWeightedObjective() - avgFitness;
double diff = chromosome.getFitness() - avgFitness;
sumSqDiff += diff * diff;
}
......@@ -155,6 +161,19 @@ public class FitnessCalculator {
return (double) Math.sqrt(sumSqDiff / popSize);
}
/**
* 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/
public boolean isBetter(Chromosome c1, Chromosome c2) {
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;
}
......
......@@ -425,7 +425,7 @@ public class GeneticAlgorithm {
// chromosome.setResultOld(new CopyOnWriteArrayList<>());
// }
decoder.decodeChromosomeWithCache(chromosome);
decoder.decodeChromosomeWithCache(chromosome,false);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(_fitnessCalculator.calculateFitness(chromosome, _objectiveWeights));
}
......
......@@ -25,6 +25,10 @@ public class GeneticOperations {
private static ScheduleParams param;
public GeneticOperations() {
}
public GeneticOperations(GlobalParam globalParam,List<Entry> _allOperations,ScheduleParams _param) {
_GlobalParam=globalParam;
allOperations = _allOperations;
......@@ -424,10 +428,12 @@ public class GeneticOperations {
public void DelOrder(Chromosome chromosome) {
List<Entry> allOperations = chromosome.getAllOperations();
List<GlobalOperationInfo> globalOpList= chromosome.getGlobalOpList();
if(chromosome.getOrders()==null||chromosome.getOrders().size()==0)
return;
List<Order> orders = chromosome.getOrders();
List<Integer> OperationSequencing= chromosome.getOperationSequencing();
List<Integer> newoorderids= orders.stream()
.filter(t->t.isNewCreate())
.filter(t->t.isNewSfCreate())
.map(Order::getId)
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
......
......@@ -343,7 +343,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
/**
* 使用构造启发式算法生成初始种群
*/
public List<Chromosome> generateHeuristicInitialPopulation(ScheduleParams param, List<GlobalOperationInfo> globalOpList) {
public List<Chromosome> generateHeuristicInitialPopulation(ScheduleParams param) {
List<Chromosome> population = new ArrayList<>();
int populationSize = param.getPopulationSize();
this.baseTime=param.getBaseTime();
......
......@@ -894,7 +894,7 @@ public class MaterialRequirementServicebf {
childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(forder.getId());
childorder.setNewCreate(true);
childorder.setNewSfCreate(true);
childorder.setTargetFinishedOperationId(new ArrayList<>());
childorder.getTargetFinishedOperationId().add(operation.getId());
childorder.setSerie(forder.getSerie());
......
package com.aps.service.Algorithm;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
* 多种局部搜索算法并行
*/
public class ParallelLocalSearch {
private final ExecutorService executor;
private GlobalParam globalParam;
private List<Entry> allOperations;
private List<GlobalOperationInfo> globalOpList;
private FitnessCalculator fitnessCalculator;
private ObjectiveWeights objectiveWeights;
public ParallelLocalSearch(GlobalParam globalParam, List<Entry> allOperations, List<GlobalOperationInfo> globalOpList, FitnessCalculator fitnessCalculator, ObjectiveWeights objectiveWeights) {
this.globalParam = globalParam;
this.allOperations = allOperations;
this.globalOpList = globalOpList;
this.fitnessCalculator = fitnessCalculator;
this.objectiveWeights = objectiveWeights;
this.executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
}
/**
* 并行局部搜索
*/
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
List<Callable<Chromosome>> tasks = new ArrayList<>();
// 添加爬山法任务
// tasks.add(() -> {
// HillClimbing hillClimbing = new HillClimbing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
// return hillClimbing.search(chromosome, decoder, param);
// });
// 添加变邻域搜索任务
tasks.add(() -> {
VariableNeighborhoodSearch vns = new VariableNeighborhoodSearch(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
return vns.search(chromosome, decoder, param);
});
// 添加模拟退火任务
// tasks.add(() -> {
// SimulatedAnnealing sa = new SimulatedAnnealing(globalParam, allOperations, globalOpList, fitnessCalculator, objectiveWeights);
// return sa.search(chromosome, decoder, param);
// });
// 执行所有任务
List<Chromosome> results = new ArrayList<>();
try {
List<Future<Chromosome>> futures = executor.invokeAll(tasks);
for (Future<Chromosome> future : futures) {
results.add(future.get());
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
// 选择最优解
Chromosome best = chromosome;
for (Chromosome result : results) {
if (isBetter(result, best)) {
best = result;
}
}
return best;
}
/**
* 比较两个染色体的优劣
*/
private boolean isBetter(Chromosome c1, Chromosome c2) {
return c1.getFitness() > c2.getFitness();
}
/**
* 关闭线程池
*/
public void shutdown() {
executor.shutdown();
}
}
\ No newline at end of file
......@@ -1885,7 +1885,7 @@ if(targetOp.getSequence()>1) {
decoder.decode(chromosome);
decoder.decode(chromosome,false);
KpiCalculator kpiCalculator=new KpiCalculator(chromosome);
kpiCalculator.calculatekpi();
......
package com.aps.service.Algorithm;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import java.util.*;
/**
* 禁忌搜索+模拟退火混合算法
*/
public class TabuSearchWithSA {
private final Random rnd = new Random();
private GlobalParam globalParam;
private List<Entry> allOperations;
private List<GlobalOperationInfo> globalOpList;
private FitnessCalculator fitnessCalculator;
private ObjectiveWeights objectiveWeights;
// 禁忌表
private List<Chromosome> tabuList;
private int tabuListSize = 50;
public TabuSearchWithSA(GlobalParam globalParam, List<Entry> allOperations, List<GlobalOperationInfo> globalOpList, FitnessCalculator fitnessCalculator, ObjectiveWeights objectiveWeights) {
this.globalParam = globalParam;
this.allOperations = allOperations;
this.globalOpList = globalOpList;
this.fitnessCalculator = fitnessCalculator;
this.objectiveWeights = objectiveWeights;
this.tabuList = new ArrayList<>();
}
/**
* 禁忌搜索+模拟退火混合搜索
*/
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
// 初始化温度
double temperature = 100.0;
double coolingRate = 0.95;
int iterations = 0;
int maxIterations = 1000;
int noImprovementCount = 0;
int maxNoImprovement = 100;
while (iterations < maxIterations && noImprovementCount < maxNoImprovement) {
// 生成邻域解
List<Chromosome> neighbors = generateNeighbors(current);
// 过滤禁忌解
List<Chromosome> validNeighbors = filterTabuSolutions(neighbors);
// 评估所有邻域解
Chromosome bestNeighbor = null;
double bestNeighborFitness = Double.NEGATIVE_INFINITY;
for (Chromosome neighbor : validNeighbors) {
decode(decoder, neighbor, param);
if (neighbor.getFitness() > bestNeighborFitness) {
bestNeighborFitness = neighbor.getFitness();
bestNeighbor = neighbor;
}
}
if (bestNeighbor != null) {
// 计算能量差
decode(decoder, current, param);
double energyDifference = bestNeighbor.getFitness() - current.getFitness();
// 结合模拟退火的概率接受机制
if (energyDifference > 0 || rnd.nextDouble() < Math.exp(energyDifference / temperature)) {
// 更新当前解
current = bestNeighbor;
// 更新禁忌表
addToTabuList(current);
// 更新最优解
if (isBetter(current, best)) {
best = current;
noImprovementCount = 0;
} else {
noImprovementCount++;
}
}
}
// 降温
temperature *= coolingRate;
iterations++;
}
return best;
}
/**
* 生成邻域解
*/
private List<Chromosome> generateNeighbors(Chromosome chromosome) {
List<Chromosome> neighbors = new ArrayList<>();
// 生成多个邻域解
for (int i = 0; i < 10; i++) {
int neighborType = rnd.nextInt(4);
switch (neighborType) {
case 0:
neighbors.add(generateSwapNeighbor(chromosome));
break;
case 1:
neighbors.add(generateReverseNeighbor(chromosome));
break;
case 2:
neighbors.add(generateInsertNeighbor(chromosome));
break;
case 3:
neighbors.add(generateMachineChangeNeighbor(chromosome));
break;
}
}
return neighbors;
}
/**
* 过滤禁忌解
*/
private List<Chromosome> filterTabuSolutions(List<Chromosome> neighbors) {
List<Chromosome> validNeighbors = new ArrayList<>();
for (Chromosome neighbor : neighbors) {
if (!isTabu(neighbor)) {
validNeighbors.add(neighbor);
}
}
// 如果没有有效邻域解,返回所有邻域解
if (validNeighbors.isEmpty()) {
return neighbors;
}
return validNeighbors;
}
/**
* 检查解是否在禁忌表中
*/
private boolean isTabu(Chromosome chromosome) {
for (Chromosome tabuChromosome : tabuList) {
if (chromosome.getGeneStr().equals(tabuChromosome.getGeneStr())) {
return true;
}
}
return false;
}
/**
* 添加解到禁忌表
*/
private void addToTabuList(Chromosome chromosome) {
tabuList.add(chromosome);
if (tabuList.size() > tabuListSize) {
tabuList.remove(0);
}
}
/**
* 生成交换邻域解
*/
private Chromosome generateSwapNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
while (idx2 == idx1) {
idx2 = rnd.nextInt(os.size());
}
Collections.swap(os, idx1, idx2);
neighbor.setOperationSequencing(os);
}
return neighbor;
}
/**
* 生成反转邻域解
*/
private Chromosome generateReverseNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int start = rnd.nextInt(os.size());
int end = rnd.nextInt(os.size());
while (end <= start) {
end = rnd.nextInt(os.size());
}
Collections.reverse(os.subList(start, end + 1));
neighbor.setOperationSequencing(os);
}
return neighbor;
}
/**
* 生成插入邻域解
*/
private Chromosome generateInsertNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2) {
int idx1 = rnd.nextInt(os.size());
int idx2 = rnd.nextInt(os.size());
while (idx2 == idx1) {
idx2 = rnd.nextInt(os.size());
}
int value = os.remove(idx1);
os.add(idx2, value);
neighbor.setOperationSequencing(os);
}
return neighbor;
}
/**
* 生成机器选择邻域解
*/
private Chromosome generateMachineChangeNeighbor(Chromosome chromosome) {
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> ms = neighbor.getMachineSelection();
if (!ms.isEmpty()) {
int idx = rnd.nextInt(ms.size());
GlobalOperationInfo globalOp = globalOpList.get(idx);
Entry op = globalOp.getOp();
if (op.getMachineOptions().size() > 1) {
int currentMachineSeq = ms.get(idx);
List<Integer> availableMachines = new ArrayList<>();
for (int i = 1; i <= op.getMachineOptions().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 neighbor;
}
/**
* 解码染色体
*/
private void decode(GeneticDecoder decoder, Chromosome chromosome, ScheduleParams param) {
chromosome.setResult(new java.util.concurrent.CopyOnWriteArrayList<>());
decoder.decodeChromosomeWithCache(chromosome);
if (chromosome.getFitness() == 0) {
chromosome.setFitness(fitnessCalculator.calculateFitness(chromosome, objectiveWeights));
}
}
/**
* 比较两个染色体的优劣
*/
private boolean isBetter(Chromosome c1, Chromosome c2) {
return c1.getFitness() > c2.getFitness();
}
}
\ No newline at end of file
......@@ -222,7 +222,7 @@ public class PlanResultService {
lockedOrderProcessorService.markLockedOrdersOccupiedTime(machines, timeConfig.getBaseTime());
// 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());
double[] customWeights = new double[] { 0.4, 0.1, 0.1, 0.1, 0.3 }; // 延迟时间权重提升到0.5
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
......@@ -238,7 +238,7 @@ public class PlanResultService {
_sceneService.saveChromosomeToFile(chromosome, SceneId);
WriteScheduleSummary(chromosome);
// WriteScheduleSummary(chromosome);
return chromosome;
......
......@@ -132,7 +132,7 @@ public class SceneService {
try {
ObjectMapper objectMapper = createObjectMapper();
SceneChromsome sceneChromsome=(SceneChromsome)redisUtils.get("SceneId."+sceneId);
SceneChromsome sceneChromsome=null;//(SceneChromsome)redisUtils.get("SceneId."+sceneId);
if(sceneChromsome==null)
{
sceneChromsome=new SceneChromsome();
......@@ -163,7 +163,7 @@ public class SceneService {
sceneChromsome.getSceneDetails().add(sceneDetail);
redisUtils.set("SceneId."+sceneId,sceneChromsome);
// redisUtils.set("SceneId."+sceneId,sceneChromsome);
File file = getChromosomeFile(sceneId,sceneChromsome.getVersion().toString());
......
......@@ -39,7 +39,8 @@ public class PlanResultServiceTest {
// TestSortService sortService=new TestSortService();
// sortService.test1();
// nsgaiiUtils.Test();
planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4");//2000
planResultService.execute2("08B1D87FE1B84ECDBAC2E546DDB6FB81");//2000
// planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4");//2000
// planResultService.execute2("C8B533BD8944405B9A2F8823C575C204");//500
// planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");//20
// planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D");
......
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