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
e56eef9d
Commit
e56eef9d
authored
Mar 20, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
解码优化
parent
103266f2
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
660 additions
and
62 deletions
+660
-62
FileHelper.java
src/main/java/com/aps/common/util/FileHelper.java
+1
-1
GeneticAlgorithm.java
...main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
+3
-3
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+654
-56
MaterialRequirementService.java
...com/aps/service/Algorithm/MaterialRequirementService.java
+2
-2
No files found.
src/main/java/com/aps/common/util/FileHelper.java
View file @
e56eef9d
...
...
@@ -22,7 +22,7 @@ public class FileHelper {
String
filePath
=
LOG_FILE_PATH
+
date
+
LOG_FILE
;
try
(
PrintWriter
writer
=
new
PrintWriter
(
new
FileWriter
(
filePath
,
true
)))
{
String
timestamp
=
LocalDateTime
.
now
().
format
(
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
));
String
timestamp
=
LocalDateTime
.
now
().
format
(
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss
.SSS
"
));
writer
.
println
(
"["
+
timestamp
+
"] "
+
message
);
System
.
out
.
println
(
"["
+
timestamp
+
"] "
+
message
);
...
...
src/main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
View file @
e56eef9d
...
...
@@ -118,11 +118,11 @@ public class GeneticAlgorithm {
FileHelper
.
writeLogFile
(
"初始化种群-----------开始-------"
);
// 步骤1:初始化种群
//
List<Chromosome> population = initialization.generateInitialPopulation(param, globalOpList);
List
<
Chromosome
>
population
=
initialization
.
generateInitialPopulation
(
param
,
globalOpList
);
// 步骤1:使用构造启发式算法生成初始种群
FileHelper
.
writeLogFile
(
"构造启发式初始化-----------开始-------"
);
List
<
Chromosome
>
population
=
initialization
.
generateHeuristicInitialPopulation
(
param
,
globalOpList
);
//
List<Chromosome> population = initialization.generateHeuristicInitialPopulation(param, globalOpList);
FileHelper
.
writeLogFile
(
"构造启发式初始化-----------结束-------"
);
...
...
@@ -477,7 +477,7 @@ return population;
FileHelper
.
writeLogFile
(
"解码---------------"
+
population
.
size
()
);
GeneticDecoder
decoder
=
new
GeneticDecoder
(
_GlobalParam
,
param
.
getBaseTime
(),
machines
,
orders
,
materials
,
machineScheduler
,
materialRequirementService
,
sceneId
);
boolean
ismore
=
tru
e
;
boolean
ismore
=
fals
e
;
if
(
ismore
)
{
CompletableFuture
.
allOf
(
population
.
stream
()
.
map
(
chromosome
->
CompletableFuture
.
runAsync
(()
->
decode
(
decoder
,
chromosome
,
param
,
allOperations
,
globalOpList
),
decodeExecutor
))
...
...
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
e56eef9d
...
...
@@ -21,6 +21,7 @@ import java.time.Duration;
import
java.time.LocalDateTime
;
import
java.time.temporal.ChronoUnit
;
import
java.util.*
;
import
java.util.concurrent.CompletableFuture
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.CopyOnWriteArrayList
;
import
java.util.concurrent.atomic.AtomicInteger
;
...
...
@@ -338,10 +339,29 @@ if(finishedOrder==null||finishedOrder.size()==0)
orderProcessCounter
.
put
(
orderid
,
scheduledCount
);
}
public
void
decode
(
Chromosome
chromosome
)
{
int
operationCount
=
chromosome
.
getAllOperations
().
size
();
int
cpuCores
=
Runtime
.
getRuntime
().
availableProcessors
();
//
// // 根据工序数量和CPU核心数决定是否使用内部并行
if
(
operationCount
>
500
&&
cpuCores
>
4
)
{
// 使用并行处理
FileHelper
.
writeLogFile
(
"使用并行处理 _s"
);
parallelDecodeByMachine
(
chromosome
);
FileHelper
.
writeLogFile
(
"使用并行处理 _e"
);
}
// else {
// 使用串行处理
// FileHelper.writeLogFile("使用串行处理 _s");
// serialDecode(chromosome);
// FileHelper.writeLogFile("使用串行处理 _e");
//}
}
/**
* 染色体解码为调度方案
*/
public
void
d
ecode
(
Chromosome
chromosome
)
{
public
void
serialD
ecode
(
Chromosome
chromosome
)
{
// List<OrderMaterialRequirement> orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam);
...
...
@@ -356,9 +376,14 @@ if(finishedOrder==null||finishedOrder.size()==0)
List
<
GlobalOperationInfo
>
globalOpList
=
chromosome
.
getGlobalOpList
();
List
<
Entry
>
allOperations
=
chromosome
.
getAllOperations
();
_allOperations
=
chromosome
.
getAllOperations
();
Map
<
Integer
,
GlobalOperationInfo
>
globalOpMap
=
globalOpList
.
stream
()
.
collect
(
Collectors
.
toMap
(
GlobalOperationInfo:
:
getGlobalOpId
,
g
->
g
));
Map
<
Long
,
Machine
>
machineIdMap
=
chromosome
.
getMachines
().
stream
()
.
collect
(
Collectors
.
toMap
(
Machine:
:
getId
,
m
->
m
));
// 验证:MachineSelection长度必须与全局工序数一致
if
(
chromosome
.
getMachineSelection
().
size
()
!=
globalOpList
.
size
())
{
...
...
@@ -369,6 +394,8 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 步骤1:生成“工序→机器/加工时间”映射
List
<
OpMachine
>
opMachineMap
=
new
ArrayList
<>();
Map
<
String
,
OpMachine
>
opMachineKeyMap
=
new
HashMap
<>();
for
(
GlobalOperationInfo
globalOp
:
globalOpList
)
{
int
globalOpId
=
globalOp
.
getGlobalOpId
();
Entry
op
=
globalOp
.
getOp
();
...
...
@@ -397,26 +424,37 @@ if(finishedOrder==null||finishedOrder.size()==0)
opMachine
.
setSingleOut
(
selectedMachine
.
getSingleOut
());
opMachineMap
.
add
(
opMachine
);
String
key
=
opMachine
.
getGroupId
()
+
"_"
+
opMachine
.
getSequence
();
opMachineKeyMap
.
put
(
key
,
opMachine
);
}
// 步骤2:按OperationSequencing顺序调度工序
Map
<
Integer
,
Integer
>
orderProcessCounter
=
allOperations
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
Entry:
:
getGroupId
,
Collectors
.
collectingAndThen
(
Collectors
.
counting
(),
Long:
:
intValue
)))
.
entrySet
().
stream
()
.
collect
(
Collectors
.
toMap
(
Map
.
Entry
::
getKey
,
e
->
0
));
// Map<Integer, Integer> orderProcessCounter = allOperations.stream()
// .collect(Collectors.groupingBy(Entry::getGroupId, Collectors.collectingAndThen(
// Collectors.counting(), Long::intValue)))
// .entrySet().stream()
// .collect(Collectors.toMap(Map.Entry::getKey, e -> 0));
//
// Map<Integer, Integer> orderLastEndTime = allOperations.stream()
// .collect(Collectors.groupingBy(Entry::getGroupId))
// .keySet().stream()
// .collect(Collectors.toMap(k -> k, k -> 0));
Map
<
Integer
,
Integer
>
orderLastEndTime
=
allOperations
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
Entry:
:
getGroupId
))
.
keySet
().
stream
()
.
collect
(
Collectors
.
toMap
(
k
->
k
,
k
->
0
));
// 步骤2:按OperationSequencing顺序调度工序
Map
<
Integer
,
Integer
>
orderProcessCounter
=
new
HashMap
<>();
Map
<
Integer
,
Integer
>
orderLastEndTime
=
new
HashMap
<>();
for
(
Entry
op
:
allOperations
)
{
int
groupId
=
op
.
getGroupId
();
orderProcessCounter
.
putIfAbsent
(
groupId
,
0
);
orderLastEndTime
.
putIfAbsent
(
groupId
,
0
);
}
// Map<Long, String> machineState = chromosome.getMachines().stream()
// .collect(Collectors.toMap(Machine::getId, m -> ""));
// List<Entry> allScheduledOps = new ArrayList<>();
// 缓存机器任务
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
=
new
HashMap
<>();
for
(
int
groupId
:
chromosome
.
getOperationSequencing
())
{
int
scheduledCount
=
orderProcessCounter
.
get
(
groupId
);
List
<
Entry
>
orderOps
=
allOperations
.
stream
()
...
...
@@ -444,43 +482,47 @@ if(finishedOrder==null||finishedOrder.size()==0)
}
// 从映射表中获取机器和加工时间
OpMachine
machineOption
=
opMachineMap
.
stream
()
.
filter
(
m
->
m
.
getGroupId
()
==
groupId
&&
m
.
getSequence
()==
opSequence
)
.
findFirst
()
.
orElse
(
null
);
// OpMachine machineOption=opMachineMap.stream()
// .filter(m -> m.getGroupId() == groupId&&m.getSequence()==opSequence)
// .findFirst()
// .orElse(null);
String
opMachineKey
=
groupId
+
"_"
+
opSequence
;
OpMachine
machineOption
=
opMachineKeyMap
.
get
(
opMachineKey
);
Long
machineId
=
machineOption
.
getMachineId
();
double
processTime
=
machineOption
.
getProcessingTime
();
Machine
targetMachine
=
chromosome
.
getMachines
().
stream
()
.
filter
(
m
->
m
.
getId
()
==
machineId
)
.
findFirst
()
.
orElse
(
null
);
int
prevtime
=
0
;
//后处理时间
int
teardownTime
=
currentOp
.
getTeardownTime
();
if
(!
currentOp
.
getPrevEntryIds
().
isEmpty
())
{
// 处理多个前工序
prevtime
=
CalPrevtime
(
prevtime
,
currentOp
,
chromosome
,
processTime
,
targetMachine
);
}
//
Machine targetMachine = chromosome.getMachines().stream()
//
.filter(m -> m.getId() == machineId)
//
.findFirst()
//
.orElse(null);
// Machine targetMachine = machineIdMap.get(machineId);
//
int prevtime = 0;
//
//后处理时间
//
int teardownTime = currentOp.getTeardownTime();
//
if (!currentOp.getPrevEntryIds().isEmpty()) {
//
// 处理多个前工序
//
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine);
//
}
// 上个离散参数
// String lastDiscreteParameter = machineState.get(machineId);
int
bomtime
=
getOperationBOMTime
(
currentOp
,
chromosome
);
//
int bomtime = getOperationBOMTime(currentOp,chromosome);
int
prevendtime
=
prevtime
;
prevtime
=
Math
.
max
(
prevtime
,
bomtime
);
Machine
machine
=
chromosome
.
getMachines
().
stream
()
.
filter
(
m
->
m
.
getId
()
==
machineId
)
.
findFirst
()
.
orElse
(
null
);
// int prevendtime=prevtime;
// prevtime = Math.max(prevtime, bomtime);
// Machine machine = chromosome.getMachines().stream()
// .filter(m -> m.getId() == machineId)
// .findFirst()
// .orElse(null);
// Machine machine = machineIdMap.get(machineId);
// int changeoverTime =0; //(lastDiscreteParameter.isEmpty() ||
// lastDiscreteParameter.equals(currentOp.getDiscreteParameter())) ? 0 : 0;
int
actualEndTime
=
processWithSingleMachine
(
currentOp
,
machine
,
processTime
,
prevtime
,
machineOption
,
chromosome
,
false
,
prevendtim
e
);
int
actualEndTime
=
processOperation
(
currentOp
,
machineId
,
processTime
,
machineOption
,
chromosome
,
machineIdMap
,
machineTasksCache
);
// int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime,machineTasksCach
e);
orderProcessCounter
.
put
(
groupId
,
orderProcessCounter
.
get
(
groupId
)
+
1
);
orderLastEndTime
.
put
(
groupId
,
actualEndTime
);
...
...
@@ -494,11 +536,562 @@ if(finishedOrder==null||finishedOrder.size()==0)
calculateScheduleResult
(
chromosome
);
}
public
void
parallelDecode
(
Chromosome
chromosome
)
{
FileHelper
.
writeLogFile
(
"构建工序依赖图 _s"
);
// 1. 构建工序依赖图
Map
<
Integer
,
List
<
Integer
>>
dependencyGraph
=
buildDependencyGraph
(
chromosome
);
FileHelper
.
writeLogFile
(
"拓扑排序 _s"
);
// 2. 拓扑排序
List
<
Integer
>
topologicalOrder
=
topologicalSort
(
dependencyGraph
,
chromosome
);
FileHelper
.
writeLogFile
(
"按设备分组 _s"
);
// 3. 按设备分组
Map
<
Long
,
List
<
Integer
>>
machineToOpsMap
=
new
HashMap
<>();
Map
<
Integer
,
Integer
>
opToGroupIdMap
=
new
HashMap
<>();
Map
<
Integer
,
Long
>
opToMachineMap
=
new
HashMap
<>();
List
<
GlobalOperationInfo
>
globalOpList
=
chromosome
.
getGlobalOpList
();
// 步骤1:生成“工序→机器/加工时间”映射
List
<
OpMachine
>
opMachineMap
=
new
ArrayList
<>();
Map
<
String
,
OpMachine
>
opMachineKeyMap
=
new
HashMap
<>();
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
=
new
HashMap
<>();
Map
<
Long
,
Machine
>
machineIdMap
=
chromosome
.
getMachines
().
stream
()
.
collect
(
Collectors
.
toMap
(
Machine:
:
getId
,
m
->
m
));
for
(
GlobalOperationInfo
globalOp
:
globalOpList
)
{
int
globalOpId
=
globalOp
.
getGlobalOpId
();
Entry
op
=
globalOp
.
getOp
();
int
groupId
=
globalOp
.
getGroupId
();
int
sequence
=
globalOp
.
getSequence
();
// 从MachineSelection中获取当前工序的机器选择顺序号
int
machineSeq
=
chromosome
.
getMachineSelection
().
get
(
globalOpId
);
List
<
MachineOption
>
optionalMachines
=
op
.
getMachineOptions
();
// 验证:机器顺序号必须在可选范围内
if
(
machineSeq
<
1
||
machineSeq
>
optionalMachines
.
size
())
{
throw
new
IllegalStateException
(
String
.
format
(
"全局工序%d(订单%d工序%d)的机器顺序号%d超出范围(1-%d)"
,
globalOpId
,
groupId
,
sequence
,
machineSeq
,
optionalMachines
.
size
()));
}
// 获取选择的设备ID和加工时间
MachineOption
selectedMachine
=
optionalMachines
.
get
(
machineSeq
-
1
);
OpMachine
opMachine
=
new
OpMachine
();
opMachine
.
setGroupId
(
groupId
);
opMachine
.
setSequence
(
sequence
);
opMachine
.
setMachineId
(
selectedMachine
.
getMachineId
());
opMachine
.
setProcessingTime
(
selectedMachine
.
getProcessingTime
());
opMachine
.
setRuntime
(
selectedMachine
.
getRuntime
());
opMachine
.
setSingleOut
(
selectedMachine
.
getSingleOut
());
opMachineMap
.
add
(
opMachine
);
String
key
=
opMachine
.
getGroupId
()
+
"_"
+
opMachine
.
getSequence
();
opMachineKeyMap
.
put
(
key
,
opMachine
);
}
FileHelper
.
writeLogFile
(
"预处理工序信息 _s"
);
// 预处理工序信息
for
(
int
opId
:
topologicalOrder
)
{
Entry
op
=
findOperationById
(
chromosome
,
opId
);
if
(
op
!=
null
)
{
// 假设已经为工序分配了设备
String
opMachineKey
=
op
.
getGroupId
()
+
"_"
+
op
.
getSequence
();
OpMachine
machineOption
=
opMachineKeyMap
.
get
(
opMachineKey
);
if
(
machineOption
!=
null
)
{
machineToOpsMap
.
computeIfAbsent
(
machineOption
.
getMachineId
(),
k
->
new
ArrayList
<>()).
add
(
opId
);
opToGroupIdMap
.
put
(
opId
,
op
.
getGroupId
());
opToMachineMap
.
put
(
opId
,
machineOption
.
getMachineId
());
}
}
}
// 4. 并行处理
Map
<
Integer
,
CompletableFuture
<
Void
>>
opFutures
=
new
HashMap
<>();
Map
<
Long
,
CompletableFuture
<
Void
>>
machineFutures
=
new
HashMap
<>();
FileHelper
.
writeLogFile
(
"并行处理 _s"
);
for
(
int
opId
:
topologicalOrder
)
{
// 获取当前工序的依赖
Entry
op
=
findOperationById
(
chromosome
,
opId
);
List
<
Integer
>
dependencies
=
dependencyGraph
.
getOrDefault
(
opId
,
Collections
.
emptyList
());
// 等待所有依赖完成
List
<
CompletableFuture
<
Void
>>
dependencyFutures
=
dependencies
.
stream
()
.
map
(
opFutures:
:
get
)
.
filter
(
Objects:
:
nonNull
)
.
collect
(
Collectors
.
toList
());
String
opMachineKey
=
op
.
getGroupId
()
+
"_"
+
op
.
getSequence
();
OpMachine
machineOption
=
opMachineKeyMap
.
get
(
opMachineKey
);
Long
machineId
=
machineOption
.
getMachineId
();
double
processTime
=
machineOption
.
getProcessingTime
();
// 等待当前设备的上一个工序完成
CompletableFuture
<
Void
>
machineFuture
=
machineFutures
.
getOrDefault
(
machineId
,
CompletableFuture
.
completedFuture
(
null
));
// 合并所有依赖
List
<
CompletableFuture
<
Void
>>
allDependencies
=
new
ArrayList
<>(
dependencyFutures
);
allDependencies
.
add
(
machineFuture
);
// 创建当前工序的处理任务
CompletableFuture
<
Void
>
currentFuture
=
CompletableFuture
.
allOf
(
allDependencies
.
toArray
(
new
CompletableFuture
[
0
]))
.
thenRunAsync
(()
->
{
// 处理当前工序
int
actualEndTime
=
processOperation
(
op
,
machineId
,
processTime
,
machineOption
,
chromosome
,
machineIdMap
,
machineTasksCache
);
});
// 保存当前工序的Future
opFutures
.
put
(
opId
,
currentFuture
);
// 更新设备的Future
machineFutures
.
put
(
machineId
,
currentFuture
);
}
// 等待所有工序完成
CompletableFuture
.
allOf
(
opFutures
.
values
().
toArray
(
new
CompletableFuture
[
0
])).
join
();
FileHelper
.
writeLogFile
(
"calculateScheduleResult _s"
);
if
(
chromosome
.
getReOrderids
()!=
null
&&
chromosome
.
getReOrderids
().
size
()>
0
)
{
chromosome
.
getOperationSequencing
().
removeIf
(
t
->
chromosome
.
getReOrderids
().
contains
(
t
));
}
calculateScheduleResult
(
chromosome
);
}
public
void
parallelDecodeByMachine
(
Chromosome
chromosome
)
{
// 1. 获取工序处理顺序
List
<
Integer
>
operationSequencing
=
chromosome
.
getOperationSequencing
();
List
<
GlobalOperationInfo
>
globalOpList
=
chromosome
.
getGlobalOpList
();
List
<
Entry
>
allOperations
=
chromosome
.
getAllOperations
();
// 2. 构建工序依赖图
Map
<
Integer
,
List
<
Integer
>>
dependencyGraph
=
buildDependencyGraph
(
chromosome
);
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
=
new
HashMap
<>();
Map
<
Long
,
Machine
>
machineIdMap
=
chromosome
.
getMachines
().
stream
()
.
collect
(
Collectors
.
toMap
(
Machine:
:
getId
,
m
->
m
));
// 生成“工序→机器/加工时间”映射
List
<
OpMachine
>
opMachineMap
=
new
ArrayList
<>();
Map
<
String
,
OpMachine
>
opMachineKeyMap
=
new
HashMap
<>();
for
(
GlobalOperationInfo
globalOp
:
globalOpList
)
{
int
globalOpId
=
globalOp
.
getGlobalOpId
();
Entry
op
=
globalOp
.
getOp
();
int
groupId
=
globalOp
.
getGroupId
();
int
sequence
=
globalOp
.
getSequence
();
// 从MachineSelection中获取当前工序的机器选择顺序号
int
machineSeq
=
chromosome
.
getMachineSelection
().
get
(
globalOpId
);
List
<
MachineOption
>
optionalMachines
=
op
.
getMachineOptions
();
// 验证:机器顺序号必须在可选范围内
if
(
machineSeq
<
1
||
machineSeq
>
optionalMachines
.
size
())
{
throw
new
IllegalStateException
(
String
.
format
(
"全局工序%d(订单%d工序%d)的机器顺序号%d超出范围(1-%d)"
,
globalOpId
,
groupId
,
sequence
,
machineSeq
,
optionalMachines
.
size
()));
}
// 获取选择的设备ID和加工时间
MachineOption
selectedMachine
=
optionalMachines
.
get
(
machineSeq
-
1
);
OpMachine
opMachine
=
new
OpMachine
();
opMachine
.
setGroupId
(
groupId
);
opMachine
.
setSequence
(
sequence
);
opMachine
.
setMachineId
(
selectedMachine
.
getMachineId
());
opMachine
.
setProcessingTime
(
selectedMachine
.
getProcessingTime
());
opMachine
.
setRuntime
(
selectedMachine
.
getRuntime
());
opMachine
.
setSingleOut
(
selectedMachine
.
getSingleOut
());
opMachineMap
.
add
(
opMachine
);
String
key
=
opMachine
.
getGroupId
()
+
"_"
+
opMachine
.
getSequence
();
opMachineKeyMap
.
put
(
key
,
opMachine
);
}
// 初始化订单处理计数器
Map
<
Integer
,
Integer
>
orderProcessCounter
=
new
HashMap
<>();
for
(
Entry
op
:
allOperations
)
{
int
groupId
=
op
.
getGroupId
();
orderProcessCounter
.
putIfAbsent
(
groupId
,
0
);
}
Map
<
Long
,
List
<
Entry
>>
machineToOpsMap
=
new
HashMap
<>();
//按照 OperationSequencing 顺序生成 machineToOpsMap
for
(
int
groupId
:
operationSequencing
)
{
int
scheduledCount
=
orderProcessCounter
.
get
(
groupId
);
List
<
Entry
>
orderOps
=
allOperations
.
stream
()
.
filter
(
t
->
t
.
getGroupId
()
==
groupId
)
.
sorted
(
Comparator
.
comparing
(
Entry:
:
getSequence
))
.
collect
(
Collectors
.
toList
());
if
(
scheduledCount
>=
orderOps
.
size
())
{
throw
new
IllegalStateException
(
String
.
format
(
"订单%d的工序已全部调度(共%d道),无需重复处理!"
,
groupId
,
orderOps
.
size
()));
}
Entry
currentOp
=
orderOps
.
get
(
scheduledCount
);
String
opMachineKey
=
groupId
+
"_"
+
currentOp
.
getSequence
();
OpMachine
machineOption
=
opMachineKeyMap
.
get
(
opMachineKey
);
Long
machineId
=
machineOption
.
getMachineId
();
machineToOpsMap
.
computeIfAbsent
(
machineId
,
k
->
new
ArrayList
<>()).
add
(
currentOp
);
orderProcessCounter
.
put
(
groupId
,
orderProcessCounter
.
get
(
groupId
)
+
1
);
}
// 6. 按照每个设备队列中第一个工序的 sequence 递增顺序排序
List
<
Map
.
Entry
<
Long
,
List
<
Entry
>>>
sortedMachineEntries
=
new
ArrayList
<>(
machineToOpsMap
.
entrySet
());
sortedMachineEntries
.
sort
((
e1
,
e2
)
->
{
List
<
Entry
>
ops1
=
e1
.
getValue
();
List
<
Entry
>
ops2
=
e2
.
getValue
();
if
(
ops1
.
isEmpty
()
&&
ops2
.
isEmpty
())
{
return
0
;
}
if
(
ops1
.
isEmpty
())
{
return
1
;
}
if
(
ops2
.
isEmpty
())
{
return
-
1
;
}
int
sequence1
=
ops1
.
get
(
0
).
getSequence
();
int
sequence2
=
ops2
.
get
(
0
).
getSequence
();
int
sequenceCompare
=
Integer
.
compare
(
sequence1
,
sequence2
);
if
(
sequenceCompare
==
0
)
{
// sequence 相同的情况下,按照设备下 Entry 的数量递增排序
return
Integer
.
compare
(
ops1
.
size
(),
ops2
.
size
());
}
else
{
return
sequenceCompare
;
}
});
// 7. 初始化同步机制
// Map<Integer, CompletableFuture<Void>> opFutures = new ConcurrentHashMap<>();
// Map<Long, CompletableFuture<Void>> machineFutures = new ConcurrentHashMap<>();
//
// // 8. 并行处理每个设备的工序(按照排序后的顺序)
// List<CompletableFuture<Void>> allMachineFutures = new ArrayList<>();
//
// for (Map.Entry<Long, List<Entry>> entry : sortedMachineEntries) {
// final Long machineId = entry.getKey();
// final List<Entry> ops = entry.getValue();
// FileHelper.writeLogFile("使用并行处理 _s---"+machineId);
// CompletableFuture<Void> machineFuture = CompletableFuture.runAsync(() -> {
// // 顺序处理设备上的工序
// int i=0;
// for (Entry op : ops) {
// int opId = op.getId();
// String opMachineKey = op.getGroupId() + "_" + op.getSequence();
// OpMachine machineOption = opMachineKeyMap.get(opMachineKey);
//
//
// double processTime = machineOption.getProcessingTime();
// // 获取当前工序的依赖
// List<Integer> dependencies = dependencyGraph.getOrDefault(opId, Collections.emptyList());
// // 等待所有依赖完成
// List<CompletableFuture<Void>> dependencyFutures = dependencies.stream()
// .map(opFutures::get)
// .filter(Objects::nonNull)
// .collect(Collectors.toList());
//
// // 等待设备上一个工序完成
// CompletableFuture<Void> prevMachineFuture = machineFutures.getOrDefault(machineId, CompletableFuture.completedFuture(null));
//
// // 合并所有依赖
// List<CompletableFuture<Void>> allDependencies = new ArrayList<>(dependencyFutures);
// allDependencies.add(prevMachineFuture);
// if(machineId==2341) {
// FileHelper.writeLogFile("使用并行处理 ---" + machineId + "----" + i);
// }
// // 创建当前工序的处理任务
// CompletableFuture<Void> currentFuture = CompletableFuture.allOf(allDependencies.toArray(new CompletableFuture[0]))
// .thenRun(() -> {
// // 处理当前工序
// int actualEndTime = processOperation(op,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache);
//
// });
//
// // 保存当前工序的Future
// opFutures.put(opId, currentFuture);
// // 更新设备的Future
// machineFutures.put(machineId, currentFuture);
//
// // 等待当前工序完成
// try {
// currentFuture.get();
// } catch (Exception e) {
// e.printStackTrace();
// }
// i++;
// if(i==ops.size())
// {
// FileHelper.writeLogFile("使用并行处理 _e---"+machineId);
//
// }
// }
// });
//
// allMachineFutures.add(machineFuture);
// }
// 7. 改进的并行处理:只对工序少的设备并行,工序多的设备串行
Map
<
Integer
,
Boolean
>
opCompleted
=
new
HashMap
<>();
final
Object
lock
=
new
Object
();
List
<
Thread
>
threads
=
new
ArrayList
<>();
for
(
Map
.
Entry
<
Long
,
List
<
Entry
>>
entry
:
sortedMachineEntries
)
{
final
Long
machineId
=
entry
.
getKey
();
final
List
<
Entry
>
ops
=
entry
.
getValue
();
// 工序超过500的设备直接在主线程串行处理
if
(
ops
.
size
()
>
500
)
{
// FileHelper.writeLogFile("设备 " + machineId + " 有 " + ops.size() + " 个工序,直接串行处理");
processMachineOps
(
chromosome
,
machineId
,
ops
,
dependencyGraph
,
opCompleted
,
lock
,
opMachineKeyMap
,
machineIdMap
,
machineTasksCache
);
}
else
{
// 工序少的设备创建线程处理
Thread
thread
=
new
Thread
(()
->
{
processMachineOps
(
chromosome
,
machineId
,
ops
,
dependencyGraph
,
opCompleted
,
lock
,
opMachineKeyMap
,
machineIdMap
,
machineTasksCache
);
});
thread
.
start
();
threads
.
add
(
thread
);
}
}
// 等待所有线程完成
for
(
Thread
thread
:
threads
)
{
try
{
thread
.
join
();
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
}
// 9. 等待所有设备处理完成
// CompletableFuture.allOf(allMachineFutures.toArray(new CompletableFuture[0])).join();
if
(
chromosome
.
getReOrderids
()!=
null
&&
chromosome
.
getReOrderids
().
size
()>
0
)
{
chromosome
.
getOperationSequencing
().
removeIf
(
t
->
chromosome
.
getReOrderids
().
contains
(
t
));
}
calculateScheduleResult
(
chromosome
);
}
/**
* 处理单个设备的工序
*/
private
void
processMachineOps
(
Chromosome
chromosome
,
Long
machineId
,
List
<
Entry
>
ops
,
Map
<
Integer
,
List
<
Integer
>>
dependencyGraph
,
Map
<
Integer
,
Boolean
>
opCompleted
,
Object
lock
,
Map
<
String
,
OpMachine
>
opMachineKeyMap
,
Map
<
Long
,
Machine
>
machineIdMap
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
)
{
//long machineStartTime = System.currentTimeMillis();
for
(
int
i
=
0
;
i
<
ops
.
size
();
i
++)
{
Entry
op
=
ops
.
get
(
i
);
int
opId
=
op
.
getId
();
long
opStartTime
=
System
.
currentTimeMillis
();
// 获取当前工序的依赖
List
<
Integer
>
dependencies
=
dependencyGraph
.
getOrDefault
(
opId
,
Collections
.
emptyList
());
// 等待所有依赖完成
boolean
allDependenciesCompleted
;
synchronized
(
lock
)
{
allDependenciesCompleted
=
true
;
for
(
int
depId
:
dependencies
)
{
if
(!
opCompleted
.
getOrDefault
(
depId
,
false
))
{
allDependenciesCompleted
=
false
;
break
;
}
}
}
if
(!
allDependenciesCompleted
)
{
// 需要等待依赖
waitForDependencies
(
dependencies
,
opCompleted
,
lock
);
}
String
opMachineKey
=
op
.
getGroupId
()
+
"_"
+
op
.
getSequence
();
OpMachine
machineOption
=
opMachineKeyMap
.
get
(
opMachineKey
);
double
processTime
=
machineOption
.
getProcessingTime
();
// 处理当前工序
// long processStartTime = System.currentTimeMillis();
int
actualEndTime
=
processOperation
(
op
,
machineId
,
processTime
,
machineOption
,
chromosome
,
machineIdMap
,
machineTasksCache
);
// long processEndTime = System.currentTimeMillis();
// 标记工序完成
synchronized
(
lock
)
{
opCompleted
.
put
(
opId
,
true
);
}
// long opEndTime = System.currentTimeMillis();
// if (i % 100 == 0 || i == ops.size() - 1) {
// FileHelper.writeLogFile("设备 " + machineId + " 工序 " + i + "/" + ops.size() +
// " 完成,总耗时:" + (opEndTime - machineStartTime) + "ms,本工序耗时:" + (opEndTime - opStartTime) + "ms");
// }
}
// long machineEndTime = System.currentTimeMillis();
// FileHelper.writeLogFile("设备 " + machineId + " 处理完成,总工序:" + ops.size() +
// ",总耗时:" + (machineEndTime - machineStartTime) + "ms");
}
/**
* 等待依赖工序完成
*/
private
void
waitForDependencies
(
List
<
Integer
>
dependencies
,
Map
<
Integer
,
Boolean
>
opCompleted
,
Object
lock
)
{
while
(
true
)
{
boolean
allCompleted
;
synchronized
(
lock
)
{
allCompleted
=
true
;
for
(
int
depId
:
dependencies
)
{
if
(!
opCompleted
.
getOrDefault
(
depId
,
false
))
{
allCompleted
=
false
;
break
;
}
}
if
(
allCompleted
)
{
break
;
}
}
// 短暂休眠,避免CPU空转
try
{
Thread
.
sleep
(
10
);
}
catch
(
InterruptedException
e
)
{
Thread
.
currentThread
().
interrupt
();
break
;
}
}
}
/**
* 构建工序依赖图,只考虑通过 getPrevOperationId 定义的依赖关系
*/
private
Map
<
Integer
,
List
<
Integer
>>
buildDependencyGraph
(
Chromosome
chromosome
)
{
Map
<
Integer
,
List
<
Integer
>>
dependencyGraph
=
new
HashMap
<>();
// 只添加通过 getPrevOperationId 定义的依赖关系
for
(
Entry
op
:
chromosome
.
getAllOperations
())
{
int
opId
=
op
.
getId
();
List
<
Integer
>
dependencies
=
new
ArrayList
<>();
// 添加前序工序依赖(包括订单内和跨订单的依赖)
for
(
OperationDependency
dep
:
op
.
getPrevEntryIds
())
{
dependencies
.
add
(
dep
.
getPrevOperationId
());
}
dependencyGraph
.
put
(
opId
,
dependencies
);
}
return
dependencyGraph
;
}
/**
* 拓扑排序
*/
private
List
<
Integer
>
topologicalSort
(
Map
<
Integer
,
List
<
Integer
>>
graph
,
Chromosome
chromosome
)
{
List
<
Integer
>
result
=
new
ArrayList
<>();
Map
<
Integer
,
Integer
>
inDegree
=
new
HashMap
<>();
// 初始化入度
for
(
Integer
node
:
graph
.
keySet
())
{
inDegree
.
put
(
node
,
0
);
}
for
(
List
<
Integer
>
dependencies
:
graph
.
values
())
{
for
(
Integer
dep
:
dependencies
)
{
inDegree
.
put
(
dep
,
inDegree
.
getOrDefault
(
dep
,
0
)
+
1
);
}
}
// 获取订单处理顺序
List
<
Integer
>
operationSequencing
=
chromosome
.
getOperationSequencing
();
// 构建订单ID到工序ID的映射
Map
<
Integer
,
List
<
Integer
>>
orderToOpIdsMap
=
new
HashMap
<>();
for
(
Entry
op
:
chromosome
.
getAllOperations
())
{
int
groupId
=
op
.
getGroupId
();
int
opId
=
op
.
getId
();
orderToOpIdsMap
.
computeIfAbsent
(
groupId
,
k
->
new
ArrayList
<>()).
add
(
opId
);
}
// 按照 OperationSequencing 的顺序处理订单
for
(
int
groupId
:
operationSequencing
)
{
List
<
Integer
>
opIds
=
orderToOpIdsMap
.
getOrDefault
(
groupId
,
Collections
.
emptyList
());
// 处理当前订单的所有工序
Queue
<
Integer
>
queue
=
new
LinkedList
<>();
for
(
int
opId
:
opIds
)
{
if
(
inDegree
.
getOrDefault
(
opId
,
0
)
==
0
)
{
queue
.
offer
(
opId
);
}
}
while
(!
queue
.
isEmpty
())
{
Integer
node
=
queue
.
poll
();
result
.
add
(
node
);
if
(
graph
.
containsKey
(
node
))
{
for
(
Integer
neighbor
:
graph
.
get
(
node
))
{
int
newInDegree
=
inDegree
.
get
(
neighbor
)
-
1
;
inDegree
.
put
(
neighbor
,
newInDegree
);
if
(
newInDegree
==
0
&&
opIds
.
contains
(
neighbor
))
{
queue
.
offer
(
neighbor
);
}
}
}
}
}
return
result
;
}
/**
* 根据工序ID查找工序
*/
private
Entry
findOperationById
(
Chromosome
chromosome
,
int
opId
)
{
for
(
Entry
op
:
chromosome
.
getAllOperations
())
{
if
(
op
.
getId
()
==
opId
)
{
return
op
;
}
}
return
null
;
}
private
int
processOperation
(
Entry
currentOp
,
Long
machineId
,
double
processTime
,
OpMachine
machineOption
,
Chromosome
chromosome
,
Map
<
Long
,
Machine
>
machineIdMap
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
)
{
Machine
targetMachine
=
machineIdMap
.
get
(
machineId
);
int
prevtime
=
0
;
//后处理时间
int
teardownTime
=
currentOp
.
getTeardownTime
();
if
(!
currentOp
.
getPrevEntryIds
().
isEmpty
())
{
// 处理多个前工序
prevtime
=
CalPrevtime
(
prevtime
,
currentOp
,
chromosome
,
processTime
,
targetMachine
);
}
int
bomtime
=
getOperationBOMTime
(
currentOp
,
chromosome
);
int
prevendtime
=
prevtime
;
prevtime
=
Math
.
max
(
prevtime
,
bomtime
);
Machine
machine
=
machineIdMap
.
get
(
machineId
);
int
actualEndTime
=
processWithSingleMachine
(
currentOp
,
machine
,
processTime
,
prevtime
,
machineOption
,
chromosome
,
false
,
prevendtime
,
machineTasksCache
);
return
actualEndTime
;
}
private
int
processWithSingleMachine
(
Entry
operation
,
Machine
machine
,
double
processingTime
,
int
prevOperationEndTime
,
OpMachine
machineOption
,
Chromosome
chromosome
,
boolean
calbom
,
int
prevendtime
)
{
int
prevOperationEndTime
,
OpMachine
machineOption
,
Chromosome
chromosome
,
boolean
calbom
,
int
prevendtime
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
)
{
int
processingTimeTotal
=
0
;
int
earliestStartTime
=
prevOperationEndTime
;
if
(
operation
.
getConstTime
()==
1
)
//常数时间
...
...
@@ -551,12 +1144,16 @@ if(finishedOrder==null||finishedOrder.size()==0)
}
int
setupTime
=
0
;
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
=
chromosome
.
getResult
().
stream
()
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
;
if
(
machineTasksCache
.
containsKey
(
machine
.
getId
()))
{
machineTasks
=
machineTasksCache
.
get
(
machine
.
getId
());
}
else
{
machineTasks
=
chromosome
.
getResult
().
stream
()
.
filter
(
t
->
t
.
getMachineId
()
==
machine
.
getId
())
.
sorted
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getStartTime
))
.
collect
(
Collectors
.
toCollection
(
CopyOnWriteArrayList:
:
new
));
machineTasksCache
.
put
(
machine
.
getId
(),
machineTasks
);
}
GAScheduleResult
lastGeneOnMachine
=
null
;
if
(
machineTasks
!=
null
&&
machineTasks
.
size
()>
0
)
...
...
@@ -595,7 +1192,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
:
earliestStartTime
;
}
bomtime
=
EditOperationBOMTime
(
operation
,
chromosome
,
earliestStartTime
);
bomtime
=
EditOperationBOMTime
(
operation
,
chromosome
,
earliestStartTime
,
machineTasksCache
);
if
(
bomtime
>
prevendtime
&&
bomtime
<
earliestStartTimeold
)
...
...
@@ -610,7 +1207,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
.
sorted
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getStartTime
))
.
collect
(
Collectors
.
toCollection
(
CopyOnWriteArrayList:
:
new
));
machineTasksCache
.
put
(
machine
.
getId
(),
machineTasks
);
if
(
machineTasks
!=
null
&&
machineTasks
.
size
()>
0
&&
_globalParam
.
is_smoothChangeOver
())
{
...
...
@@ -747,7 +1344,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
// FileHelper.writeLogFile(" 结束 "+ConvertTime(startTime)+"--"+ConvertTime(endTime)+" "+operation.getGroupId()+" : "+operation.getId()+",处理时间: " + processingTime + ", 后处理: " + teardownTime +
// ", 前处理: " + preTime + ", 换型: " + setupTime+ ", 数量: " + operation.getQuantity()+ ", 设备: "+machine.getId()+ ", 是否可中断: "+operation.getIsInterrupt());
machineTasksCache
.
remove
(
machine
.
getId
());
return
endTime
;
}
...
...
@@ -931,7 +1528,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
return
Math
.
max
(
rawTime
,
sfTime
);
}
private
int
EditOperationBOMTime
(
Entry
currentOp
,
Chromosome
chromosome
,
int
earliestStartTime
)
{
private
int
EditOperationBOMTime
(
Entry
currentOp
,
Chromosome
chromosome
,
int
earliestStartTime
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
)
{
List
<
OrderMaterialRequirement
>
opboms
=
currentOp
.
getMaterialRequirements
();
...
...
@@ -940,18 +1537,19 @@ if(finishedOrder==null||finishedOrder.size()==0)
return
0
;
}
LocalDateTime
earliestStartTime1
=
baseTime
.
plusSeconds
(
earliestStartTime
);
materialRequirementService
.
EditOperationBOM
(
currentOp
,
chromosome
,
earliestStartTime1
,
this
);
materialRequirementService
.
EditOperationBOM
(
currentOp
,
chromosome
,
earliestStartTime1
,
this
,
machineTasksCache
);
return
getOperationBOMTime
(
currentOp
,
chromosome
);
}
public
void
EditorderOperation
(
Chromosome
chromosome
,
int
groupId
,
double
needed
){
public
void
EditorderOperation
(
Chromosome
chromosome
,
int
groupId
,
double
needed
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
){
List
<
Entry
>
orderOps
=
chromosome
.
getAllOperations
().
stream
()
.
filter
(
t
->
t
.
getGroupId
()
==
groupId
)
.
sorted
(
Comparator
.
comparing
(
Entry:
:
getSequence
))
.
collect
(
Collectors
.
toList
());
for
(
Entry
currentOp
:
orderOps
)
{
if
(
currentOp
.
isNewCreate
())
{
...
...
@@ -1002,8 +1600,8 @@ return getOperationBOMTime(currentOp, chromosome);
.
filter
(
m
->
m
.
getId
()
==
machineId
)
.
findFirst
()
.
orElse
(
null
);
int
actualEndTime
=
processWithSingleMachine
(
currentOp
,
machine
,
processTime
,
prevtime
,
opMachine
,
chromosome
,
true
,
prevendtime
);
// 缓存机器任务
int
actualEndTime
=
processWithSingleMachine
(
currentOp
,
machine
,
processTime
,
prevtime
,
opMachine
,
chromosome
,
true
,
prevendtime
,
machineTasksCache
);
}
...
...
src/main/java/com/aps/service/Algorithm/MaterialRequirementService.java
View file @
e56eef9d
...
...
@@ -1140,7 +1140,7 @@ if(headers1==null)
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public
void
EditOperationBOM
(
Entry
operation
,
Chromosome
chromosome
,
LocalDateTime
earliestStartTime
,
GeneticDecoder
coder
)
{
public
void
EditOperationBOM
(
Entry
operation
,
Chromosome
chromosome
,
LocalDateTime
earliestStartTime
,
GeneticDecoder
coder
,
Map
<
Long
,
CopyOnWriteArrayList
<
GAScheduleResult
>>
machineTasksCache
)
{
List
<
OrderMaterialRequirement
>
materialRequirements
=
new
ArrayList
<>();
String
sceneId
=
chromosome
.
getScenarioID
();
...
...
@@ -1319,7 +1319,7 @@ if(headers1==null)
for
(
Integer
orderid
:
orderids
)
{
coder
.
ClearorderOperationResult
(
chromosome
,
orderid
);
coder
.
EditorderOperation
(
chromosome
,
orderid
,
needed
);
coder
.
EditorderOperation
(
chromosome
,
orderid
,
needed
,
machineTasksCache
);
}
}
else
{
...
...
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