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
f7bdf363
Commit
f7bdf363
authored
Nov 30, 2025
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
遗传算法
parent
eee3a165
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1154 additions
and
333 deletions
+1154
-333
ResourceGanttController.java
...ava/com/aps/controller/gantt/ResourceGanttController.java
+4
-4
GAScheduleResult.java
src/main/java/com/aps/entity/Algorithm/GAScheduleResult.java
+10
-3
GroupResult.java
...va/com/aps/entity/Algorithm/IDAndChildID/GroupResult.java
+26
-0
NodeInfo.java
.../java/com/aps/entity/Algorithm/IDAndChildID/NodeInfo.java
+35
-0
Entry.java
src/main/java/com/aps/entity/basic/Entry.java
+7
-1
GlobalParam.java
src/main/java/com/aps/entity/basic/GlobalParam.java
+5
-3
Order.java
src/main/java/com/aps/entity/basic/Order.java
+4
-1
ScheduleChromosome.java
src/main/java/com/aps/entity/basic/ScheduleChromosome.java
+33
-33
GeneticAlgorithm.java
...main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
+25
-19
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+186
-22
GeneticOperations.java
...ain/java/com/aps/service/Algorithm/GeneticOperations.java
+6
-2
IdGroupingWithDualSerial.java
...a/com/aps/service/Algorithm/IdGroupingWithDualSerial.java
+561
-0
Initialization.java
src/main/java/com/aps/service/Algorithm/Initialization.java
+4
-2
MachineCalculator.java
...ain/java/com/aps/service/Algorithm/MachineCalculator.java
+39
-36
OrderSortService.java
...main/java/com/aps/service/Algorithm/OrderSortService.java
+2
-1
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
+17
-17
MachineSchedulerService.java
...in/java/com/aps/service/plan/MachineSchedulerService.java
+12
-1
PlanResultService.java
src/main/java/com/aps/service/plan/PlanResultService.java
+175
-185
OrderSortServiceTest.java
src/test/java/com/aps/demo/OrderSortServiceTest.java
+1
-1
No files found.
src/main/java/com/aps/controller/gantt/ResourceGanttController.java
View file @
f7bdf363
...
...
@@ -106,9 +106,9 @@ public class ResourceGanttController {
@GetMapping
(
"/getScene"
)
@Operation
(
summary
=
"获取所有场景ID"
,
description
=
"获取所有场景ID"
)
public
List
<
Chromosome
>
getScene
()
{
public
Chromosome
getScene
()
{
// 调用 PlanResultService 获取 ScheduleChromosome 列表
List
<
Chromosome
>
scheduleChromosomes
=
planResultService
.
execute1
();
Chromosome
scheduleChromosomes
=
planResultService
.
execute1
();
// 提取所有场景ID
return
scheduleChromosomes
;
...
...
@@ -116,9 +116,9 @@ public class ResourceGanttController {
@GetMapping
(
"/getScene2"
)
@Operation
(
summary
=
"获取所有场景ID"
,
description
=
"获取所有场景ID"
)
public
List
<
Chromosome
>
getScene2
()
{
public
Chromosome
getScene2
()
{
// 调用 PlanResultService 获取 ScheduleChromosome 列表
List
<
Chromosome
>
scheduleChromosomes
=
planResultService
.
execute2
(
"EAA26D85B5824B40A17554297B4EA32B
"
);
Chromosome
scheduleChromosomes
=
planResultService
.
execute2
(
"B571EF6682DB463AB2977B1055A74112
"
);
// 提取所有场景ID
return
scheduleChromosomes
;
...
...
src/main/java/com/aps/entity/Algorithm/GAScheduleResult.java
View file @
f7bdf363
...
...
@@ -12,11 +12,18 @@ import java.util.List;
@Data
public
class
GAScheduleResult
{
private
int
GroupId
;
private
int
ProductId
;
private
int
OperationId
;
/**
* 工单ID
*/
public
String
ExecId
;
public
String
OrderId
;
private
String
productId
;
private
long
MachineId
;
private
int
StartTime
;
// 相对开始时间(分钟)
private
int
EndTime
;
// 相对结束时间(分钟)
private
int
StartTime
;
// 相对开始时间(秒)
private
int
EndTime
;
// 相对结束时间(秒)
private
int
teardownTime
;
//后处理
private
double
Quantity
;
// 批次大小(订单可拆分)
private
List
<
ScheduleResultDetail
>
GeneDetails
;
// 时间详情
private
double
OneTime
;
// 单件工时
...
...
src/main/java/com/aps/entity/Algorithm/IDAndChildID/GroupResult.java
0 → 100644
View file @
f7bdf363
package
com
.
aps
.
entity
.
Algorithm
.
IDAndChildID
;
import
java.util.List
;
import
java.util.Map
;
/**
* 作者:佟礼
* 时间:2025-11-29
*/
// 存储分组结果:节点信息列表、新父子映射
// 存储分组结果:节点信息列表、原始ID(String)→全局序号映射
// 存储分组结果:节点信息列表、原始ID→全局序号映射
public
class
GroupResult
{
private
List
<
NodeInfo
>
nodeInfoList
;
private
Map
<
String
,
Integer
>
originalToGlobalSerial
;
public
GroupResult
(
List
<
NodeInfo
>
nodeInfoList
,
Map
<
String
,
Integer
>
originalToGlobalSerial
)
{
this
.
nodeInfoList
=
nodeInfoList
;
this
.
originalToGlobalSerial
=
originalToGlobalSerial
;
}
// getter
public
List
<
NodeInfo
>
getNodeInfoList
()
{
return
nodeInfoList
;
}
public
Map
<
String
,
Integer
>
getOriginalToGlobalSerial
()
{
return
originalToGlobalSerial
;
}
}
src/main/java/com/aps/entity/Algorithm/IDAndChildID/NodeInfo.java
0 → 100644
View file @
f7bdf363
package
com
.
aps
.
entity
.
Algorithm
.
IDAndChildID
;
import
lombok.Data
;
import
java.util.List
;
/**
* 作者:佟礼
* 时间:2025-11-29
*/
// 存储节点信息:原ID、新序号、新父ID、新子ID列表
@Data
// 存储节点信息:原ID(String)、全局新序号、分组内序号、新父ID列表、新子ID列表
public
class
NodeInfo
{
private
String
originalId
;
// 原始ID
private
Integer
globalSerial
;
// 全局新序号
private
Integer
groupSerial
;
// 分组内序号
private
List
<
Integer
>
newParentIds
;
// 新父ID列表(基于全局序号)
private
List
<
Integer
>
newChildIds
;
// 新子ID列表(基于全局序号)
public
NodeInfo
(
String
originalId
,
Integer
globalSerial
,
Integer
groupSerial
,
List
<
Integer
>
newParentIds
,
List
<
Integer
>
newChildIds
)
{
this
.
originalId
=
originalId
;
this
.
globalSerial
=
globalSerial
;
this
.
groupSerial
=
groupSerial
;
this
.
newParentIds
=
newParentIds
;
this
.
newChildIds
=
newChildIds
;
}
@Override
public
String
toString
()
{
return
originalId
+
":"
+
globalSerial
;
}
}
src/main/java/com/aps/entity/basic/Entry.java
View file @
f7bdf363
...
...
@@ -29,6 +29,7 @@ public class Entry {
*/
public
String
OrderId
;
private
String
productId
;
/**
* 工单ID
*/
...
...
@@ -36,7 +37,7 @@ public class Entry {
/**
* 离散参数
*/
public
String
DiscreteParameter
;
public
List
<
String
>
DiscreteParameter
;
/**
* 基因编号
*/
...
...
@@ -58,6 +59,11 @@ public class Entry {
*/
public
List
<
Integer
>
PrevEntryIds
;
//前工序
/**
* 前工单ID
*/
public
List
<
Integer
>
NextEntryIds
;
//后工序
/**
* 是否可中断,间缝插针
*/
...
...
src/main/java/com/aps/entity/basic/GlobalParam.java
View file @
f7bdf363
...
...
@@ -11,15 +11,17 @@ public class GlobalParam {
/// <summary>
/// 是否可以打破优先级
/// </summary>
p
ublic
static
boolean
IsBreakPriority
=
false
;
p
rivate
boolean
IsBreakPriority
=
false
;
/// <summary>
/// 是否多台设备
/// </summary>
p
ublic
static
boolean
IsMultipleMachine
=
false
;
p
rivate
boolean
IsMultipleMachine
=
false
;
/// <summary>
/// 是否重叠
/// </summary>
public
static
boolean
IsOverlap
=
false
;
private
boolean
IsOverlap
=
false
;
private
boolean
_smoothSetup
=
false
;
// 默认true,不占用设备时长
}
src/main/java/com/aps/entity/basic/Order.java
View file @
f7bdf363
...
...
@@ -11,11 +11,14 @@ import java.time.OffsetDateTime;
@Data
public
class
Order
{
private
int
id
;
private
String
OrderId
;
private
int
productId
;
private
String
materialId
;
private
double
quantity
=
100
;
// 100个
private
double
sYQuantity
;
private
Offset
DateTime
dueDate
;
private
Local
DateTime
dueDate
;
private
LocalDateTime
orderCompletion
;
private
double
tardiness
;
private
int
priority
;
...
...
src/main/java/com/aps/entity/basic/ScheduleChromosome.java
View file @
f7bdf363
...
...
@@ -96,38 +96,38 @@ public class ScheduleChromosome {
private
List
<
Order
>
calTardiness
()
{
tardiness
=
0
;
for
(
Order
order
:
orders
)
{
final
int
orderId
=
order
.
getId
();
List
<
Gene
>
orderGroups
=
genes
.
stream
()
.
filter
(
g
->
g
.
getOrderId
()
==
orderId
)
.
collect
(
Collectors
.
toList
());
int
orderCompletion
=
orderGroups
.
stream
()
.
mapToInt
(
Gene:
:
getEndTime
)
.
max
()
.
orElse
(
0
);
LocalDateTime
orderCompletionTime
=
baseTime
.
plusMinutes
(
orderCompletion
);
order
.
setOrderCompletion
(
orderCompletionTime
);
order
.
setTardiness
(
0
);
// 修复:统一时间类型
LocalDateTime
dueDateTime
=
order
.
getDueDate
().
toLocalDateTim
e
();
if
(
orderCompletionTime
.
isAfter
(
dueDateTime
))
{
// 方法1:使用分钟计算再转换为小时(推荐)
long
totalMinutes
=
java
.
time
.
temporal
.
ChronoUnit
.
MINUTES
.
between
(
dueDateTime
,
orderCompletionTime
);
double
tardinessHours
=
totalMinutes
/
60.0
;
// 方法2:或者保持原有逻辑但使用统一的时间类型
// long diffHours = java.time.temporal.ChronoUnit.HOURS.between(dueDateTime, orderCompletionTime);
// long remainingMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime) % 60;
// double tardinessHours = diffHours + (double) remainingMinutes / 60;
order
.
setTardiness
(
tardinessHours
);
tardiness
+=
tardinessHours
;
}
}
return
orders
;
//
for (Order order : orders) {
//
final int orderId = order.getId();
//
List<Gene> orderGroups = genes.stream()
//
.filter(g -> g.getOrderId() == orderId)
//
.collect(Collectors.toList());
//
//
int orderCompletion = orderGroups.stream()
//
.mapToInt(Gene::getEndTime)
//
.max()
//
.orElse(0);
//
//
LocalDateTime orderCompletionTime = baseTime.plusMinutes(orderCompletion);
//
order.setOrderCompletion(orderCompletionTime);
//
order.setTardiness(0);
//
//
// 修复:统一时间类型
// LocalDateTime dueDateTime = order.getDueDat
e();
//
//
if (orderCompletionTime.isAfter(dueDateTime)) {
//
// 方法1:使用分钟计算再转换为小时(推荐)
//
long totalMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime);
//
double tardinessHours = totalMinutes / 60.0;
//
//
// 方法2:或者保持原有逻辑但使用统一的时间类型
//
// long diffHours = java.time.temporal.ChronoUnit.HOURS.between(dueDateTime, orderCompletionTime);
//
// long remainingMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime) % 60;
//
// double tardinessHours = diffHours + (double) remainingMinutes / 60;
//
//
order.setTardiness(tardinessHours);
//
tardiness += tardinessHours;
//
}
//
}
return
null
;
}
}
\ No newline at end of file
src/main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
View file @
f7bdf363
...
...
@@ -6,10 +6,7 @@ import com.aps.entity.Algorithm.Chromosome;
import
com.aps.entity.Algorithm.GlobalOperationInfo
;
import
com.aps.entity.Algorithm.Pair
;
import
com.aps.entity.Algorithm.ScheduleParams
;
import
com.aps.entity.basic.Entry
;
import
com.aps.entity.basic.Machine
;
import
com.aps.entity.basic.Material
;
import
com.aps.entity.basic.Order
;
import
com.aps.entity.basic.*
;
import
com.aps.service.plan.MachineSchedulerService
;
import
java.util.*
;
...
...
@@ -25,20 +22,22 @@ public class GeneticAlgorithm {
private
final
MachineSchedulerService
machineScheduler
;
private
final
List
<
Order
>
orders
;
private
final
List
<
Material
>
materials
;
private
static
GlobalParam
_GlobalParam
;
public
GeneticAlgorithm
(
List
<
Machine
>
machines
,
List
<
Order
>
orders
,
public
GeneticAlgorithm
(
GlobalParam
globalParam
,
List
<
Machine
>
machines
,
List
<
Order
>
orders
,
List
<
Material
>
materials
,
MachineSchedulerService
machineScheduler
)
{
this
.
machines
=
machines
;
this
.
orders
=
orders
;
this
.
materials
=
materials
;
this
.
machineScheduler
=
machineScheduler
;
_GlobalParam
=
globalParam
;
}
public
List
<
Chromosome
>
Run
(
ScheduleParams
param
,
List
<
Entry
>
allOperations
)
{
public
Chromosome
Run
(
ScheduleParams
param
,
List
<
Entry
>
allOperations
)
{
System
.
out
.
println
(
"开始"
);
Initialization
initialization
=
new
Initialization
(
allOperations
);
Initialization
initialization
=
new
Initialization
(
_GlobalParam
,
allOperations
);
GeneticOperations
geneticOps
=
new
GeneticOperations
(
allOperations
);
GeneticOperations
geneticOps
=
new
GeneticOperations
(
_GlobalParam
,
allOperations
);
// 预生成全局工序列表(所有初始化方法共享同一顺序)
List
<
GlobalOperationInfo
>
globalOpList
=
initialization
.
generateGlobalOpList
();
...
...
@@ -124,36 +123,43 @@ public class GeneticAlgorithm {
Iteration
++;
}
if
(
Iteration
>
2
0
)
if
(
Iteration
>
1
0
)
{
break
;
}
}
// 步骤3:返回最优解
return
population
.
stream
()
.
sorted
((
c1
,
c2
)
->
Double
.
compare
(
c2
.
getFitness
(),
c1
.
getFitness
()))
.
limit
(
10
)
.
collect
(
Collectors
.
toList
());
return
best
;
}
private
void
Chromosomedecode
(
ScheduleParams
param
,
List
<
Entry
>
allOperations
,
List
<
GlobalOperationInfo
>
globalOpList
,
List
<
Chromosome
>
population
)
{
GeneticDecoder
decoder
=
new
GeneticDecoder
(
param
.
getBaseTime
(),
machines
,
orders
,
materials
,
machineScheduler
);
GeneticDecoder
decoder
=
new
GeneticDecoder
(
_GlobalParam
,
param
.
getBaseTime
(),
machines
,
orders
,
materials
,
machineScheduler
);
FitnessCalculator
fitnessCalc
=
new
FitnessCalculator
();
population
.
parallelStream
().
forEach
(
chromosome
->
{
// population.parallelStream().forEach(chromosome -> {
// chromosome.setResult(new ArrayList<>());
//
// // 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
//
// decoder.decodeChromosomeWithCache(chromosome, globalOpList, allOperations);
// chromosome.setFitness(fitnessCalc.calculateFitness(chromosome));
// });
population
.
forEach
(
chromosome
->
{
chromosome
.
setResult
(
new
ArrayList
<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome
.
setMachines
(
ProductionDeepCopyUtil
.
deepCopyList
(
machines
));
// 简单拷贝,实际可能需要深拷贝
decoder
.
decodeChromosomeWithCache
(
chromosome
,
globalOpList
,
allOperations
);
chromosome
.
setFitness
(
fitnessCalc
.
calculateFitness
(
chromosome
));
Chromosome
chromosomen
=
decoder
.
decodeChromosomeWithCache
(
chromosome
,
globalOpList
,
allOperations
);
if
(
chromosomen
.
getFitness
()==
0
)
{
chromosomen
.
setFitness
(
fitnessCalc
.
calculateFitness
(
chromosomen
));
}
});
}
}
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
f7bdf363
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/service/Algorithm/GeneticOperations.java
View file @
f7bdf363
...
...
@@ -18,9 +18,13 @@ import java.util.stream.Collectors;
*/
public
class
GeneticOperations
{
private
final
Random
rnd
=
new
Random
();
private
static
GlobalParam
_GlobalParam
;
private
static
List
<
Entry
>
allOperations
;
public
GeneticOperations
(
List
<
Entry
>
allOperations
)
{
public
GeneticOperations
(
GlobalParam
globalParam
,
List
<
Entry
>
allOperations
)
{
_GlobalParam
=
globalParam
;
GeneticOperations
.
allOperations
=
allOperations
;
}
...
...
@@ -225,7 +229,7 @@ public class GeneticOperations {
Random
rnd
=
new
Random
();
List
<
OperationSequencingWeight
>
indexWeights
=
CommonCalculator
.
getOsw
(
os
,
allOperations
);
if
(!
GlobalParam
.
IsBreakPriority
)
{
if
(!
_GlobalParam
.
isIsBreakPriority
()
)
{
if
(
weight
==
0
)
{
return
indexWeights
.
get
(
rnd
.
nextInt
(
indexWeights
.
size
()));
}
else
{
...
...
src/main/java/com/aps/service/Algorithm/IdGroupingWithDualSerial.java
0 → 100644
View file @
f7bdf363
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/service/Algorithm/Initialization.java
View file @
f7bdf363
...
...
@@ -17,9 +17,11 @@ import java.util.stream.IntStream;
*/
public
class
Initialization
{
private
static
List
<
Entry
>
allOperations
;
private
static
GlobalParam
_globalParam
;
public
Initialization
(
List
<
Entry
>
allOperations
)
{
public
Initialization
(
GlobalParam
globalParam
,
List
<
Entry
>
allOperations
)
{
Initialization
.
allOperations
=
allOperations
;
_globalParam
=
globalParam
;
}
/**
* 预生成全局工序列表(按“订单0→订单1→…+订单内工序1→2→…”排序,分配GlobalOpId)
...
...
@@ -257,7 +259,7 @@ int populationSize=param.getPopulationSize();
*/
private
List
<
Integer
>
shuffleWithPriority
(
List
<
Integer
>
os
)
{
if
(!
GlobalParam
.
IsBreakPriority
)
{
if
(!
_globalParam
.
isIsBreakPriority
()
)
{
return
new
ArrayList
<>(
os
);
}
...
...
src/main/java/com/aps/service/Algorithm/MachineCalculator.java
View file @
f7bdf363
...
...
@@ -4,6 +4,7 @@ import com.aps.common.util.ProductionDeepCopyUtil;
import
com.aps.entity.Algorithm.GAScheduleResult
;
import
com.aps.entity.Algorithm.ScheduleResultDetail
;
import
com.aps.entity.basic.*
;
import
com.aps.service.plan.AlgorithmScheduler8
;
import
com.aps.service.plan.MachineSchedulerService
;
import
com.baomidou.mybatisplus.core.toolkit.StringUtils
;
...
...
@@ -37,15 +38,15 @@ public class MachineCalculator {
* 获取机器下一个可用时间窗口(考虑班次约束)
*/
public
List
<
ScheduleResultDetail
>
getNextAvailableTime
(
Machine
machine
,
int
proposedStartTime
,
int
prevtime
,
double
processingTime
,
int
prevtime
,
int
processingTime
,
List
<
GAScheduleResult
>
existingTasks
,
boolean
isInterrupt
,
boolean
istask
,
boolean
islockMachineTime
)
{
LocalDateTime
startTime
=
baseTime
.
plus
(
proposedStartTime
,
ChronoUnit
.
MINUTE
S
);
LocalDateTime
startTime
=
baseTime
.
plus
(
proposedStartTime
,
ChronoUnit
.
SECOND
S
);
String
prevtimestr
=
""
;
if
(
prevtime
>
-
1
)
{
prevtimestr
=
baseTime
.
plus
(
prevtime
,
ChronoUnit
.
MINUTE
S
)
prevtimestr
=
baseTime
.
plus
(
prevtime
,
ChronoUnit
.
SECOND
S
)
.
format
(
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
));
}
...
...
@@ -55,54 +56,49 @@ public class MachineCalculator {
}
// 查找最早可用开始时间
private
List
<
ScheduleResultDetail
>
findEarliestStart
(
Machine
machine
,
double
processingTime
,
LocalDateTime
currentTime
,
String
prevtime
,
List
<
GAScheduleResult
>
existingTasks
,
boolean
checkprevtime
,
boolean
islockMachineTime
)
{
// 获取设备上已有任务
private
List
<
ScheduleResultDetail
>
findEarliestStart
(
Machine
machine
,
int
processingTime
,
LocalDateTime
currentTime
,
String
prevtime
,
List
<
GAScheduleResult
>
existingTasks
,
boolean
checkprevtime
,
boolean
islockMachineTime
)
{
List
<
GAScheduleResult
>
machineTasks
=
existingTasks
.
stream
()
.
filter
(
t
->
t
.
getMachineId
()
==
machine
.
getId
())
.
sorted
(
Comparator
.
comparingInt
(
GAScheduleResult:
:
getStartTime
))
.
collect
(
Collectors
.
toList
());
List
<
ScheduleResultDetail
>
times
=
new
ArrayList
<>();
TimeSegment
slot
=
GetCurrentOrNextShift
(
machine
,
currentTime
,
prevtime
,
checkprevtime
);
LocalDateTime
startCandidate
=
slot
.
getStart
().
isAfter
(
(
prevtime
.
isEmpty
()
?
currentTime
:
LocalDateTime
.
parse
(
prevtime
,
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
)))
)
?
slot
.
getStart
()
:
(
prevtime
.
isEmpty
()
?
currentTime
:
LocalDateTime
.
parse
(
prevtime
,
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
)));
TimeSegment
slot
=
GetCurrentOrNextShift
(
machine
,
currentTime
,
prevtime
,
checkprevtime
);
if
(
slot
==
null
)
return
times
;
LocalDateTime
endCandidate
=
startCandidate
.
plus
((
long
)
processingTime
,
ChronoUnit
.
MINUTES
);
LocalDateTime
prevTimeDateTime
=
StringUtils
.
isEmpty
(
prevtime
)
?
null
:
LocalDateTime
.
parse
(
prevtime
);
LocalDateTime
startCandidate
=
slot
.
getStart
().
isAfter
(
prevTimeDateTime
!=
null
?
prevTimeDateTime
:
currentTime
)
?
slot
.
getStart
()
:
(
prevTimeDateTime
!=
null
?
prevTimeDateTime
:
currentTime
);
LocalDateTime
endCandidate
=
startCandidate
.
plusSeconds
(
processingTime
);
// 检查是否在可用时间段内
if
(
endCandidate
.
isAfter
(
slot
.
getEnd
()))
{
// 放不下,继续寻找后续可用时间
return
CaldEarliestStart
(
machine
,
processingTime
,
currentTime
,
prevtime
,
machineTasks
,
checkprevtime
,
islockMachineTime
);
return
CaldEarliestStart
(
machine
,
processingTime
,
currentTime
,
prevtime
,
machineTasks
,
checkprevtime
,
islockMachineTime
);
}
else
{
ScheduleResultDetail
time
=
new
ScheduleResultDetail
();
time
.
setKey
(
slot
.
getKey
());
time
.
setStartTime
((
int
)
ChronoUnit
.
MINUTE
S
.
between
(
baseTime
,
startCandidate
));
time
.
setEndTime
((
int
)
ChronoUnit
.
MINUTE
S
.
between
(
baseTime
,
endCandidate
));
time
.
setStartTime
((
int
)
ChronoUnit
.
SECOND
S
.
between
(
baseTime
,
startCandidate
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECOND
S
.
between
(
baseTime
,
endCandidate
));
times
.
add
(
time
);
if
(
islockMachineTime
)
{
if
(
islockMachineTime
)
{
RemoveMachineAvailable
(
machine
,
time
);
}
return
times
;
}
}
private
List
<
ScheduleResultDetail
>
CaldEarliestStart
(
Machine
machine
,
double
processingTime
,
LocalDateTime
currentTime
,
Machine
machine
,
int
processingTime
,
LocalDateTime
currentTime
,
String
prevtime
,
List
<
GAScheduleResult
>
machineTasks
,
boolean
checkprevtime
,
boolean
islockMachineTime
)
{
double
remainingTime
=
processingTime
;
int
remainingTime
=
processingTime
;
LocalDateTime
st
=
StringUtils
.
isEmpty
(
prevtime
)
?
currentTime
:
LocalDateTime
.
parse
(
prevtime
);
LocalDateTime
prevEnd
=
LocalDateTime
.
of
(
2000
,
1
,
1
,
0
,
0
,
0
);
List
<
ScheduleResultDetail
>
times
=
new
ArrayList
<>();
...
...
@@ -122,7 +118,7 @@ public class MachineCalculator {
LocalDateTime
finalPrevEnd
=
prevEnd
;
boolean
hasTask
=
machineTasks
.
stream
()
.
anyMatch
(
t
->
{
LocalDateTime
taskStart
=
baseTime
.
plus
Minute
s
(
t
.
getStartTime
());
LocalDateTime
taskStart
=
baseTime
.
plus
Second
s
(
t
.
getStartTime
());
return
taskStart
.
isAfter
(
finalPrevEnd
)
&&
taskStart
.
isBefore
(
shiftStart
);
});
...
...
@@ -158,29 +154,34 @@ public class MachineCalculator {
prevEnd
=
shiftEnd
;
// 计算有效时间
LocalDateTime
effectiveStart
=
st
.
isAfter
(
shiftStart
)
?
st
:
shiftStart
;
long
available
Minutes
=
ChronoUnit
.
MINUTE
S
.
between
(
effectiveStart
,
shiftEnd
);
long
available
Seconds
=
ChronoUnit
.
SECOND
S
.
between
(
effectiveStart
,
shiftEnd
);
// 处理当前班次
double
processable
=
Math
.
min
(
remainingTime
,
(
int
)
availableMinute
s
);
int
processable
=
Math
.
min
(
remainingTime
,
(
int
)
availableSecond
s
);
remainingTime
-=
processable
;
currentTime
=
effectiveStart
.
plus
Minutes
((
long
)
processable
);
currentTime
=
effectiveStart
.
plus
Seconds
(
processable
);
// 添加时间详情
ScheduleResultDetail
time
=
new
ScheduleResultDetail
();
time
.
setKey
(
shift
.
getKey
());
time
.
setStartTime
((
int
)
ChronoUnit
.
MINUTE
S
.
between
(
baseTime
,
effectiveStart
));
time
.
setEndTime
((
int
)
ChronoUnit
.
MINUTE
S
.
between
(
baseTime
,
currentTime
));
time
.
setStartTime
((
int
)
ChronoUnit
.
SECOND
S
.
between
(
baseTime
,
effectiveStart
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECOND
S
.
between
(
baseTime
,
currentTime
));
times
.
add
(
time
);
if
(
islockMachineTime
)
{
// 还原未使用的时间段
RemoveMachineAvailable
(
machine
,
time
);
}
}
// 还原未使用的时间段
if
(
islockMachineTime
)
{
// 还原未使用的时间段
AddMachineAvailable
(
machine
,
oldTimes
);
}
return
times
;
}
/**
* 获取设备当前或下一个有效班次
*/
...
...
@@ -196,7 +197,7 @@ public class MachineCalculator {
if
(
start
==
null
)
{
// 生成新时间段
List
<
TimeSegment
>
timeSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
time
);
List
<
TimeSegment
>
timeSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
time
.
plusDays
(
1
)
);
machine
.
getAvailability
().
addAll
(
timeSegments
);
// 更新设备时间线
...
...
@@ -215,6 +216,8 @@ public class MachineCalculator {
return
start
;
}
private
void
RemoveMachineAvailable
(
Machine
machine
,
ScheduleResultDetail
geneDetails
)
{
List
<
TimeSegment
>
timeSegments
=
new
ArrayList
<>();
...
...
@@ -226,11 +229,11 @@ public class MachineCalculator {
if
(
index
>
-
1
)
{
TimeSegment
targetSegment
=
machine
.
getAvailability
().
get
(
index
);
LocalDateTime
geneEndTime
=
baseTime
.
plus
Minute
s
(
geneDetails
.
getEndTime
());
LocalDateTime
geneEndTime
=
baseTime
.
plus
Second
s
(
geneDetails
.
getEndTime
());
if
(
targetSegment
.
getEnd
().
isAfter
(
geneEndTime
))
{
TimeSegment
usedSegment
=
new
TimeSegment
();
usedSegment
.
setStart
(
baseTime
.
plus
Minute
s
(
geneDetails
.
getStartTime
()));
usedSegment
.
setStart
(
baseTime
.
plus
Second
s
(
geneDetails
.
getStartTime
()));
usedSegment
.
setEnd
(
geneEndTime
);
usedSegment
.
setHoliday
(
false
);
usedSegment
.
setKey
(
UUID
.
randomUUID
().
toString
());
...
...
src/main/java/com/aps/service/Algorithm/OrderSortService.java
View file @
f7bdf363
...
...
@@ -9,6 +9,7 @@ import org.springframework.util.CollectionUtils;
import
javax.annotation.PostConstruct
;
import
java.lang.reflect.Method
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.OffsetDateTime
;
import
java.util.*
;
import
java.util.function.Function
;
...
...
@@ -35,7 +36,7 @@ public class OrderSortService {
registerFieldExtractor
(
"dueDate"
,
Order
->
{
// 直接返回LocalDate,处理null情况
return
Optional
.
ofNullable
(
Order
.
getDueDate
())
.
map
(
Offset
DateTime:
:
toLocalDate
)
.
map
(
Local
DateTime:
:
toLocalDate
)
.
orElse
(
null
);
});
registerFieldExtractor
(
"priority"
,
Order:
:
getPriority
);
...
...
src/main/java/com/aps/service/plan/AlgorithmScheduler6.java
View file @
f7bdf363
...
...
@@ -324,7 +324,7 @@ public class AlgorithmScheduler6 {
LocalDateTime
completionTime
=
chromosome
.
getBaseTime
().
plusMinutes
(
orderCompletion
);
// 修复:正确处理OffsetDateTime到LocalDateTime的转换
LocalDateTime
dueDateTime
=
order
.
getDueDate
()
.
toLocalDateTime
()
;
LocalDateTime
dueDateTime
=
order
.
getDueDate
();
if
(
completionTime
.
isAfter
(
dueDateTime
))
{
// 计算延迟小时数(修复时间计算)
...
...
src/main/java/com/aps/service/plan/AlgorithmScheduler7.java
View file @
f7bdf363
...
...
@@ -473,7 +473,7 @@ public class AlgorithmScheduler7 {
if
(
order
!=
null
)
{
LocalDateTime
completionTime
=
chromosome
.
getBaseTime
().
plusMinutes
(
orderCompletion
);
LocalDateTime
dueDateTime
=
order
.
getDueDate
()
.
toLocalDateTime
()
;
LocalDateTime
dueDateTime
=
order
.
getDueDate
();
if
(
completionTime
.
isAfter
(
dueDateTime
))
{
long
totalMinutes
=
java
.
time
.
temporal
.
ChronoUnit
.
MINUTES
.
between
(
dueDateTime
,
completionTime
);
...
...
src/main/java/com/aps/service/plan/AlgorithmScheduler8.java
View file @
f7bdf363
...
...
@@ -94,7 +94,7 @@ public class AlgorithmScheduler8 {
// 为每个订单分配工序
for
(
Order
order
:
_orders
)
{
Product
product
=
_products
.
stream
()
.
filter
(
p
->
p
.
getId
()
==
order
.
getProductId
())
.
filter
(
p
->
p
.
getId
()
==
order
.
getProductId
())
.
findFirst
()
.
orElseThrow
(()
->
new
NoSuchElementException
(
"Product not found: "
+
order
.
getProductId
()));
...
...
@@ -322,7 +322,7 @@ public class AlgorithmScheduler8 {
// 创建基因
Gene
gene
=
new
Gene
();
gene
.
setOrderId
(
order
.
getId
());
//
gene.setOrderId(order.getId());
gene
.
setProductId
(
order
.
getProductId
());
gene
.
setOperationId
(
operation
.
getId
());
gene
.
setMachineId
(
machine
.
getId
());
...
...
@@ -415,21 +415,21 @@ public class AlgorithmScheduler8 {
.
mapToInt
(
Gene:
:
getEndTime
)
.
max
()
.
orElse
(
0
);
Order
order
=
_orders
.
stream
()
.
filter
(
o
->
o
.
getId
()
==
group
.
getKey
())
.
findFirst
()
.
orElse
(
null
);
if
(
order
!=
null
)
{
LocalDateTime
completionTime
=
chromosome
.
getBaseTime
().
plusMinutes
(
orderCompletion
);
LocalDateTime
dueDateTime
=
order
.
getDueDate
().
toLocalDateTim
e
();
if
(
completionTime
.
isAfter
(
dueDateTime
))
{
long
hours
=
ChronoUnit
.
HOURS
.
between
(
dueDateTime
,
completionTime
);
long
minutes
=
ChronoUnit
.
MINUTES
.
between
(
dueDateTime
,
completionTime
)
%
60
;
tardiness
+=
hours
+
(
double
)
minutes
/
60
;
}
}
//
Order order = _orders.stream()
//
.filter(o -> o.getId() == group.getKey())
//
.findFirst()
//
.orElse(null);
//
//
if (order != null) {
//
LocalDateTime completionTime = chromosome.getBaseTime().plusMinutes(orderCompletion);
// LocalDateTime dueDateTime = order.getDueDat
e();
//
//
if (completionTime.isAfter(dueDateTime)) {
//
long hours = ChronoUnit.HOURS.between(dueDateTime, completionTime);
//
long minutes = ChronoUnit.MINUTES.between(dueDateTime, completionTime) % 60;
//
tardiness += hours + (double) minutes / 60;
//
}
//
}
}
// 3. 总换型时间
...
...
src/main/java/com/aps/service/plan/MachineSchedulerService.java
View file @
f7bdf363
...
...
@@ -206,7 +206,12 @@ public class MachineSchedulerService {
&&
s
.
getDays
()
!=
null
&&
containsDay
(
s
.
getDays
(),
date
.
getDayOfWeek
()))
.
collect
(
Collectors
.
toList
());
if
(
shifts
==
null
||
shifts
.
size
()==
0
)
{
shifts
=
machine
.
getShifts
().
stream
()
.
filter
(
s
->
s
.
getDays
()
!=
null
&&
containsDay
(
s
.
getDays
(),
date
.
getDayOfWeek
()))
.
collect
(
Collectors
.
toList
());
}
for
(
Shift
shift
:
shifts
)
{
LocalDateTime
shiftStart
=
date
.
atTime
(
shift
.
getStartTime
());
LocalDateTime
shiftEnd
=
shift
.
getEndTime
().
isBefore
(
shift
.
getStartTime
())
?
...
...
@@ -247,6 +252,12 @@ public class MachineSchedulerService {
}
private
List
<
TimeSegment
>
mergeSegments
(
List
<
TimeSegment
>
segments
)
{
if
(
segments
==
null
||
segments
.
size
()==
0
)
{
return
null
;
}
List
<
TimeSegment
>
maintenanceSegments
=
segments
.
stream
()
.
filter
(
t
->
t
.
getType
()
==
SegmentType
.
MAINTENANCE
)
.
collect
(
Collectors
.
toList
());
...
...
src/main/java/com/aps/service/plan/PlanResultService.java
View file @
f7bdf363
This diff is collapsed.
Click to expand it.
src/test/java/com/aps/demo/OrderSortServiceTest.java
View file @
f7bdf363
...
...
@@ -69,7 +69,7 @@ class OrderSortServiceTest {
order
.
setProductId
(
100
+
i
);
order
.
setQuantity
(
50.0
*
i
);
order
.
setPriority
(
15
-
i
);
// 优先级:5,4,3,2,1(倒序)
order
.
setDueDate
(
OffsetDateTime
.
now
().
plusDays
(
i
));
// 到期日递增
//
order.setDueDate(OffsetDateTime.now().plusDays(i)); // 到期日递增
order
.
setTardiness
(
i
*
0.5
);
order
.
setCanSplit
(
i
%
2
==
0
);
order
.
setCanInterrupt
(
i
%
3
==
0
);
...
...
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