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
3995638d
Commit
3995638d
authored
Apr 20, 2026
by
jidongtao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加注释
parent
73a7b529
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
85 additions
and
31 deletions
+85
-31
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+82
-31
MachineCalculator.java
...ain/java/com/aps/service/Algorithm/MachineCalculator.java
+3
-0
No files found.
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
3995638d
...
@@ -1106,11 +1106,18 @@ public class GeneticDecoder {
...
@@ -1106,11 +1106,18 @@ public class GeneticDecoder {
int
setupTime
=
0
;
int
setupTime
=
0
;
long
machineId
=
machine
.
getId
();
long
machineId
=
machine
.
getId
();
// 只有存在物料约束(或本次被强制要求重算 BOM)的工序,才需要联立求解“机台何时能排”和“物料何时可用”。
// targetFinishedOperationId != null 的工序通常由前置成品工序驱动,这里不再额外触发一轮 BOM 试算。
boolean
needMaterialCheck
=
(
operation
.
getMaterialRequirements
()!=
null
&&
operation
.
getMaterialRequirements
().
size
()>
0
&&
operation
.
getTargetFinishedOperationId
()==
null
)||
calbom
;
boolean
needMaterialCheck
=
(
operation
.
getMaterialRequirements
()!=
null
&&
operation
.
getMaterialRequirements
().
size
()>
0
&&
operation
.
getTargetFinishedOperationId
()==
null
)||
calbom
;
// 正式落排后还要再做一次带提交的物料校验,把试算阶段推导出的 BOM 状态真正写回 chromosome。
boolean
commitMaterialCheck
=
needMaterialCheck
;
boolean
commitMaterialCheck
=
needMaterialCheck
;
// baseEarliestStartTime:不考虑 BOM 推迟时的理论最早开工时间。
// candidateStartTime:固定点迭代时本轮尝试的开工时间。
// bomtime:按当前候选开工时间试算出来的物料最早可开工时间。
int
baseEarliestStartTime
=
earliestStartTime
;
int
baseEarliestStartTime
=
earliestStartTime
;
int
candidateStartTime
=
earliestStartTime
;
int
candidateStartTime
=
earliestStartTime
;
int
bomtime
=
0
;
int
bomtime
=
0
;
// 机台时间和物料时间可能会互相推动,最多迭代 maxSolveIterations 次来找收敛点。
int
maxSolveIterations
=
Math
.
max
(
1
,
_globalParam
.
getMaterialSolveMaxIterations
());
int
maxSolveIterations
=
Math
.
max
(
1
,
_globalParam
.
getMaterialSolveMaxIterations
());
boolean
converged
=
!
needMaterialCheck
;
boolean
converged
=
!
needMaterialCheck
;
Entry
scheduledOperation
=
operation
;
Entry
scheduledOperation
=
operation
;
...
@@ -1120,8 +1127,13 @@ public class GeneticDecoder {
...
@@ -1120,8 +1127,13 @@ public class GeneticDecoder {
MachineSchedulePreview
machinePreview
=
null
;
MachineSchedulePreview
machinePreview
=
null
;
CopyOnWriteArrayList
<
ScheduleResultDetail
>
geneDetails
=
new
CopyOnWriteArrayList
<>();
CopyOnWriteArrayList
<
ScheduleResultDetail
>
geneDetails
=
new
CopyOnWriteArrayList
<>();
// 固定点求解过程:
// 1. 先按 candidateStartTime 试排机台;
// 2. 再按试排结果试算物料/BOM 的最早可开工时间;
// 3. 如果物料时间继续把开工点往后推,就用新时间再次试排,直到收敛。
if
(
needMaterialCheck
)
{
if
(
needMaterialCheck
)
{
for
(
int
iteration
=
0
;
iteration
<
maxSolveIterations
;
iteration
++)
{
for
(
int
iteration
=
0
;
iteration
<
maxSolveIterations
;
iteration
++)
{
// trial BOM 试算会在内部恢复快照,因此每轮都重新从最新 chromosome 中取对象,避免拿到旧引用。
Entry
refreshedOperation
=
entryIndexById
.
get
(
operationId
);
Entry
refreshedOperation
=
entryIndexById
.
get
(
operationId
);
if
(
refreshedOperation
!=
null
)
{
if
(
refreshedOperation
!=
null
)
{
scheduledOperation
=
refreshedOperation
;
scheduledOperation
=
refreshedOperation
;
...
@@ -1137,13 +1149,15 @@ public class GeneticDecoder {
...
@@ -1137,13 +1149,15 @@ public class GeneticDecoder {
{
{
candidateStartTime
=
Math
.
max
(
candidateStartTime
,
lastGeneOnMachine
.
getEndTime
());
candidateStartTime
=
Math
.
max
(
candidateStartTime
,
lastGeneOnMachine
.
getEndTime
());
}
}
//
0 884400
//
先在机台侧做一次“试排”,geneDetails 中会记录本轮临时占用的机台时间段。
machinePreview
=
buildMachinePreview
(
scheduledOperation
,
scheduledMachine
,
processingTime
,
processingTimeTotal
,
machinePreview
=
buildMachinePreview
(
scheduledOperation
,
scheduledMachine
,
processingTime
,
processingTimeTotal
,
candidateStartTime
,
lastGeneOnMachine
,
machineTasks
,
chromosome
);
candidateStartTime
,
lastGeneOnMachine
,
machineTasks
,
chromosome
);
try
{
try
{
//
864000
//
物料侧只做试算,不提交最终状态;本轮只关心 BOM 约束会把开工时间推迟到哪里。
bomtime
=
EditOperationBOMTime
(
scheduledOperation
,
chromosome
,
machinePreview
.
getStartTime
(),
machineTasksCache
,
entryIndexById
,
scheduleIndexById
,
false
);
bomtime
=
EditOperationBOMTime
(
scheduledOperation
,
chromosome
,
machinePreview
.
getStartTime
(),
machineTasksCache
,
entryIndexById
,
scheduleIndexById
,
false
);
}
finally
{
}
finally
{
// buildMachinePreview 会临时锁住机台 availability,这里无论成功或异常都必须释放,
// 否则下一轮迭代会被本轮的试排残留状态污染。
Machine
liveMachineAfterTrial
=
getMachineById
(
chromosome
,
machineId
);
Machine
liveMachineAfterTrial
=
getMachineById
(
chromosome
,
machineId
);
if
(
liveMachineAfterTrial
!=
null
)
{
if
(
liveMachineAfterTrial
!=
null
)
{
AddMachineAvailable
(
liveMachineAfterTrial
,
machinePreview
.
getGeneDetails
());
AddMachineAvailable
(
liveMachineAfterTrial
,
machinePreview
.
getGeneDetails
());
...
@@ -1152,7 +1166,9 @@ public class GeneticDecoder {
...
@@ -1152,7 +1166,9 @@ public class GeneticDecoder {
}
}
}
}
// 下一轮候选开工时间取“基准最早开工”和“物料最早可开工”两者中的较晚值。
int
nextCandidateStartTime
=
Math
.
max
(
baseEarliestStartTime
,
bomtime
);
int
nextCandidateStartTime
=
Math
.
max
(
baseEarliestStartTime
,
bomtime
);
// 如果物料时间已经不再把机台试排结果往后推,说明机台时间与物料时间达成一致。
if
(
nextCandidateStartTime
<=
machinePreview
.
getStartTime
())
{
if
(
nextCandidateStartTime
<=
machinePreview
.
getStartTime
())
{
converged
=
true
;
converged
=
true
;
candidateStartTime
=
nextCandidateStartTime
;
candidateStartTime
=
nextCandidateStartTime
;
...
@@ -1161,6 +1177,7 @@ public class GeneticDecoder {
...
@@ -1161,6 +1177,7 @@ public class GeneticDecoder {
candidateStartTime
=
nextCandidateStartTime
;
candidateStartTime
=
nextCandidateStartTime
;
}
}
// 固定点求解结束后,用收敛得到的候选开工时间作为正式排产的最早开工时间。
earliestStartTime
=
candidateStartTime
;
earliestStartTime
=
candidateStartTime
;
Entry
refreshedOperation
=
entryIndexById
.
get
(
operationId
);
Entry
refreshedOperation
=
entryIndexById
.
get
(
operationId
);
if
(
refreshedOperation
!=
null
)
{
if
(
refreshedOperation
!=
null
)
{
...
@@ -1176,35 +1193,35 @@ public class GeneticDecoder {
...
@@ -1176,35 +1193,35 @@ public class GeneticDecoder {
lastGeneOnMachine
=
getLastMachineTask
(
machineTasks
);
lastGeneOnMachine
=
getLastMachineTask
(
machineTasks
);
needMaterialCheck
=
false
;
needMaterialCheck
=
false
;
}
}
// 旧兜底单次试算路径:当前固定点迭代执行完后会把 needMaterialCheck 置为 false,
// 因此这段分支实际上不会再进入。先注释保留,后续若确认无用可直接删除,
// 或按真实意图改成 !converged 时的兜底处理。
if
(
needMaterialCheck
)
{
//
if(needMaterialCheck) {
int
earliestStartTimeold
=
earliestStartTime
;
//
int earliestStartTimeold=earliestStartTime;
if
(
_globalParam
.
is_smoothChangeOver
())
{
//
if (_globalParam.is_smoothChangeOver()) {
//
Map
<
Integer
,
Object
>
reslte
=
calculateSetupTime
(
lastGeneOnMachine
,
operation
,
machine
,
earliestStartTime
,
processingTimeTotal
,
_globalParam
.
is_smoothChangeOverInWeek
(),
chromosome
.
getAllOperations
());
//
Map<Integer, Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine, earliestStartTime, processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(), chromosome.getAllOperations());
// setupTime = (int) reslte.get(1);//换型时间
//
// setupTime = (int) reslte.get(1);//换型时间
// int setupStartTime = (int) reslte.get(2);//换型开始时间
//
// int setupStartTime = (int) reslte.get(2);//换型开始时间
//earliestStartTime=(int)reslte.get(3);//上个任务的结束时间
//
//earliestStartTime=(int)reslte.get(3);//上个任务的结束时间
earliestStartTime
=
(
int
)
reslte
.
get
(
4
);
//最早开工时间
//
earliestStartTime = (int) reslte.get(4);//最早开工时间
}
//
}
LocalDateTime
startTime1
=
baseTime
.
plus
(
earliestStartTime
,
ChronoUnit
.
SECONDS
);
//
LocalDateTime startTime1 = baseTime.plus(earliestStartTime, ChronoUnit.SECONDS);
//
TimeSegment
slot
=
machineCalculator
.
GetCurrentOrNextShift
(
machine
,
startTime1
,
""
,
false
);
//
TimeSegment slot = machineCalculator.GetCurrentOrNextShift(machine, startTime1, "", false);
//
if
(
slot
!=
null
)
//
if(slot!=null)
{
//
{
earliestStartTime
=
slot
.
getStart
().
isAfter
(
startTime1
)
//
earliestStartTime = slot.getStart().isAfter(startTime1)
?(
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
slot
.
getStart
())
//
?(int) ChronoUnit.SECONDS.between(baseTime, slot.getStart())
:
earliestStartTime
;
//
: earliestStartTime;
//
}
//
}
bomtime
=
EditOperationBOMTime
(
operation
,
chromosome
,
earliestStartTime
,
machineTasksCache
,
entryIndexById
,
scheduleIndexById
,
false
);
//
bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache, entryIndexById, scheduleIndexById, false);
//
//
earliestStartTime
=
Math
.
max
(
earliestStartTime
,
bomtime
);
//
earliestStartTime = Math.max(earliestStartTime, bomtime);
}
//
}
// machineTasks =chromosome.getResult().stream()
// machineTasks =chromosome.getResult().stream()
...
@@ -1214,11 +1231,14 @@ public class GeneticDecoder {
...
@@ -1214,11 +1231,14 @@ public class GeneticDecoder {
//
//
// machineTasksCache.put(machine.getId(), machineTasks);
// machineTasksCache.put(machine.getId(), machineTasks);
// 正式落排前,再取一次当前机台最后一道工序,保证换型计算基于最新排程结果。
if
(
machineTasks
!=
null
&&
machineTasks
.
size
()>
0
&&
_globalParam
.
is_smoothChangeOver
())
if
(
machineTasks
!=
null
&&
machineTasks
.
size
()>
0
&&
_globalParam
.
is_smoothChangeOver
())
{
{
lastGeneOnMachine
=
machineTasks
.
get
(
machineTasks
.
size
()-
1
);
lastGeneOnMachine
=
machineTasks
.
get
(
machineTasks
.
size
()-
1
);
}
}
// 下面开始生成正式的 geneDetails。
// 与 buildMachinePreview 的区别是:这里得到的结果会继续向下写入 GAScheduleResult,成为真正排程结果。
if
(
_globalParam
.
is_smoothChangeOver
())
{
if
(
_globalParam
.
is_smoothChangeOver
())
{
//是否考虑换型时间
//是否考虑换型时间
Map
<
Integer
,
Object
>
reslte
=
calculateSetupTime
(
lastGeneOnMachine
,
operation
,
machine
,
earliestStartTime
,
processingTimeTotal
,
_globalParam
.
is_smoothChangeOverInWeek
(),
chromosome
.
getAllOperations
());
Map
<
Integer
,
Object
>
reslte
=
calculateSetupTime
(
lastGeneOnMachine
,
operation
,
machine
,
earliestStartTime
,
processingTimeTotal
,
_globalParam
.
is_smoothChangeOverInWeek
(),
chromosome
.
getAllOperations
());
...
@@ -1290,6 +1310,9 @@ public class GeneticDecoder {
...
@@ -1290,6 +1310,9 @@ public class GeneticDecoder {
// 准备工时 加入到加工时间里
// 准备工时 加入到加工时间里
// 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间
// 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间
// 正式提交 BOM 校验:
// 1. 按最终 startTime 重新计算一次物料占用,并把状态真正写回;
// 2. 如果提交后的 BOM 时间仍然晚于 startTime,说明机台时间与物料时间没有收敛,需要直接报错。
if
(
commitMaterialCheck
)
{
if
(
commitMaterialCheck
)
{
int
committedBomTime
=
EditOperationBOMTime
(
operation
,
chromosome
,
startTime
,
machineTasksCache
,
entryIndexById
,
scheduleIndexById
,
true
);
int
committedBomTime
=
EditOperationBOMTime
(
operation
,
chromosome
,
startTime
,
machineTasksCache
,
entryIndexById
,
scheduleIndexById
,
true
);
bomtime
=
Math
.
max
(
bomtime
,
committedBomTime
);
bomtime
=
Math
.
max
(
bomtime
,
committedBomTime
);
...
@@ -1407,6 +1430,10 @@ public class GeneticDecoder {
...
@@ -1407,6 +1430,10 @@ public class GeneticDecoder {
}
}
}
}
/**
* 按当前候选开工时间做一次机台侧试排。
* 注意:该方法会临时占用 machine.availability 中对应的时段,调用方用完后必须配合 AddMachineAvailable 释放。
*/
private
MachineSchedulePreview
buildMachinePreview
(
Entry
operation
,
Machine
machine
,
double
processingTime
,
int
processingTimeTotal
,
private
MachineSchedulePreview
buildMachinePreview
(
Entry
operation
,
Machine
machine
,
double
processingTime
,
int
processingTimeTotal
,
int
earliestStartTime
,
GAScheduleResult
lastGeneOnMachine
,
int
earliestStartTime
,
GAScheduleResult
lastGeneOnMachine
,
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
,
Chromosome
chromosome
)
{
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
,
Chromosome
chromosome
)
{
...
@@ -1416,6 +1443,7 @@ public class GeneticDecoder {
...
@@ -1416,6 +1443,7 @@ public class GeneticDecoder {
CopyOnWriteArrayList
<
ScheduleResultDetail
>
geneDetails
;
CopyOnWriteArrayList
<
ScheduleResultDetail
>
geneDetails
;
if
(
_globalParam
.
is_smoothChangeOver
())
{
if
(
_globalParam
.
is_smoothChangeOver
())
{
// 先把换型时间、换型起点以及加工总时长修正到当前候选时间点。
Map
<
Integer
,
Object
>
reslte
=
calculateSetupTime
(
lastGeneOnMachine
,
operation
,
machine
,
previewStart
,
previewProcessingTotal
,
_globalParam
.
is_smoothChangeOverInWeek
(),
chromosome
.
getAllOperations
());
Map
<
Integer
,
Object
>
reslte
=
calculateSetupTime
(
lastGeneOnMachine
,
operation
,
machine
,
previewStart
,
previewProcessingTotal
,
_globalParam
.
is_smoothChangeOverInWeek
(),
chromosome
.
getAllOperations
());
setupTime
=(
int
)
reslte
.
get
(
1
);
setupTime
=(
int
)
reslte
.
get
(
1
);
int
setupStartTime
=(
int
)
reslte
.
get
(
2
);
int
setupStartTime
=(
int
)
reslte
.
get
(
2
);
...
@@ -1423,10 +1451,12 @@ public class GeneticDecoder {
...
@@ -1423,10 +1451,12 @@ public class GeneticDecoder {
previewProcessingTotal
=(
int
)
reslte
.
get
(
5
);
previewProcessingTotal
=(
int
)
reslte
.
get
(
5
);
if
(
setupTime
==
0
)
if
(
setupTime
==
0
)
{
{
// 没有换型占用时,直接查机台下一段可排的可用窗口。
geneDetails
=
machineCalculator
.
getNextAvailableTime
(
machine
,
previewStart
,
-
1
,
geneDetails
=
machineCalculator
.
getNextAvailableTime
(
machine
,
previewStart
,
-
1
,
previewProcessingTotal
,
machineTasks
,
operation
.
getIsInterrupt
()!=
1
,
true
,
processingTime
,
operation
.
getQuantity
(),
true
);
previewProcessingTotal
,
machineTasks
,
operation
.
getIsInterrupt
()!=
1
,
true
,
processingTime
,
operation
.
getQuantity
(),
true
);
}
else
{
}
else
{
// 有换型占用时,需要把换型段和加工段一起拼成完整的试排结果。
CopyOnWriteArrayList
<
TimeSegment
>
AvailableTimeSegment
=
(
CopyOnWriteArrayList
<
TimeSegment
>)
reslte
.
get
(
6
);
CopyOnWriteArrayList
<
TimeSegment
>
AvailableTimeSegment
=
(
CopyOnWriteArrayList
<
TimeSegment
>)
reslte
.
get
(
6
);
Map
<
Integer
,
Object
>
result
=
machineCalculator
.
CreateScheduleResult
(
machine
,
previewProcessingTotal
,
previewStart
,
Map
<
Integer
,
Object
>
result
=
machineCalculator
.
CreateScheduleResult
(
machine
,
previewProcessingTotal
,
previewStart
,
AvailableTimeSegment
,
processingTime
,
operation
.
getQuantity
(),
operation
.
getIsInterrupt
()
!=
1
,
setupTime
,
_globalParam
.
is_smoothChangeOverInWeek
(),
setupStartTime
);
AvailableTimeSegment
,
processingTime
,
operation
.
getQuantity
(),
operation
.
getIsInterrupt
()
!=
1
,
setupTime
,
_globalParam
.
is_smoothChangeOverInWeek
(),
setupStartTime
);
...
@@ -1435,10 +1465,12 @@ public class GeneticDecoder {
...
@@ -1435,10 +1465,12 @@ public class GeneticDecoder {
geneDetails
=(
CopyOnWriteArrayList
<
ScheduleResultDetail
>)
result
.
get
(
2
);
geneDetails
=(
CopyOnWriteArrayList
<
ScheduleResultDetail
>)
result
.
get
(
2
);
}
}
}
else
{
}
else
{
// 不考虑平滑换型时,只需要找加工段可用窗口。
geneDetails
=
machineCalculator
.
getNextAvailableTime
(
machine
,
previewStart
,
-
1
,
geneDetails
=
machineCalculator
.
getNextAvailableTime
(
machine
,
previewStart
,
-
1
,
previewProcessingTotal
,
machineTasks
,
operation
.
getIsInterrupt
()!=
1
,
true
,
processingTime
,
operation
.
getQuantity
(),
true
);
previewProcessingTotal
,
machineTasks
,
operation
.
getIsInterrupt
()!=
1
,
true
,
processingTime
,
operation
.
getQuantity
(),
true
);
}
}
// geneDetails 可能跨多个班次/时段,开始时间取最小值,结束时间取最大值。
int
startTime
=
geneDetails
.
stream
()
int
startTime
=
geneDetails
.
stream
()
.
mapToInt
(
ScheduleResultDetail:
:
getStartTime
)
.
mapToInt
(
ScheduleResultDetail:
:
getStartTime
)
.
min
()
.
min
()
...
@@ -1450,6 +1482,7 @@ public class GeneticDecoder {
...
@@ -1450,6 +1482,7 @@ public class GeneticDecoder {
return
new
MachineSchedulePreview
(
startTime
,
endTime
,
setupTime
,
geneDetails
);
return
new
MachineSchedulePreview
(
startTime
,
endTime
,
setupTime
,
geneDetails
);
}
}
// 按机台缓存已排结果,避免固定点迭代期间反复全表扫描 chromosome.getResult()。
private
CopyOnWriteArrayList
<
GAScheduleResult
>
getMachineTasks
(
long
machineId
,
Chromosome
chromosome
,
private
CopyOnWriteArrayList
<
GAScheduleResult
>
getMachineTasks
(
long
machineId
,
Chromosome
chromosome
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
)
{
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
)
{
if
(
machineTasksCache
.
containsKey
(
machineId
))
{
if
(
machineTasksCache
.
containsKey
(
machineId
))
{
...
@@ -1463,6 +1496,7 @@ public class GeneticDecoder {
...
@@ -1463,6 +1496,7 @@ public class GeneticDecoder {
return
machineTasks
;
return
machineTasks
;
}
}
// 当前机台最后一道已排工序,用于约束连续排程和换型起点。
private
GAScheduleResult
getLastMachineTask
(
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
)
{
private
GAScheduleResult
getLastMachineTask
(
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
)
{
if
(
machineTasks
!=
null
&&
machineTasks
.
size
()>
0
)
if
(
machineTasks
!=
null
&&
machineTasks
.
size
()>
0
)
{
{
...
@@ -1471,6 +1505,7 @@ public class GeneticDecoder {
...
@@ -1471,6 +1505,7 @@ public class GeneticDecoder {
return
null
;
return
null
;
}
}
// trial BOM 恢复快照后,旧的 Machine 引用可能已经失效,因此统一从 chromosome 中重新取当前有效对象。
private
Machine
getMachineById
(
Chromosome
chromosome
,
long
machineId
)
{
private
Machine
getMachineById
(
Chromosome
chromosome
,
long
machineId
)
{
return
chromosome
.
getMachines
().
stream
()
return
chromosome
.
getMachines
().
stream
()
.
filter
(
m
->
m
.
getId
()
==
machineId
)
.
filter
(
m
->
m
.
getId
()
==
machineId
)
...
@@ -1629,6 +1664,10 @@ public class GeneticDecoder {
...
@@ -1629,6 +1664,10 @@ public class GeneticDecoder {
}
}
/**
* 汇总当前工序的物料约束,返回所有原料/半成品中最晚满足的那个时刻。
* 返回值含义是“这道工序最早允许因物料而开工的秒数”。
*/
private
int
getOperationBOMTime
(
Entry
currentOp
,
Chromosome
chromosome
)
{
private
int
getOperationBOMTime
(
Entry
currentOp
,
Chromosome
chromosome
)
{
List
<
OrderMaterialRequirement
>
opboms
=
currentOp
.
getMaterialRequirements
();
List
<
OrderMaterialRequirement
>
opboms
=
currentOp
.
getMaterialRequirements
();
...
@@ -1696,10 +1735,16 @@ public class GeneticDecoder {
...
@@ -1696,10 +1735,16 @@ public class GeneticDecoder {
return
Math
.
max
(
rawTime
,
sfTime
);
return
Math
.
max
(
rawTime
,
sfTime
);
}
}
// 默认走正式提交路径,调用方不传 commitChanges 时认为要把物料状态真实写回。
private
int
EditOperationBOMTime
(
Entry
currentOp
,
Chromosome
chromosome
,
int
earliestStartTime
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
,
Map
<
Integer
,
Entry
>
entryIndexById
,
Map
<
Integer
,
GAScheduleResult
>
scheduleIndexById
)
{
private
int
EditOperationBOMTime
(
Entry
currentOp
,
Chromosome
chromosome
,
int
earliestStartTime
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
,
Map
<
Integer
,
Entry
>
entryIndexById
,
Map
<
Integer
,
GAScheduleResult
>
scheduleIndexById
)
{
return
EditOperationBOMTime
(
currentOp
,
chromosome
,
earliestStartTime
,
machineTasksCache
,
entryIndexById
,
scheduleIndexById
,
true
);
return
EditOperationBOMTime
(
currentOp
,
chromosome
,
earliestStartTime
,
machineTasksCache
,
entryIndexById
,
scheduleIndexById
,
true
);
}
}
/**
* 按指定 earliestStartTime 重新计算当前工序的 BOM 可开工时间。
* commitChanges=true:正式提交,真实修改物料/订单/排程状态。
* commitChanges=false:只做试算,方法结束后恢复 chromosome 和相关索引缓存。
*/
private
int
EditOperationBOMTime
(
Entry
currentOp
,
Chromosome
chromosome
,
int
earliestStartTime
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
,
Map
<
Integer
,
Entry
>
entryIndexById
,
Map
<
Integer
,
GAScheduleResult
>
scheduleIndexById
,
boolean
commitChanges
)
{
private
int
EditOperationBOMTime
(
Entry
currentOp
,
Chromosome
chromosome
,
int
earliestStartTime
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
,
Map
<
Integer
,
Entry
>
entryIndexById
,
Map
<
Integer
,
GAScheduleResult
>
scheduleIndexById
,
boolean
commitChanges
)
{
List
<
OrderMaterialRequirement
>
opboms
=
currentOp
.
getMaterialRequirements
();
List
<
OrderMaterialRequirement
>
opboms
=
currentOp
.
getMaterialRequirements
();
if
(
opboms
==
null
)
if
(
opboms
==
null
)
...
@@ -1708,20 +1753,24 @@ public class GeneticDecoder {
...
@@ -1708,20 +1753,24 @@ public class GeneticDecoder {
}
}
LocalDateTime
earliestStartTime1
=
baseTime
.
plusSeconds
(
earliestStartTime
);
LocalDateTime
earliestStartTime1
=
baseTime
.
plusSeconds
(
earliestStartTime
);
if
(
commitChanges
)
{
if
(
commitChanges
)
{
// 正式提交模式:直接把当前开工时间对应的物料占用/供应结果写回业务对象。
materialRequirementService
.
EditOperationBOM
(
currentOp
,
chromosome
,
earliestStartTime1
,
this
,
machineTasksCache
,
entryIndexById
,
scheduleIndexById
,
baseTime
,
true
);
materialRequirementService
.
EditOperationBOM
(
currentOp
,
chromosome
,
earliestStartTime1
,
this
,
machineTasksCache
,
entryIndexById
,
scheduleIndexById
,
baseTime
,
true
);
return
getOperationBOMTime
(
currentOp
,
chromosome
);
return
getOperationBOMTime
(
currentOp
,
chromosome
);
}
}
// 试算模式:先复制一份完整状态,等 BOM 计算完成后再整体恢复。
TrialDecodeSnapshot
snapshot
=
createTrialDecodeSnapshot
(
chromosome
);
TrialDecodeSnapshot
snapshot
=
createTrialDecodeSnapshot
(
chromosome
);
try
{
try
{
materialRequirementService
.
EditOperationBOM
(
currentOp
,
chromosome
,
earliestStartTime1
,
this
,
machineTasksCache
,
entryIndexById
,
scheduleIndexById
,
baseTime
,
true
);
materialRequirementService
.
EditOperationBOM
(
currentOp
,
chromosome
,
earliestStartTime1
,
this
,
machineTasksCache
,
entryIndexById
,
scheduleIndexById
,
baseTime
,
true
);
return
getOperationBOMTime
(
currentOp
,
chromosome
);
return
getOperationBOMTime
(
currentOp
,
chromosome
);
}
finally
{
}
finally
{
// 试算期间 materialRequirementService 可能会改动 machine/order/material/result,这里统一回滚。
restoreTrialDecodeSnapshot
(
snapshot
,
chromosome
,
machineTasksCache
,
entryIndexById
,
scheduleIndexById
);
restoreTrialDecodeSnapshot
(
snapshot
,
chromosome
,
machineTasksCache
,
entryIndexById
,
scheduleIndexById
);
}
}
}
}
// 试算 BOM 会改动多类状态对象,因此先把排程求解会依赖的核心集合做一次深拷贝快照。
private
TrialDecodeSnapshot
createTrialDecodeSnapshot
(
Chromosome
chromosome
)
{
private
TrialDecodeSnapshot
createTrialDecodeSnapshot
(
Chromosome
chromosome
)
{
TrialDecodeSnapshot
snapshot
=
new
TrialDecodeSnapshot
();
TrialDecodeSnapshot
snapshot
=
new
TrialDecodeSnapshot
();
snapshot
.
machines
=
ProductionDeepCopyUtil
.
deepCopyList
(
chromosome
.
getMachines
(),
Machine
.
class
);
snapshot
.
machines
=
ProductionDeepCopyUtil
.
deepCopyList
(
chromosome
.
getMachines
(),
Machine
.
class
);
...
@@ -1733,6 +1782,7 @@ public class GeneticDecoder {
...
@@ -1733,6 +1782,7 @@ public class GeneticDecoder {
return
snapshot
;
return
snapshot
;
}
}
// 恢复试算前的 chromosome 状态,并同步重建几个按 id/机台组织的缓存索引。
private
void
restoreTrialDecodeSnapshot
(
TrialDecodeSnapshot
snapshot
,
Chromosome
chromosome
,
private
void
restoreTrialDecodeSnapshot
(
TrialDecodeSnapshot
snapshot
,
Chromosome
chromosome
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
,
Map
<
Integer
,
Entry
>
entryIndexById
,
Map
<
Integer
,
Entry
>
entryIndexById
,
...
@@ -2550,6 +2600,7 @@ public class GeneticDecoder {
...
@@ -2550,6 +2600,7 @@ public class GeneticDecoder {
return
reslte
;
return
reslte
;
}
}
// 释放试排阶段占用的机台 availability 段,避免临时状态污染下一轮排程/BOM 试算。
public
void
AddMachineAvailable
(
Machine
machine
,
List
<
ScheduleResultDetail
>
geneDetails
)
{
public
void
AddMachineAvailable
(
Machine
machine
,
List
<
ScheduleResultDetail
>
geneDetails
)
{
if
(
geneDetails
==
null
||
geneDetails
.
isEmpty
())
return
;
if
(
geneDetails
==
null
||
geneDetails
.
isEmpty
())
return
;
...
...
src/main/java/com/aps/service/Algorithm/MachineCalculator.java
View file @
3995638d
...
@@ -41,6 +41,7 @@ public class MachineCalculator {
...
@@ -41,6 +41,7 @@ public class MachineCalculator {
/**
/**
* 获取机器下一个可用时间窗口(考虑班次约束)
* 获取机器下一个可用时间窗口(考虑班次约束)
*/
*/
// 从 proposedStartTime 开始查找机台下一段可排窗口;必要时会把命中的 availability 临时标记为已占用。
public
CopyOnWriteArrayList
<
ScheduleResultDetail
>
getNextAvailableTime
(
Machine
machine
,
int
proposedStartTime
,
public
CopyOnWriteArrayList
<
ScheduleResultDetail
>
getNextAvailableTime
(
Machine
machine
,
int
proposedStartTime
,
int
prevtime
,
int
processingTime
,
int
prevtime
,
int
processingTime
,
CopyOnWriteArrayList
<
GAScheduleResult
>
existingTasks
,
CopyOnWriteArrayList
<
GAScheduleResult
>
existingTasks
,
...
@@ -70,6 +71,7 @@ public class MachineCalculator {
...
@@ -70,6 +71,7 @@ public class MachineCalculator {
return
findAvailableSegments
(
machine
,
startTime
,
existingTasks
,
processingTime
,
isInterrupt
);
return
findAvailableSegments
(
machine
,
startTime
,
existingTasks
,
processingTime
,
isInterrupt
);
}
}
// 基于已选可用时段组装排程结果,并把换型段/加工段对应的 availability 临时占用。
public
Map
<
Integer
,
Object
>
CreateScheduleResult
(
public
Map
<
Integer
,
Object
>
CreateScheduleResult
(
Machine
machine
,
int
processingTime
,
int
proposedStartTime
,
CopyOnWriteArrayList
<
TimeSegment
>
timeSegments
,
Machine
machine
,
int
processingTime
,
int
proposedStartTime
,
CopyOnWriteArrayList
<
TimeSegment
>
timeSegments
,
double
oneTime
,
double
quantity
double
oneTime
,
double
quantity
...
@@ -1289,6 +1291,7 @@ public class MachineCalculator {
...
@@ -1289,6 +1291,7 @@ public class MachineCalculator {
return
times
;
return
times
;
}
}
// 把目标 availability 按本次排程切成“剩余可用段”和“本次已占用段”,并把占用段 key 回写到 geneDetails。
private
CopyOnWriteArrayList
<
TimeSegment
>
RemoveMachineAvailable
(
Machine
machine
,
ScheduleResultDetail
geneDetails
,
TimeSegment
targetSegment
)
{
private
CopyOnWriteArrayList
<
TimeSegment
>
RemoveMachineAvailable
(
Machine
machine
,
ScheduleResultDetail
geneDetails
,
TimeSegment
targetSegment
)
{
...
...
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