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
a5817c7e
Commit
a5817c7e
authored
Jul 23, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bom
parent
60970636
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
218 additions
and
48 deletions
+218
-48
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+9
-4
GeneticDecoderBom.java
...ain/java/com/aps/service/Algorithm/GeneticDecoderBom.java
+206
-41
PlanResultService.java
src/main/java/com/aps/service/plan/PlanResultService.java
+1
-1
PlanResultServiceTest.java
src/test/java/com/aps/demo/PlanResultServiceTest.java
+2
-2
No files found.
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
a5817c7e
...
...
@@ -690,11 +690,11 @@ public class GeneticDecoder {
long
slowOpThresholdNs
=
500_000_000L
;
// 500ms
Map
<
Integer
,
Integer
>
targetGroupEnd
=
new
HashMap
<>();
for
(
int
groupId
:
chromosome
.
getOperationSequencing
())
{
int
scheduledCount
=
orderProcessCounter
.
get
(
groupId
);
if
(
groupId
==
1
)
if
(
groupId
==
1
5
||
groupId
==
16
)
{
int
i
=
0
;
}
...
...
@@ -723,7 +723,7 @@ public class GeneticDecoder {
orderAnchor
=
bom
.
computeHybridSemiAnchor
(
this
,
groupId
,
entrysBygroupId
,
opMachineKeyMap
,
chromosome
,
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
reForwardFinishedOrderIds
,
_globalParam
,
order
);
reForwardFinishedOrderIds
,
_globalParam
,
order
,
targetGroupEnd
);
if
(
orderAnchor
<
0
)
{
orderIsJit
=
false
;
...
...
@@ -742,7 +742,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
()
,
targetGroupEnd
);
if
(
orderAnchor
<
0
)
{
orderIsJit
=
false
;
orderSchedulingInfo
.
put
(
groupId
,
...
...
@@ -859,6 +859,11 @@ public class GeneticDecoder {
opCount
++;
if
(
currentOp
.
getId
()==
60
)
{
int
k
=
0
;
}
orderProcessCounter
.
put
(
groupId
,
orderProcessCounter
.
get
(
groupId
)
+
1
);
orderLastEndTime
.
put
(
groupId
,
actualEndTime
);
...
...
src/main/java/com/aps/service/Algorithm/GeneticDecoderBom.java
View file @
a5817c7e
...
...
@@ -36,7 +36,10 @@ public class GeneticDecoderBom {
Map
<
String
,
OpMachine
>
opMachineKeyMap
,
Chromosome
chromosome
,
Map
<
Integer
,
GAScheduleResult
>
scheduleIndexById
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
,
Map
<
Long
,
Machine
>
machineIdMap
,
Map
<
Integer
,
Entry
>
entryIndexById
,
boolean
isCheckMp
)
{
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
,
Map
<
Long
,
Machine
>
machineIdMap
,
Map
<
Integer
,
Entry
>
entryIndexById
,
boolean
isCheckMp
,
Map
<
Integer
,
Integer
>
targetGroupEnd
)
{
List
<
Entry
>
semiOps
=
entrysBygroupId
.
get
(
semiGroupId
);
if
(
semiOps
==
null
||
semiOps
.
isEmpty
())
return
0
;
...
...
@@ -53,18 +56,26 @@ public class GeneticDecoderBom {
||
lastOp
.
getTargetFinishedOperationId
().
isEmpty
())
break
;
int
targetOpId
=
lastOp
.
getTargetFinishedOperationId
().
get
(
0
);
int
targetGroupId
=
findGroupForOperation
(
targetOpId
,
entrysBygroupId
);
Entry
targetOp
=
entryIndexById
.
get
(
targetOpId
);
List
<
Integer
>
simGroupId
=
targetOp
.
getDependentOnOrderIds
();
if
(
targetGroupId
<
0
)
break
;
List
<
Entry
>
targetOps
=
entrysBygroupId
.
get
(
targetGroupId
);
if
(
targetOps
==
null
||
targetOps
.
isEmpty
())
break
;
Entry
firstTargetOp
=
targetOps
.
get
(
0
);
//半成品对应的成品工序
Entry
targetOp
=
entryIndexById
.
get
(
targetOpId
);
//成品工序下所有半成品订单
List
<
Integer
>
simGroupIds
=
targetOp
!=
null
?
targetOp
.
getDependentOnOrderIds
()
:
null
;
//是否头多半成品
boolean
hasMultipleSemi
=
simGroupIds
!=
null
&&
simGroupIds
.
size
()
>
1
;
if
(
Entry
.
SchedulingMode
.
FORWARD
.
name
().
equals
(
firstTargetOp
.
getSchedulingMode
()))
{
int
rootStart
=
forwardEstimateToOperation
(
decoder
,
targetOpId
,
targetGroupId
,
0
,
entrysBygroupId
,
opMachineKeyMap
,
chromosome
,
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
false
);
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
false
,
null
);
List
<
Integer
>
chainGroupIds
=
new
ArrayList
<>(
intermediateGroupIds
);
chainGroupIds
.
add
(
targetGroupId
);
...
...
@@ -73,56 +84,119 @@ public class GeneticDecoderBom {
int
anchor
=
rootStart
;
// FileHelper.writeLogFile(" 成品开始 "+targetGroupId+" : "+rootStart);
if
(!
hasMultipleSemi
)
{
if
(
anchor
==
0
)
{
return
-
1
;
}
for
(
int
i
=
intermediateGroupIds
.
size
()
-
1
;
i
>=
0
;
i
--)
{
int
sfGroupId
=
intermediateGroupIds
.
get
(
i
);
int
start1
=
forwardEstimateToOperation
(
decoder
,
0
,
sfGroupId
,
anchor
,
int
sfGroupId
=
intermediateGroupIds
.
get
(
i
);
int
start1
=
forwardEstimateToOperation
(
decoder
,
0
,
sfGroupId
,
anchor
,
entrysBygroupId
,
opMachineKeyMap
,
chromosome
,
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
true
);
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
true
,
null
);
// FileHelper.writeLogFile(" 半成品开始 "+sfGroupId+" : "+start1+" - "+anchor);
if
(
start1
<=
0
)
{
isFORWARD
=
true
;
if
(
start1
<=
0
)
{
isFORWARD
=
true
;
break
;
}
if
(
i
!=
0
)
{
if
(
i
!=
0
)
{
anchor
-=
start1
;
if
(
anchor
<
0
)
{
isFORWARD
=
true
;
if
(
anchor
<
0
)
{
isFORWARD
=
true
;
break
;
}
}
else
{
if
(
anchor
-
start1
<
0
)
{
isFORWARD
=
true
;
}
else
{
if
(
anchor
-
start1
<
0
)
{
isFORWARD
=
true
;
break
;
}
}
}
if
(
isFORWARD
)
{
for
(
int
i
=
intermediateGroupIds
.
size
()
-
1
;
i
>=
0
;
i
--)
{
List
<
Entry
>
ops1
=
entrysBygroupId
.
get
(
intermediateGroupIds
.
get
(
i
));
ops1
.
forEach
(
t
->
t
.
setSchedulingMode
(
Entry
.
SchedulingMode
.
FORWARD
.
name
()));
}
if
(
isFORWARD
)
return
-
1
;
}
return
Math
.
max
(
0
,
anchor
);
}
else
{
int
maxOtherSemiEnd
=
0
;
if
(
targetGroupEnd
!=
null
&&
targetGroupEnd
.
get
(
targetGroupId
)!=
null
)
{
maxOtherSemiEnd
=
targetGroupEnd
.
get
(
targetGroupId
);
}
else
{
// 多半成品:临时设备占用表,跨组追踪设备时间
Map
<
Long
,
Integer
>
tempMachineEnd
=
new
HashMap
<>();
for
(
int
otherGroupId
:
simGroupIds
)
{
// if (otherGroupId == semiGroupId) continue;
Set
<
Integer
>
visited
=
new
HashSet
<>();
int
chainEnd
=
estimateChainEnd
(
decoder
,
otherGroupId
,
rootStart
,
entrysBygroupId
,
opMachineKeyMap
,
chromosome
,
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
tempMachineEnd
,
visited
);
if
(
chainEnd
>
maxOtherSemiEnd
)
{
maxOtherSemiEnd
=
chainEnd
;
}
}
targetGroupEnd
.
put
(
targetGroupId
,
maxOtherSemiEnd
);
}
anchor
=
Math
.
max
(
anchor
,
maxOtherSemiEnd
);
for
(
int
i
=
intermediateGroupIds
.
size
()
-
1
;
i
>=
0
;
i
--)
{
int
sfGroupId
=
intermediateGroupIds
.
get
(
i
);
int
start1
=
forwardEstimateToOperation
(
decoder
,
0
,
sfGroupId
,
anchor
,
entrysBygroupId
,
opMachineKeyMap
,
chromosome
,
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
true
,
null
);
if
(
start1
<=
0
)
{
isFORWARD
=
true
;
break
;
}
if
(
i
!=
0
)
{
anchor
-=
start1
;
if
(
anchor
<
0
)
{
isFORWARD
=
true
;
break
;
}
}
else
{
if
(
anchor
-
start1
<
0
)
{
isFORWARD
=
true
;
break
;
}
}
}
if
(
isFORWARD
)
{
// 倒排失败,尝试延迟对齐
int
effectiveAnchor
=
Math
.
max
(
rootStart
,
maxOtherSemiEnd
);
int
forwardEnd
=
forwardEstimateToOperation
(
decoder
,
0
,
semiGroupId
,
0
,
entrysBygroupId
,
opMachineKeyMap
,
chromosome
,
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
false
,
null
);
if
(
forwardEnd
>
0
&&
forwardEnd
<=
effectiveAnchor
)
{
return
effectiveAnchor
;
}
for
(
int
i
=
intermediateGroupIds
.
size
()
-
1
;
i
>=
0
;
i
--)
{
List
<
Entry
>
ops1
=
entrysBygroupId
.
get
(
intermediateGroupIds
.
get
(
i
));
ops1
.
forEach
(
t
->
t
.
setSchedulingMode
(
Entry
.
SchedulingMode
.
FORWARD
.
name
()));
ops1
.
forEach
(
t
->
t
.
setSchedulingMode
(
Entry
.
SchedulingMode
.
FORWARD
.
name
()));
}
return
-
1
;
}
}
return
Math
.
max
(
0
,
anchor
);
}
intermediateGroupIds
.
add
(
targetGroupId
);
...
...
@@ -131,6 +205,81 @@ public class GeneticDecoderBom {
return
0
;
}
/**
* 递归估算一个组及其所有子依赖链的设备占用时间
* 通过 getDependentOnOrderIds() 找到该组工序依赖的下游半成品组,
* 从最深层的子半成品(先跑)到当前组(后跑),
* 深层组的设备时间累积到 tempMachineEnd,浅层组自然排队
*
* @param groupId 起始组ID
* @param tempMachineEnd 设备占用表(会被更新)
* @param visited 已访问组集合,防止循环依赖
* @return 该组链的最大结束时间
*/
/**
* 递归估算一个组及其所有子依赖链的设备占用时间
* 通过 getDependentOnOrderIds() 找到该组工序依赖的下游半成品组,
* 从最深层的子半成品(先跑)到当前组(后跑),
* 深层组的设备时间累积到 tempMachineEnd,浅层组自然排队
*
* @param groupId 起始组ID
* @param backwardAnchor 倒排目标结束时间,>0时优先尝试倒排,=0则直接正排
* @param tempMachineEnd 设备占用表(会被更新)
* @param visited 已访问组集合,防止循环依赖
* @return 该组链的最大结束时间
*/
private
int
estimateChainEnd
(
GeneticDecoder
decoder
,
int
groupId
,
int
backwardAnchor
,
Map
<
Integer
,
List
<
Entry
>>
entrysBygroupId
,
Map
<
String
,
OpMachine
>
opMachineKeyMap
,
Chromosome
chromosome
,
Map
<
Integer
,
GAScheduleResult
>
scheduleIndexById
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
,
Map
<
Long
,
Machine
>
machineIdMap
,
Map
<
Integer
,
Entry
>
entryIndexById
,
Map
<
Long
,
Integer
>
tempMachineEnd
,
Set
<
Integer
>
visited
)
{
if
(!
visited
.
add
(
groupId
))
return
0
;
// 防止循环依赖
List
<
Entry
>
ops
=
entrysBygroupId
.
get
(
groupId
);
if
(
ops
==
null
||
ops
.
isEmpty
())
return
0
;
// 先递归估算该组依赖的子半成品(子依赖始终正排,找到最小必需结束时间)
int
subMaxEnd
=
0
;
for
(
Entry
op
:
ops
)
{
List
<
Integer
>
depGroupIds
=
op
.
getDependentOnOrderIds
();
if
(
depGroupIds
!=
null
)
{
for
(
int
depGroupId
:
depGroupIds
)
{
if
(
depGroupId
!=
groupId
)
{
int
subEnd
=
estimateChainEnd
(
decoder
,
depGroupId
,
0
,
entrysBygroupId
,
opMachineKeyMap
,
chromosome
,
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
tempMachineEnd
,
visited
);
if
(
subEnd
>
subMaxEnd
)
subMaxEnd
=
subEnd
;
}
}
}
}
// 优先尝试倒排:尽量晚结束,给同层其他半成品留出更大的锚点空间
if
(
backwardAnchor
>
0
)
{
int
backwardStart
=
forwardEstimateToOperation
(
decoder
,
0
,
groupId
,
backwardAnchor
,
entrysBygroupId
,
opMachineKeyMap
,
chromosome
,
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
true
,
tempMachineEnd
);
// 倒排成功(start > 0)且子依赖能在倒排开始前完成
if
(
backwardStart
>
0
&&
backwardStart
>=
subMaxEnd
)
{
return
backwardAnchor
;
}
}
// 倒排失败或未指定锚点:正排,从子依赖结束时间开始(tempMachineEnd + subMaxEnd 双重保障)
int
forwardEnd
=
forwardEstimateToOperation
(
decoder
,
0
,
groupId
,
subMaxEnd
,
entrysBygroupId
,
opMachineKeyMap
,
chromosome
,
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
false
,
tempMachineEnd
);
return
Math
.
max
(
forwardEnd
,
subMaxEnd
);
}
private
int
findGroupForOperation
(
int
opId
,
Map
<
Integer
,
List
<
Entry
>>
entrysBygroupId
)
{
...
...
@@ -148,7 +297,11 @@ public class GeneticDecoderBom {
Map
<
Integer
,
GAScheduleResult
>
scheduleIndexById
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
,
Map
<
Long
,
Machine
>
machineIdMap
,
Map
<
Integer
,
Entry
>
entryIndexById
,
boolean
isJit
)
{
Map
<
Integer
,
Entry
>
entryIndexById
,
boolean
isJit
,
Map
<
Long
,
Integer
>
tempMachineEnd
)
{
if
(
startSecond
<=
0
&&
isJit
)
{
return
-
1
;
}
List
<
Entry
>
ops
=
entrysBygroupId
.
get
(
groupId
);
if
(
ops
==
null
)
return
0
;
...
...
@@ -169,6 +322,7 @@ if(isJit)
.
collect
(
Collectors
.
toMap
(
Machine:
:
getId
,
m
->
m
,
(
a
,
b
)
->
a
));
int
nextAvailableStart
=
startSecond
;
Map
<
Long
,
Integer
>
machineLastEndInOrder
=
new
HashMap
<>();
boolean
useTempMachineEnd
=
tempMachineEnd
!=
null
;
for
(
Entry
op
:
sorted
)
{
String
key
=
groupId
+
"_"
+
op
.
getSequence
();
...
...
@@ -196,8 +350,16 @@ if(isJit)
Integer
lastInOrder
=
machineLastEndInOrder
.
get
(
mId
);
if
(
lastInOrder
!=
null
)
start
=
Math
.
max
(
start
,
lastInOrder
);
// 临时设备占用表:跨组追踪设备占用
if
(
useTempMachineEnd
)
{
Integer
lastEnd
=
tempMachineEnd
.
get
(
mId
);
if
(
lastEnd
!=
null
)
{
start
=
Math
.
max
(
start
,
lastEnd
);
}
}
// 该设备上已排产的其他任务(半成品占位)的结束时间
if
(
machineTasksCache
!=
null
)
{
if
(
!
useTempMachineEnd
&&
machineTasksCache
!=
null
)
{
CopyOnWriteArrayList
<
GAScheduleResult
>
tasks
=
machineTasksCache
.
get
(
mId
);
if
(
tasks
!=
null
)
{
for
(
GAScheduleResult
t
:
tasks
)
{
...
...
@@ -235,6 +397,9 @@ if(isJit)
if
(
result
!=
null
)
{
start
=
result
.
getStartTime
()-
result
.
getChangeOverTime
();
end
=
result
.
getEndTime
();
if
(
useTempMachineEnd
)
{
tempMachineEnd
.
put
(
mId
,
end
);
}
}
else
{
return
-
1
;
}
...
...
@@ -396,7 +561,7 @@ if(isJit)
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
,
Map
<
Long
,
Machine
>
machineIdMap
,
Map
<
Integer
,
Entry
>
entryIndexById
,
Set
<
Integer
>
reForwardFinishedOrderIds
,
GlobalParam
_globalParam
,
Order
order
)
{
Set
<
Integer
>
reForwardFinishedOrderIds
,
GlobalParam
_globalParam
,
Order
order
,
Map
<
Integer
,
Integer
>
targetGroupEnd
)
{
List
<
Entry
>
sfOps
=
entrysBygroupId
.
get
(
semiOrderId
);
if
(
sfOps
==
null
||
sfOps
.
isEmpty
())
return
0
;
...
...
@@ -418,7 +583,7 @@ int start=Integer.MAX_VALUE;
// 成品还没排(不应该发生在JIT模式),降级为原有逻辑
return
computeSemiFinishedAnchor
(
decoder
,
semiOrderId
,
entrysBygroupId
,
opMachineKeyMap
,
chromosome
,
scheduleIndexById
,
machineTasksCache
,
machineIdMap
,
entryIndexById
,
_globalParam
.
isIsCheckMp
());
machineIdMap
,
entryIndexById
,
_globalParam
.
isIsCheckMp
()
,
targetGroupEnd
);
}
...
...
src/main/java/com/aps/service/plan/PlanResultService.java
View file @
a5817c7e
...
...
@@ -297,7 +297,7 @@ public class PlanResultService {
if
(!
saved
)
{
throw
new
BusinessException
(
"排产计算结果保存失败,请稍后重试或联系管理员"
);
}
//
WriteScheduleSummary(chromosome);
WriteScheduleSummary
(
chromosome
);
return
chromosome
;
...
...
src/test/java/com/aps/demo/PlanResultServiceTest.java
View file @
a5817c7e
...
...
@@ -43,9 +43,9 @@ public class PlanResultServiceTest {
// planResultService.execute2("64E64F6B68094AF38CEDC418630C3CC2");//2000
// planResultService.execute2("E1448B3C9C8743DEAB39708F2CFE348A");//倒排bomces
//
planResultService.execute2("85DA28EC5F4643449E65A51253D5F127"); //bom 多半成品
planResultService
.
execute2
(
"85DA28EC5F4643449E65A51253D5F127"
);
//bom 多半成品
planResultService
.
execute2
(
"FB14AF1623CB461D9BEDAFC35DBF0AFC"
);
//重叠
//
planResultService.execute2("FB14AF1623CB461D9BEDAFC35DBF0AFC"); //重叠
// planResultService.execute2("F8F147BD627C47B1A190399DD7A697F6");
...
...
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