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
d49ae691
Commit
d49ae691
authored
Jan 11, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
计算可用时间时,维修记录在可用时间的中间,造成死循环
parent
da07192c
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
162 additions
and
69 deletions
+162
-69
ScheduleParams.java
src/main/java/com/aps/entity/Algorithm/ScheduleParams.java
+1
-1
GeneticAlgorithm.java
...main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
+19
-8
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+15
-7
MachineCalculator.java
...ain/java/com/aps/service/Algorithm/MachineCalculator.java
+31
-21
MaterialRequirementService.java
...com/aps/service/Algorithm/MaterialRequirementService.java
+1
-1
NSGAIIUtils.java
src/main/java/com/aps/service/Algorithm/NSGAIIUtils.java
+3
-3
RoutingDataService.java
...in/java/com/aps/service/Algorithm/RoutingDataService.java
+15
-2
AlgorithmScheduler6.java
src/main/java/com/aps/service/plan/AlgorithmScheduler6.java
+1
-1
AlgorithmScheduler7.java
src/main/java/com/aps/service/plan/AlgorithmScheduler7.java
+1
-1
AlgorithmScheduler8.java
src/main/java/com/aps/service/plan/AlgorithmScheduler8.java
+2
-2
MachineSchedulerService.java
...in/java/com/aps/service/plan/MachineSchedulerService.java
+47
-11
PlanResultService.java
src/main/java/com/aps/service/plan/PlanResultService.java
+21
-6
MachineSchedulerTest.java
src/test/java/com/aps/demo/MachineSchedulerTest.java
+1
-1
PlanResultServiceTest.java
src/test/java/com/aps/demo/PlanResultServiceTest.java
+4
-4
No files found.
src/main/java/com/aps/entity/Algorithm/ScheduleParams.java
View file @
d49ae691
...
...
@@ -14,7 +14,7 @@ public class ScheduleParams {
private
LocalDateTime
baseTime
;
// 当前基准时间
// 基础参数(自适应调整的基准值)
private
static
final
int
MIN_POPULATION_SIZE
=
2
0
;
private
static
final
int
MIN_POPULATION_SIZE
=
5
0
;
private
static
final
int
MAX_POPULATION_SIZE
=
500
;
private
static
final
int
MIN_MAX_ITERATIONS
=
20
;
private
static
final
int
MAX_MAX_ITERATIONS
=
200
;
...
...
src/main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
View file @
d49ae691
...
...
@@ -8,6 +8,7 @@ import com.aps.entity.Algorithm.*;
import
com.aps.entity.Algorithm.IDAndChildID.GroupResult
;
import
com.aps.entity.basic.*
;
import
com.aps.service.plan.MachineSchedulerService
;
import
com.aps.service.plan.SceneService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
java.time.LocalDateTime
;
...
...
@@ -39,8 +40,11 @@ public class GeneticAlgorithm {
private
List
<
OrderMaterialRequirement
>
orderMaterials
;
private
SceneService
_sceneService
;
public
GeneticAlgorithm
(
GlobalParam
globalParam
,
List
<
Machine
>
machines
,
List
<
Order
>
orders
,
List
<
Material
>
materials
,
MachineSchedulerService
machineScheduler
,
List
<
GroupResult
>
entryRel
,
MaterialRequirementService
_materialRequirementService
)
{
List
<
Material
>
materials
,
MachineSchedulerService
machineScheduler
,
List
<
GroupResult
>
entryRel
,
MaterialRequirementService
_materialRequirementService
,
SceneService
sceneService
)
{
this
.
machines
=
machines
;
this
.
orders
=
orders
;
this
.
materials
=
materials
;
...
...
@@ -48,6 +52,7 @@ public class GeneticAlgorithm {
_GlobalParam
=
globalParam
;
_entryRel
=
entryRel
;
materialRequirementService
=
_materialRequirementService
;
_sceneService
=
sceneService
;
}
...
...
@@ -69,6 +74,7 @@ public class GeneticAlgorithm {
}
if
(
materials
!=
null
&&
materials
.
size
()>
0
)
{
materialRequirementService
.
init
(
materials
,
orders
,
allOperations
,
_entryRel
,
machineScheduler
,
machines
,
_GlobalParam
);
orderMaterials
=
materialRequirementService
.
buildMultiLevelRequirementNetwork
(
param
.
getBaseTime
());
...
...
@@ -92,7 +98,7 @@ public class GeneticAlgorithm {
List
<
Chromosome
>
population
=
initialization
.
generateInitialPopulation
(
param
,
globalOpList
);
population
=
chromosomeDistinct
(
population
);
//
population= chromosomeDistinct(population);
...
...
@@ -174,7 +180,7 @@ public class GeneticAlgorithm {
nextPopulation
=
chromosomeDistinct
(
nextPopulation
);
Chromosomedecode
(
param
,
allOperations
,
globalOpList
,
nextPopulation
);
FileHelper
.
writeLogFile
(
"变异批量解码-----------
开始
-------"
);
FileHelper
.
writeLogFile
(
"变异批量解码-----------
结束
-------"
);
// // 精英保留
// List<Chromosome> population1 = population.stream()
// .sorted((c1, c2) -> Double.compare(c2.getFitness(), c1.getFitness()))
...
...
@@ -211,7 +217,7 @@ public class GeneticAlgorithm {
Iteration
++;
}
if
(
Iteration
>
5
)
if
(
Iteration
>
10
)
{
break
;
}
...
...
@@ -240,14 +246,14 @@ public class GeneticAlgorithm {
private
Chromosome
GetBest
(
List
<
List
<
Chromosome
>>
fronts
,
String
msg
)
{
WriteKpis
(
fronts
,
msg
);
//
WriteKpis(fronts,msg);
List
<
Chromosome
>
fChromosomes
=
fronts
.
get
(
0
);
fChromosomes
.
sort
((
c1
,
c2
)
->
{
int
rankCompare
=
Double
.
compare
(
c1
.
getCrowdingDistance
(),
c2
.
getCrowdingDistance
());
return
rankCompare
!=
0
?
rankCompare
:
Double
.
compare
(
c1
.
getFitness
(),
c2
.
getFitness
());
});
Chromosome
best
=
fChromosomes
.
get
(
0
);
WriteKpi
(
best
,
"最大"
);
//
WriteKpi(best,"最大");
return
best
;
}
...
...
@@ -289,6 +295,8 @@ public class GeneticAlgorithm {
private
void
Chromosomedecode
(
ScheduleParams
param
,
List
<
Entry
>
allOperations
,
List
<
GlobalOperationInfo
>
globalOpList
,
List
<
Chromosome
>
population
)
{
FileHelper
.
writeLogFile
(
"解码---------------"
+
population
.
size
()
);
GeneticDecoder
decoder
=
new
GeneticDecoder
(
_GlobalParam
,
param
.
getBaseTime
(),
machines
,
orders
,
materials
,
machineScheduler
,
orderMaterials
);
if
(
population
!=
null
&&
population
.
size
()>
0
)
{
...
...
@@ -296,12 +304,15 @@ public class GeneticAlgorithm {
chromosome
.
setResult
(
new
ArrayList
<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome
.
setInitMachines
(
ProductionDeepCopyUtil
.
deepCopyList
(
machines
));
// 简单拷贝,实际可能需要深拷贝
//
chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome
.
setMachines
(
ProductionDeepCopyUtil
.
deepCopyList
(
machines
));
// 简单拷贝,实际可能需要深拷贝
chromosome
.
setAllOperations
(
allOperations
);
// 简单拷贝,实际可能需要深拷贝
chromosome
.
setGlobalOpList
(
globalOpList
);
// 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
decoder
.
decodeChromosomeWithCache
(
chromosome
);
chromosome
.
setBaseTime
(
param
.
getBaseTime
());
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder
.
decodeChromosomeWithCache
(
chromosome
);
if
(
chromosome
.
getFitness
()
==
0
)
{
chromosome
.
setFitness
(
_fitnessCalculator
.
calculateFitness
(
chromosome
,
_objectiveWeights
));
}
...
...
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
d49ae691
...
...
@@ -67,7 +67,7 @@ public class GeneticDecoder {
public
Chromosome
decodeChromosomeWithCache
(
Chromosome
chromosome
)
{
String
cacheKey
=
createCacheKey
(
chromosome
);
FileHelper
.
writeLogFile
(
"解码-----------开始-------"
+
chromosome
.
getID
()+
":"
+
cacheKey
);
//
FileHelper.writeLogFile("解码-----------开始-------"+chromosome.getID()+":"+cacheKey );
_allOperations
=
chromosome
.
getAllOperations
();
if
(
orderMaterials
!=
null
&&
orderMaterials
.
size
()>
0
&&
_globalParam
.
isIsCheckSf
())
{
...
...
@@ -84,7 +84,7 @@ public class GeneticDecoder {
// 缓存命中:复用缓存结果
Chromosome
cachedResult
=
decodingCache
.
get
(
cacheKey
);
// 赋值给染色体
chromosome
.
setInitMachines
(
ProductionDeepCopyUtil
.
deepCopyList
(
cachedResult
.
getInitMachines
(),
Machine
.
class
));
//
chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(cachedResult.getInitMachines(),Machine.class));
chromosome
.
setObjectives
(
cachedResult
.
getObjectives
());
chromosome
.
setMakespan
(
cachedResult
.
getMakespan
());
...
...
@@ -94,7 +94,7 @@ public class GeneticDecoder {
chromosome
.
setDelayTime
(
cachedResult
.
getDelayTime
());
chromosome
.
setResult
(
ProductionDeepCopyUtil
.
deepCopyList
(
cachedResult
.
getResult
(),
GAScheduleResult
.
class
));
// Chromosome chromosomen= ProductionDeepCopyUtil.deepCopy(cachedResult);
FileHelper
.
writeLogFile
(
"解码-----------结束-------"
+
chromosome
.
getID
());
//
FileHelper.writeLogFile("解码-----------结束-------"+chromosome.getID());
return
chromosome
;
}
...
...
@@ -125,7 +125,7 @@ public class GeneticDecoder {
}
finally
{
cacheLock
.
unlock
();
}
FileHelper
.
writeLogFile
(
"解码-----------结束-------"
+
chromosome
.
getID
());
//
FileHelper.writeLogFile("解码-----------结束-------"+chromosome.getID());
return
chromosome
;
}
...
...
@@ -376,8 +376,10 @@ if(finishedOrder==null||finishedOrder.size()==0)
int
preTime
=
machineOption
.
getPreTime
();
int
setupTime
=
calculateSetupTime
(
chromosome
.
getResult
(),
operation
,
machine
,
machineOption
);
FileHelper
.
writeLogFile
(
" "
+
operation
.
getGroupId
()+
" : "
+
operation
.
getId
()+
",处理时间: "
+
processingTime
+
", 后处理: "
+
teardownTime
+
", 前处理: "
+
preTime
+
", 换型: "
+
setupTime
+
", 数量: "
+
operation
.
getQuantity
()+
", 设备: "
+
machine
.
getId
()+
", 是否可中断: "
+
operation
.
getIsInterrupt
());
// FileHelper.writeLogFile(" 开始 "+operation.getGroupId()+" : "+operation.getId()+",处理时间: " + processingTime + ", 后处理: " + teardownTime +
// ", 前处理: " + preTime + ", 换型: " + setupTime+ ", 数量: " + operation.getQuantity()+ ", 设备: "+machine.getId()+ ", 是否可中断: "+operation.getIsInterrupt());
// 确定任务的最早开始时间(基于前一道工序的完整结束时间,包含后处理)
...
...
@@ -432,6 +434,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
List
<
ScheduleResultDetail
>
geneDetails
=
machineCalculator
.
getNextAvailableTime
(
machine
,
earliestStartTime
,
-
1
,
processingTimeTotal
,
chromosome
.
getResult
(),
operation
.
IsInterrupt
!=
1
,
true
,
processingTime
,
operation
.
getQuantity
(),
true
);
...
...
@@ -510,6 +513,11 @@ if(finishedOrder==null||finishedOrder.size()==0)
// System.out.println("huanxingshijian="+result.getChangeOverTime()+"-------------------"+result.getOrderId()+"--------"+result.getExecId()+"---------"+prev.getOrderId()+"--------"+prev.getExecId());
chromosome
.
getResult
().
add
(
result
);
// FileHelper.writeLogFile(" 结束 "+ConvertTime(startTime)+"--"+ConvertTime(endTime)+" "+operation.getGroupId()+" : "+operation.getId()+",处理时间: " + processingTime + ", 后处理: " + teardownTime +
// ", 前处理: " + preTime + ", 换型: " + setupTime+ ", 数量: " + operation.getQuantity()+ ", 设备: "+machine.getId()+ ", 是否可中断: "+operation.getIsInterrupt());
return
endTime
;
}
...
...
@@ -819,7 +827,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
return
(
timeDifference
/
time1
)
>
qty
?
qty
:
(
timeDifference
/
time1
);
}
private
String
ConvertTime
(
int
minute
)
{
return
baseTime
.
plusSeconds
(
minute
).
format
(
java
.
time
.
format
.
DateTimeFormatter
.
ofPattern
(
"MM-dd HH:mm"
));
return
baseTime
.
plusSeconds
(
minute
).
format
(
java
.
time
.
format
.
DateTimeFormatter
.
ofPattern
(
"
YYYY-
MM-dd HH:mm"
));
}
private
int
calculateSetupTime
(
List
<
GAScheduleResult
>
existingGenes
,
Entry
operation
,
Machine
machine
,
MachineOption
machineOption
)
{
GAScheduleResult
lastGeneOnMachine
=
existingGenes
.
stream
()
...
...
src/main/java/com/aps/service/Algorithm/MachineCalculator.java
View file @
d49ae691
package
com
.
aps
.
service
.
Algorithm
;
import
com.aps.common.util.FileHelper
;
import
com.aps.common.util.ProductionDeepCopyUtil
;
import
com.aps.entity.Algorithm.GAScheduleResult
;
import
com.aps.entity.Algorithm.ScheduleResultDetail
;
...
...
@@ -180,11 +181,16 @@ public class MachineCalculator {
LocalDateTime
prevEnd
=
LocalDateTime
.
of
(
2000
,
1
,
1
,
0
,
0
,
0
);
List
<
ScheduleResultDetail
>
times
=
new
ArrayList
<>();
List
<
ScheduleResultDetail
>
oldTimes
=
new
ArrayList
<>();
List
<
TimeSegment
>
timeSegments
=
findAvailableSegments
(
machine
,
currentTime
,
machineTasks
,
remainingTime
,
isInterrupt
);
int
i
=
0
;
int
i
=
0
;
while
(
remainingTime
>
0
)
{
TimeSegment
shift
=
timeSegments
.
get
(
i
);
if
(
shift
==
null
)
break
;
LocalDateTime
shiftStart
=
shift
.
getStart
();
LocalDateTime
shiftEnd
=
shift
.
getEnd
();
...
...
@@ -218,7 +224,7 @@ i++;
return
times
;
}
/**
* 查找满足时长要求的无冲突可用时段
(对应原C#方法)
* 查找满足时长要求的无冲突可用时段
* @param machine 设备
* @param start 起始时间
* @param machineTasks 设备已有任务
...
...
@@ -234,10 +240,7 @@ i++;
boolean
requireContinuous
)
{
List
<
TimeSegment
>
availableSegments
=
new
ArrayList
<>();
LocalDateTime
current
=
start
;
if
(
requiredMinutes
>
3600
*
3999
)
{
int
i
=
0
;
}
// 预先排序设备可用片段,避免后续遍历混乱
List
<
TimeSegment
>
allUseTimeSegment
=
machine
.
getAvailability
().
stream
()
.
filter
(
slot
->
!
slot
.
isUsed
()
&&
slot
.
getType
()
!=
SegmentType
.
MAINTENANCE
)
...
...
@@ -260,9 +263,15 @@ if(requiredMinutes>3600*3999)
.
max
(
Comparator
.
comparing
(
TimeSegment:
:
getEnd
,
(
a
,
b
)
->
a
.
compareTo
(
b
)))
.
map
(
TimeSegment:
:
getEnd
)
.
orElse
(
current
);
List
<
TimeSegment
>
newSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
lastSegmentEnd
.
plusDays
(
1
));
int
days
=((
int
)
((
requiredMinutes
-
totalUseTime
)/
24
/
3600
));
if
(
days
<=
200
)
{
days
=
0
;
}
List
<
TimeSegment
>
newSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
lastSegmentEnd
.
plusDays
(
1
),
days
);
addSegmentsWithDeduplication
(
machine
,
newSegments
);
// 重新过滤可用片段
useSegments
=
filterValidUseSegments
(
machine
.
getAvailability
(),
current
,
requireContinuous
,
requiredMinutes
);
// 重新计算总可用时间
...
...
@@ -272,14 +281,15 @@ if(requiredMinutes>3600*3999)
// 若总可用时间满足要求,处理冲突
if
(
totalUseTime
>=
requiredMinutes
)
{
// 获取当前可用片段范围内的冲突
LocalDateTime
firstSegmentStart
=
useSegments
.
get
(
0
).
getStart
();
LocalDateTime
firstSegmentStart
=
useSegments
.
get
(
0
).
getStart
()
.
compareTo
(
current
)
<
0
?
current:
useSegments
.
get
(
0
).
getStart
()
;
LocalDateTime
lastSegmentEnd
=
useSegments
.
get
(
useSegments
.
size
()
-
1
).
getEnd
();
//获取维修和当前任务
List
<
TimeSegment
>
conflictSegments
=
getConflictIntervals
(
machine
,
machineTasks
,
firstSegmentStart
,
lastSegmentEnd
);
if
(
conflictSegments
==
null
||
conflictSegments
.
isEmpty
())
{
// 无冲突:直接返回可用片段(保留原有逻辑)
if
(
useSegments
.
get
(
0
).
getStart
().
compareTo
(
current
)
<
0
)
{
spiltMachineAvailable
(
machine
,
useSegments
.
get
(
0
),
current
);
spiltMachineAvailable
(
machine
,
useSegments
.
get
(
0
),
current
);
useSegments
.
get
(
0
).
setStart
(
current
);
}
return
useSegments
;
...
...
@@ -308,7 +318,7 @@ if(requiredMinutes>3600*3999)
.
max
(
Comparator
.
comparing
(
TimeSegment:
:
getEnd
,
(
a
,
b
)
->
a
.
compareTo
(
b
)))
.
map
(
TimeSegment:
:
getEnd
)
.
orElse
(
current
);
List
<
TimeSegment
>
newSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
lastSegmentEnd
.
plusDays
(
1
));
List
<
TimeSegment
>
newSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
lastSegmentEnd
.
plusDays
(
1
)
,
0
);
addSegmentsWithDeduplication
(
machine
,
newSegments
);
}
}
...
...
@@ -320,7 +330,7 @@ if(requiredMinutes>3600*3999)
LocalDateTime
currentTime
,
boolean
requireContinuous
,
double
requiredMinutes
)
{
// 空判断
:对应C#的 allSegments == null || allSegments.Count == 0
// 空判断
if
(
allSegments
==
null
||
allSegments
.
isEmpty
())
{
return
new
ArrayList
<>();
}
...
...
@@ -356,7 +366,7 @@ if(requiredMinutes>3600*3999)
return
useSegments
.
stream
()
.
mapToDouble
(
segment
->
{
// 取片段起始时间和当前时间的最大值,
对应C#的
t.Start < currentTime ? currentTime : t.Start
// 取片段起始时间和当前时间的最大值,t.Start < currentTime ? currentTime : t.Start
LocalDateTime
effectiveStart
=
segment
.
getStart
().
compareTo
(
currentTime
)
<
0
?
currentTime
:
segment
.
getStart
();
// 计算单个片段的有效时长(分钟),并乘以效率值,对应C#的 (t.End - effectiveStart).TotalMinutes * t.Efficiency
double
segmentSeconds
=
ChronoUnit
.
SECONDS
.
between
(
effectiveStart
,
segment
.
getEnd
());
...
...
@@ -373,7 +383,7 @@ if(requiredMinutes>3600*3999)
List
<
TimeSegment
>
baseValidSegments
,
LocalDateTime
currentTime
,
double
requiredContinuous
)
{
// 空判断
:对应C#的 baseValidSegments.Count == 0
// 空判断
if
(
baseValidSegments
==
null
||
baseValidSegments
.
isEmpty
())
{
return
new
ArrayList
<>();
}
...
...
@@ -383,9 +393,9 @@ if(requiredMinutes>3600*3999)
double
tempContinuous
=
0.0
;
LocalDateTime
lastSegmentEnd
=
currentTime
;
// 遍历基础有效片段,筛选出可拼接成连续时长的片段组
(对应C#的foreach)
// 遍历基础有效片段,筛选出可拼接成连续时长的片段组
for
(
TimeSegment
segment
:
baseValidSegments
)
{
// 确定有效起始时间:
对应C#的三元表达式 segment.Start > currentTime ? segment.Start : currentTime
// 确定有效起始时间:
LocalDateTime
effectiveStart
=
segment
.
getStart
().
compareTo
(
currentTime
)
>
0
?
segment
.
getStart
()
:
currentTime
;
if
(
effectiveStart
.
compareTo
(
segment
.
getEnd
())
>=
0
)
{
...
...
@@ -397,7 +407,7 @@ if(requiredMinutes>3600*3999)
if
(!
tempContinuousGroup
.
isEmpty
()
&&
effectiveStart
.
compareTo
(
lastSegmentEnd
)
!=
0
)
{
// 不衔接:先判断临时组是否满足连续时长,满足则加入结果
if
(
tempContinuous
>=
requiredContinuous
)
{
continuousCompliantSegments
.
addAll
(
tempContinuousGroup
);
// 对应C#的AddRange
continuousCompliantSegments
.
addAll
(
tempContinuousGroup
);
}
// 重置临时组
tempContinuousGroup
.
clear
();
...
...
@@ -427,7 +437,7 @@ if(requiredMinutes>3600*3999)
continuousCompliantSegments
.
addAll
(
tempContinuousGroup
);
}
// 去重并排序(避免重复片段)
,对应C#的MergeSegments方法
// 去重并排序(避免重复片段)
return
MergeSegments
(
continuousCompliantSegments
);
}
...
...
@@ -494,7 +504,7 @@ if(requiredMinutes>3600*3999)
LocalDateTime
currentTime
,
double
requiredMinutes
)
{
// 遍历所有冲突片段
,对应C#的foreach循环
// 遍历所有冲突片段
for
(
TimeSegment
conflict
:
conflictSegments
)
{
LocalDateTime
currentTime1
=
currentTime
;
// 过滤冲突前的可用片段(
...
...
@@ -578,7 +588,7 @@ if(requiredMinutes>3600*3999)
if
(
start
==
null
)
{
// 生成新时间段
List
<
TimeSegment
>
timeSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
time
.
plusDays
(
1
));
List
<
TimeSegment
>
timeSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
time
.
plusDays
(
1
)
,
0
);
machine
.
getAvailability
().
addAll
(
timeSegments
);
...
...
@@ -679,7 +689,7 @@ if(requiredMinutes>3600*3999)
if
(
isTimeAfterMaxEnd
)
{
// 生成新的时间段并添加到设备可用班次中
LocalDateTime
generateStartTime
=
maxEndTime
.
orElse
(
LocalDateTime
.
now
());
List
<
TimeSegment
>
timeSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
generateStartTime
);
List
<
TimeSegment
>
timeSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
generateStartTime
,
0
);
machine
.
getAvailability
().
addAll
(
timeSegments
);
// 更新机器列表中的对应机器
...
...
src/main/java/com/aps/service/Algorithm/MaterialRequirementService.java
View file @
d49ae691
...
...
@@ -252,7 +252,7 @@ if(routingIds.size()==0)
wrapper
.
eq
(
RoutingHeader:
:
getMaterialId
,
materialID
)
.
eq
(
RoutingHeader:
:
getIsDeleted
,
0
);
// .eq(RoutingHeader::getApprovalStatus, 1); // 添加 is_deleted=0 过滤条件
headers1
=
routingHeaderMapper
.
select
One
(
wrapper
);
headers1
=
routingHeaderMapper
.
select
List
(
wrapper
).
stream
().
findFirst
().
orElse
(
null
);
if
(
headers1
!=
null
)
{
headers
.
add
(
headers1
);
routingIds
=
headers1
.
getId
().
longValue
();
...
...
src/main/java/com/aps/service/Algorithm/NSGAIIUtils.java
View file @
d49ae691
...
...
@@ -98,7 +98,7 @@ public class NSGAIIUtils {
fronts
.
add
(
front1
);
int
i
=
0
;
while
(
fronts
.
get
(
i
).
size
()
>
0
)
{
while
(
!
fronts
.
get
(
i
).
isEmpty
()
)
{
List
<
Chromosome
>
nextFront
=
new
ArrayList
<>();
for
(
Chromosome
p
:
fronts
.
get
(
i
))
{
for
(
Chromosome
q
:
dominanceMatrix
.
get
(
p
))
{
...
...
@@ -110,9 +110,9 @@ public class NSGAIIUtils {
}
}
i
++;
if
(!
nextFront
.
isEmpty
())
{
fronts
.
add
(
nextFront
);
}
}
}
assignRankToSolutions
(
fronts
);
...
...
src/main/java/com/aps/service/Algorithm/RoutingDataService.java
View file @
d49ae691
...
...
@@ -136,7 +136,7 @@ public class RoutingDataService {
}
List
<
Entry
>
entrys
=
new
ArrayList
<>();
Set
<
Long
>
machineIds
=
new
HashSet
<>();
Map
<
Long
,
Double
>
machineIds
=
new
HashMap
<>();
for
(
int
i
=
index
;
i
<
results
.
size
();
i
++)
{
GroupResult
groupResult
=
results
.
get
(
i
);
List
<
NodeInfo
>
nodeInfoList
=
groupResult
.
getNodeInfoList
();
...
...
@@ -234,7 +234,20 @@ public class RoutingDataService {
if
(
Equipments
!=
null
&&
Equipments
.
size
()
>
0
)
{
List
<
MachineOption
>
mos
=
new
ArrayList
<>();
for
(
ProdEquipment
e
:
Equipments
)
{
machineIds
.
add
(
e
.
getEquipId
());
Double
totalprocessTime
=
e
.
getSpeed
()*
entry
.
getQuantity
();
if
(
machineIds
.
containsKey
(
e
.
getEquipId
()))
{
if
(
machineIds
.
get
(
e
.
getEquipId
())<
totalprocessTime
)
{
machineIds
.
replace
(
e
.
getEquipId
(),
totalprocessTime
);
}
}
else
{
machineIds
.
put
(
e
.
getEquipId
(),
totalprocessTime
);
}
MachineOption
mo
=
new
MachineOption
();
mo
.
setMachineId
(
e
.
getEquipId
());
mo
.
setRuntime
(
e
.
getRuntime
());
...
...
src/main/java/com/aps/service/plan/AlgorithmScheduler6.java
View file @
d49ae691
...
...
@@ -715,7 +715,7 @@ public class AlgorithmScheduler6 {
if
(
start
==
null
)
{
// 生成新时间段
List
<
TimeSegment
>
timeSegments
=
_machineScheduler
.
generateTimeSegment
(
machine
,
time
);
List
<
TimeSegment
>
timeSegments
=
_machineScheduler
.
generateTimeSegment
(
machine
,
time
,
0
);
machine
.
getAvailability
().
addAll
(
timeSegments
);
// 更新设备时间线
...
...
src/main/java/com/aps/service/plan/AlgorithmScheduler7.java
View file @
d49ae691
...
...
@@ -829,7 +829,7 @@ public class AlgorithmScheduler7 {
if
(
start
==
null
)
{
// 生成新时间段
List
<
TimeSegment
>
timeSegments
=
_machineScheduler
.
generateTimeSegment
(
machine
,
time
);
List
<
TimeSegment
>
timeSegments
=
_machineScheduler
.
generateTimeSegment
(
machine
,
time
,
0
);
machine
.
getAvailability
().
addAll
(
timeSegments
);
// 更新设备时间线
...
...
src/main/java/com/aps/service/plan/AlgorithmScheduler8.java
View file @
d49ae691
...
...
@@ -623,7 +623,7 @@ public class AlgorithmScheduler8 {
// 如果没有找到合适的时间段,生成新的时间段
System
.
out
.
println
(
" 未找到合适的工作时间段,生成新时间段"
);
List
<
TimeSegment
>
timeSegments
=
_machineScheduler
.
generateTimeSegment
(
machine
,
time
);
List
<
TimeSegment
>
timeSegments
=
_machineScheduler
.
generateTimeSegment
(
machine
,
time
,
0
);
machine
.
getAvailability
().
addAll
(
timeSegments
);
// 查找新生成的时间段
...
...
@@ -887,7 +887,7 @@ public class AlgorithmScheduler8 {
if
(
start
==
null
)
{
// 生成新时间段
List
<
TimeSegment
>
timeSegments
=
_machineScheduler
.
generateTimeSegment
(
machine
,
time
);
List
<
TimeSegment
>
timeSegments
=
_machineScheduler
.
generateTimeSegment
(
machine
,
time
,
0
);
machine
.
getAvailability
().
addAll
(
timeSegments
);
// 更新设备时间线
...
...
src/main/java/com/aps/service/plan/MachineSchedulerService.java
View file @
d49ae691
...
...
@@ -3,6 +3,7 @@ package com.aps.service.plan;
import
com.aps.common.util.FileHelper
;
import
com.aps.common.util.ProductionDeepCopyUtil
;
import
com.aps.entity.basic.*
;
...
...
@@ -114,20 +115,35 @@ public class MachineSchedulerService {
return
timeline
;
}
public
List
<
TimeSegment
>
generateTimeSegment
(
Machine
machine
,
LocalDateTime
currentTime
)
{
public
List
<
TimeSegment
>
generateTimeSegment
(
Machine
machine
,
LocalDateTime
currentTime
,
int
days
)
{
if
(
days
==
0
)
{
days
=
200
;
}
cacheLock
.
lock
();
Long
machineId
=
machine
.
getId
();
MachineTimeline
timeline
=
timelineCache
.
get
(
machineId
);
try
{
if
(
timeline
==
null
)
{
if
(
currentTime
==
null
)
{
currentTime
=
LocalDateTime
.
now
();
}
timeline
=
new
MachineTimeline
();
timeline
.
setMachineId
(
machine
.
getId
());
timeline
.
setValidFrom
(
currentTime
);
timeline
.
setValidTo
(
currentTime
.
plusDays
(
200
));
timeline
.
setValidTo
(
currentTime
.
plusDays
(
days
));
timeline
.
setLastUpdated
(
LocalDateTime
.
now
());
timeline
.
setSegments
(
new
ArrayList
<>());
}
else
{
if
(
currentTime
==
null
)
{
currentTime
=
timeline
.
getValidTo
().
plusDays
(
1
);
}
if
(
timeline
.
getValidTo
().
compareTo
(
currentTime
)
>
0
)
{
LocalDateTime
currentTime1
=
currentTime
;
List
<
TimeSegment
>
timeSegments
=
timeline
.
getSegments
().
stream
()
...
...
@@ -136,7 +152,7 @@ try {
return
ProductionDeepCopyUtil
.
deepCopyList
(
timeSegments
,
TimeSegment
.
class
);
}
else
{
timeline
.
setValidTo
(
currentTime
.
plusDays
(
200
));
timeline
.
setValidTo
(
currentTime
.
plusDays
(
days
));
timeline
.
setLastUpdated
(
LocalDateTime
.
now
());
}
}
...
...
@@ -145,7 +161,7 @@ try {
}
LocalDate
currentDate
=
currentTime
.
toLocalDate
();
LocalDate
endDate
=
currentTime
.
plusDays
(
200
).
toLocalDate
();
LocalDate
endDate
=
currentTime
.
plusDays
(
days
).
toLocalDate
();
List
<
TimeSegment
>
segments
=
new
ArrayList
<>();
...
...
@@ -177,7 +193,7 @@ try {
if
(
maintenanceWindow
.
getStartTime
().
isBefore
(
currentTime
)&&
maintenanceWindow
.
getEndTime
().
isAfter
(
maxEnd
))
{
currentTime
=
maintenanceWindow
.
getEndTime
();
segments
=
generateTimeSegment
(
machine
,
currentTime
);
segments
=
generateTimeSegment
(
machine
,
currentTime
,
days
);
break
;
}
else
{
updateSegmentsForMaintenance
(
segments
,
maintenanceWindow
.
getStartTime
(),
maintenanceWindow
.
getEndTime
());
...
...
@@ -192,15 +208,35 @@ try {
timeline
.
setSegments
(
mergeSegments
(
timeline
.
getSegments
()));
segments
=
mergeSegments
(
segments
);
cacheLock
.
lock
();
try
{
timelineCache
.
put
(
machineId
,
timeline
);
}
finally
{
cacheLock
.
unlock
();
cacheLock
.
lock
();
try
{
timelineCache
.
put
(
machineId
,
timeline
);
}
finally
{
cacheLock
.
unlock
();
}
return
segments
;
}
/**
* 追加片段并去重、排序(避免冗余片段和遍历混乱)
*/
public
void
addSegmentsWithDeduplication
(
Machine
machine
,
List
<
TimeSegment
>
newSegments
)
{
// 空判断:新片段为null或空集合时直接返回,对应C#的 newSegments == null || newSegments.Count == 0
if
(
newSegments
==
null
||
newSegments
.
isEmpty
())
{
return
;
}
// 追加新片段,对应C#的 machine.Availability.AddRange(newSegments)
machine
.
getAvailability
().
addAll
(
newSegments
);
return
segments
;
// 合并片段(去重+排序),并重新赋值给设备的可用片段列表,对应C#的 machine.Availability = MergeSegments(...)
List
<
TimeSegment
>
mergedSegments
=
mergeSegments
(
machine
.
getAvailability
());
machine
.
setAvailability
(
mergedSegments
);
}
private
boolean
isHoliday
(
Machine
machine
,
LocalDate
currentDate
)
{
...
...
src/main/java/com/aps/service/plan/PlanResultService.java
View file @
d49ae691
...
...
@@ -288,7 +288,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
GlobalParam
globalParam
=
new
GlobalParam
();
// 5. 执行调度算法
param
.
initAdaptiveParams
(
allOperations
.
size
());
GeneticAlgorithm
scheduler
=
new
GeneticAlgorithm
(
globalParam
,
machines
,
orders
,
null
,
machineScheduler
,
null
,
materialRequirementService
);
//new GeneticAlgorithm(products, machines, orders, machineScheduler);
GeneticAlgorithm
scheduler
=
new
GeneticAlgorithm
(
globalParam
,
machines
,
orders
,
null
,
machineScheduler
,
null
,
materialRequirementService
,
_sceneService
);
//new GeneticAlgorithm(products, machines, orders, machineScheduler);
Chromosome
Chromosomes
=
scheduler
.
Run
(
param
,
allOperations
);
WriteScheduleSummary
(
Chromosomes
);
ScheduleOperationService
ScheduleOperation
=
new
ScheduleOperationService
();
...
...
@@ -331,6 +331,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
// 3. 构建订单-工序数据
List
<
Order
>
orders
=
InitOrder
(
ProdLaunchOrders
);
List
<
Material
>
Materials
=
InitMaterial
();
Map
<
Integer
,
Object
>
list
=
InitEntrys
(
SceneId
,
ProdEquipments
,
orders
);
...
...
@@ -339,17 +340,29 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
List
<
GroupResult
>
entryRel
=(
List
<
GroupResult
>)
list
.
get
(
2
);
Set
<
Long
>
machineIds
=(
Set
<
Long
>)
list
.
get
(
3
);
Map
<
Long
,
Double
>
machineIds
=(
Map
<
Long
,
Double
>)
list
.
get
(
3
);
machines
=
machines
.
stream
().
filter
(
t
->
machineIds
.
containsKey
(
t
.
getId
())).
collect
(
Collectors
.
toList
());
for
(
Machine
machine
:
machines
){
Long
machineId
=
machine
.
getId
();
if
(
machineIds
.
get
(
machineId
)>
3600
*
24
*
200
)
{
int
day
=
(
int
)
(
machineIds
.
get
(
machineId
)
/
3600
/
24
)+
100
;
List
<
TimeSegment
>
segments
=
machineScheduler
.
generateTimeSegment
(
machine
,
null
,
day
);
machineScheduler
.
addSegmentsWithDeduplication
(
machine
,
segments
);
}
}
// 按照优先级排序
entrys
.
sort
(
Comparator
.
comparing
(
Entry:
:
getPriority
)
);
machines
=
machines
.
stream
().
filter
(
t
->
machineIds
.
contains
(
t
.
getId
())).
collect
(
Collectors
.
toList
());
// 5. 执行调度算法
GeneticAlgorithm
scheduler
=
new
GeneticAlgorithm
(
globalParam
,
machines
,
orders
,
Materials
,
machineScheduler
,
entryRel
,
materialRequirementService
);
//new GeneticAlgorithm(products, machines, orders, machineScheduler);
GeneticAlgorithm
scheduler
=
new
GeneticAlgorithm
(
globalParam
,
machines
,
orders
,
Materials
,
machineScheduler
,
entryRel
,
materialRequirementService
,
_sceneService
);
//new GeneticAlgorithm(products, machines, orders, machineScheduler);
param
.
initAdaptiveParams
(
entrys
.
size
());
double
[]
customWeights
=
new
double
[]
{
0.4
,
0.1
,
0.1
,
0.1
,
0.3
};
// 延迟时间权重提升到0.5
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
...
...
@@ -360,7 +373,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
kpiCalculator
.
calculatekpi
();
_sceneService
.
saveChromosomeToFile
(
chromosome
,
SceneId
);
WriteScheduleSummary
(
chromosome
);
//
WriteScheduleSummary(chromosome);
return
chromosome
;
...
...
@@ -371,6 +384,8 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
public
Chromosome
EditOperation
(
String
SceneId
,
Entry
operation
)
{
Chromosome
chromosome
=
_sceneService
.
loadChromosomeFromFile
(
SceneId
);
if
(
chromosome
==
null
||
chromosome
.
getAllOperations
()
==
null
)
{
...
...
@@ -673,7 +688,7 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
machines
=
machines
.
stream
().
filter
(
t
->
machineIds
.
contains
(
t
.
getId
())).
collect
(
Collectors
.
toList
());
// 5. 执行调度算法
GeneticAlgorithm
scheduler
=
new
GeneticAlgorithm
(
globalParam
,
machines
,
orders
,
Materials
,
machineScheduler
,
entryRel
,
materialRequirementService
);
//new GeneticAlgorithm(products, machines, orders, machineScheduler);
GeneticAlgorithm
scheduler
=
new
GeneticAlgorithm
(
globalParam
,
machines
,
orders
,
Materials
,
machineScheduler
,
entryRel
,
materialRequirementService
,
_sceneService
);
//new GeneticAlgorithm(products, machines, orders, machineScheduler);
param
.
initAdaptiveParams
(
entrys
.
size
());
double
[]
customWeights
=
new
double
[]
{
0.4
,
0.1
,
0.1
,
0.1
,
0.3
};
// 延迟时间权重提升到0.5
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
...
...
src/test/java/com/aps/demo/MachineSchedulerTest.java
View file @
d49ae691
...
...
@@ -77,7 +77,7 @@ public class MachineSchedulerTest {
if
(!
machines
.
isEmpty
())
{
Machine
firstMachine
=
machines
.
get
(
0
);
List
<
TimeSegment
>
segments
=
machineScheduler
.
generateTimeSegment
(
firstMachine
,
LocalDateTime
.
of
(
2025
,
10
,
1
,
0
,
0
,
0
));
firstMachine
,
LocalDateTime
.
of
(
2025
,
10
,
1
,
0
,
0
,
0
)
,
0
);
System
.
out
.
println
(
"直接生成的时间段数量: "
+
segments
.
size
());
}
...
...
src/test/java/com/aps/demo/PlanResultServiceTest.java
View file @
d49ae691
...
...
@@ -38,18 +38,18 @@ public class PlanResultServiceTest {
// nsgaiiUtils.Test();
//planResultService.execute2("C5FB5EF2A7334A0A92F826F4937E1008");
// planResultService.execute2("F79370487E4C455B8C4CF9BA41541CA9
");
// planResultService.execute2("726D4C1A712B4B1393175BD44B775B66
");
planResultService
.
execute2
(
"BCA6FA43FFA444D3952CF8F6E1EA291B"
);
// LocalDateTime t= LocalDateTime.of(2025, 11, 15, 6, 51, 11);
// List<Integer> opids=new ArrayList<>();
// opids.add(1);
// planResultService.Move("B571EF6682DB463AB2977B1055A74112",opids,t,3403L);
// planResultService.Redecode("B6AE363FF5044DDF8DECE32D5FE0F7EA
");
// planResultService.Redecode("12345679
");
// MaintenanceWindow maintenanceWindow=new MaintenanceWindow();
// maintenanceWindow.setStartTime(LocalDateTime.of(2025, 10, 21, 0, 0, 0));
// maintenanceWindow.setEndTime(LocalDateTime.of(2025, 10, 31, 0, 0, 0));
// planResultService.AddMaintenanceWindow("B6AE363FF5044DDF8DECE32D5FE0F7EA",1245l,maintenanceWindow);
planResultService
.
DelOperation
(
"B6AE363FF5044DDF8DECE32D5FE0F7EA"
,
7
);
//
planResultService.DelOperation("B6AE363FF5044DDF8DECE32D5FE0F7EA",7);
// planResultService.SpiltOrder("A41D662EE0764D008173C5A0E42B15F6","5f9d5383-b89a-4a4f-8805-2f617c711968",new Double[]{500d, 500d});
}
...
...
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