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
a0c8a9c1
Commit
a0c8a9c1
authored
Mar 13, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
重叠
parent
ff8e1628
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
164 additions
and
109 deletions
+164
-109
ScheduleResultDetail.java
...n/java/com/aps/entity/Algorithm/ScheduleResultDetail.java
+1
-1
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+128
-74
MachineCalculator.java
...ain/java/com/aps/service/Algorithm/MachineCalculator.java
+30
-29
RoutingDataService.java
...in/java/com/aps/service/Algorithm/RoutingDataService.java
+2
-2
PlanResultServiceTest.java
src/test/java/com/aps/demo/PlanResultServiceTest.java
+3
-3
No files found.
src/main/java/com/aps/entity/Algorithm/ScheduleResultDetail.java
View file @
a0c8a9c1
...
@@ -16,7 +16,7 @@ public class ScheduleResultDetail {
...
@@ -16,7 +16,7 @@ public class ScheduleResultDetail {
private
int
EndTime
;
// 相对结束时间(秒)
private
int
EndTime
;
// 相对结束时间(秒)
private
double
OneTime
;
// 单件工时
private
double
OneTime
;
// 单件工时
private
double
Quantity
;
// 时间段
private
double
Quantity
;
// 时间段
private
double
efficiency
=
1
;
//效率
private
List
<
TimeSegment
>
usedSegment
;
private
List
<
TimeSegment
>
usedSegment
;
...
...
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
a0c8a9c1
...
@@ -720,8 +720,9 @@ if(finishedOrder==null||finishedOrder.size()==0)
...
@@ -720,8 +720,9 @@ if(finishedOrder==null||finishedOrder.size()==0)
List
<
GAScheduleResult
>
newScheduleResult
=
new
ArrayList
<>();
List
<
GAScheduleResult
>
newScheduleResult
=
new
ArrayList
<>();
List
<
ScheduleResultDetail
>
newScheduleResultDetails
=
new
ArrayList
<>();
List
<
ScheduleResultDetail
>
newScheduleResultDetails
=
new
ArrayList
<>();
for
(
OperationDependency
opid
:
SSOperations
)
{
for
(
int
j
=
0
;
j
<
SSOperations
.
size
();
j
++)
{
OperationDependency
opid
=
SSOperations
.
get
(
j
);
List
<
GAScheduleResult
>
prevOperations
=
chromosome
.
getResult
().
stream
()
List
<
GAScheduleResult
>
prevOperations
=
chromosome
.
getResult
().
stream
()
.
filter
(
t
->
t
.
getGroupId
()
==
currentOp
.
getGroupId
()
&&
t
.
getOperationId
()
==
opid
.
getPrevOperationId
())
.
filter
(
t
->
t
.
getGroupId
()
==
currentOp
.
getGroupId
()
&&
t
.
getOperationId
()
==
opid
.
getPrevOperationId
())
.
collect
(
Collectors
.
toList
());
//多台
.
collect
(
Collectors
.
toList
());
//多台
...
@@ -729,24 +730,58 @@ if(finishedOrder==null||finishedOrder.size()==0)
...
@@ -729,24 +730,58 @@ if(finishedOrder==null||finishedOrder.size()==0)
newScheduleResult
.
add
(
prevOp
);
newScheduleResult
.
add
(
prevOp
);
newScheduleResultDetails
.
addAll
(
prevOp
.
getGeneDetails
());
newScheduleResultDetails
.
addAll
(
prevOp
.
getGeneDetails
());
}
}
if
(
j
==
SSOperations
.
size
()-
1
)
{
int
prevtime1
=
CalSSPrevtime
(
newScheduleResult
,
newScheduleResultDetails
,
prevtime
,
currentOp
,
chromosome
,
processTime
,
machine
);
prevtime
=
Math
.
max
(
prevtime
,
prevtime1
);
}
else
{
Entry
entry
=
chromosome
.
getAllOperations
().
stream
()
.
filter
(
t
->
t
.
getId
()==
opid
.
getPrevOperationId
())
.
findFirst
().
orElse
(
null
);
OperationDependency
opid2
=
SSOperations
.
get
(
j
+
1
);
Entry
entry1
=
chromosome
.
getAllOperations
().
stream
()
.
filter
(
t
->
t
.
getId
()==
opid2
.
getPrevOperationId
())
.
findFirst
().
orElse
(
null
);
if
(
entry
.
getRoutingDetailId
()!=
entry1
.
getRoutingDetailId
())
{
int
prevtime1
=
CalSSPrevtime
(
newScheduleResult
,
newScheduleResultDetails
,
prevtime
,
currentOp
,
chromosome
,
processTime
,
machine
);
prevtime
=
Math
.
max
(
prevtime
,
prevtime1
);
newScheduleResult
.
clear
();
newScheduleResultDetails
.
clear
();
}
}
}
}
return
prevtime
;
}
}
private
int
CalSSPrevtime
(
List
<
GAScheduleResult
>
newScheduleResult
,
List
<
ScheduleResultDetail
>
newScheduleResultDetails
,
int
prevtime
,
Entry
currentOp
,
Chromosome
chromosome
,
double
processTime
,
Machine
machine
)
{
int
prevperationEndTime
=
newScheduleResult
.
stream
()
int
prevperationEndTime
=
newScheduleResult
.
stream
()
.
mapToInt
(
GAScheduleResult:
:
getEndTime
)
.
mapToInt
(
GAScheduleResult:
:
getEndTime
)
.
max
()
.
max
()
.
orElse
(
0
);
.
orElse
(
0
);
prevtime
=
calculateNextOperationStartTime
(
newScheduleResult
,
newScheduleResultDetails
,
0
,
processTime
);
//
prevtime = calculateNextOperationStartTime(newScheduleResult, newScheduleResultDetails, 0, processTime);
// 下一工序结束时间需晚于上一工序结束时间一个产品加工时间
// 下一工序结束时间需晚于上一工序结束时间一个产品加工时间
//
int ssStartTimeWithCalendar = calculateSSStartTimeWithCalendar(
int
ssStartTimeWithCalendar
=
calculateSSStartTimeWithCalendar
(
//
newScheduleResult,
newScheduleResult
,
//
newScheduleResultDetails,
newScheduleResultDetails
,
//
currentOp,
currentOp
,
//
machine,
machine
,
//
processTime,
processTime
,
//
prevtime);
prevtime
);
//
//
//
prevtime = Math.max(prevtime, ssStartTimeWithCalendar);
prevtime
=
Math
.
max
(
prevtime
,
ssStartTimeWithCalendar
);
double
nextopplanend
=
prevperationEndTime
+
processTime
;
double
nextopplanend
=
prevperationEndTime
+
processTime
;
...
@@ -765,15 +800,14 @@ if(finishedOrder==null||finishedOrder.size()==0)
...
@@ -765,15 +800,14 @@ if(finishedOrder==null||finishedOrder.size()==0)
);
);
}
}
}
return
prevtime
;
return
prevtime
;
}
}
private
int
getOperationBOMTime
(
Entry
currentOp
,
Chromosome
chromosome
)
{
private
int
getOperationBOMTime
(
Entry
currentOp
,
Chromosome
chromosome
)
{
List
<
OrderMaterialRequirement
>
opboms
=
currentOp
.
getMaterialRequirements
();
List
<
OrderMaterialRequirement
>
opboms
=
currentOp
.
getMaterialRequirements
();
if
(
opboms
==
null
)
if
(
opboms
==
null
||!
_globalParam
.
isIsCheckMp
()
)
{
{
return
0
;
return
0
;
}
}
...
@@ -782,7 +816,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
...
@@ -782,7 +816,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
int
rawTime
=
0
,
sfTime
=
0
;
int
rawTime
=
0
,
sfTime
=
0
;
if
(
opboms
!=
null
&&
!
opboms
.
isEmpty
())
{
if
(
opboms
!=
null
&&
!
opboms
.
isEmpty
())
{
// 计算RawTime
// 计算RawTime
if
(
_globalParam
.
isIsCheckMp
())
{
Optional
<
LocalDateTime
>
rawDateOpt
=
opboms
.
stream
()
Optional
<
LocalDateTime
>
rawDateOpt
=
opboms
.
stream
()
.
filter
(
t
->
t
.
getMaterialTypeName
().
equals
(
"MP"
))
.
filter
(
t
->
t
.
getMaterialTypeName
().
equals
(
"MP"
))
.
map
(
OrderMaterialRequirement:
:
getUseTime
)
.
map
(
OrderMaterialRequirement:
:
getUseTime
)
...
@@ -791,7 +825,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
...
@@ -791,7 +825,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
rawTime
=
(
int
)
Duration
.
between
(
baseTime
,
rawDateOpt
.
get
()).
getSeconds
();
rawTime
=
(
int
)
Duration
.
between
(
baseTime
,
rawDateOpt
.
get
()).
getSeconds
();
}
}
}
// 计算SFTime
// 计算SFTime
List
<
OrderMaterialRequirement
>
sfBoms
=
opboms
.
stream
()
List
<
OrderMaterialRequirement
>
sfBoms
=
opboms
.
stream
()
...
@@ -1106,32 +1140,38 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
...
@@ -1106,32 +1140,38 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
return
prevtime
;
return
prevtime
;
}
}
double
prevTimePerUnit
=
prevScheduleResults
.
stream
()
.
mapToDouble
(
r
->
r
.
getOneTime
())
double
totalPrevProcessTime
=
prevScheduleResults
.
stream
()
.
sum
()
/
qty
;
.
mapToDouble
(
r
->
r
.
getOneTime
()
*
r
.
getQuantity
())
.
sum
();
double
prevTimePerUnit
=
totalPrevProcessTime
/
qty
;
double
currentTimePerUnit
=
processTime
;
double
currentTimePerUnit
=
processTime
;
//前工序生产多少个后工序可以开工
int
leadCount
=
(
int
)
calculateLeadProductionItems
(
qty
,
prevTimePerUnit
,
currentTimePerUnit
);
int
leadCount
=
(
int
)
calculateLeadProductionItems
(
qty
,
prevTimePerUnit
,
currentTimePerUnit
);
int
productionTimeForLeadCount
=
calculateProductionTimeWithCalendar
(
int
productionTimeForLeadCount
=
calculateProductionTimeWithCalendar
(
prevDetails
,
leadCount
,
machine
,
currentOp
);
prevDetails
,
leadCount
,
machine
,
currentOp
);
int
prevEndTime
=
prevScheduleResults
.
stream
()
//
int prevEndTime = prevScheduleResults.stream()
.
mapToInt
(
GAScheduleResult:
:
getEndTime
)
//
.mapToInt(GAScheduleResult::getEndTime)
.
max
()
//
.max()
.
orElse
(
0
);
//
.orElse(0);
//
int
minEndTimeForContinuity
=
prevEndTime
-
(
int
)
((
qty
-
leadCount
)
*
prevTimePerUnit
);
//
int minEndTimeForContinuity = prevEndTime - (int) ((qty - leadCount) * prevTimePerUnit);
int
adjustedStartTime
=
Math
.
max
(
productionTimeForLeadCount
,
minEndTimeForContinuity
);
//
int adjustedStartTime = Math.max(productionTimeForLeadCount, minEndTimeForContinuity);
adjustedStartTime
=
Math
.
max
(
adjustedStartTime
,
prevtime
);
// int adjustedStartTime = Math.max(productionTimeForLeadCount
, prevtime);
int
totalProcessingTime
=
(
int
)
(
currentTimePerUnit
*
qty
);
//
int totalProcessingTime = (int) (currentTimePerUnit * qty);
int
continuityAdjustedTime
=
ensureContinuousProduction
(
machine
,
adjustedStartTime
,
//
int continuityAdjustedTime = ensureContinuousProduction(machine, adjustedStartTime,
totalProcessingTime
,
currentOp
);
//
totalProcessingTime, currentOp);
return
Math
.
max
(
adjustedStartTime
,
continuityAdjustedTime
);
return
productionTimeForLeadCount
;
//
Math.max(adjustedStartTime, continuityAdjustedTime);
}
}
/**
/**
* 确保下一工序能够连续生产(不中断)
* 确保下一工序能够连续生产(不中断)
...
@@ -1188,42 +1228,56 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
...
@@ -1188,42 +1228,56 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
if
(
details
==
null
||
details
.
isEmpty
()
||
leadCount
<=
0
)
{
if
(
details
==
null
||
details
.
isEmpty
()
||
leadCount
<=
0
)
{
return
0
;
return
0
;
}
}
List
<
ScheduleResultDetail
>
alldetails
=
new
ArrayList
<>();
Set
<
Integer
>
timePoints
=
new
TreeSet
<>();
for
(
ScheduleResultDetail
detail
:
details
)
{
for
(
ScheduleResultDetail
detail
:
details
)
{
timePoints
.
add
(
detail
.
getStartTime
());
if
(
detail
.
getUsedSegment
()!=
null
&&
detail
.
getUsedSegment
().
size
()>
0
)
timePoints
.
add
(
detail
.
getEndTime
());
{
}
for
(
TimeSegment
slot:
detail
.
getUsedSegment
())
{
List
<
Integer
>
sortedTimes
=
new
ArrayList
<>(
timePoints
);
LocalDateTime
startCandidate
=
slot
.
getStart
();
LocalDateTime
endCandidate
=
slot
.
getEnd
();
double
accumulatedQty
=
0.0
;
for
(
int
i
=
0
;
i
<
sortedTimes
.
size
()
-
1
;
i
++)
{
int
startTime
=
sortedTimes
.
get
(
i
);
int
endTime
=
sortedTimes
.
get
(
i
+
1
);
int
duration
=
endTime
-
startTime
;
if
(
duration
<=
0
)
continue
;
ScheduleResultDetail
time
=
new
ScheduleResultDetail
();
time
.
setKey
(
slot
.
getKey
());
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
startCandidate
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
endCandidate
));
time
.
setOneTime
(
detail
.
getOneTime
());
alldetails
.
add
(
time
);
}
}
else
{
double
efficiency
=
details
.
stream
()
alldetails
.
add
(
ProductionDeepCopyUtil
.
deepCopy
(
detail
));
.
filter
(
d
->
d
.
getStartTime
()
<=
startTime
&&
d
.
getEndTime
()
>=
endTime
)
}
.
mapToDouble
(
d
->
d
.
getProcessingTime
()
>
0
?
1.0
/
d
.
getOneTime
()
:
0
)
}
.
sum
();
alldetails
.
stream
().
sorted
(
Comparator
.
comparingInt
(
ScheduleResultDetail:
:
getStartTime
));
int
EndTime
=
0
;
double
accumulatedQty
=
0.0
;
for
(
ScheduleResultDetail
detail
:
alldetails
)
{
double
segmentQty
=
efficiency
*
duration
;
int
startTime
=
detail
.
getStartTime
();
int
endTime
=
detail
.
getEndTime
();
//实际可用时长
double
duration
=
(
endTime
-
startTime
)*
detail
.
getEfficiency
();
if
(
accumulatedQty
+
segmentQty
>=
leadCount
)
{
double
cQty
=
accumulatedQty
+
duration
/
detail
.
getOneTime
();
//实际可生产数量
if
(
cQty
>
leadCount
)
{
double
remainingQty
=
leadCount
-
accumulatedQty
;
double
remainingQty
=
leadCount
-
accumulatedQty
;
int
requiredTime
=
(
int
)
Math
.
ceil
(
remainingQty
/
efficiency
);
int
requiredTime
=
(
int
)
Math
.
ceil
(
remainingQty
*
detail
.
getOneTime
()
/
detail
.
getEfficiency
()
);
return
startTime
+
requiredTime
;
return
startTime
+
requiredTime
;
}
else
{
accumulatedQty
=
cQty
;
EndTime
=
endTime
;
}
}
accumulatedQty
+=
segmentQty
;
}
}
return
details
.
stream
()
.
mapToInt
(
ScheduleResultDetail:
:
getEndTime
)
.
max
()
.
orElse
(
0
)
;
return
EndTime
;
}
}
/**
/**
...
@@ -1360,7 +1414,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
...
@@ -1360,7 +1414,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
* @return 工序1需要提前生产的件数
* @return 工序1需要提前生产的件数
*/
*/
private
double
calculateLeadProductionItems
(
double
qty
,
double
time1
,
double
time2
)
{
private
double
calculateLeadProductionItems
(
double
qty
,
double
time1
,
double
time2
)
{
if
(
time1
<
time2
)
{
if
(
time1
<
=
time2
)
{
return
1
;
return
1
;
}
}
if
(
qty
<=
0
||
time1
<=
0
||
time2
<=
0
)
{
if
(
qty
<=
0
||
time1
<=
0
||
time2
<=
0
)
{
...
@@ -1368,7 +1422,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
...
@@ -1368,7 +1422,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
}
}
double
totalTime1
=
qty
*
time1
;
double
totalTime1
=
qty
*
time1
;
double
totalTime2
=
qty
*
time2
;
double
totalTime2
=
qty
*
time2
;
double
timeDifference
=
totalTime2
-
totalTime1
;
double
timeDifference
=
0
-(
totalTime2
-
totalTime1
)
;
return
(
timeDifference
/
time1
)
>
qty
?
qty
:
(
timeDifference
/
time1
);
return
(
timeDifference
/
time1
)
>
qty
?
qty
:
(
timeDifference
/
time1
);
}
}
...
...
src/main/java/com/aps/service/Algorithm/MachineCalculator.java
View file @
a0c8a9c1
...
@@ -10,6 +10,7 @@ import com.aps.service.plan.MachineSchedulerService;
...
@@ -10,6 +10,7 @@ import com.aps.service.plan.MachineSchedulerService;
import
com.baomidou.mybatisplus.core.toolkit.StringUtils
;
import
com.baomidou.mybatisplus.core.toolkit.StringUtils
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.time.Duration
;
import
java.time.Duration
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
java.time.format.DateTimeFormatter
;
import
java.time.format.DateTimeFormatter
;
...
@@ -272,7 +273,7 @@ public class MachineCalculator {
...
@@ -272,7 +273,7 @@ public class MachineCalculator {
String
prevtime
,
CopyOnWriteArrayList
<
GAScheduleResult
>
existingTasks
,
double
oneTime
,
double
quantity
,
boolean
checkprevtime
,
boolean
islockMachineTime
String
prevtime
,
CopyOnWriteArrayList
<
GAScheduleResult
>
existingTasks
,
double
oneTime
,
double
quantity
,
boolean
checkprevtime
,
boolean
islockMachineTime
,
boolean
isInterrupt
)
{
,
boolean
isInterrupt
)
{
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
=
null
;
CopyOnWriteArrayList
<
GAScheduleResult
>
machineTasks
=
null
;
if
(
existingTasks
!=
null
)
{
if
(
existingTasks
!=
null
&&
existingTasks
.
size
()>
0
)
{
machineTasks
=
existingTasks
.
stream
()
machineTasks
=
existingTasks
.
stream
()
.
filter
(
t
->
t
.
getMachineId
()
==
machine
.
getId
())
.
filter
(
t
->
t
.
getMachineId
()
==
machine
.
getId
())
.
sorted
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getStartTime
))
.
sorted
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getStartTime
))
...
@@ -506,6 +507,7 @@ public class MachineCalculator {
...
@@ -506,6 +507,7 @@ public class MachineCalculator {
CopyOnWriteArrayList
<
ScheduleResultDetail
>
times
=
new
CopyOnWriteArrayList
<>();
CopyOnWriteArrayList
<
ScheduleResultDetail
>
times
=
new
CopyOnWriteArrayList
<>();
//第一个数据
TimeSegment
shiftfrist
=
timeSegments
.
get
(
0
);
TimeSegment
shiftfrist
=
timeSegments
.
get
(
0
);
Map
<
Integer
,
Object
>
outMap
=
CreateScheduleResultDetail
(
shiftfrist
,
st
,
remainingTime
,
oneTime
);
Map
<
Integer
,
Object
>
outMap
=
CreateScheduleResultDetail
(
shiftfrist
,
st
,
remainingTime
,
oneTime
);
...
@@ -517,7 +519,7 @@ public class MachineCalculator {
...
@@ -517,7 +519,7 @@ public class MachineCalculator {
usedSegments
.
addAll
(
usedSegments1
);
usedSegments
.
addAll
(
usedSegments1
);
}
}
// 计算有效时间
// 计算有效时间
//中间的数据
CopyOnWriteArrayList
<
TimeSegment
>
timeSegments2
=
new
CopyOnWriteArrayList
<>(
timeSegments
.
subList
(
1
,
timeSegments
.
size
()-
1
));
CopyOnWriteArrayList
<
TimeSegment
>
timeSegments2
=
new
CopyOnWriteArrayList
<>(
timeSegments
.
subList
(
1
,
timeSegments
.
size
()-
1
));
...
@@ -531,7 +533,14 @@ public class MachineCalculator {
...
@@ -531,7 +533,14 @@ public class MachineCalculator {
time
.
setKey
(
UUID
.
randomUUID
().
toString
());
time
.
setKey
(
UUID
.
randomUUID
().
toString
());
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveStart
));
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveStart
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveend
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveend
));
time
.
setQuantity
((
int
)(
processable
/
oneTime
));
BigDecimal
bd
=
new
BigDecimal
(
String
.
valueOf
(
processable
/
oneTime
));
BigDecimal
roundedBd
=
bd
.
setScale
(
4
,
RoundingMode
.
HALF_UP
);
time
.
setQuantity
(
roundedBd
.
doubleValue
());
time
.
setOneTime
(
oneTime
);
time
.
setOneTime
(
oneTime
);
time
.
setUsedSegment
(
timeSegments2
);
time
.
setUsedSegment
(
timeSegments2
);
timeSegments2
.
forEach
(
t
->
t
.
setUsed
(
true
));
timeSegments2
.
forEach
(
t
->
t
.
setUsed
(
true
));
...
@@ -540,7 +549,7 @@ public class MachineCalculator {
...
@@ -540,7 +549,7 @@ public class MachineCalculator {
times
.
add
(
time
);
times
.
add
(
time
);
//最后的时间段
TimeSegment
shiftlast
=
timeSegments
.
get
(
timeSegments
.
size
()-
1
);
TimeSegment
shiftlast
=
timeSegments
.
get
(
timeSegments
.
size
()-
1
);
Map
<
Integer
,
Object
>
outMaplast
=
CreateScheduleResultDetail
(
shiftlast
,
st
,
remainingTime
,
oneTime
);
Map
<
Integer
,
Object
>
outMaplast
=
CreateScheduleResultDetail
(
shiftlast
,
st
,
remainingTime
,
oneTime
);
...
@@ -586,7 +595,12 @@ public class MachineCalculator {
...
@@ -586,7 +595,12 @@ public class MachineCalculator {
time
.
setStartTime
(
Math
.
abs
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveStart
)));
time
.
setStartTime
(
Math
.
abs
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveStart
)));
time
.
setEndTime
(
Math
.
abs
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
currentTime
)));
time
.
setEndTime
(
Math
.
abs
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
currentTime
)));
time
.
setQuantity
((
int
)(
processable
/
oneTime
));
time
.
setEfficiency
(
shift
.
getEfficiency
());
BigDecimal
bd
=
new
BigDecimal
(
String
.
valueOf
(
processable
/
oneTime
));
BigDecimal
roundedBd
=
bd
.
setScale
(
4
,
RoundingMode
.
HALF_UP
);
time
.
setQuantity
(
roundedBd
.
doubleValue
());
time
.
setOneTime
(
oneTime
);
time
.
setOneTime
(
oneTime
);
Map
<
Integer
,
Object
>
outMap
=
new
HashMap
<>();
Map
<
Integer
,
Object
>
outMap
=
new
HashMap
<>();
outMap
.
put
(
1
,
remainingTime
);
outMap
.
put
(
1
,
remainingTime
);
...
@@ -737,7 +751,7 @@ public class MachineCalculator {
...
@@ -737,7 +751,7 @@ public class MachineCalculator {
if
(
currentTotal
>=
requiredMinutes
)
{
if
(
currentTotal
>=
requiredMinutes
)
{
//
✔️
总时长满足,尝试往前减索引,找「最小满足索引」(减少后续裁剪的工作量)
// 总时长满足,尝试往前减索引,找「最小满足索引」(减少后续裁剪的工作量)
if
(
targetIndex
>
0
)
{
if
(
targetIndex
>
0
)
{
double
prevTotal
=
calculateTotalMinutesByIndex
(
availableSegments
,
currentTime
,
targetIndex
-
1
);
double
prevTotal
=
calculateTotalMinutesByIndex
(
availableSegments
,
currentTime
,
targetIndex
-
1
);
if
(
prevTotal
>=
requiredMinutes
)
{
if
(
prevTotal
>=
requiredMinutes
)
{
...
@@ -750,7 +764,7 @@ public class MachineCalculator {
...
@@ -750,7 +764,7 @@ public class MachineCalculator {
double
syday
=
(
int
)
Math
.
ceil
((
requiredMinutes
-
currentTotal
)/(
double
)
ONE_DAY_MINUTES
);
double
syday
=
(
int
)
Math
.
ceil
((
requiredMinutes
-
currentTotal
)/(
double
)
ONE_DAY_MINUTES
);
//
❌
总时长不足,往后加索引(每次加5,大步前进,加快逼近速度)
// 总时长不足,往后加索引(每次加5,大步前进,加快逼近速度)
targetIndex
+=
Math
.
max
(
syday
,
5
);
targetIndex
+=
Math
.
max
(
syday
,
5
);
if
(
targetIndex
>=
totalSegmentCount
)
{
if
(
targetIndex
>=
totalSegmentCount
)
{
// 所有片段总时长不足,抛出异常
// 所有片段总时长不足,抛出异常
...
@@ -1026,6 +1040,7 @@ public class MachineCalculator {
...
@@ -1026,6 +1040,7 @@ public class MachineCalculator {
LocalDateTime
taskStart
=
baseTime
.
plusSeconds
(
t
.
getStartTime
());
LocalDateTime
taskStart
=
baseTime
.
plusSeconds
(
t
.
getStartTime
());
return
taskStart
.
isAfter
(
finalPrevEnd
)
&&
taskStart
.
isBefore
(
shiftStart
);
return
taskStart
.
isAfter
(
finalPrevEnd
)
&&
taskStart
.
isBefore
(
shiftStart
);
});
});
if
(!
hasTask
)
{
if
(!
hasTask
)
{
// 检查班次间维修窗口
// 检查班次间维修窗口
if
(
machine
.
getMaintenanceWindows
()
!=
null
)
{
if
(
machine
.
getMaintenanceWindows
()
!=
null
)
{
...
@@ -1107,9 +1122,9 @@ public class MachineCalculator {
...
@@ -1107,9 +1122,9 @@ public class MachineCalculator {
if
(
slot
==
null
)
{
if
(
slot
==
null
)
{
return
null
;
return
null
;
}
}
int
processingTime1
=(
int
)
Math
.
ceil
(
processingTime
/
slot
.
getEfficiency
());
// 计算候选开始/结束时间(当前时间往前推加工时长)
// 计算候选开始/结束时间(当前时间往前推加工时长)
LocalDateTime
startCandidate
=
currentTime
.
minusSeconds
(
processingTime
);
LocalDateTime
startCandidate
=
currentTime
.
minusSeconds
(
processingTime
1
);
LocalDateTime
endCandidate
=
currentTime
;
LocalDateTime
endCandidate
=
currentTime
;
// 检查是否在可用时间段内
// 检查是否在可用时间段内
...
@@ -1225,8 +1240,8 @@ public class MachineCalculator {
...
@@ -1225,8 +1240,8 @@ public class MachineCalculator {
.
filter
(
t
->
baseTime
.
plusSeconds
(
t
.
getStartTime
()).
isAfter
(
shiftStart
)
.
filter
(
t
->
baseTime
.
plusSeconds
(
t
.
getStartTime
()).
isAfter
(
shiftStart
)
&&
baseTime
.
plusSeconds
(
t
.
getStartTime
()).
isBefore
(
finalPrevEnd
))
&&
baseTime
.
plusSeconds
(
t
.
getStartTime
()).
isBefore
(
finalPrevEnd
))
.
findFirst
();
.
findFirst
();
boolean
hasTask
=
CheckTask
(
machine
,
machineTasks
,
prevEnd
,
shiftStart
);
if
(
task
.
isPresent
()
)
{
if
(
hasTask
)
{
// 班次间有任务,重置状态重新查找
// 班次间有任务,重置状态重新查找
currentTime
=
shiftStart
;
currentTime
=
shiftStart
;
remainingTime
=
processingTime
;
remainingTime
=
processingTime
;
...
@@ -1236,23 +1251,6 @@ public class MachineCalculator {
...
@@ -1236,23 +1251,6 @@ public class MachineCalculator {
}
}
}
}
// 检查维护窗口
if
(
machine
.
getMaintenanceWindows
()
!=
null
&&
!
machine
.
getMaintenanceWindows
().
isEmpty
())
{
LocalDateTime
finalPrevEnd
=
prevEnd
;
Optional
<
MaintenanceWindow
>
maintenanceTask
=
machine
.
getMaintenanceWindows
().
stream
()
.
filter
(
t
->
t
.
getStartTime
().
isAfter
(
shiftStart
)
&&
t
.
getStartTime
().
isBefore
(
finalPrevEnd
))
.
findFirst
();
if
(
maintenanceTask
.
isPresent
())
{
// 班次间有维护任务,重置状态重新查找
currentTime
=
shiftStart
;
remainingTime
=
processingTime
;
prevEnd
=
LocalDateTime
.
of
(
2000
,
1
,
1
,
0
,
0
);
times
.
clear
();
continue
;
}
}
}
}
// 调整班次有效结束时间(不超过当前时间)
// 调整班次有效结束时间(不超过当前时间)
...
@@ -1262,11 +1260,14 @@ public class MachineCalculator {
...
@@ -1262,11 +1260,14 @@ public class MachineCalculator {
Duration
availableDuration
=
Duration
.
between
(
shiftStart
,
effectiveEnd
);
Duration
availableDuration
=
Duration
.
between
(
shiftStart
,
effectiveEnd
);
long
availableMinutes
=
availableDuration
.
getSeconds
();
long
availableMinutes
=
availableDuration
.
getSeconds
();
// 当前班次可处理的时长(不超过剩余需要的时长)
// 当前班次可处理的时长(不超过剩余需要的时长)
int
processableMinutes
=
(
int
)
Math
.
min
(
remainingTime
,
availableMinutes
);
int
processableMinutes
=
(
int
)
Math
.
min
(
remainingTime
,
availableMinutes
);
long
availableSeconds_e
=
Math
.
round
(
processableMinutes
/
shift
.
getEfficiency
())
;
// 计算当前班次的有效开始时间
// 计算当前班次的有效开始时间
LocalDateTime
effectiveStart
=
effectiveEnd
.
minusSeconds
(
processableMinutes
);
LocalDateTime
effectiveStart
=
effectiveEnd
.
minusSeconds
(
availableSeconds_e
);
prevEnd
=
effectiveStart
;
// 更新上一班次结束时间
prevEnd
=
effectiveStart
;
// 更新上一班次结束时间
remainingTime
-=
processableMinutes
;
// 剩余时长递减
remainingTime
-=
processableMinutes
;
// 剩余时长递减
currentTime
=
effectiveStart
;
// 更新当前时间,继续循环
currentTime
=
effectiveStart
;
// 更新当前时间,继续循环
...
...
src/main/java/com/aps/service/Algorithm/RoutingDataService.java
View file @
a0c8a9c1
...
@@ -98,12 +98,12 @@ public class RoutingDataService {
...
@@ -98,12 +98,12 @@ public class RoutingDataService {
Map
<
Integer
,
Object
>
list
=
new
HashMap
<>();
Map
<
Integer
,
Object
>
list
=
new
HashMap
<>();
List
<
String
>
soutceExecId
=
ProdOrderProcesss
.
stream
()
List
<
String
>
soutceExecId
=
ProdOrderProcesss
.
stream
()
.
map
(
ProdOrderProcess:
:
getExecId
)
.
map
(
ProdOrderProcess:
:
getExecId
)
.
distinct
()
// 提取Exec_ID
//
.distinct() // 提取Exec_ID
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
List
<
String
>
targetExecId
=
ProdOrderProcesss
.
stream
()
List
<
String
>
targetExecId
=
ProdOrderProcesss
.
stream
()
.
map
(
ProdOrderProcess:
:
getTargetExecId
)
.
map
(
ProdOrderProcess:
:
getTargetExecId
)
.
distinct
()
// 提取TARGET_Exec_ID
//
.distinct() // 提取TARGET_Exec_ID
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
List
<
String
>
ExecIdNoChild
=
ProdProcessExecs
.
stream
()
List
<
String
>
ExecIdNoChild
=
ProdProcessExecs
.
stream
()
...
...
src/test/java/com/aps/demo/PlanResultServiceTest.java
View file @
a0c8a9c1
...
@@ -42,7 +42,7 @@ public class PlanResultServiceTest {
...
@@ -42,7 +42,7 @@ public class PlanResultServiceTest {
// planResultService.execute2("5475E00B844847ACB6DC20227967BA2F");
// planResultService.execute2("5475E00B844847ACB6DC20227967BA2F");
// planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D");
// planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D");
planResultService
.
execute2
(
"92BB773E1E2447C99D8176C991D5C9D2"
);
//
planResultService.execute2("92BB773E1E2447C99D8176C991D5C9D2");
// planResultService.execute2("265F24B6DF3C40E4B17D193B0CC8AAF2");
// planResultService.execute2("265F24B6DF3C40E4B17D193B0CC8AAF2");
// LocalDateTime t= LocalDateTime.of(2026, 02, 14, 1, 25, 52);
// LocalDateTime t= LocalDateTime.of(2026, 02, 14, 1, 25, 52);
// List<Integer> opids=new ArrayList<>();//BCA6FA43FFA444D3952CF8F6E1EA291B
// List<Integer> opids=new ArrayList<>();//BCA6FA43FFA444D3952CF8F6E1EA291B
...
@@ -56,7 +56,7 @@ public class PlanResultServiceTest {
...
@@ -56,7 +56,7 @@ public class PlanResultServiceTest {
// maintenanceWindow.setEndTime(LocalDateTime.of(2025, 9, 19, 0, 0, 0));
// maintenanceWindow.setEndTime(LocalDateTime.of(2025, 9, 19, 0, 0, 0));
// planResultService.AddMaintenanceWindow("5475E00B844847ACB6DC20227967BA2F",2488l,maintenanceWindow);
// planResultService.AddMaintenanceWindow("5475E00B844847ACB6DC20227967BA2F",2488l,maintenanceWindow);
// // planResultService.DelOperation("B6AE363FF5044DDF8DECE32D5FE0F7EA",7);
// // planResultService.DelOperation("B6AE363FF5044DDF8DECE32D5FE0F7EA",7);
planResultService
.
SpiltOperation
(
"92BB773E1E2447C99D8176C991D5C9D2"
,
1
,
new
Double
[]{
50
d
,
50
d
});
// planResultService.SpiltOrder("A41D662EE0764D008173C5A0E42B15F6","5f9d5383-b89a-4a4f-8805-2f617c711968",new Double[]{500d, 500d});
// 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