Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
HYH.APSJ
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
佟礼
HYH.APSJ
Commits
932c42d2
Commit
932c42d2
authored
Apr 02, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
混合算法
parent
ad57430d
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
898 additions
and
1092 deletions
+898
-1092
Chromosome.java
src/main/java/com/aps/entity/Algorithm/Chromosome.java
+44
-18
FitnessCalculator.java
...ain/java/com/aps/service/Algorithm/FitnessCalculator.java
+20
-1
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+3
-3
HybridAlgorithm.java
src/main/java/com/aps/service/Algorithm/HybridAlgorithm.java
+69
-132
ParallelLocalSearch.java
...n/java/com/aps/service/Algorithm/ParallelLocalSearch.java
+0
-91
SimulatedAnnealing.java
...in/java/com/aps/service/Algorithm/SimulatedAnnealing.java
+102
-615
TabuSearch.java
src/main/java/com/aps/service/Algorithm/TabuSearch.java
+18
-210
VariableNeighborhoodSearch.java
...com/aps/service/Algorithm/VariableNeighborhoodSearch.java
+642
-22
No files found.
src/main/java/com/aps/entity/Algorithm/Chromosome.java
View file @
932c42d2
...
...
@@ -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,7 +48,10 @@ public class Chromosome {
private
String
geneStr
;
public
String
getGeneStr
()
{
geneStr
=
getMachineStr
()+
"_"
+
getOperationStr
();
if
(
geneStrDirty
||
machineStrDirty
||
operationStrDirty
)
{
geneStr
=
getMachineStr
()
+
"_"
+
getOperationStr
();
geneStrDirty
=
false
;
}
return
geneStr
;
}
...
...
@@ -51,26 +59,44 @@ public class Chromosome {
public
String
getMachineStr
()
{
machineStr
=
Optional
.
ofNullable
(
machineSelection
)
if
(
machineStrDirty
)
{
machineStr
=
Optional
.
ofNullable
(
machineSelection
)
.
orElse
(
Collections
.
emptyList
())
.
stream
()
.
map
(
String:
:
valueOf
)
// Integer转String
.
map
(
String:
:
valueOf
)
.
collect
(
Collectors
.
joining
(
","
));
machineStrDirty
=
false
;
geneStrDirty
=
true
;
}
return
machineStr
;
}
public
String
getOperationStr
()
{
operationStr
=
Optional
.
ofNullable
(
operationSequencing
)
if
(
operationStrDirty
)
{
operationStr
=
Optional
.
ofNullable
(
operationSequencing
)
.
orElse
(
Collections
.
emptyList
())
.
stream
()
.
map
(
String:
:
valueOf
)
// Integer转String
.
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
;
}
public
void
setOperationSequencing
(
List
<
Integer
>
operationSequencing
)
{
this
.
operationSequencing
=
operationSequencing
;
this
.
operationStrDirty
=
true
;
this
.
geneStrDirty
=
true
;
}
...
...
src/main/java/com/aps/service/Algorithm/FitnessCalculator.java
View file @
932c42d2
...
...
@@ -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
.
get
WeightedObjective
()
-
avgFitness
;
double
diff
=
chromosome
.
get
Fitness
()
-
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
;
}
...
...
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
932c42d2
...
...
@@ -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
Concurrent
HashMap
<>();
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
Concurrent
HashMap
<>();
for
(
Entry
op
:
allOperations
)
{
int
groupId
=
op
.
getGroupId
();
orderProcessCounter
.
putIfAbsent
(
groupId
,
0
);
...
...
src/main/java/com/aps/service/Algorithm/HybridAlgorithm.java
View file @
932c42d2
package
com
.
aps
.
service
.
Algorithm
;
import
com.aps.common.util.DateTimeUtil
;
import
com.aps.common.util.DateTimeUtil
;
import
com.aps.common.util.DeepCopyUtil
;
import
com.aps.common.util.FileHelper
;
import
com.aps.common.util.ProductionDeepCopyUtil
;
...
...
@@ -55,7 +55,7 @@ public class HybridAlgorithm {
// 初始化算法实例
private
HillClimbing
_hillClimbing
;
private
SimulatedAnnealing
_simulatedAnnealing
;
private
ParallelLocalSearch
_parallelLocalSearch
;
// 初始化算法实例
private
TabuSearch
_tabuSearch
;
...
...
@@ -109,11 +109,10 @@ int opcount=allOperations.size();
// 预生成全局工序列表(所有初始化方法共享同一顺序)
List
<
GlobalOperationInfo
>
globalOpList
=
initialization
.
generateGlobalOpList
();
// 初始化变邻域搜索
_vns
=
new
VariableNeighborhoodSearch
(
_GlobalParam
,
allOperations
,
globalOpList
,
_fitnessCalculator
,
_objectiveWeights
);
_vns
=
new
VariableNeighborhoodSearch
(
allOperations
,
_fitnessCalculator
);
_hillClimbing
=
new
HillClimbing
(
allOperations
);
_simulatedAnnealing
=
new
SimulatedAnnealing
(
allOperations
);
_parallelLocalSearch
=
new
ParallelLocalSearch
(
_GlobalParam
,
allOperations
,
globalOpList
,
_fitnessCalculator
,
_objectiveWeights
);
_tabuSearch
=
new
TabuSearch
(
_GlobalParam
,
allOperations
,
globalOpList
,
_fitnessCalculator
,
_objectiveWeights
);
_simulatedAnnealing
=
new
SimulatedAnnealing
(
allOperations
,
_fitnessCalculator
);
_tabuSearch
=
new
TabuSearch
(
allOperations
);
_tabuSearchWithSA
=
new
TabuSearchWithSA
(
_GlobalParam
,
allOperations
,
globalOpList
,
_fitnessCalculator
,
_objectiveWeights
);
FileHelper
.
writeLogFile
(
"初始化种群-----------开始-------"
);
...
...
@@ -146,7 +145,7 @@ int opcount=allOperations.size();
FileHelper
.
writeLogFile
(
"爬山法局部优化-----------开始-------"
);
GeneticDecoder
hillClimbingDecoder
=
new
GeneticDecoder
(
_GlobalParam
,
param
.
getBaseTime
(),
machines
,
orders
,
materials
,
machineScheduler
,
materialRequirementService
,
sceneId
);
Chromosome
optimized
=
_hillClimbing
.
BatchSearchAll
(
population
,
machines
,
hillClimbingDecoder
);
Chromosome
optimized
=
_hillClimbing
.
search
(
population
.
get
(
0
),
hillClimbingDecoder
,
machines
);
FileHelper
.
writeLogFile
(
"爬山法局部优化-----------结束-------"
);
return
getBestChromosome
(
optimized
,
param
.
getBaseTime
(),
starttime
);
}
...
...
@@ -156,27 +155,25 @@ int opcount=allOperations.size();
// 步骤2:对初始种群进行模拟退火+爬山法优化
GeneticDecoder
saDecoder1
=
new
GeneticDecoder
(
_GlobalParam
,
param
.
getBaseTime
(),
machines
,
orders
,
materials
,
machineScheduler
,
materialRequirementService
,
sceneId
);
GeneticDecoder
vnsDecoder1
=
new
GeneticDecoder
(
_GlobalParam
,
param
.
getBaseTime
(),
machines
,
orders
,
materials
,
machineScheduler
,
materialRequirementService
,
sceneId
);
if
(
opcount
<
800
)
{
FileHelper
.
writeLogFile
(
"模拟退火+爬山法优化-----------开始-------"
);
Chromosome
saHcOptimized
=
_simulatedAnnealing
.
batchSearchGetMax
(
population
,
saDecoder1
,
machines
);
Chromosome
saHcOptimized
=
_simulatedAnnealing
.
searchWithHillClimbing
(
population
.
get
(
0
),
_vns
,
saDecoder1
,
machines
);
FileHelper
.
writeLogFile
(
"模拟退火+爬山法优化-----------结束-------"
);
return
getBestChromosome
(
saHcOptimized
,
param
.
getBaseTime
(),
starttime
);
}
List
<
List
<
Chromosome
>>
combinedFronts
=
_nsgaIIUtils
.
parallelFastNonDominatedSort
(
population
);
Chromosome
best
=
ProductionDeepCopyUtil
.
deepCopy
(
population
.
get
(
0
),
Chromosome
.
class
);
// GetBest(combinedFronts,"初始");
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
())
{
...
...
@@ -185,7 +182,8 @@ int opcount=allOperations.size();
}
int
Iteration
=
0
;
int
noImproveCount
=
0
;
int
maxNoImprove
=
10
;
// 步骤2:迭代进化
FileHelper
.
writeLogFile
(
"迭代进化-----------开始-------"
+
param
.
getMaxIterations
());
for
(
int
iter
=
0
;
iter
<
param
.
getMaxIterations
();
iter
++)
{
...
...
@@ -193,6 +191,7 @@ int opcount=allOperations.size();
FileHelper
.
writeLogFile
(
"迭代进化------"
+
iter
+
"-----开始-------"
);
// 计算种群适应度标准差,微调参数
double
fitnessStd
=
_fitnessCalculator
.
calculateFitnessStd
(
population
);
param
.
fineTuneParams
(
iter
,
fitnessStd
);
...
...
@@ -204,141 +203,54 @@ int opcount=allOperations.size();
}
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
(
validP
opulation
);
List
<
Chromosome
>
selected
=
geneticOps
.
tournamentSelection
(
p
opulation
);
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
(
"并行局部搜索-----------开始-------"
);
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
);
List
<
Chromosome
>
newPopulation
=
new
ArrayList
<>();
newPopulation
.
add
(
best
);
while
(
newPopulation
.
size
()
<
param
.
getPopulationSize
())
{
// 选择父代
Chromosome
parent1
=
selected
.
get
(
rnd
.
nextInt
(
selected
.
size
()));
Chromosome
parent2
=
selected
.
get
(
rnd
.
nextInt
(
selected
.
size
()));
// 交叉
Chromosome
child
=
parent1
;
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
);
}
child
=
children
.
getFirst
();
child
.
setID
(
UUID
.
randomUUID
().
toString
());
}
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
);
geneticOps
.
mutate
(
child
,
globalOpList
);
}
}
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());
// 核心融合链(工业级标准顺序:GA生成子代 → SA跳坑 → VNS扩邻域 → TS精优化)
child
=
_simulatedAnnealing
.
search
(
child
,
_tabuSearch
,
_vns
,
saDecoder1
,
machines
);
child
=
_vns
.
search
(
child
,
vnsDecoder1
,
machines
);
newPopulation
.
add
(
child
);
}
population
=
chromosomeDistinctByObjectives
(
newPopulation
);;
best
=
GetBest
(
combinedFronts
,
String
.
valueOf
(
iter
));
if
(
bestFitness
<
best
.
getFitness
())
if
(
_fitnessCalculator
.
isBetter
(
population
.
get
(
0
),
best
))
{
bestFitness
=
best
.
getFitness
();
Iteration
=
1
;
best
=
ProductionDeepCopyUtil
.
deepCopy
(
population
.
get
(
0
),
Chromosome
.
class
);
// GetBest(combinedFronts,"初始");
noImproveCount
=
1
;
}
else
{
Iteration
++;
if
(
Iteration
>
5
)
{
noImproveCount
++;
if
(
noImproveCount
>
5
)
{
// 当连续 5 代无最优解提升时,降低交叉概率(如从 0.8 降至 0.5)、提高变异概率(如从 0.1 升至 0.2)
param
.
fineTuneParams
();
}
}
if
(
Iteration
>
10
)
if
(
noImproveCount
>
maxNoImprove
)
{
break
;
}
...
...
@@ -413,7 +325,7 @@ int opcount=allOperations.size();
}
/**
* 按Objectives去重
,相同目标值的方案只保留一个(保留fitness最大的)
* 按Objectives去重
*/
private
List
<
Chromosome
>
chromosomeDistinctByObjectives
(
List
<
Chromosome
>
population
)
{
...
...
@@ -440,7 +352,32 @@ int opcount=allOperations.size();
}
}
return
new
ArrayList
<>(
objectivesMap
.
values
());
// 按 fitnessLevel 倒序排序(多层次比较)
List
<
Chromosome
>
result
=
new
ArrayList
<>(
objectivesMap
.
values
());
result
.
sort
((
c1
,
c2
)
->
{
if
(
isBetter
(
c1
,
c2
))
{
return
-
1
;
// c1 比 c2 好,c1 应该排在前面
}
else
if
(
isBetter
(
c2
,
c1
))
{
return
1
;
// c2 比 c1 好,c2 应该排在前面
}
else
{
return
0
;
// 两者相等
}
});
return
result
;
}
/**
* 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/
private
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
;
}
private
List
<
Chromosome
>
chromosomeDistinct1
(
List
<
Chromosome
>
population
)
...
...
src/main/java/com/aps/service/Algorithm/ParallelLocalSearch.java
deleted
100644 → 0
View file @
ad57430d
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
src/main/java/com/aps/service/Algorithm/SimulatedAnnealing.java
View file @
932c42d2
...
...
@@ -20,15 +20,17 @@ public class SimulatedAnnealing {
private
List
<
Entry
>
allOperations
;
private
FitnessCalculator
fitnessCalculator
;
private
Map
<
String
,
Entry
>
entrys
;
private
Map
<
Integer
,
Entry
>
entrybyids
;
public
SimulatedAnnealing
(
List
<
Entry
>
allOperations
)
{
public
SimulatedAnnealing
(
List
<
Entry
>
allOperations
,
FitnessCalculator
fitnessCalculator
)
{
this
.
allOperations
=
allOperations
;
Map
<
Integer
,
Object
>
mp
=
buildEntryKey
();
this
.
fitnessCalculator
=
fitnessCalculator
;
entrys
=(
Map
<
String
,
Entry
>)
mp
.
get
(
1
);
entrybyids
=(
Map
<
Integer
,
Entry
>)
mp
.
get
(
2
);
...
...
@@ -40,7 +42,7 @@ private Map<String, Entry> entrys;
new
ArrayBlockingQueue
<>(
200
),
// 有界队列,避免内存溢出
new
ThreadPoolExecutor
.
CallerRunsPolicy
()
// 任务满了主线程执行,不丢失任务
);
public
List
<
Chromosome
>
batchSearch
(
List
<
Chromosome
>
chromosomes
,
GeneticDecoder
decoder
,
List
<
Machine
>
machines
)
{
public
List
<
Chromosome
>
batchSearch
(
List
<
Chromosome
>
chromosomes
,
VariableNeighborhoodSearch
vns
,
GeneticDecoder
decoder
,
List
<
Machine
>
machines
)
{
List
<
Chromosome
>
saHcOptimized
=
new
ArrayList
<>();
// CompletableFuture.allOf(chromosomes.stream()
// .map(chromosome -> CompletableFuture.runAsync(() -> {
...
...
@@ -50,15 +52,15 @@ private Map<String, Entry> entrys;
// .toArray(CompletableFuture[]::new))
// .join();
for
(
Chromosome
chromosome:
chromosomes
)
{
Chromosome
optimized
=
searchWithHillClimbing
(
chromosome
,
decoder
,
machines
);
Chromosome
optimized
=
searchWithHillClimbing
(
chromosome
,
vns
,
decoder
,
machines
);
saHcOptimized
.
add
(
optimized
);
}
return
saHcOptimized
;
}
public
Chromosome
batchSearchGetMax
(
List
<
Chromosome
>
chromosomes
,
GeneticDecoder
decoder
,
List
<
Machine
>
machines
)
{
List
<
Chromosome
>
saHcOptimized
=
batchSearch
(
chromosomes
,
decoder
,
machines
);
public
Chromosome
batchSearchGetMax
(
List
<
Chromosome
>
chromosomes
,
VariableNeighborhoodSearch
vns
,
GeneticDecoder
decoder
,
List
<
Machine
>
machines
)
{
List
<
Chromosome
>
saHcOptimized
=
batchSearch
(
chromosomes
,
vns
,
decoder
,
machines
);
int
bestidx
=
Getbest
(
saHcOptimized
,
null
);
if
(
bestidx
>-
1
)
{
...
...
@@ -72,7 +74,7 @@ private Map<String, Entry> entrys;
* 模拟退火搜索,当温度降低到一定程度后切换到爬山法
* 流程:模拟退火全局探索(按概率接受劣解)→ 降温 → 温度低时爬山法局部求精 → 输出最优
*/
public
Chromosome
searchWithHillClimbing
(
Chromosome
chromosome
,
GeneticDecoder
decoder
,
List
<
Machine
>
machines
)
{
public
Chromosome
searchWithHillClimbing
(
Chromosome
chromosome
,
VariableNeighborhoodSearch
vns
,
GeneticDecoder
decoder
,
List
<
Machine
>
machines
)
{
FileHelper
.
writeLogFile
(
"模拟退火+爬山法 - 开始执行"
);
Chromosome
current
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
...
...
@@ -102,7 +104,7 @@ private Map<String, Entry> entrys;
boolean
improved
=
false
;
// 1. 使用智能策略生成邻域解(找瓶颈工序/设备)
Chromosome
neighbor
=
generateNeighbor
(
current
);
Chromosome
neighbor
=
vns
.
generateNeighbor
(
current
);
// 2. 解码
decode
(
decoder
,
neighbor
,
machines
);
...
...
@@ -118,14 +120,14 @@ private Map<String, Entry> entrys;
acceptCount
++;
// 更新全局最优
if
(
isBetter
(
current
,
best
))
{
best
=
ProductionDeepCopyUtil
.
deepCopy
(
current
,
Chromosome
.
class
);
writeKpi
(
best
);
improved
=
true
;
improveCount
++;
noImproveCount
=
0
;
FileHelper
.
writeLogFile
(
String
.
format
(
"模拟退火+爬山法 - 迭代%d:找到更优解,fitness=%.4f"
,
i
,
best
.
getFitness
()));
}
}
if
(!
improved
)
{
...
...
@@ -162,6 +164,95 @@ private Map<String, Entry> entrys;
// 7. 输出全局最优排产
return
best
;
}
/**
* 模拟退火搜索
* 流程:模拟退火全局探索(按概率接受劣解)→ 降温 → 输出最优
*/
public
Chromosome
search
(
Chromosome
chromosome
,
TabuSearch
tabusearch
,
VariableNeighborhoodSearch
vns
,
GeneticDecoder
decoder
,
List
<
Machine
>
machines
)
{
FileHelper
.
writeLogFile
(
"模拟退火+爬山法 - 开始执行"
);
Chromosome
current
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
decode
(
decoder
,
current
,
machines
);
Chromosome
best
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
writeKpi
(
best
);
// 初始化解码
// FileHelper.writeLogFile("模拟退火+爬山法 - 初始化解码完成");
// 初始化温度
double
temperature
=
100.0
;
double
coolingRate
=
0.95
;
double
temperatureThreshold
=
1.0
;
int
maxIterations
=
300
;
int
noImproveCount
=
0
;
int
maxNoImprove
=
50
;
FileHelper
.
writeLogFile
(
String
.
format
(
"模拟退火+爬山法 - 参数配置:温度=%.1f, 降温率=%.2f, 阈值=%.1f, 最大迭代=%d"
,
temperature
,
coolingRate
,
temperatureThreshold
,
maxIterations
));
int
acceptCount
=
0
;
int
improveCount
=
0
;
for
(
int
i
=
0
;
i
<
maxIterations
;
i
++)
{
boolean
improved
=
false
;
// 1. 使用智能策略生成邻域解(找瓶颈工序/设备)
Chromosome
neighbor
=
vns
.
generateNeighbor
(
current
);
// 2. 解码
decode
(
decoder
,
neighbor
,
machines
);
// 跳过禁忌解(除非是最优解)
if
(
tabusearch
.
isTabu
(
neighbor
.
getGeneStr
())
&&
!
isBetter
(
current
,
best
))
{
temperature
*=
coolingRate
;
continue
;
}
// 3. 计算能量差
double
energyDifference
=
calculateEnergyDifference
(
neighbor
,
current
);
// 4. 按概率接受新解(模拟退火核心:有概率接受劣解)
boolean
accepted
=
false
;
if
(
energyDifference
>
0
||
rnd
.
nextDouble
()
<
Math
.
exp
(
energyDifference
/
temperature
))
{
current
=
neighbor
;
accepted
=
true
;
acceptCount
++;
best
=
ProductionDeepCopyUtil
.
deepCopy
(
current
,
Chromosome
.
class
);
tabusearch
.
addToTabuList
(
best
.
getGeneStr
());
writeKpi
(
best
);
improved
=
true
;
improveCount
++;
noImproveCount
=
0
;
FileHelper
.
writeLogFile
(
String
.
format
(
"模拟退火+爬山法 - 迭代%d:找到更优解,fitness=%.4f"
,
i
,
best
.
getFitness
()));
}
if
(!
improved
)
{
noImproveCount
++;
}
// 5. 降温
temperature
*=
coolingRate
;
// 每50次迭代输出一次状态
if
((
i
+
1
)
%
50
==
0
)
{
FileHelper
.
writeLogFile
(
String
.
format
(
"模拟退火+爬山法 - 迭代%d/%d:温度=%.4f, 接受数=%d, 改进数=%d, 无改进连续=%d"
,
i
+
1
,
maxIterations
,
temperature
,
acceptCount
,
improveCount
,
noImproveCount
));
}
}
FileHelper
.
writeLogFile
(
String
.
format
(
"模拟退火+爬山法 - 完成所有%d次迭代,最终fitness=%.4f"
,
maxIterations
,
best
.
getFitness
()));
// 7. 输出全局最优排产
return
best
;
}
private
void
writeKpi
(
Chromosome
chromosome
)
{
String
fitness
=
""
;
double
[]
fitness1
=
chromosome
.
getFitnessLevel
();
...
...
@@ -221,66 +312,7 @@ private Map<String, Entry> entrys;
return
filteredGroups
;
}
/**
* 构建位置索引: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索引
*/
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
<
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
*/
...
...
@@ -301,544 +333,6 @@ private Map<String, Entry> entrys;
return
index0
;
}
/**
* 生成邻域解 - 智能策略:优先处理瓶颈工序/设备
* 策略:
* 1. 优先处理瓶颈设备上的工序(换设备)
* 2. 瓶颈设备上的工序往前移动
* 3. 非瓶颈设备上的工序往后移动(给瓶颈工序腾位置)
*/
private
Chromosome
generateNeighbor
(
Chromosome
chromosome
)
{
List
<
GAScheduleResult
>
results
=
chromosome
.
getResult
();
if
(
results
==
null
||
results
.
isEmpty
())
{
return
generateRandomNeighbor
(
chromosome
,
entrys
);
}
// 构建位置索引
Map
<
String
,
Integer
>
positionIndex
=
buildPositionIndex
(
chromosome
);
Map
<
Integer
,
Entry
>
positionToEntryIndex
=
buildPositionToEntryIndex
(
chromosome
,
entrys
);
Map
<
String
,
Integer
>
MachinePositionIndex
=
buildEntryMachinePositionIndex
(
chromosome
);
// 1. 找出瓶颈设备
Long
bottleneckMachineId
=
findBottleneckMachine
(
chromosome
);
if
(
bottleneckMachineId
!=
null
)
{
// 找出瓶颈设备上的工序
List
<
GAScheduleResult
>
bottleneckOps
=
findOpsOnBottleneckMachine
(
chromosome
,
bottleneckMachineId
);
if
(!
bottleneckOps
.
isEmpty
())
{
// 70%概率优先处理瓶颈设备
if
(
rnd
.
nextDouble
()
<
0.7
)
{
int
strategy
=
rnd
.
nextInt
(
10
);
if
(
strategy
<=
3
)
{
// 策略1:瓶颈设备上的工序换设备
return
tryChangeMachineForBottleneckOp
(
chromosome
,
bottleneckOps
,
entrys
,
MachinePositionIndex
);
}
else
if
(
strategy
<=
8
)
{
// 策略2:瓶颈设备上的工序往前移动
return
tryMoveBottleneckOpForward
(
chromosome
,
bottleneckOps
,
positionIndex
,
positionToEntryIndex
,
entrys
);
}
else
if
(
strategy
<=
10
)
{
// 策略3:非瓶颈设备上的工序往后移动
return
tryMoveNonBottleneckOpBackward
(
chromosome
,
bottleneckMachineId
,
positionIndex
,
positionToEntryIndex
,
entrys
);
}
}
}
}
// 默认策略:随机邻域
return
generateRandomNeighbor
(
chromosome
,
entrys
);
}
/**
* 识别瓶颈设备(利用率最高的设备)
*/
private
Long
findBottleneckMachine
(
Chromosome
chromosome
)
{
Map
<
Long
,
Double
>
utilization
=
calculateMachineUtilization
(
chromosome
);
if
(
utilization
.
isEmpty
())
{
return
null
;
}
return
utilization
.
entrySet
().
stream
()
.
max
(
Map
.
Entry
.
comparingByValue
())
.
map
(
Map
.
Entry
::
getKey
)
.
orElse
(
null
);
}
/**
* 查找在瓶颈设备上的工序
*/
private
List
<
GAScheduleResult
>
findOpsOnBottleneckMachine
(
Chromosome
chromosome
,
Long
bottleneckMachineId
)
{
if
(
bottleneckMachineId
==
null
)
{
return
new
ArrayList
<>();
}
return
chromosome
.
getResult
().
stream
()
.
filter
(
r
->
r
.
getMachineId
()
==
bottleneckMachineId
)
.
collect
(
Collectors
.
toList
());
}
/**
* 计算设备利用率
*/
private
Map
<
Long
,
Double
>
calculateMachineUtilization
(
Chromosome
chromosome
)
{
Map
<
Long
,
Double
>
utilization
=
new
HashMap
<>();
List
<
GAScheduleResult
>
results
=
chromosome
.
getResult
();
if
(
results
==
null
||
results
.
isEmpty
())
{
return
utilization
;
}
int
maxEndTime
=
results
.
stream
()
.
mapToInt
(
GAScheduleResult:
:
getEndTime
)
.
max
()
.
orElse
(
1
);
Map
<
Long
,
List
<
GAScheduleResult
>>
machineResults
=
results
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
GAScheduleResult:
:
getMachineId
));
for
(
Map
.
Entry
<
Long
,
List
<
GAScheduleResult
>>
entry
:
machineResults
.
entrySet
())
{
long
machineId
=
entry
.
getKey
();
List
<
GAScheduleResult
>
machineOps
=
entry
.
getValue
();
int
totalProcessingTime
=
machineOps
.
stream
()
.
mapToInt
(
r
->
r
.
getEndTime
()
-
r
.
getStartTime
())
.
sum
();
double
util
=
(
double
)
totalProcessingTime
/
maxEndTime
;
utilization
.
put
(
machineId
,
util
);
}
return
utilization
;
}
/**
* 尝试给瓶颈设备上的工序换设备
*/
private
Chromosome
tryChangeMachineForBottleneckOp
(
Chromosome
chromosome
,
List
<
GAScheduleResult
>
bottleneckOps
,
Map
<
String
,
Entry
>
entrys
,
Map
<
String
,
Integer
>
MachinePositionIndex
)
{
// 优先选择有多设备选项的工序
List
<
GAScheduleResult
>
candidates
=
bottleneckOps
.
stream
()
.
filter
(
op
->
{
Entry
entry
=
entrybyids
.
get
(
op
.
getOperationId
());
return
entry
!=
null
&&
entry
.
getMachineOptions
().
size
()
>
1
;
})
.
collect
(
Collectors
.
toList
());
if
(
candidates
.
isEmpty
())
{
return
generateRandomNeighbor
(
chromosome
,
entrys
);
}
// 从候选中随机选择一个工序,给它换设备
GAScheduleResult
selectedOp
=
candidates
.
get
(
rnd
.
nextInt
(
candidates
.
size
()));
// 找到这个工序在globalOpList中的位置
int
maPos
=
-
1
;
Entry
entry
=
entrybyids
.
get
(
selectedOp
.
getOperationId
());
if
(
entry
!=
null
&&
entry
.
getMachineOptions
().
size
()
>
1
)
{
maPos
=
MachinePositionIndex
.
get
(
entry
.
getGroupId
()
+
"_"
+
entry
.
getSequence
());
if
(
maPos
>=
0
)
{
return
generateMachineChangeForSpecificOp
(
chromosome
,
entry
.
getMachineOptions
(),
maPos
);
}
}
// 直接换设备
return
generateMachineChangeNeighbor
(
chromosome
);
}
/**
* 给指定位置的工序换设备
*/
private
Chromosome
generateMachineChangeForSpecificOp
(
Chromosome
chromosome
,
List
<
MachineOption
>
machineOptions
,
int
idx
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
ms
=
neighbor
.
getMachineSelection
();
if
(!
ms
.
isEmpty
()
&&
idx
>=
0
&&
idx
<
ms
.
size
())
{
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
neighbor
;
}
/**
* 尝试将瓶颈设备上的工序往前移动
*/
private
Chromosome
tryMoveBottleneckOpForward
(
Chromosome
chromosome
,
List
<
GAScheduleResult
>
bottleneckOps
,
Map
<
String
,
Integer
>
positionIndex
,
Map
<
Integer
,
Entry
>
positionToEntryIndex
,
Map
<
String
,
Entry
>
entrys
)
{
if
(
bottleneckOps
.
isEmpty
())
{
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
// 随机选择一个瓶颈工序
// GAScheduleResult randomOp = bottleneckOps.get(rnd.nextInt(bottleneckOps.size()));
// 计算所有订单的完成时间
List
<
GAScheduleResult
>
allResults
=
chromosome
.
getResult
();
Map
<
Integer
,
Integer
>
orderCompletionTimes
=
calculateOrderCompletionTimes
(
allResults
);
// 找出最晚完成的订单(延期候选)
int
latestCompletionTime
=
orderCompletionTimes
.
values
().
stream
()
.
mapToInt
(
Integer:
:
intValue
)
.
max
()
.
orElse
(
0
);
// 按优先级和订单完成时间排序:优先选择高优先级+延期订单的工序
List
<
GAScheduleResult
>
sortedBottleneckOps
=
new
ArrayList
<>(
bottleneckOps
);
sortedBottleneckOps
.
sort
((
a
,
b
)
->
{
Entry
entryA
=
entrybyids
.
get
(
a
.
getOperationId
());
Entry
entryB
=
entrybyids
.
get
(
b
.
getOperationId
());
if
(
entryA
!=
null
&&
entryB
!=
null
)
{
// 首先比较优先级(高优先级在前)
int
priorityCompare
=
Double
.
compare
(
entryB
.
getPriority
(),
entryA
.
getPriority
());
if
(
priorityCompare
!=
0
)
{
return
priorityCompare
;
}
// 优先级相同,比较订单完成时间(晚完成的在前,即更可能延期)
int
endTimeA
=
orderCompletionTimes
.
getOrDefault
(
a
.
getGroupId
(),
0
);
int
endTimeB
=
orderCompletionTimes
.
getOrDefault
(
b
.
getGroupId
(),
0
);
return
Integer
.
compare
(
endTimeB
,
endTimeA
);
}
return
0
;
});
GAScheduleResult
selectedOp
=
sortedBottleneckOps
.
get
(
rnd
.
nextInt
(
Math
.
min
(
5
,
sortedBottleneckOps
.
size
())));
Entry
entry
=
entrybyids
.
get
(
selectedOp
.
getOperationId
())
;
String
key
=
entry
.
getGroupId
()
+
"_"
+
entry
.
getSequence
();
Integer
opPos
=
positionIndex
.
get
(
key
);
if
(
opPos
==
null
||
opPos
<=
0
)
{
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
// 往前移动1-3步
// int steps = rnd.nextInt(3) + 1;
// return moveOperationForward(chromosome,positionToEntryIndex, opPos, steps);
// 使用插入方式往前移动(1-5步)
int
steps
=
rnd
.
nextInt
(
5
)
+
1
;
return
insertOperationForward
(
chromosome
,
opPos
,
steps
,
entrys
);
}
/**
* 计算每个订单的最后完成时间
*/
private
Map
<
Integer
,
Integer
>
calculateOrderCompletionTimes
(
List
<
GAScheduleResult
>
allResults
)
{
Map
<
Integer
,
Integer
>
orderEndTimes
=
new
HashMap
<>();
for
(
GAScheduleResult
result
:
allResults
)
{
int
groupId
=
result
.
getGroupId
();
int
endTime
=
result
.
getEndTime
();
orderEndTimes
.
put
(
groupId
,
Math
.
max
(
orderEndTimes
.
getOrDefault
(
groupId
,
0
),
endTime
));
}
return
orderEndTimes
;
}
/**
* 尝试将非瓶颈设备上的工序往后移动(给瓶颈工序腾位置)
*/
private
Chromosome
tryMoveNonBottleneckOpBackward
(
Chromosome
chromosome
,
Long
bottleneckMachineId
,
Map
<
String
,
Integer
>
positionIndex
,
Map
<
Integer
,
Entry
>
positionToEntryIndex
,
Map
<
String
,
Entry
>
entrys
)
{
List
<
GAScheduleResult
>
results
=
chromosome
.
getResult
();
if
(
results
==
null
)
{
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
// 找出非瓶颈设备上的工序
List
<
GAScheduleResult
>
nonBottleneckOps
=
results
.
stream
()
.
filter
(
r
->
r
.
getMachineId
()
!=
bottleneckMachineId
)
.
collect
(
Collectors
.
toList
());
if
(
nonBottleneckOps
.
isEmpty
())
{
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
// 随机选择一个非瓶颈工序
GAScheduleResult
randomOp
=
nonBottleneckOps
.
get
(
rnd
.
nextInt
(
nonBottleneckOps
.
size
()));
Entry
entry
=
entrybyids
.
get
(
randomOp
.
getOperationId
());
String
key
=
entry
.
getGroupId
()+
"_"
+
entry
.
getSequence
();
Integer
opPos
=
positionIndex
.
get
(
key
);
if
(
opPos
==
null
||
opPos
>=
chromosome
.
getOperationSequencing
().
size
()
-
1
)
{
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
// 往后移动1-3步
int
steps
=
rnd
.
nextInt
(
3
)
+
1
;
return
moveOperationBackward
(
chromosome
,
positionToEntryIndex
,
opPos
,
steps
);
}
/**
* 将工序往前移动
*/
private
Chromosome
moveOperationForward
(
Chromosome
chromosome
,
Map
<
Integer
,
Entry
>
originalPositionIndex
,
int
pos
,
int
steps
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
pos
<=
0
||
pos
>=
os
.
size
())
{
return
neighbor
;
}
// 获取要移动的工序和目标位置的工序(基于原始chromosome)
Entry
opToMove
=
originalPositionIndex
.
get
(
pos
);
if
(
opToMove
==
null
)
{
return
neighbor
;
}
int
targetPos
=
Math
.
max
(
0
,
pos
-
steps
);
Entry
targetOp
=
originalPositionIndex
.
get
(
targetPos
);
// 检查是否可以交换
if
(
targetOp
!=
null
&&
opToMove
.
getGroupId
()
==
targetOp
.
getGroupId
())
{
return
neighbor
;
}
if
(
targetOp
!=
null
&&
Math
.
abs
(
targetOp
.
getPriority
()
-
opToMove
.
getPriority
())
>
0.001
)
{
return
neighbor
;
}
// 直接交换到目标位置
java
.
util
.
Collections
.
swap
(
os
,
pos
,
targetPos
);
neighbor
.
setOperationSequencing
(
os
);
return
neighbor
;
}
/**
* 将工序往后移动
*/
private
Chromosome
moveOperationBackward
(
Chromosome
chromosome
,
Map
<
Integer
,
Entry
>
originalPositionIndex
,
int
pos
,
int
steps
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
pos
<
0
||
pos
>=
os
.
size
()
-
1
)
{
return
neighbor
;
}
// 获取要移动的工序和目标位置的工序(基于原始chromosome)
Entry
opToMove
=
originalPositionIndex
.
get
(
pos
);
if
(
opToMove
==
null
)
{
return
neighbor
;
}
int
targetPos
=
Math
.
min
(
os
.
size
()
-
1
,
pos
+
steps
);
Entry
targetOp
=
originalPositionIndex
.
get
(
targetPos
);
// 检查是否可以交换
if
(
targetOp
!=
null
&&
opToMove
.
getGroupId
()
==
targetOp
.
getGroupId
())
{
return
neighbor
;
}
if
(
targetOp
!=
null
&&
Math
.
abs
(
targetOp
.
getPriority
()
-
opToMove
.
getPriority
())
>
0.001
)
{
return
neighbor
;
}
// 直接交换到目标位置
java
.
util
.
Collections
.
swap
(
os
,
pos
,
targetPos
);
neighbor
.
setOperationSequencing
(
os
);
return
neighbor
;
}
/**
* 将工序往前插入(不交换,直接插入到目标位置)
*/
private
Chromosome
insertOperationForward
(
Chromosome
chromosome
,
int
pos
,
int
steps
,
Map
<
String
,
Entry
>
entrys
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
pos
<=
0
||
pos
>=
os
.
size
())
{
return
neighbor
;
}
// 获取要移动的工序(基于原始chromosome)
Map
<
Integer
,
Entry
>
originalPositionIndex
=
buildPositionToEntryIndex
(
chromosome
,
entrys
);
Entry
opToMove
=
originalPositionIndex
.
get
(
pos
);
if
(
opToMove
==
null
)
{
return
neighbor
;
}
// 找到最远可以插入的位置(不打破优先级)
int
targetPos
=
Math
.
max
(
0
,
pos
-
steps
);
int
finalTargetPos
=
pos
;
for
(
int
i
=
pos
-
1
;
i
>=
targetPos
;
i
--)
{
Entry
leftOp
=
originalPositionIndex
.
get
(
i
);
if
(
leftOp
!=
null
&&
opToMove
.
getGroupId
()
==
leftOp
.
getGroupId
())
{
break
;
}
if
(
leftOp
!=
null
&&
Math
.
abs
(
leftOp
.
getPriority
()
-
opToMove
.
getPriority
())
>
0.001
)
{
break
;
}
finalTargetPos
=
i
;
}
if
(
finalTargetPos
==
pos
)
{
return
neighbor
;
}
// 执行插入:移除原位置,插入到目标位置
int
value
=
os
.
remove
(
pos
);
os
.
add
(
finalTargetPos
,
value
);
neighbor
.
setOperationSequencing
(
os
);
return
neighbor
;
}
/**
* 随机生成邻域解(兜底策略)
*/
private
Chromosome
generateRandomNeighbor
(
Chromosome
chromosome
,
Map
<
String
,
Entry
>
entrys
)
{
int
neighborType
=
rnd
.
nextInt
(
4
);
switch
(
neighborType
)
{
case
0
:
return
generateSwapNeighbor
(
chromosome
,
entrys
);
case
1
:
return
generateReverseNeighbor
(
chromosome
,
entrys
);
case
2
:
return
generateInsertNeighbor
(
chromosome
,
entrys
);
case
3
:
return
generateMachineChangeNeighbor
(
chromosome
);
default
:
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
}
/**
* 生成交换邻域解 - 只在相同优先级的工序之间交换
*/
private
Chromosome
generateSwapNeighbor
(
Chromosome
chromosome
,
Map
<
String
,
Entry
>
entrys
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
os
.
size
()
>=
2
)
{
Map
<
Integer
,
Entry
>
positionIndex
=
buildPositionToEntryIndex
(
neighbor
,
entrys
);
int
maxAttempts
=
50
;
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
;
}
}
}
}
return
neighbor
;
}
/**
* 生成反转邻域解 - 只反转相同优先级的连续工序
*/
private
Chromosome
generateReverseNeighbor
(
Chromosome
chromosome
,
Map
<
String
,
Entry
>
entrys
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
os
.
size
()
>=
2
)
{
Map
<
Integer
,
Entry
>
positionIndex
=
buildPositionToEntryIndex
(
neighbor
,
entrys
);
int
maxAttempts
=
50
;
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
;
}
}
}
return
neighbor
;
}
/**
* 生成插入邻域解 - 只插入到相同优先级的位置
*/
private
Chromosome
generateInsertNeighbor
(
Chromosome
chromosome
,
Map
<
String
,
Entry
>
entrys
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
os
.
size
()
>=
2
)
{
Map
<
Integer
,
Entry
>
positionIndex
=
buildPositionToEntryIndex
(
neighbor
,
entrys
);
int
maxAttempts
=
50
;
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
;
}
}
}
}
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
=
chromosome
.
getGlobalOpList
().
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
;
}
/**
* 解码染色体
*/
...
...
@@ -857,14 +351,7 @@ private Map<String, Entry> entrys;
* 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/
private
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
;
return
fitnessCalculator
.
isBetter
(
c1
,
c2
);
}
private
int
Getbest
(
List
<
Chromosome
>
candidates
,
Chromosome
best
)
{
// 找出最佳候选方案
...
...
src/main/java/com/aps/service/Algorithm/TabuSearch.java
View file @
932c42d2
...
...
@@ -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
src/main/java/com/aps/service/Algorithm/VariableNeighborhoodSearch.java
View file @
932c42d2
...
...
@@ -6,6 +6,7 @@ import com.aps.entity.basic.*;
import
java.util.*
;
import
java.util.concurrent.CopyOnWriteArrayList
;
import
java.util.stream.Collectors
;
/**
* 变邻域搜索算法
...
...
@@ -14,28 +15,34 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public
class
VariableNeighborhoodSearch
{
private
final
Random
rnd
=
new
Random
();
private
GlobalParam
globalParam
;
private
List
<
Entry
>
allOperations
;
private
List
<
GlobalOperationInfo
>
globalOpList
;
private
FitnessCalculator
fitnessCalculator
;
private
ObjectiveWeights
objectiveWeights
;
public
VariableNeighborhoodSearch
(
GlobalParam
globalParam
,
List
<
Entry
>
allOperations
,
List
<
GlobalOperationInfo
>
globalOpList
,
FitnessCalculator
fitnessCalculator
,
ObjectiveWeights
objectiveWeights
)
{
this
.
globalParam
=
globalParam
;
private
Map
<
String
,
Entry
>
entrys
;
private
Map
<
Integer
,
Entry
>
entrybyids
;
public
VariableNeighborhoodSearch
(
List
<
Entry
>
allOperations
,
FitnessCalculator
fitnessCalculator
)
{
this
.
allOperations
=
allOperations
;
this
.
globalOpList
=
globalOpList
;
this
.
fitnessCalculator
=
fitnessCalculator
;
this
.
objectiveWeights
=
objectiveWeights
;
Map
<
Integer
,
Object
>
mp
=
buildEntryKey
();
entrys
=(
Map
<
String
,
Entry
>)
mp
.
get
(
1
);
entrybyids
=(
Map
<
Integer
,
Entry
>)
mp
.
get
(
2
);
}
/**
* 对种群中的每个个体进行变邻域搜索
*/
public
List
<
Chromosome
>
search
(
List
<
Chromosome
>
population
,
GeneticDecoder
decoder
,
ScheduleParams
param
)
{
public
List
<
Chromosome
>
search
(
List
<
Chromosome
>
population
,
GeneticDecoder
decoder
,
List
<
Machine
>
machines
)
{
List
<
Chromosome
>
improvedPopulation
=
new
ArrayList
<>();
for
(
Chromosome
chromosome
:
population
)
{
Chromosome
improvedChromosome
=
search
(
chromosome
,
decoder
,
param
);
Chromosome
improvedChromosome
=
search
(
chromosome
,
decoder
,
machines
);
improvedPopulation
.
add
(
improvedChromosome
);
}
...
...
@@ -45,7 +52,7 @@ public class VariableNeighborhoodSearch {
/**
* 对单个个体进行变邻域搜索
*/
public
Chromosome
search
(
Chromosome
chromosome
,
GeneticDecoder
decoder
,
ScheduleParams
param
)
{
public
Chromosome
search
(
Chromosome
chromosome
,
GeneticDecoder
decoder
,
List
<
Machine
>
machines
)
{
// 深拷贝当前染色体
Chromosome
current
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
Chromosome
best
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
...
...
@@ -59,10 +66,10 @@ public class VariableNeighborhoodSearch {
NeighborhoodStructure
neighborhood
=
neighborhoods
.
get
(
k
);
// 生成邻域解
Chromosome
neighbor
=
generateNeighbor
(
current
,
neighborhood
);
Chromosome
neighbor
=
generateNeighbor
(
current
);
// 局部搜索
Chromosome
localBest
=
localSearch
(
neighbor
,
decoder
,
param
);
Chromosome
localBest
=
localSearch
(
neighbor
,
decoder
,
null
);
// 邻域移动
if
(
isBetter
(
localBest
,
best
))
{
...
...
@@ -99,11 +106,540 @@ public class VariableNeighborhoodSearch {
}
/**
* 生成邻域解
* 生成邻域解 - 智能策略:优先处理瓶颈工序/设备
* 策略:
* 1. 优先处理瓶颈设备上的工序(换设备)
* 2. 瓶颈设备上的工序往前移动
* 3. 非瓶颈设备上的工序往后移动(给瓶颈工序腾位置)
*/
private
Chromosome
generateNeighbor
(
Chromosome
chromosome
,
NeighborhoodStructure
neighborhood
)
{
public
Chromosome
generateNeighbor
(
Chromosome
chromosome
)
{
List
<
GAScheduleResult
>
results
=
chromosome
.
getResult
();
if
(
results
==
null
||
results
.
isEmpty
())
{
return
generateRandomNeighbor
(
chromosome
,
entrys
);
}
// 构建位置索引
Map
<
String
,
Integer
>
positionIndex
=
buildPositionIndex
(
chromosome
);
Map
<
Integer
,
Entry
>
positionToEntryIndex
=
buildPositionToEntryIndex
(
chromosome
,
entrys
);
Map
<
String
,
Integer
>
MachinePositionIndex
=
buildEntryMachinePositionIndex
(
chromosome
);
// 1. 找出瓶颈设备
Long
bottleneckMachineId
=
findBottleneckMachine
(
chromosome
);
if
(
bottleneckMachineId
!=
null
)
{
// 找出瓶颈设备上的工序
List
<
GAScheduleResult
>
bottleneckOps
=
findOpsOnBottleneckMachine
(
chromosome
,
bottleneckMachineId
);
if
(!
bottleneckOps
.
isEmpty
())
{
// 70%概率优先处理瓶颈设备
if
(
rnd
.
nextDouble
()
<
0.7
)
{
int
strategy
=
rnd
.
nextInt
(
10
);
if
(
strategy
<=
3
)
{
// 策略1:瓶颈设备上的工序换设备
return
tryChangeMachineForBottleneckOp
(
chromosome
,
bottleneckOps
,
entrys
,
MachinePositionIndex
);
}
else
if
(
strategy
<=
8
)
{
// 策略2:瓶颈设备上的工序往前移动
return
tryMoveBottleneckOpForward
(
chromosome
,
bottleneckOps
,
positionIndex
,
positionToEntryIndex
,
entrys
);
}
else
if
(
strategy
<=
10
)
{
// 策略3:非瓶颈设备上的工序往后移动
return
tryMoveNonBottleneckOpBackward
(
chromosome
,
bottleneckMachineId
,
positionIndex
,
positionToEntryIndex
,
entrys
);
}
}
}
}
// 默认策略:随机邻域
return
generateRandomNeighbor
(
chromosome
,
entrys
);
}
/**
* 识别瓶颈设备(利用率最高的设备)
*/
private
Long
findBottleneckMachine
(
Chromosome
chromosome
)
{
Map
<
Long
,
Double
>
utilization
=
calculateMachineUtilization
(
chromosome
);
if
(
utilization
.
isEmpty
())
{
return
null
;
}
return
utilization
.
entrySet
().
stream
()
.
max
(
Map
.
Entry
.
comparingByValue
())
.
map
(
Map
.
Entry
::
getKey
)
.
orElse
(
null
);
}
/**
* 查找在瓶颈设备上的工序
*/
private
List
<
GAScheduleResult
>
findOpsOnBottleneckMachine
(
Chromosome
chromosome
,
Long
bottleneckMachineId
)
{
if
(
bottleneckMachineId
==
null
)
{
return
new
ArrayList
<>();
}
return
chromosome
.
getResult
().
stream
()
.
filter
(
r
->
r
.
getMachineId
()
==
bottleneckMachineId
)
.
collect
(
Collectors
.
toList
());
}
/**
* 计算设备利用率
*/
private
Map
<
Long
,
Double
>
calculateMachineUtilization
(
Chromosome
chromosome
)
{
Map
<
Long
,
Double
>
utilization
=
new
HashMap
<>();
List
<
GAScheduleResult
>
results
=
chromosome
.
getResult
();
if
(
results
==
null
||
results
.
isEmpty
())
{
return
utilization
;
}
int
maxEndTime
=
results
.
stream
()
.
mapToInt
(
GAScheduleResult:
:
getEndTime
)
.
max
()
.
orElse
(
1
);
Map
<
Long
,
List
<
GAScheduleResult
>>
machineResults
=
results
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
GAScheduleResult:
:
getMachineId
));
for
(
Map
.
Entry
<
Long
,
List
<
GAScheduleResult
>>
entry
:
machineResults
.
entrySet
())
{
long
machineId
=
entry
.
getKey
();
List
<
GAScheduleResult
>
machineOps
=
entry
.
getValue
();
int
totalProcessingTime
=
machineOps
.
stream
()
.
mapToInt
(
r
->
r
.
getEndTime
()
-
r
.
getStartTime
())
.
sum
();
double
util
=
(
double
)
totalProcessingTime
/
maxEndTime
;
utilization
.
put
(
machineId
,
util
);
}
return
utilization
;
}
/**
* 尝试给瓶颈设备上的工序换设备
*/
private
Chromosome
tryChangeMachineForBottleneckOp
(
Chromosome
chromosome
,
List
<
GAScheduleResult
>
bottleneckOps
,
Map
<
String
,
Entry
>
entrys
,
Map
<
String
,
Integer
>
MachinePositionIndex
)
{
// 优先选择有多设备选项的工序
List
<
GAScheduleResult
>
candidates
=
bottleneckOps
.
stream
()
.
filter
(
op
->
{
Entry
entry
=
entrybyids
.
get
(
op
.
getOperationId
());
return
entry
!=
null
&&
entry
.
getMachineOptions
().
size
()
>
1
;
})
.
collect
(
Collectors
.
toList
());
if
(
candidates
.
isEmpty
())
{
return
generateRandomNeighbor
(
chromosome
,
entrys
);
}
// 从候选中随机选择一个工序,给它换设备
GAScheduleResult
selectedOp
=
candidates
.
get
(
rnd
.
nextInt
(
candidates
.
size
()));
// 找到这个工序在globalOpList中的位置
int
maPos
=
-
1
;
Entry
entry
=
entrybyids
.
get
(
selectedOp
.
getOperationId
());
if
(
entry
!=
null
&&
entry
.
getMachineOptions
().
size
()
>
1
)
{
maPos
=
MachinePositionIndex
.
get
(
entry
.
getGroupId
()
+
"_"
+
entry
.
getSequence
());
if
(
maPos
>=
0
)
{
return
generateMachineChangeForSpecificOp
(
chromosome
,
entry
.
getMachineOptions
(),
maPos
);
}
}
// 直接换设备
return
generateMachineChangeNeighbor
(
chromosome
);
}
/**
* 给指定位置的工序换设备
*/
private
Chromosome
generateMachineChangeForSpecificOp
(
Chromosome
chromosome
,
List
<
MachineOption
>
machineOptions
,
int
idx
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
neighborhood
.
apply
(
neighbor
);
List
<
Integer
>
ms
=
neighbor
.
getMachineSelection
();
if
(!
ms
.
isEmpty
()
&&
idx
>=
0
&&
idx
<
ms
.
size
())
{
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
neighbor
;
}
/**
* 尝试将瓶颈设备上的工序往前移动
*/
private
Chromosome
tryMoveBottleneckOpForward
(
Chromosome
chromosome
,
List
<
GAScheduleResult
>
bottleneckOps
,
Map
<
String
,
Integer
>
positionIndex
,
Map
<
Integer
,
Entry
>
positionToEntryIndex
,
Map
<
String
,
Entry
>
entrys
)
{
if
(
bottleneckOps
.
isEmpty
())
{
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
// 随机选择一个瓶颈工序
// GAScheduleResult randomOp = bottleneckOps.get(rnd.nextInt(bottleneckOps.size()));
// 计算所有订单的完成时间
List
<
GAScheduleResult
>
allResults
=
chromosome
.
getResult
();
Map
<
Integer
,
Integer
>
orderCompletionTimes
=
calculateOrderCompletionTimes
(
allResults
);
// 找出最晚完成的订单(延期候选)
int
latestCompletionTime
=
orderCompletionTimes
.
values
().
stream
()
.
mapToInt
(
Integer:
:
intValue
)
.
max
()
.
orElse
(
0
);
// 按优先级和订单完成时间排序:优先选择高优先级+延期订单的工序
List
<
GAScheduleResult
>
sortedBottleneckOps
=
new
ArrayList
<>(
bottleneckOps
);
sortedBottleneckOps
.
sort
((
a
,
b
)
->
{
Entry
entryA
=
entrybyids
.
get
(
a
.
getOperationId
());
Entry
entryB
=
entrybyids
.
get
(
b
.
getOperationId
());
if
(
entryA
!=
null
&&
entryB
!=
null
)
{
// 首先比较优先级(高优先级在前)
int
priorityCompare
=
Double
.
compare
(
entryB
.
getPriority
(),
entryA
.
getPriority
());
if
(
priorityCompare
!=
0
)
{
return
priorityCompare
;
}
// 优先级相同,比较订单完成时间(晚完成的在前,即更可能延期)
int
endTimeA
=
orderCompletionTimes
.
getOrDefault
(
a
.
getGroupId
(),
0
);
int
endTimeB
=
orderCompletionTimes
.
getOrDefault
(
b
.
getGroupId
(),
0
);
return
Integer
.
compare
(
endTimeB
,
endTimeA
);
}
return
0
;
});
GAScheduleResult
selectedOp
=
sortedBottleneckOps
.
get
(
rnd
.
nextInt
(
Math
.
min
(
5
,
sortedBottleneckOps
.
size
())));
Entry
entry
=
entrybyids
.
get
(
selectedOp
.
getOperationId
())
;
String
key
=
entry
.
getGroupId
()
+
"_"
+
entry
.
getSequence
();
Integer
opPos
=
positionIndex
.
get
(
key
);
if
(
opPos
==
null
||
opPos
<=
0
)
{
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
// 往前移动1-3步
// int steps = rnd.nextInt(3) + 1;
// return moveOperationForward(chromosome,positionToEntryIndex, opPos, steps);
// 使用插入方式往前移动(1-5步)
int
steps
=
rnd
.
nextInt
(
5
)
+
1
;
return
insertOperationForward
(
chromosome
,
opPos
,
steps
,
entrys
);
}
/**
* 计算每个订单的最后完成时间
*/
private
Map
<
Integer
,
Integer
>
calculateOrderCompletionTimes
(
List
<
GAScheduleResult
>
allResults
)
{
Map
<
Integer
,
Integer
>
orderEndTimes
=
new
HashMap
<>();
for
(
GAScheduleResult
result
:
allResults
)
{
int
groupId
=
result
.
getGroupId
();
int
endTime
=
result
.
getEndTime
();
orderEndTimes
.
put
(
groupId
,
Math
.
max
(
orderEndTimes
.
getOrDefault
(
groupId
,
0
),
endTime
));
}
return
orderEndTimes
;
}
/**
* 尝试将非瓶颈设备上的工序往后移动(给瓶颈工序腾位置)
*/
private
Chromosome
tryMoveNonBottleneckOpBackward
(
Chromosome
chromosome
,
Long
bottleneckMachineId
,
Map
<
String
,
Integer
>
positionIndex
,
Map
<
Integer
,
Entry
>
positionToEntryIndex
,
Map
<
String
,
Entry
>
entrys
)
{
List
<
GAScheduleResult
>
results
=
chromosome
.
getResult
();
if
(
results
==
null
)
{
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
// 找出非瓶颈设备上的工序
List
<
GAScheduleResult
>
nonBottleneckOps
=
results
.
stream
()
.
filter
(
r
->
r
.
getMachineId
()
!=
bottleneckMachineId
)
.
collect
(
Collectors
.
toList
());
if
(
nonBottleneckOps
.
isEmpty
())
{
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
// 随机选择一个非瓶颈工序
GAScheduleResult
randomOp
=
nonBottleneckOps
.
get
(
rnd
.
nextInt
(
nonBottleneckOps
.
size
()));
Entry
entry
=
entrybyids
.
get
(
randomOp
.
getOperationId
());
String
key
=
entry
.
getGroupId
()+
"_"
+
entry
.
getSequence
();
Integer
opPos
=
positionIndex
.
get
(
key
);
if
(
opPos
==
null
||
opPos
>=
chromosome
.
getOperationSequencing
().
size
()
-
1
)
{
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
// 往后移动1-3步
int
steps
=
rnd
.
nextInt
(
3
)
+
1
;
return
moveOperationBackward
(
chromosome
,
positionToEntryIndex
,
opPos
,
steps
);
}
/**
* 将工序往前移动
*/
private
Chromosome
moveOperationForward
(
Chromosome
chromosome
,
Map
<
Integer
,
Entry
>
originalPositionIndex
,
int
pos
,
int
steps
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
pos
<=
0
||
pos
>=
os
.
size
())
{
return
neighbor
;
}
// 获取要移动的工序和目标位置的工序(基于原始chromosome)
Entry
opToMove
=
originalPositionIndex
.
get
(
pos
);
if
(
opToMove
==
null
)
{
return
neighbor
;
}
int
targetPos
=
Math
.
max
(
0
,
pos
-
steps
);
Entry
targetOp
=
originalPositionIndex
.
get
(
targetPos
);
// 检查是否可以交换
if
(
targetOp
!=
null
&&
opToMove
.
getGroupId
()
==
targetOp
.
getGroupId
())
{
return
neighbor
;
}
if
(
targetOp
!=
null
&&
Math
.
abs
(
targetOp
.
getPriority
()
-
opToMove
.
getPriority
())
>
0.001
)
{
return
neighbor
;
}
// 直接交换到目标位置
java
.
util
.
Collections
.
swap
(
os
,
pos
,
targetPos
);
neighbor
.
setOperationSequencing
(
os
);
return
neighbor
;
}
/**
* 将工序往后移动
*/
private
Chromosome
moveOperationBackward
(
Chromosome
chromosome
,
Map
<
Integer
,
Entry
>
originalPositionIndex
,
int
pos
,
int
steps
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
pos
<
0
||
pos
>=
os
.
size
()
-
1
)
{
return
neighbor
;
}
// 获取要移动的工序和目标位置的工序(基于原始chromosome)
Entry
opToMove
=
originalPositionIndex
.
get
(
pos
);
if
(
opToMove
==
null
)
{
return
neighbor
;
}
int
targetPos
=
Math
.
min
(
os
.
size
()
-
1
,
pos
+
steps
);
Entry
targetOp
=
originalPositionIndex
.
get
(
targetPos
);
// 检查是否可以交换
if
(
targetOp
!=
null
&&
opToMove
.
getGroupId
()
==
targetOp
.
getGroupId
())
{
return
neighbor
;
}
if
(
targetOp
!=
null
&&
Math
.
abs
(
targetOp
.
getPriority
()
-
opToMove
.
getPriority
())
>
0.001
)
{
return
neighbor
;
}
// 直接交换到目标位置
java
.
util
.
Collections
.
swap
(
os
,
pos
,
targetPos
);
neighbor
.
setOperationSequencing
(
os
);
return
neighbor
;
}
/**
* 将工序往前插入(不交换,直接插入到目标位置)
*/
private
Chromosome
insertOperationForward
(
Chromosome
chromosome
,
int
pos
,
int
steps
,
Map
<
String
,
Entry
>
entrys
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
pos
<=
0
||
pos
>=
os
.
size
())
{
return
neighbor
;
}
// 获取要移动的工序(基于原始chromosome)
Map
<
Integer
,
Entry
>
originalPositionIndex
=
buildPositionToEntryIndex
(
chromosome
,
entrys
);
Entry
opToMove
=
originalPositionIndex
.
get
(
pos
);
if
(
opToMove
==
null
)
{
return
neighbor
;
}
// 找到最远可以插入的位置(不打破优先级)
int
targetPos
=
Math
.
max
(
0
,
pos
-
steps
);
int
finalTargetPos
=
pos
;
for
(
int
i
=
pos
-
1
;
i
>=
targetPos
;
i
--)
{
Entry
leftOp
=
originalPositionIndex
.
get
(
i
);
if
(
leftOp
!=
null
&&
opToMove
.
getGroupId
()
==
leftOp
.
getGroupId
())
{
break
;
}
if
(
leftOp
!=
null
&&
Math
.
abs
(
leftOp
.
getPriority
()
-
opToMove
.
getPriority
())
>
0.001
)
{
break
;
}
finalTargetPos
=
i
;
}
if
(
finalTargetPos
==
pos
)
{
return
neighbor
;
}
// 执行插入:移除原位置,插入到目标位置
int
value
=
os
.
remove
(
pos
);
os
.
add
(
finalTargetPos
,
value
);
neighbor
.
setOperationSequencing
(
os
);
return
neighbor
;
}
/**
* 随机生成邻域解(兜底策略)
*/
private
Chromosome
generateRandomNeighbor
(
Chromosome
chromosome
,
Map
<
String
,
Entry
>
entrys
)
{
int
neighborType
=
rnd
.
nextInt
(
4
);
switch
(
neighborType
)
{
case
0
:
return
generateSwapNeighbor
(
chromosome
,
entrys
);
case
1
:
return
generateReverseNeighbor
(
chromosome
,
entrys
);
case
2
:
return
generateInsertNeighbor
(
chromosome
,
entrys
);
case
3
:
return
generateMachineChangeNeighbor
(
chromosome
);
default
:
return
generateSwapNeighbor
(
chromosome
,
entrys
);
}
}
/**
* 生成交换邻域解 - 只在相同优先级的工序之间交换
*/
private
Chromosome
generateSwapNeighbor
(
Chromosome
chromosome
,
Map
<
String
,
Entry
>
entrys
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
os
.
size
()
>=
2
)
{
Map
<
Integer
,
Entry
>
positionIndex
=
buildPositionToEntryIndex
(
neighbor
,
entrys
);
int
maxAttempts
=
50
;
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
;
}
}
}
}
return
neighbor
;
}
/**
* 生成反转邻域解 - 只反转相同优先级的连续工序
*/
private
Chromosome
generateReverseNeighbor
(
Chromosome
chromosome
,
Map
<
String
,
Entry
>
entrys
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
os
.
size
()
>=
2
)
{
Map
<
Integer
,
Entry
>
positionIndex
=
buildPositionToEntryIndex
(
neighbor
,
entrys
);
int
maxAttempts
=
50
;
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
;
}
}
}
return
neighbor
;
}
/**
* 生成插入邻域解 - 只插入到相同优先级的位置
*/
private
Chromosome
generateInsertNeighbor
(
Chromosome
chromosome
,
Map
<
String
,
Entry
>
entrys
)
{
Chromosome
neighbor
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
if
(
os
.
size
()
>=
2
)
{
Map
<
Integer
,
Entry
>
positionIndex
=
buildPositionToEntryIndex
(
neighbor
,
entrys
);
int
maxAttempts
=
50
;
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
;
}
}
}
}
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
=
chromosome
.
getGlobalOpList
().
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
;
}
...
...
@@ -121,12 +657,12 @@ public class VariableNeighborhoodSearch {
// 生成所有可能的邻域解
List
<
Chromosome
>
neighbors
=
new
ArrayList
<>();
for
(
NeighborhoodStructure
neighborhood
:
defineNeighborhoods
())
{
neighbors
.
add
(
generateNeighbor
(
current
,
neighborhood
));
neighbors
.
add
(
generateNeighbor
(
current
));
}
// 评估所有邻域解
for
(
Chromosome
neighbor
:
neighbors
)
{
decode
(
decoder
,
neighbor
,
param
);
decode
(
decoder
,
neighbor
,
null
);
if
(
isBetter
(
neighbor
,
best
))
{
best
=
neighbor
;
current
=
neighbor
;
...
...
@@ -138,15 +674,19 @@ public class VariableNeighborhoodSearch {
return
best
;
}
/**
* 解码染色体
*/
private
void
decode
(
GeneticDecoder
decoder
,
Chromosome
chromosome
,
ScheduleParams
param
)
{
private
void
decode
(
GeneticDecoder
decoder
,
Chromosome
chromosome
,
List
<
Machine
>
machines
)
{
chromosome
.
setResult
(
new
CopyOnWriteArrayList
<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome
.
setMachines
(
ProductionDeepCopyUtil
.
deepCopyList
(
machines
,
Machine
.
class
));
// 简单拷贝,实际可能需要深拷贝
decoder
.
decodeChromosomeWithCache
(
chromosome
);
if
(
chromosome
.
getFitness
()
==
0
)
{
chromosome
.
setFitness
(
fitnessCalculator
.
calculateFitness
(
chromosome
,
objectiveWeights
));
}
}
/**
...
...
@@ -216,7 +756,7 @@ public class VariableNeighborhoodSearch {
if
(
ms
.
isEmpty
())
return
;
int
idx
=
rnd
.
nextInt
(
ms
.
size
());
GlobalOperationInfo
globalOp
=
globalOpList
.
get
(
idx
);
GlobalOperationInfo
globalOp
=
chromosome
.
getGlobalOpList
()
.
get
(
idx
);
Entry
op
=
globalOp
.
getOp
();
if
(
op
.
getMachineOptions
().
size
()
>
1
)
{
...
...
@@ -235,6 +775,86 @@ public class VariableNeighborhoodSearch {
}
}
}
/**
* 构建位置索引: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索引
*/
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
<
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
<
Integer
,
Object
>
buildEntryKey
()
{
Map
<
Integer
,
Object
>
index0
=
new
HashMap
<>();
Map
<
String
,
Entry
>
index
=
new
HashMap
<>();
Map
<
Integer
,
Entry
>
index2
=
new
HashMap
<>();
List
<
Entry
>
allOps
=
this
.
allOperations
;
for
(
Entry
op
:
allOps
)
{
String
key
=
op
.
getGroupId
()
+
"_"
+
op
.
getSequence
();
index
.
put
(
key
,
op
);
index2
.
put
(
op
.
getId
(),
op
);
}
index0
.
put
(
1
,
index
);
index0
.
put
(
2
,
index2
);
return
index0
;
}
/**
* 邻域结构接口
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment