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
41cab0d7
Commit
41cab0d7
authored
Jul 06, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化
parent
7c25b0fe
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
2534 additions
and
477 deletions
+2534
-477
FileHelper.java
src/main/java/com/aps/common/util/FileHelper.java
+26
-0
Chromosome.java
src/main/java/com/aps/entity/Algorithm/Chromosome.java
+55
-5
Entry.java
src/main/java/com/aps/entity/basic/Entry.java
+3
-0
AdaptiveLargeNeighborhoodSearch.java
...ps/service/Algorithm/AdaptiveLargeNeighborhoodSearch.java
+1003
-0
CpSatFjspModel.java
src/main/java/com/aps/service/Algorithm/CpSatFjspModel.java
+97
-14
CpSatInitializer.java
...main/java/com/aps/service/Algorithm/CpSatInitializer.java
+3
-3
CpSatLnsNeighborhood.java
.../java/com/aps/service/Algorithm/CpSatLnsNeighborhood.java
+512
-0
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+14
-6
HillClimbing.java
src/main/java/com/aps/service/Algorithm/HillClimbing.java
+2
-2
HybridAlgorithm.java
src/main/java/com/aps/service/Algorithm/HybridAlgorithm.java
+88
-2
Initialization.java
src/main/java/com/aps/service/Algorithm/Initialization.java
+8
-2
KpiLowerBoundCalculator.java
...va/com/aps/service/Algorithm/KpiLowerBoundCalculator.java
+271
-0
RoutingDataService.java
...in/java/com/aps/service/Algorithm/RoutingDataService.java
+3
-1
SimulatedAnnealing.java
...in/java/com/aps/service/Algorithm/SimulatedAnnealing.java
+274
-392
VariableNeighborhoodSearch.java
...com/aps/service/Algorithm/VariableNeighborhoodSearch.java
+173
-48
PlanResultServiceTest.java
src/test/java/com/aps/demo/PlanResultServiceTest.java
+2
-2
No files found.
src/main/java/com/aps/common/util/FileHelper.java
View file @
41cab0d7
...
...
@@ -10,6 +10,32 @@ public class FileHelper {
private
static
final
String
LOG_FILE
=
"schedule_log.txt"
;
private
static
final
String
LOG_FILE_PATH
=
"log/"
;
// 日志级别
private
static
final
int
LOG_LEVEL_DEBUG
=
0
;
private
static
final
int
LOG_LEVEL_INFO
=
1
;
private
static
final
int
LOG_LEVEL_WARN
=
2
;
private
static
int
currentLogLevel
=
LOG_LEVEL_INFO
;
// 局部搜索优化
public
static
void
log
(
String
message
)
{
log
(
message
,
LOG_LEVEL_INFO
,
true
);
}
public
static
void
log
(
String
message
,
boolean
enableLogging
)
{
log
(
message
,
LOG_LEVEL_INFO
,
enableLogging
);
}
public
static
void
log
(
String
message
,
int
level
)
{
log
(
message
,
level
,
false
);
}
public
static
void
log
(
String
message
,
int
level
,
boolean
enableLogging
)
{
if
(
enableLogging
&&
level
>=
currentLogLevel
)
{
writeLogFile
(
message
);
}
}
public
static
void
writeLogFile
(
String
message
)
{
String
date
=
LocalDateTime
.
now
().
format
(
DateTimeFormatter
.
ofPattern
(
"yyyyMMdd"
))+
"-"
;
...
...
src/main/java/com/aps/entity/Algorithm/Chromosome.java
View file @
41cab0d7
...
...
@@ -133,7 +133,7 @@ public class Chromosome {
private
TreeMap
<
String
,
Material
>
materials
=
new
TreeMap
<>();
// private List<Material> materials = new ArrayList<>();
// private List<Material> materials = new ArrayList<>();
private
List
<
String
>
materialIds
=
new
ArrayList
<>();
/*
...
...
@@ -142,6 +142,12 @@ public class Chromosome {
private
double
[]
Objectives
=
new
double
[
0
];
// 多目标值:[Makespan, TotalFlowTime, TotalChangeover, LoadStd, Delay]
private
double
[]
MaxObjectives
=
new
double
[
0
];
//
private
double
[]
MinObjectives
=
new
double
[
0
];
//
private
double
[]
weights
=
new
double
[
0
];
/**
* 各目标维度的理论下界(用于计算 Gap = (current - lowerBound) / lowerBound)。
* 由 KpiLowerBoundCalculator 在 decode 后计算并填入。
*/
private
double
[]
LowerBoundObjectives
=
new
double
[
0
];
private
int
Rank
;
// 非支配排序等级(1最优)
private
double
CrowdingDistance
=
0
;
// 拥挤距离 越小越优
/*
...
...
@@ -255,7 +261,7 @@ public class Chromosome {
*
* @return 不在 allOperations 中的 GAScheduleResult 列表;若均存在则返回空列表
*/
public
List
<
GAScheduleResult
>
getResultsNotInAllOperations
()
{
public
List
<
GAScheduleResult
>
checkResultsNotInAllOperations1
()
{
if
(
Result
==
null
||
Result
.
isEmpty
())
{
return
Collections
.
emptyList
();
}
...
...
@@ -265,7 +271,7 @@ public class Chromosome {
Set
<
Integer
>
allOpIds
=
allOperations
.
stream
()
.
map
(
com
.
aps
.
entity
.
basic
.
Entry
::
getId
)
.
collect
(
Collectors
.
toSet
());
List
<
GAScheduleResult
>
NotInAllOperations
=
Result
.
stream
()
List
<
GAScheduleResult
>
NotInAllOperations
=
Result
.
stream
()
.
filter
(
r
->
!
allOpIds
.
contains
(
r
.
getOperationId
()))
.
collect
(
Collectors
.
toList
());
...
...
@@ -281,8 +287,52 @@ public class Chromosome {
*
* @return 存在则返回 true,否则返回 false
*/
public
boolean
hasResultNotInAllOperations
()
{
return
!
getResultsNotInAllOperations
().
isEmpty
();
// public boolean hasResultNotInAllOperations1() {
// / return !getResultsNotInAllOperations1().isEmpty();
// }
/**
* LNS 需要:创建染色体的深拷贝(machineSelection 和 operationSequencing 独立副本)
* 大对象(globalOpList / allOperations / orders / materials)共享引用
*/
public
Chromosome
deepCopy
()
{
Chromosome
copy
=
new
Chromosome
();
if
(
machineSelection
!=
null
)
{
copy
.
machineSelection
=
new
CopyOnWriteArrayList
<>(
machineSelection
);
copy
.
machineStrDirty
=
true
;
}
if
(
operationSequencing
!=
null
)
{
copy
.
operationSequencing
=
new
CopyOnWriteArrayList
<>(
operationSequencing
);
copy
.
operationStrDirty
=
true
;
}
copy
.
geneStrDirty
=
true
;
if
(
Objectives
!=
null
)
copy
.
Objectives
=
Arrays
.
copyOf
(
Objectives
,
Objectives
.
length
);
if
(
WeightedObjectives
!=
null
)
copy
.
WeightedObjectives
=
Arrays
.
copyOf
(
WeightedObjectives
,
WeightedObjectives
.
length
);
if
(
fitnessLevel
!=
null
)
copy
.
fitnessLevel
=
Arrays
.
copyOf
(
fitnessLevel
,
fitnessLevel
.
length
);
if
(
LowerBoundObjectives
!=
null
)
copy
.
LowerBoundObjectives
=
Arrays
.
copyOf
(
LowerBoundObjectives
,
LowerBoundObjectives
.
length
);
copy
.
WeightedObjective
=
WeightedObjective
;
copy
.
Makespan
=
Makespan
;
copy
.
TotalFlowTime
=
TotalFlowTime
;
copy
.
TotalChangeoverTime
=
TotalChangeoverTime
;
copy
.
MachineLoadStd
=
MachineLoadStd
;
copy
.
Fitness
=
Fitness
;
copy
.
Rank
=
Rank
;
copy
.
CrowdingDistance
=
CrowdingDistance
;
copy
.
gsOrls
=
gsOrls
;
copy
.
generateType
=
generateType
+
"_copy"
;
copy
.
globalParamSnapshot
=
globalParamSnapshot
;
copy
.
objectiveWeights
=
objectiveWeights
;
copy
.
globalOpList
=
globalOpList
;
copy
.
allOperations
=
allOperations
;
copy
.
orders
=
orders
;
copy
.
InitMachines
=
InitMachines
;
copy
.
materials
=
materials
;
copy
.
materialIds
=
materialIds
;
copy
.
OperatRel
=
OperatRel
;
copy
.
orderMaterials
=
orderMaterials
;
copy
.
Machines
=
Machines
;
if
(
Result
!=
null
)
copy
.
Result
=
new
CopyOnWriteArrayList
<>(
Result
);
return
copy
;
}
}
src/main/java/com/aps/entity/basic/Entry.java
View file @
41cab0d7
...
...
@@ -85,6 +85,9 @@ public class Entry {
* 工序顺序
*/
private
int
sequence
;
private
double
minProcessingTime
;
// 加工时间 (秒)
/**
* 可选设备列表
*/
...
...
src/main/java/com/aps/service/Algorithm/AdaptiveLargeNeighborhoodSearch.java
0 → 100644
View file @
41cab0d7
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/service/Algorithm/CpSatFjspModel.java
View file @
41cab0d7
package
com
.
aps
.
service
.
Algorithm
;
import
com.aps.common.util.FileHelper
;
import
com.aps.entity.Algorithm.Chromosome
;
import
com.aps.entity.Algorithm.GlobalOperationInfo
;
import
com.aps.entity.basic.Entry
;
import
com.aps.entity.basic.Machine
;
import
com.aps.entity.basic.MachineOption
;
import
com.aps.entity.basic.Order
;
import
com.google.ortools.Loader
;
import
com.google.ortools.sat.CpModel
;
import
com.google.ortools.sat.CpSolver
;
...
...
@@ -16,6 +18,7 @@ import com.google.ortools.sat.LinearExpr;
import
com.google.ortools.sat.Literal
;
import
java.time.LocalDateTime
;
import
java.time.temporal.ChronoUnit
;
import
java.util.*
;
import
java.util.concurrent.CopyOnWriteArrayList
;
...
...
@@ -48,6 +51,9 @@ public class CpSatFjspModel {
private
final
List
<
Machine
>
machines
;
private
final
List
<
GlobalOperationInfo
>
globalOpList
;
private
final
List
<
Entry
>
allOperations
;
private
final
LocalDateTime
baseTime
;
private
final
List
<
Order
>
orders
;
private
final
int
operationCount
;
private
CpModel
model
;
...
...
@@ -61,11 +67,14 @@ public class CpSatFjspModel {
public
CpSatFjspModel
(
List
<
GlobalOperationInfo
>
globalOpList
,
List
<
Entry
>
allOperations
,
List
<
Machine
>
machines
,
List
<
Order
>
orders
,
LocalDateTime
baseTime
)
{
this
.
globalOpList
=
globalOpList
;
this
.
allOperations
=
allOperations
;
this
.
machines
=
machines
;
this
.
operationCount
=
globalOpList
.
size
();
this
.
orders
=
orders
;
this
.
baseTime
=
baseTime
;
}
private
int
estimateHorizon
()
{
...
...
@@ -221,28 +230,90 @@ public class CpSatFjspModel {
globalOpList
.
get
(
i
).
getOp
().
getPriority
());
}
int
priorityTerms
=
0
;
for
(
int
i
=
0
;
i
<
operationCount
;
i
++)
{
if
(
globalOpList
.
get
(
i
).
getOp
().
getPriority
()
>
0
)
priorityTerms
++;
}
List
<
LinearArgument
>
objTerms
=
new
ArrayList
<>();
List
<
Long
>
objWeights
=
new
ArrayList
<>();
LinearArgument
[]
objVars
=
new
LinearArgument
[
1
+
priorityTerms
];
long
[]
objCoeffs
=
new
long
[
1
+
priorityTerms
];
objVars
[
0
]
=
makespanVar
;
objCoeffs
[
0
]
=
100
;
objTerms
.
add
(
makespanVar
);
objWeights
.
add
(
100L
);
int
t
=
1
;
for
(
int
i
=
0
;
i
<
operationCount
;
i
++)
{
double
priority
=
globalOpList
.
get
(
i
).
getOp
().
getPriority
();
if
(
priority
>
0
)
{
objVars
[
t
]
=
endVars
.
get
(
i
);
objCoeffs
[
t
]
=
(
long
)(
maxPriority
-
priority
+
1
);
t
++;
objTerms
.
add
(
endVars
.
get
(
i
));
objWeights
.
add
((
long
)(
maxPriority
-
priority
+
1
));
}
}
model
.
minimize
(
LinearExpr
.
weightedSum
(
objVars
,
objCoeffs
));
}
// ==================== 新增目标1:Tardiness(延迟时间) ====================
// 按订单分组,找到每个订单最后一道工序的end_time
Map
<
Integer
,
List
<
Integer
>>
groupOps
=
new
LinkedHashMap
<>();
Map
<
Integer
,
Long
>
groupDueDates
=
new
HashMap
<>();
for
(
int
i
=
0
;
i
<
operationCount
;
i
++)
{
GlobalOperationInfo
info
=
globalOpList
.
get
(
i
);
int
groupId
=
info
.
getGroupId
();
groupOps
.
computeIfAbsent
(
groupId
,
k
->
new
ArrayList
<>()).
add
(
i
);
if
(!
groupDueDates
.
containsKey
(
groupId
))
{
Order
order
=
orders
.
stream
()
.
filter
(
o
->
info
.
getOp
().
getOrderId
().
equals
(
o
.
getOrderId
()))
.
findFirst
().
orElse
(
null
);
if
(
order
!=
null
&&
order
.
getDueDate
()
!=
null
)
{
long
dueMin
=
ChronoUnit
.
MINUTES
.
between
(
baseTime
,
order
.
getDueDate
());
groupDueDates
.
put
(
groupId
,
dueMin
*
60
);
}
}
}
long
totalTardinessWeight
=
80L
;
for
(
Map
.
Entry
<
Integer
,
List
<
Integer
>>
entry
:
groupOps
.
entrySet
())
{
int
groupId
=
entry
.
getKey
();
List
<
Integer
>
opIndices
=
entry
.
getValue
();
// 找到该订单最后完成的工序
IntVar
lastEnd
=
model
.
newIntVar
(
0
,
horizonSeconds
,
"lastEnd_g"
+
groupId
);
List
<
LinearArgument
>
endCandidates
=
new
ArrayList
<>();
for
(
int
idx
:
opIndices
)
{
endCandidates
.
add
(
endVars
.
get
(
idx
));
}
model
.
addMaxEquality
(
lastEnd
,
endCandidates
.
toArray
(
new
LinearArgument
[
0
]));
Long
dueDateSec
=
groupDueDates
.
get
(
groupId
);
if
(
dueDateSec
!=
null
)
{
IntVar
tardiness
=
model
.
newIntVar
(
0
,
horizonSeconds
,
"tardiness_g"
+
groupId
);
LinearArgument
diff
=
LinearExpr
.
sum
(
new
LinearArgument
[]{
lastEnd
,
LinearExpr
.
constant
(-
dueDateSec
)});
model
.
addMaxEquality
(
tardiness
,
new
LinearArgument
[]{
diff
,
LinearExpr
.
constant
(
0
)});
objTerms
.
add
(
tardiness
);
objWeights
.
add
(
totalTardinessWeight
);
}
}
// ==================== 新增目标2:Machine Load Balance(负载均衡) ====================
// 简化版本:取每台机器上所有工序的最大end_time,加入目标函数
// 这样 CP-SAT 会倾向于让各机器的完工时间更均匀
Map
<
Long
,
List
<
LinearArgument
>>
machineEndTimes
=
new
HashMap
<>();
for
(
int
i
=
0
;
i
<
operationCount
;
i
++)
{
GlobalOperationInfo
info
=
globalOpList
.
get
(
i
);
List
<
MachineOption
>
options
=
info
.
getOp
().
getMachineOptions
();
if
(
options
==
null
||
options
.
isEmpty
())
continue
;
for
(
MachineOption
mo
:
options
)
{
machineEndTimes
.
computeIfAbsent
(
mo
.
getMachineId
(),
k
->
new
ArrayList
<>()).
add
(
endVars
.
get
(
i
));
}
}
long
loadBalanceWeight
=
30L
;
for
(
Map
.
Entry
<
Long
,
List
<
LinearArgument
>>
entry
:
machineEndTimes
.
entrySet
())
{
IntVar
machineMakespan
=
model
.
newIntVar
(
0
,
horizonSeconds
,
"mk_m"
+
entry
.
getKey
());
model
.
addMaxEquality
(
machineMakespan
,
entry
.
getValue
().
toArray
(
new
LinearArgument
[
0
]));
objTerms
.
add
(
machineMakespan
);
objWeights
.
add
(
loadBalanceWeight
);
}
model
.
minimize
(
LinearExpr
.
weightedSum
(
objTerms
.
toArray
(
new
LinearArgument
[
0
]),
objWeights
.
stream
().
mapToLong
(
Long:
:
longValue
).
toArray
()));
}
private
boolean
enableLogging
=
true
;
/**
* 单次求解,返回一个 Chromosome
*/
...
...
@@ -258,8 +329,13 @@ public class CpSatFjspModel {
CpSolverStatus
status
=
solver
.
solve
(
model
);
if
(
status
==
CpSolverStatus
.
OPTIMAL
||
status
==
CpSolverStatus
.
FEASIBLE
)
{
long
makespanSec
=
(
long
)
solver
.
value
(
makespanVar
);
FileHelper
.
log
(
"[CpSatFjsp] 单次求解 状态="
+
status
+
" CP-SAT目标值="
+
String
.
format
(
"%,d"
,
(
long
)
solver
.
objectiveValue
())
+
" makespan="
+
String
.
format
(
"%,d秒 (%.1f小时)"
,
makespanSec
,
makespanSec
/
3600.0
),
enableLogging
);
return
extractChromosome
(
solver
);
}
FileHelper
.
log
(
"[CpSatFjsp] 单次求解 状态="
+
status
+
"(无解)"
,
enableLogging
);
return
null
;
}
...
...
@@ -328,15 +404,22 @@ public class CpSatFjspModel {
CpSolverStatus
status
=
solver
.
solve
(
model
);
if
(
status
==
CpSolverStatus
.
OPTIMAL
||
status
==
CpSolverStatus
.
FEASIBLE
)
{
long
msSec
=
(
long
)
solver
.
value
(
makespanVar
);
FileHelper
.
log
(
"[CpSatFjsp] 第"
+
(
round
+
1
)
+
"轮 状态="
+
status
+
" CP-SAT目标="
+
String
.
format
(
"%,d"
,
(
long
)
solver
.
objectiveValue
())
+
" makespan="
+
String
.
format
(
"%,d秒(%.1f小时)"
,
msSec
,
msSec
/
3600.0
),
enableLogging
);
Chromosome
chromo
=
extractChromosome
(
solver
);
if
(
chromo
!=
null
&&
!
containsDuplicate
(
results
,
chromo
))
{
chromo
.
setGsOrls
(
4
);
chromo
.
setGenerateType
(
"CP-SAT"
);
results
.
add
(
chromo
);
}
}
else
{
FileHelper
.
log
(
"[CpSatFjsp] 第"
+
(
round
+
1
)
+
"轮 状态="
+
status
+
"(无解)"
,
enableLogging
);
}
}
FileHelper
.
log
(
"[CpSatFjsp] 多样性解生成完成,共"
+
results
.
size
()
+
"个解"
,
enableLogging
);
return
results
;
}
...
...
src/main/java/com/aps/service/Algorithm/CpSatInitializer.java
View file @
41cab0d7
...
...
@@ -93,7 +93,7 @@ public class CpSatInitializer {
*/
private
List
<
Chromosome
>
smallScaleSolve
(
List
<
GlobalOperationInfo
>
globalOpList
,
int
targetCount
,
int
timeBudgetSec
)
{
CpSatFjspModel
model
=
new
CpSatFjspModel
(
globalOpList
,
allOperations
,
machines
,
baseTime
);
CpSatFjspModel
model
=
new
CpSatFjspModel
(
globalOpList
,
allOperations
,
machines
,
orders
,
baseTime
);
return
model
.
generateDiverseSolutions
(
Math
.
min
(
targetCount
,
8
),
timeBudgetSec
,
true
);
}
...
...
@@ -103,7 +103,7 @@ public class CpSatInitializer {
*/
private
List
<
Chromosome
>
mediumScaleSolve
(
List
<
GlobalOperationInfo
>
globalOpList
,
int
targetCount
,
int
timeBudgetSec
)
{
CpSatFjspModel
model
=
new
CpSatFjspModel
(
globalOpList
,
allOperations
,
machines
,
baseTime
);
CpSatFjspModel
model
=
new
CpSatFjspModel
(
globalOpList
,
allOperations
,
machines
,
orders
,
baseTime
);
int
effectiveTarget
=
Math
.
min
(
targetCount
,
5
);
int
perSolveTime
=
Math
.
max
(
timeBudgetSec
,
15
);
return
model
.
generateDiverseSolutions
(
effectiveTarget
,
perSolveTime
,
true
);
...
...
@@ -158,7 +158,7 @@ public class CpSatInitializer {
}
CpSatFjspModel
model
=
new
CpSatFjspModel
(
bottleneckOps
,
allOperations
,
bottleneckMachines
,
baseTime
);
bottleneckOps
,
allOperations
,
bottleneckMachines
,
orders
,
baseTime
);
List
<
Chromosome
>
cpSatResults
=
model
.
generateDiverseSolutions
(
effectiveTarget
,
timeBudgetSec
,
true
);
...
...
src/main/java/com/aps/service/Algorithm/CpSatLnsNeighborhood.java
0 → 100644
View file @
41cab0d7
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
41cab0d7
...
...
@@ -695,11 +695,6 @@ public class GeneticDecoder {
int
scheduledCount
=
orderProcessCounter
.
get
(
groupId
);
if
(
groupId
==
7
)
{
int
k
=
0
;
}
List
<
Entry
>
orderOps
=
new
ArrayList
<>();
boolean
orderIsJit
=
orderDueDate
.
get
(
groupId
)>
0
;
...
...
@@ -743,7 +738,7 @@ public class GeneticDecoder {
}
else
{
orderAnchor
=
bom
.
computeSemiFinishedAnchor
(
this
,
groupId
,
entrysBygroupId
,
opMachineKeyMap
,
chromosome
,
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
_globalParam
.
isIsCheckMp
());
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
_globalParam
.
isIsCheckMp
()
,
null
);
if
(
orderAnchor
<
0
)
{
orderIsJit
=
false
;
orderSchedulingInfo
.
put
(
groupId
,
...
...
@@ -3524,6 +3519,7 @@ if(geneDetails!=null&&geneDetails.size()>0)
private
void
calculateScheduleResult
(
Chromosome
chromosome
)
{
double
[]
Objectives
=
new
double
[
_globalParam
.
getObjectiveWeights
().
size
()];
double
[]
weights
=
new
double
[
_globalParam
.
getObjectiveWeights
().
size
()];
int
i
=
0
;
for
(
ObjectiveConfig
config
:
_globalParam
.
getObjectiveConfigs
())
{
...
...
@@ -3535,7 +3531,9 @@ if(geneDetails!=null&&geneDetails.size()>0)
.
max
()
.
orElse
(
0
);
Objectives
[
i
]
=
makespan
;
weights
[
i
]
=
config
.
getWeight
();
chromosome
.
setMakespan
(
makespan
);
}
if
(
GlobalParam
.
OBJECTIVE_TARDINESS
.
equals
(
config
.
getName
()))
{
// 2. 交付期满足情况(最小化延迟)
...
...
@@ -3604,6 +3602,16 @@ if(geneDetails!=null&&geneDetails.size()>0)
}
chromosome
.
setObjectives
(
Objectives
);
// 计算各 KPI 的理论下界(用于计算 Gap = (current - lowerBound) / lowerBound)
try
{
KpiLowerBoundCalculator
.
computeAndSetLowerBounds
(
chromosome
,
_globalParam
);
}
catch
(
Exception
e
)
{
// 下界计算异常不应影响主流程
com
.
aps
.
common
.
util
.
FileHelper
.
writeLogFile
(
"KPI 下界计算异常: "
+
e
.
getClass
().
getSimpleName
()
+
" - "
+
e
.
getMessage
());
}
FitnessCalculator
fitnessCalculator
=
new
FitnessCalculator
();
chromosome
.
setFitnessLevel
(
fitnessCalculator
.
calculateFitness
(
chromosome
,
_globalParam
));
...
...
src/main/java/com/aps/service/Algorithm/HillClimbing.java
View file @
41cab0d7
...
...
@@ -76,7 +76,7 @@ public class HillClimbing {
Chromosome
current
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
Chromosome
best
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
decoder
.
DelOrder
(
current
);
// 构建位置索引映射:groupId_sequence -> position
Map
<
String
,
Integer
>
positionIndex
=
buildPositionIndex
(
current
);
...
...
@@ -119,7 +119,7 @@ public class HillClimbing {
positionIndex
=
buildPositionIndex
(
current
);
entryIndex
=
buildEntryIndex
(
current
,
entrys
);
MachinePositionIndex
=
buildEntryMachinePositionIndex
(
current
);
decoder
.
DelOrder
(
current
);
//
decoder.DelOrder(current);
break
;
}
}
...
...
src/main/java/com/aps/service/Algorithm/HybridAlgorithm.java
View file @
41cab0d7
...
...
@@ -49,6 +49,8 @@ public class HybridAlgorithm {
private
String
sceneId
;
private
VariableNeighborhoodSearch
_vns
;
private
AdaptiveLargeNeighborhoodSearch
_ALNS
;
// 初始化算法实例
private
HillClimbing
_hillClimbing
;
private
SimulatedAnnealing
_simulatedAnnealing
;
...
...
@@ -116,6 +118,7 @@ public class HybridAlgorithm {
// 初始化变邻域搜索
_vns
=
new
VariableNeighborhoodSearch
(
allOperations
,
orders
,
materials
,
_entryRel
,
_fitnessCalculator
);
_vns
.
initMachineSelectFrequency
();
_ALNS
=
new
AdaptiveLargeNeighborhoodSearch
(
allOperations
,
orders
,
materials
,
_entryRel
,
_fitnessCalculator
);
_hillClimbing
=
new
HillClimbing
(
allOperations
,
orders
,
materials
,
_entryRel
,
_fitnessCalculator
);
_simulatedAnnealing
=
new
SimulatedAnnealing
(
allOperations
,
orders
,
materials
,
_entryRel
,
_fitnessCalculator
);
_tabuSearch
=
new
TabuSearch
(
allOperations
,
orders
,
materials
,
_entryRel
,
_fitnessCalculator
);
...
...
@@ -148,6 +151,26 @@ public class HybridAlgorithm {
if
(
population
==
null
||
population
.
isEmpty
())
{
throw
new
RuntimeException
(
"初始种群为空,请检查 populationSize、种群初始化和解码结果"
);
}
if
(
_GlobalParam
.
isOptimizer
())
{
FileHelper
.
writeLogFile
(
"LNS-CPSAT 邻域重优化-----------开始-------种群="
+
population
.
size
());
try
{
CpSatLnsNeighborhood
lns
=
new
CpSatLnsNeighborhood
(
allOperations
,
machines
,
orders
,
materials
,
_entryRel
,
_fitnessCalculator
);
List
<
Chromosome
>
lnsResult
=
lns
.
runLnsOnParetoFront
(
population
,
sharedDecoder
);
if
(
lnsResult
!=
null
&&
!
lnsResult
.
isEmpty
())
{
// Chromosomedecode(sharedDecoder, param, allOperations, globalOpList, lnsResult);
population
=
chromosomeDistinctByObjectives
(
lnsResult
);
if
(
population
==
null
||
population
.
isEmpty
())
{
population
=
lnsResult
;
}
}
}
catch
(
Throwable
t
)
{
FileHelper
.
writeLogFile
(
"LNS-CPSAT 失败,跳过:"
+
t
.
getMessage
());
}
FileHelper
.
writeLogFile
(
"LNS-CPSAT 邻域重优化-----------结束-------种群="
+
(
population
==
null
?
0
:
population
.
size
()));
}
// if(1==1)
// return getBestChromosome(population.get(0), param.getBaseTime(), starttime);
// 步骤2:对初始种群进行爬山法局部优化
...
...
@@ -178,9 +201,9 @@ public class HybridAlgorithm {
return
getBestChromosome
(
saHcOptimized
,
param
.
getBaseTime
(),
starttime
);
}
if
(
opcount
>
=
8
00
)
{
if
(
opcount
>
800
&&
opcount
<
20
00
)
{
Chromosome
best
=
population
.
get
(
0
);
best
=
_ALNS
.
search
(
best
,
_tabuSearch
,
_vns
,
sharedDecoder
,
machines
);
best
=
_simulatedAnnealing
.
search
(
best
,
_tabuSearch
,
_vns
,
sharedDecoder
,
machines
);
best
=
_vns
.
search
(
best
,
_tabuSearch
,
sharedDecoder
,
machines
);
...
...
@@ -189,6 +212,29 @@ public class HybridAlgorithm {
return
getBestChromosome
(
best
,
param
.
getBaseTime
(),
starttime
);
}
else
{
Chromosome
best
=
population
.
get
(
0
);
int
topN
=
Math
.
min
(
3
,
population
.
size
());
for
(
int
iter
=
0
;
iter
<
topN
;
iter
++)
{
FileHelper
.
writeLogFile
(
"迭代进化------"
+
iter
+
"-----开始-------"
);
System
.
gc
();
Chromosome
chromosome
=
population
.
get
(
iter
);
chromosome
=
_ALNS
.
search
(
chromosome
,
_tabuSearch
,
_vns
,
sharedDecoder
,
machines
);
chromosome
=
_simulatedAnnealing
.
search
(
chromosome
,
_tabuSearch
,
_vns
,
sharedDecoder
,
machines
);
chromosome
=
_vns
.
search
(
chromosome
,
_tabuSearch
,
sharedDecoder
,
machines
);
if
(
_fitnessCalculator
.
isBetter
(
chromosome
,
best
))
{
FileHelper
.
writeLogFile
(
"迭代进化------发现更优解-----------"
);
writeKpi
(
chromosome
);
best
=
chromosome
;
}
FileHelper
.
writeLogFile
(
"迭代进化------"
+
iter
+
"-----结束-------"
);
// 周期性 GC 释放内存
System
.
gc
();
}
}
...
...
@@ -514,7 +560,47 @@ public class HybridAlgorithm {
// }
}
private
void
writeKpi
(
Chromosome
chromosome
)
{
String
fitness
=
""
;
double
[]
fitness1
=
chromosome
.
getFitnessLevel
();
if
(
fitness1
!=
null
)
{
for
(
int
i
=
0
;
i
<
fitness1
.
length
;
i
++)
{
fitness
+=
fitness1
[
i
]
+
","
;
}
}
else
{
fitness
=
"null (未计算)"
;
}
log
(
String
.
format
(
"变邻域搜索 - kpi:%s"
,
fitness
),
true
);
if
(
chromosome
.
getMakespan
()!=
0
)
{
log
(
String
.
format
(
"变邻域搜索 - kpi-Makespan: %f"
,
chromosome
.
getMakespan
()));
}
if
(
chromosome
.
getDelayTime
()!=
0
)
{
log
(
String
.
format
(
"变邻域搜索 - kpi-DelayTime: %f"
,
chromosome
.
getDelayTime
()));
}
if
(
chromosome
.
getTotalChangeoverTime
()!=
0
)
{
log
(
String
.
format
(
"变邻域搜索 - kpi-ChangeoverTime: %f"
,
chromosome
.
getTotalChangeoverTime
()));
}
if
(
chromosome
.
getMachineLoadStd
()!=
0
)
{
log
(
String
.
format
(
"变邻域搜索 - kpi-MachineLoad: %f"
,
chromosome
.
getMachineLoadStd
()));
}
if
(
chromosome
.
getTotalFlowTime
()!=
0
)
{
log
(
String
.
format
(
"变邻域搜索 - kpi-FlowTime: %f"
,
chromosome
.
getTotalFlowTime
()));
}
// ==================== 打印各 KPI 的 Gap ====================
log
(
KpiLowerBoundCalculator
.
generateGapReport
(
chromosome
));
}
private
void
log
(
String
message
)
{
log
(
message
,
true
);
}
private
void
log
(
String
message
,
boolean
enableLogging
)
{
if
(
enableLogging
)
{
FileHelper
.
writeLogFile
(
message
);
}
}
}
src/main/java/com/aps/service/Algorithm/Initialization.java
View file @
41cab0d7
...
...
@@ -1137,9 +1137,15 @@ public class Initialization {
List
<
Chromosome
>
heuristicPopulation
=
generateHeuristicInitialPopulation
(
subParam
,
remaining
);
for
(
Chromosome
chromo
:
heuristicPopulation
)
{
chromo
.
setOrders
(
new
CopyOnWriteArrayList
<>(
orders
));
if
(
chromo
!=
null
)
{
chromo
.
setOrders
(
new
CopyOnWriteArrayList
<>(
orders
));
population
.
add
(
chromo
);
}
}
population
.
addAll
(
heuristicPopulation
);
}
long
cpSatCount
=
population
.
stream
()
...
...
src/main/java/com/aps/service/Algorithm/KpiLowerBoundCalculator.java
0 → 100644
View file @
41cab0d7
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/service/Algorithm/RoutingDataService.java
View file @
41cab0d7
...
...
@@ -265,6 +265,7 @@ public class RoutingDataService {
List
<
ProdEquipment
>
Equipments
=
ProdEquipments
.
stream
()
.
filter
(
t
->
t
.
getExecId
().
equals
(
op
.
getExecId
()))
.
collect
(
Collectors
.
toList
());
double
minProcessingTime
=
999999999
;
if
(
Equipments
!=
null
&&
Equipments
.
size
()
>
0
)
{
List
<
MachineOption
>
mos
=
new
ArrayList
<>();
for
(
ProdEquipment
e
:
Equipments
)
{
...
...
@@ -277,7 +278,7 @@ public class RoutingDataService {
totalprocessTime
=
e
.
getSpeed
()/
e
.
getSingleOut
().
doubleValue
()*
entry
.
getQuantity
();
}
minProcessingTime
=
Math
.
min
(
minProcessingTime
,
totalprocessTime
);
if
(
machineIds
.
containsKey
(
e
.
getEquipId
()))
{
if
(
machineIds
.
get
(
e
.
getEquipId
())<
totalprocessTime
)
...
...
@@ -307,6 +308,7 @@ public class RoutingDataService {
mos
.
add
(
mo
);
}
entry
.
setMinProcessingTime
(
minProcessingTime
);
entry
.
setMachineOptions
(
mos
);
}
}
...
...
src/main/java/com/aps/service/Algorithm/SimulatedAnnealing.java
View file @
41cab0d7
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/service/Algorithm/VariableNeighborhoodSearch.java
View file @
41cab0d7
This diff is collapsed.
Click to expand it.
src/test/java/com/aps/demo/PlanResultServiceTest.java
View file @
41cab0d7
...
...
@@ -43,8 +43,8 @@ public class PlanResultServiceTest {
// planResultService.execute2("64E64F6B68094AF38CEDC418630C3CC2");//2000
// planResultService.execute2("E1448B3C9C8743DEAB39708F2CFE348A");//倒排bomces
// planResultService.execute2("197083D0D26A449EB179AC103C753FD3
");
planResultService
.
execute2
(
"F8F147BD627C47B1A190399DD7A697F6"
);
planResultService
.
execute2
(
"85DA28EC5F4643449E65A51253D5F127
"
);
//
planResultService.execute2("F8F147BD627C47B1A190399DD7A697F6");
// planResultService.execute2("9FEDFD92BB6A4675BF9B1CC64505D1AB");
...
...
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