Commit 932c42d2 authored by Tong Li's avatar Tong Li

混合算法

parent ad57430d
......@@ -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; // 加权目标值(用于自定义权重)
......
......@@ -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;
}
......
......@@ -392,7 +392,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
public void serialDecode(Chromosome chromosome) {
// List<OrderMaterialRequirement> orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam);
List<OrderMaterialRequirement> orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam);
chromosome.setScenarioID(sceneId);
if(_globalParam.isIsCheckSf()) {
int isnew= generateGlobalOpList(chromosome);
......@@ -474,7 +474,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
Map<Integer, Entry> entryIndexById = new HashMap<>();
Map<Integer, List<Entry>> entrysBygroupId = new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById = new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById = new ConcurrentHashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
......@@ -627,7 +627,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
Map<Integer, Entry> entryIndexById = new HashMap<>();
Map<Integer, List<Entry>> entrysBygroupId = new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById= new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById= new ConcurrentHashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
......
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
......@@ -11,251 +11,59 @@ import java.util.*;
* 禁忌搜索算法
*/
public class TabuSearch {
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 List<String> tabuList;
private int tabuListSize = 50;
public TabuSearch(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;
public TabuSearch(List<Entry> allOperations) {
this.tabuList = new ArrayList<>();
// 工序越多,禁忌表越长(适配1000+工序)
this.tabuListSize = Math.min(50, allOperations.size() / 30);
}
/**
* 禁忌搜索
*/
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, ScheduleParams param) {
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
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) {
// 更新当前解
current = bestNeighbor;
// 更新禁忌表
addToTabuList(current);
// 更新最优解
if (isBetter(current, best)) {
best = current;
noImprovementCount = 0;
} else {
noImprovementCount++;
}
}
iterations++;
}
return best;
}
/**
* 生成邻域解
* 检查解是否在禁忌表中
*/
private List<Chromosome> generateNeighbors(Chromosome chromosome) {
List<Chromosome> neighbors = new ArrayList<>();
public boolean isTabu(String GeneStr) {
// 生成多个邻域解
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 tabuList.contains(GeneStr);
return neighbors;
}
/**
* 过滤禁忌解
* 添加解到禁忌表
*/
private List<Chromosome> filterTabuSolutions(List<Chromosome> neighbors) {
List<Chromosome> validNeighbors = new ArrayList<>();
for (Chromosome neighbor : neighbors) {
if (!isTabu(neighbor)) {
validNeighbors.add(neighbor);
}
public void addToTabuList(String GeneStr) {
tabuList.add(GeneStr);
if (tabuList.size() > tabuListSize) {
// 移除最早加入的禁忌解(FIFO策略)
Iterator<String> iterator = tabuList.iterator();
iterator.next();
iterator.remove();
}
}
// 如果没有有效邻域解,返回所有邻域解
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
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