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
8bc9c0c0
Commit
8bc9c0c0
authored
Apr 21, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
变领域优化
parent
78368160
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
473 additions
and
3 deletions
+473
-3
VariableNeighborhoodSearch.java
...com/aps/service/Algorithm/VariableNeighborhoodSearch.java
+473
-3
No files found.
src/main/java/com/aps/service/Algorithm/VariableNeighborhoodSearch.java
View file @
8bc9c0c0
...
@@ -72,7 +72,7 @@ public class VariableNeighborhoodSearch {
...
@@ -72,7 +72,7 @@ public class VariableNeighborhoodSearch {
private
int
currentLogLevel
=
LOG_LEVEL_INFO
;
private
int
currentLogLevel
=
LOG_LEVEL_INFO
;
// 局部搜索优化
// 局部搜索优化
private
static
final
int
MAX_LOCAL_SEARCH_NEIGHBORS
=
3
;
// 从5减少到2,大幅减少解码次数
private
static
final
int
MAX_LOCAL_SEARCH_NEIGHBORS
=
2
;
// 从5减少到2,大幅减少解码次数
private
void
log
(
String
message
)
{
private
void
log
(
String
message
)
{
log
(
message
,
LOG_LEVEL_INFO
,
false
);
log
(
message
,
LOG_LEVEL_INFO
,
false
);
...
@@ -229,6 +229,20 @@ public class VariableNeighborhoodSearch {
...
@@ -229,6 +229,20 @@ public class VariableNeighborhoodSearch {
// 机器选择变异
// 机器选择变异
neighborhoods
.
add
(
new
NeighborhoodStructure
(
"MachineChange"
,
this
::
generateMachineChangeNeighbor
));
neighborhoods
.
add
(
new
NeighborhoodStructure
(
"MachineChange"
,
this
::
generateMachineChangeNeighbor
));
// ==================== 新增激进变邻域方法 ====================
// BlockMove - 移动工序块
neighborhoods
.
add
(
new
NeighborhoodStructure
(
"BlockMove"
,
this
::
blockMoveWrapper
));
// MultiOperationSwap - 一次交换多个工序
neighborhoods
.
add
(
new
NeighborhoodStructure
(
"MultiOperationSwap"
,
this
::
multiOperationSwapWrapper
));
// MultiMachineChange - 一次改变多个工序的机器选择
neighborhoods
.
add
(
new
NeighborhoodStructure
(
"MultiMachineChange"
,
this
::
multiMachineChangeWrapper
));
// HybridShake - 混合抖动:综合调整
neighborhoods
.
add
(
new
NeighborhoodStructure
(
"HybridShake"
,
this
::
hybridShakeWrapper
));
return
neighborhoods
;
return
neighborhoods
;
}
}
...
@@ -1995,7 +2009,7 @@ public class VariableNeighborhoodSearch {
...
@@ -1995,7 +2009,7 @@ public class VariableNeighborhoodSearch {
*/
*/
private
Chromosome
localSearch
(
Chromosome
chromosome
,
GeneticDecoder
decoder
,
List
<
Machine
>
machines
)
{
private
Chromosome
localSearch
(
Chromosome
chromosome
,
GeneticDecoder
decoder
,
List
<
Machine
>
machines
)
{
geneticOperations
.
DelOrder
(
chromosome
);
geneticOperations
.
DelOrder
(
chromosome
);
Chromosome
best
=
copyChromosome
(
chromosome
);
Chromosome
best
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
decode
(
decoder
,
best
,
machines
);
decode
(
decoder
,
best
,
machines
);
writeKpi
(
best
);
writeKpi
(
best
);
// 预定义邻域结构,避免每次循环重复创建
// 预定义邻域结构,避免每次循环重复创建
...
@@ -2073,7 +2087,7 @@ public class VariableNeighborhoodSearch {
...
@@ -2073,7 +2087,7 @@ public class VariableNeighborhoodSearch {
log
(
String
.
format
(
"变邻域搜索 -复制对象S, 染色体数="
+
chromosomes
.
size
()));
log
(
String
.
format
(
"变邻域搜索 -复制对象S, 染色体数="
+
chromosomes
.
size
()));
// 并行设置染色体字段
// 并行设置染色体字段
chromosomes
.
forEach
(
chromosome
->
{
chromosomes
.
parallelStream
().
forEach
(
chromosome
->
{
if
(
chromosome
==
null
)
return
;
if
(
chromosome
==
null
)
return
;
chromosome
.
setResult
(
new
CopyOnWriteArrayList
<>());
chromosome
.
setResult
(
new
CopyOnWriteArrayList
<>());
...
@@ -2560,4 +2574,460 @@ public class VariableNeighborhoodSearch {
...
@@ -2560,4 +2574,460 @@ public class VariableNeighborhoodSearch {
this
.
score
=
score
;
this
.
score
=
score
;
}
}
}
}
// ==================== 激进变邻域方法 ====================
/**
* BlockMove - 移动工序块的变邻域方法包装器
*/
private
Chromosome
blockMoveWrapper
(
Chromosome
chromosome
)
{
Map
<
Integer
,
Object
>
obj
=
buildPositionToEntryIndex
(
chromosome
);
Map
<
Integer
,
Entry
>
positionToEntryIndex
=
(
Map
<
Integer
,
Entry
>)
obj
.
get
(
1
);
List
<
List
<
Integer
>>
positionByPriority
=
(
List
<
List
<
Integer
>>)
obj
.
get
(
2
);
return
blockMove
(
chromosome
,
positionToEntryIndex
,
positionByPriority
);
}
/**
* BlockMove - 移动一段连续的工序块到新位置
* 优先选择包含瓶颈工序的块,遵守优先级约束
*/
private
Chromosome
blockMove
(
Chromosome
chromosome
,
Map
<
Integer
,
Entry
>
positionIndex
,
List
<
List
<
Integer
>>
positionByPriority
)
{
Chromosome
neighbor
=
copyChromosome
(
chromosome
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
int
n
=
os
.
size
();
if
(
n
<
5
)
return
null
;
// 工序太少,无法进行块移动
// 获取瓶颈工序
Set
<
Integer
>
bottleneckOpIds
=
new
HashSet
<>();
try
{
Map
<
String
,
Object
>
bottleneckAnalysis
=
findBottleneckMachineWithDetails
(
chromosome
);
List
<
GAScheduleResult
>
criticalOps
=
(
List
<
GAScheduleResult
>)
bottleneckAnalysis
.
get
(
"criticalOps"
);
if
(
criticalOps
!=
null
)
{
for
(
GAScheduleResult
op
:
criticalOps
)
{
bottleneckOpIds
.
add
(
op
.
getOperationId
());
}
}
}
catch
(
Exception
e
)
{
log
(
"BlockMove: 获取瓶颈信息失败,使用正常模式"
);
}
// 找出包含瓶颈工序的位置
Set
<
Integer
>
bottleneckPositions
=
new
HashSet
<>();
for
(
Map
.
Entry
<
Integer
,
Entry
>
entry
:
positionIndex
.
entrySet
())
{
if
(
bottleneckOpIds
.
contains
(
entry
.
getValue
().
getId
()))
{
bottleneckPositions
.
add
(
entry
.
getKey
());
}
}
int
maxAttempts
=
20
;
for
(
int
attempt
=
0
;
attempt
<
maxAttempts
;
attempt
++)
{
// 1. 选择块的起始位置 - 优先选择包含瓶颈工序的区域
int
blockStart
;
if
(!
bottleneckPositions
.
isEmpty
()
&&
rnd
.
nextDouble
()
<
0.7
)
{
// 70%概率从瓶颈工序附近选择
List
<
Integer
>
bottleneckPosList
=
new
ArrayList
<>(
bottleneckPositions
);
int
bottleneckPos
=
bottleneckPosList
.
get
(
rnd
.
nextInt
(
bottleneckPosList
.
size
()));
// 在瓶颈工序周围选择起始位置
int
minStart
=
Math
.
max
(
0
,
bottleneckPos
-
5
);
int
maxStart
=
Math
.
min
(
n
-
4
,
bottleneckPos
);
blockStart
=
minStart
+
rnd
.
nextInt
(
maxStart
-
minStart
+
1
);
}
else
{
// 否则从高优先级组中选择
if
(!
positionByPriority
.
isEmpty
())
{
int
priorityGroupIndex
;
if
(
positionByPriority
.
size
()
<=
3
)
{
priorityGroupIndex
=
rnd
.
nextInt
(
positionByPriority
.
size
());
}
else
{
if
(
rnd
.
nextDouble
()
<
0.7
)
{
priorityGroupIndex
=
rnd
.
nextInt
(
Math
.
min
(
3
,
positionByPriority
.
size
()));
}
else
{
int
otherCount
=
positionByPriority
.
size
()
-
3
;
priorityGroupIndex
=
3
+
rnd
.
nextInt
(
otherCount
);
}
}
List
<
Integer
>
positionos
=
positionByPriority
.
get
(
priorityGroupIndex
);
if
(!
positionos
.
isEmpty
())
{
blockStart
=
positionos
.
get
(
rnd
.
nextInt
(
positionos
.
size
()));
blockStart
=
Math
.
max
(
0
,
Math
.
min
(
n
-
4
,
blockStart
));
}
else
{
blockStart
=
rnd
.
nextInt
(
n
-
3
);
}
}
else
{
blockStart
=
rnd
.
nextInt
(
n
-
3
);
}
}
// 2. 确定块大小:3-8个工序
int
maxBlockSize
=
Math
.
min
(
8
,
n
-
blockStart
);
int
blockSize
=
rnd
.
nextInt
(
maxBlockSize
-
2
)
+
3
;
int
blockEnd
=
blockStart
+
blockSize
;
// 检查块中的工序是否都属于相似的优先级
boolean
validBlock
=
true
;
Double
blockPriority
=
null
;
int
bottleneckCount
=
0
;
for
(
int
i
=
blockStart
;
i
<
blockEnd
&&
i
<
os
.
size
();
i
++)
{
Entry
entry
=
positionIndex
.
get
(
i
);
if
(
entry
!=
null
)
{
if
(
blockPriority
==
null
)
{
blockPriority
=
entry
.
getPriority
();
}
else
if
(
Math
.
abs
(
entry
.
getPriority
()
-
blockPriority
)
>
0.5
)
{
// 优先级差异太大,跳过这个块
validBlock
=
false
;
break
;
}
if
(
bottleneckOpIds
.
contains
(
entry
.
getId
()))
{
bottleneckCount
++;
}
}
}
if
(!
validBlock
)
continue
;
// 3. 选择新位置:不能在块内部,且尽量在同一优先级区域
List
<
Integer
>
possiblePositions
=
new
ArrayList
<>();
for
(
int
pos
=
0
;
pos
<
n
-
blockSize
+
1
;
pos
++)
{
if
(
pos
<
blockStart
-
1
||
pos
>
blockEnd
+
1
)
{
possiblePositions
.
add
(
pos
);
}
}
if
(
possiblePositions
.
isEmpty
())
continue
;
// 优先选择同样是高优先级的位置
int
newPosition
;
if
(!
positionByPriority
.
isEmpty
()
&&
blockPriority
!=
null
)
{
// 查找目标优先级组的位置
List
<
Integer
>
targetPositions
=
new
ArrayList
<>();
for
(
int
pos
:
possiblePositions
)
{
Entry
entry
=
positionIndex
.
get
(
pos
);
if
(
entry
!=
null
&&
Math
.
abs
(
entry
.
getPriority
()
-
blockPriority
)
<=
0.5
)
{
targetPositions
.
add
(
pos
);
}
}
if
(!
targetPositions
.
isEmpty
()
&&
rnd
.
nextDouble
()
<
0.7
)
{
newPosition
=
targetPositions
.
get
(
rnd
.
nextInt
(
targetPositions
.
size
()));
}
else
{
newPosition
=
possiblePositions
.
get
(
rnd
.
nextInt
(
possiblePositions
.
size
()));
}
}
else
{
newPosition
=
possiblePositions
.
get
(
rnd
.
nextInt
(
possiblePositions
.
size
()));
}
log
(
String
.
format
(
"BlockMove: 移动工序块 [%d,%d) -> %d, 块大小=%d, 瓶颈工序=%d/%d"
,
blockStart
,
blockEnd
,
newPosition
,
blockSize
,
bottleneckCount
,
blockSize
));
// 4. 执行块移动
List
<
Integer
>
block
=
new
ArrayList
<>(
os
.
subList
(
blockStart
,
blockEnd
));
os
.
subList
(
blockStart
,
blockEnd
).
clear
();
// 调整newPosition(因为移除块后索引变化了)
if
(
newPosition
>
blockStart
)
{
newPosition
-=
blockSize
;
}
os
.
addAll
(
newPosition
,
block
);
return
neighbor
;
}
return
null
;
}
/**
* MultiOperationSwap - 一次交换多个工序的包装器
*/
private
Chromosome
multiOperationSwapWrapper
(
Chromosome
chromosome
)
{
Map
<
Integer
,
Object
>
obj
=
buildPositionToEntryIndex
(
chromosome
);
Map
<
Integer
,
Entry
>
positionToEntryIndex
=
(
Map
<
Integer
,
Entry
>)
obj
.
get
(
1
);
List
<
List
<
Integer
>>
positionByPriority
=
(
List
<
List
<
Integer
>>)
obj
.
get
(
2
);
return
multiOperationSwap
(
chromosome
,
positionToEntryIndex
,
positionByPriority
);
}
/**
* MultiOperationSwap - 一次交换多对工序
* 优先选择瓶颈工序和关键路径工序,遵守优先级约束
*/
private
Chromosome
multiOperationSwap
(
Chromosome
chromosome
,
Map
<
Integer
,
Entry
>
positionIndex
,
List
<
List
<
Integer
>>
positionByPriority
)
{
Chromosome
neighbor
=
copyChromosome
(
chromosome
);
List
<
Integer
>
os
=
neighbor
.
getOperationSequencing
();
int
n
=
os
.
size
();
if
(
n
<
4
)
return
null
;
// 工序太少
// 获取瓶颈工序和关键路径工序
List
<
Integer
>
priorityPositions
=
new
ArrayList
<>();
Set
<
Integer
>
bottleneckOpIds
=
new
HashSet
<>();
try
{
Map
<
String
,
Object
>
bottleneckAnalysis
=
findBottleneckMachineWithDetails
(
chromosome
);
List
<
GAScheduleResult
>
criticalOps
=
(
List
<
GAScheduleResult
>)
bottleneckAnalysis
.
get
(
"criticalOps"
);
if
(
criticalOps
!=
null
)
{
for
(
GAScheduleResult
op
:
criticalOps
)
{
bottleneckOpIds
.
add
(
op
.
getOperationId
());
}
}
// 构建瓶颈工序的位置索引
Map
<
String
,
Integer
>
posIndex
=
buildPositionIndex
(
chromosome
);
for
(
Map
.
Entry
<
Integer
,
Entry
>
entry
:
positionIndex
.
entrySet
())
{
if
(
bottleneckOpIds
.
contains
(
entry
.
getValue
().
getId
()))
{
priorityPositions
.
add
(
entry
.
getKey
());
}
}
}
catch
(
Exception
e
)
{
log
(
"MultiOperationSwap: 获取瓶颈信息失败,使用正常模式"
);
}
int
swapPairs
=
rnd
.
nextInt
(
Math
.
min
(
3
,
n
/
2
))
+
1
;
// 1-3对交换
Set
<
Integer
>
usedPositions
=
new
HashSet
<>();
log
(
String
.
format
(
"MultiOperationSwap: 准备执行 %d 对工序交换, 瓶颈工序数=%d"
,
swapPairs
,
priorityPositions
.
size
()));
for
(
int
pair
=
0
;
pair
<
swapPairs
;
pair
++)
{
int
maxAttempts
=
50
;
boolean
found
=
false
;
for
(
int
attempt
=
0
;
attempt
<
maxAttempts
&&
!
found
;
attempt
++)
{
int
pos1
,
pos2
;
// 优先从瓶颈工序中选择,70%概率
if
(!
priorityPositions
.
isEmpty
()
&&
rnd
.
nextDouble
()
<
0.7
)
{
pos1
=
priorityPositions
.
get
(
rnd
.
nextInt
(
priorityPositions
.
size
()));
}
else
{
// 否则从优先级组中选择
if
(
positionByPriority
.
isEmpty
())
{
pos1
=
rnd
.
nextInt
(
n
);
}
else
{
// 优先选择前面的优先级组
int
priorityGroupIndex
;
if
(
positionByPriority
.
size
()
<=
3
)
{
priorityGroupIndex
=
rnd
.
nextInt
(
positionByPriority
.
size
());
}
else
{
if
(
rnd
.
nextDouble
()
<
0.7
)
{
priorityGroupIndex
=
rnd
.
nextInt
(
Math
.
min
(
3
,
positionByPriority
.
size
()));
}
else
{
int
otherCount
=
positionByPriority
.
size
()
-
3
;
priorityGroupIndex
=
3
+
rnd
.
nextInt
(
otherCount
);
}
}
List
<
Integer
>
positionos
=
positionByPriority
.
get
(
priorityGroupIndex
);
if
(
positionos
.
isEmpty
())
continue
;
pos1
=
positionos
.
get
(
rnd
.
nextInt
(
positionos
.
size
()));
}
}
// 从同一个优先级组中选择pos2,确保优先级约束
Entry
entry1
=
positionIndex
.
get
(
pos1
);
if
(
entry1
==
null
)
continue
;
List
<
Integer
>
possiblePos2
=
new
ArrayList
<>();
// 查找同优先级的工序位置
for
(
List
<
Integer
>
priorityGroup
:
positionByPriority
)
{
if
(
priorityGroup
.
contains
(
pos1
))
{
possiblePos2
=
priorityGroup
.
stream
()
.
filter
(
p
->
p
!=
pos1
&&
!
usedPositions
.
contains
(
p
))
.
collect
(
Collectors
.
toList
());
break
;
}
}
// 如果没有找到同优先级的,从瓶颈工序中找一个
if
(
possiblePos2
.
isEmpty
()
&&
!
priorityPositions
.
isEmpty
())
{
possiblePos2
=
priorityPositions
.
stream
()
.
filter
(
p
->
p
!=
pos1
&&
!
usedPositions
.
contains
(
p
))
.
collect
(
Collectors
.
toList
());
}
// 如果还是没有,随机找一个(放宽约束)
if
(
possiblePos2
.
isEmpty
())
{
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
if
(
i
!=
pos1
&&
!
usedPositions
.
contains
(
i
))
{
possiblePos2
.
add
(
i
);
}
}
}
if
(
possiblePos2
.
isEmpty
())
continue
;
pos2
=
possiblePos2
.
get
(
rnd
.
nextInt
(
possiblePos2
.
size
()));
if
(
pos1
==
pos2
||
usedPositions
.
contains
(
pos1
)
||
usedPositions
.
contains
(
pos2
))
{
continue
;
}
Entry
entry2
=
positionIndex
.
get
(
pos2
);
if
(
entry1
==
null
||
entry2
==
null
)
continue
;
// 执行交换
Integer
temp
=
os
.
get
(
pos1
);
os
.
set
(
pos1
,
os
.
get
(
pos2
));
os
.
set
(
pos2
,
temp
);
usedPositions
.
add
(
pos1
);
usedPositions
.
add
(
pos2
);
String
bottleneckTag1
=
bottleneckOpIds
.
contains
(
entry1
.
getId
())
?
"[瓶颈]"
:
""
;
String
bottleneckTag2
=
bottleneckOpIds
.
contains
(
entry2
.
getId
())
?
"[瓶颈]"
:
""
;
log
(
String
.
format
(
" 交换对 %d: pos=%d%s <-> pos=%d%s, 工单=%d<->%d"
,
pair
+
1
,
pos1
,
bottleneckTag1
,
pos2
,
bottleneckTag2
,
entry1
.
getGroupId
(),
entry2
.
getGroupId
()));
found
=
true
;
break
;
}
}
if
(
usedPositions
.
size
()
>=
2
)
{
return
neighbor
;
}
return
null
;
}
/**
* MultiMachineChange - 一次改变多个工序的机器选择的包装器
*/
private
Chromosome
multiMachineChangeWrapper
(
Chromosome
chromosome
)
{
return
multiMachineChange
(
chromosome
);
}
/**
* MultiMachineChange - 一次改变多个工序的机器选择
* 优先选择瓶颈工序和关键路径工序
*/
private
Chromosome
multiMachineChange
(
Chromosome
chromosome
)
{
Chromosome
neighbor
=
copyChromosome
(
chromosome
);
List
<
GlobalOperationInfo
>
globalOps
=
neighbor
.
getGlobalOpList
();
List
<
Integer
>
machineSelection
=
neighbor
.
getMachineSelection
();
// 获取瓶颈工序
Set
<
Integer
>
bottleneckOpIds
=
new
HashSet
<>();
try
{
Map
<
String
,
Object
>
bottleneckAnalysis
=
findBottleneckMachineWithDetails
(
chromosome
);
List
<
GAScheduleResult
>
criticalOps
=
(
List
<
GAScheduleResult
>)
bottleneckAnalysis
.
get
(
"criticalOps"
);
if
(
criticalOps
!=
null
)
{
for
(
GAScheduleResult
op
:
criticalOps
)
{
bottleneckOpIds
.
add
(
op
.
getOperationId
());
}
}
}
catch
(
Exception
e
)
{
log
(
"MultiMachineChange: 获取瓶颈信息失败,使用正常模式"
);
}
// 收集有多个机器选项的工序,优先瓶颈工序
List
<
Integer
>
eligibleOps
=
new
ArrayList
<>();
List
<
Integer
>
bottleneckEligibleOps
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
globalOps
.
size
();
i
++)
{
Entry
entry
=
globalOps
.
get
(
i
).
getOp
();
if
(
entry
!=
null
&&
entry
.
getMachineOptions
()
!=
null
&&
entry
.
getMachineOptions
().
size
()
>
1
)
{
eligibleOps
.
add
(
i
);
if
(
bottleneckOpIds
.
contains
(
entry
.
getId
()))
{
bottleneckEligibleOps
.
add
(
i
);
}
}
}
if
(
eligibleOps
.
size
()
<
2
)
{
log
(
"MultiMachineChange: 没有足够的多机器选项工序"
);
return
null
;
}
// 选择要改变的工序数量:2-5个
int
changeCount
=
Math
.
min
(
rnd
.
nextInt
(
4
)
+
2
,
eligibleOps
.
size
());
Set
<
Integer
>
selectedIndices
=
new
HashSet
<>();
log
(
String
.
format
(
"MultiMachineChange: 准备改变 %d 个工序的机器选择, 瓶颈工序数=%d/%d"
,
changeCount
,
bottleneckEligibleOps
.
size
(),
eligibleOps
.
size
()));
// 优先选择瓶颈工序,70%概率从瓶颈中选择
while
(
selectedIndices
.
size
()
<
changeCount
)
{
int
idx
;
if
(!
bottleneckEligibleOps
.
isEmpty
()
&&
rnd
.
nextDouble
()
<
0.7
)
{
idx
=
bottleneckEligibleOps
.
get
(
rnd
.
nextInt
(
bottleneckEligibleOps
.
size
()));
}
else
{
idx
=
eligibleOps
.
get
(
rnd
.
nextInt
(
eligibleOps
.
size
()));
}
if
(!
selectedIndices
.
contains
(
idx
))
{
selectedIndices
.
add
(
idx
);
}
}
// 为每个选中的工序随机选择新机器
for
(
int
idx
:
selectedIndices
)
{
Entry
entry
=
globalOps
.
get
(
idx
).
getOp
();
List
<
MachineOption
>
options
=
entry
.
getMachineOptions
();
int
currentSelection
=
machineSelection
.
get
(
idx
);
// 随机选择一个不同于当前的机器
int
newSelection
;
if
(
options
.
size
()
==
2
)
{
newSelection
=
(
currentSelection
==
1
)
?
0
:
1
;
}
else
{
do
{
newSelection
=
rnd
.
nextInt
(
options
.
size
());
}
while
(
newSelection
==
currentSelection
);
}
machineSelection
.
set
(
idx
,
newSelection
);
String
bottleneckTag
=
bottleneckOpIds
.
contains
(
entry
.
getId
())
?
"[瓶颈]"
:
""
;
log
(
String
.
format
(
" 工序%d%s (工单%d): 机器选择 %d -> %d"
,
idx
,
bottleneckTag
,
entry
.
getGroupId
(),
currentSelection
,
newSelection
));
}
return
neighbor
;
}
/**
* HybridShake - 混合抖动:同时进行位置和机器的综合调整
* 最激进的变邻域方法,用于彻底跳出局部最优
*/
private
Chromosome
hybridShakeWrapper
(
Chromosome
chromosome
)
{
Chromosome
neighbor
=
copyChromosome
(
chromosome
);
log
(
"HybridShake: 开始混合抖动调整"
);
// 50%概率进行块移动
if
(
rnd
.
nextDouble
()
<
0.5
)
{
Map
<
Integer
,
Object
>
obj
=
buildPositionToEntryIndex
(
chromosome
);
Map
<
Integer
,
Entry
>
positionToEntryIndex
=
(
Map
<
Integer
,
Entry
>)
obj
.
get
(
1
);
List
<
List
<
Integer
>>
positionByPriority
=
(
List
<
List
<
Integer
>>)
obj
.
get
(
2
);
Chromosome
blockResult
=
blockMove
(
neighbor
,
positionToEntryIndex
,
positionByPriority
);
if
(
blockResult
!=
null
)
{
neighbor
=
blockResult
;
}
}
// 50%概率进行多机器改变
if
(
rnd
.
nextDouble
()
<
0.5
)
{
Chromosome
machineResult
=
multiMachineChange
(
neighbor
);
if
(
machineResult
!=
null
)
{
neighbor
=
machineResult
;
}
}
// 30%概率进行多工序交换
if
(
rnd
.
nextDouble
()
<
0.3
)
{
Map
<
Integer
,
Object
>
obj
=
buildPositionToEntryIndex
(
chromosome
);
Map
<
Integer
,
Entry
>
positionToEntryIndex
=
(
Map
<
Integer
,
Entry
>)
obj
.
get
(
1
);
List
<
List
<
Integer
>>
positionByPriority
=
(
List
<
List
<
Integer
>>)
obj
.
get
(
2
);
Chromosome
swapResult
=
multiOperationSwap
(
neighbor
,
positionToEntryIndex
,
positionByPriority
);
if
(
swapResult
!=
null
)
{
neighbor
=
swapResult
;
}
}
log
(
"HybridShake: 混合抖动完成"
);
return
neighbor
;
}
}
}
\ No newline at end of file
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