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
1bed79d7
Commit
1bed79d7
authored
Dec 05, 2025
by
DESKTOP-VKRD9QF\Administration
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
http://39.100.78.207:1213/tongli/hyh.apsj
# Conflicts: # src/main/resources/machines.json
parents
2ba6a39a
1c20209d
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
699 additions
and
94 deletions
+699
-94
DependencyType.java
src/main/java/com/aps/entity/Algorithm/DependencyType.java
+22
-0
OperationDependency.java
...in/java/com/aps/entity/Algorithm/OperationDependency.java
+15
-0
ScheduleResultDetail.java
...n/java/com/aps/entity/Algorithm/ScheduleResultDetail.java
+36
-2
Entry.java
src/main/java/com/aps/entity/basic/Entry.java
+5
-4
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+261
-13
MachineCalculator.java
...ain/java/com/aps/service/Algorithm/MachineCalculator.java
+212
-4
ScheduleOperationService.java
...a/com/aps/service/Algorithm/ScheduleOperationService.java
+91
-15
PlanResultService.java
src/main/java/com/aps/service/plan/PlanResultService.java
+47
-16
machines.json
src/main/resources/machines.json
+10
-40
No files found.
src/main/java/com/aps/entity/Algorithm/DependencyType.java
0 → 100644
View file @
1bed79d7
package
com
.
aps
.
entity
.
Algorithm
;
/**
* 作者:佟礼
* 时间:2025-12-04
*/
public
enum
DependencyType
{
FinishToStart
(
0
),
// 完成-开始(FS):串行 下料→加工→组装
StartToStart
(
1
),
// 开始-开始(SS): 加工 A 和加工 B 可同时进行 重叠 重叠生产:涂装开始后 30 分钟,烘烤可开始
FinishToFinish
(
2
),
// 完成-完成(FF):前置工序完成后,后继工序才能完成 所有并行加工工序需同时完成
StartToFinish
(
3
);
// 开始-完成(SF):前置工序开始后,后继工序才能完成
private
final
int
value
;
DependencyType
(
int
value
)
{
this
.
value
=
value
;
}
public
int
getValue
()
{
return
value
;
}
}
src/main/java/com/aps/entity/Algorithm/OperationDependency.java
0 → 100644
View file @
1bed79d7
package
com
.
aps
.
entity
.
Algorithm
;
import
lombok.Data
;
/**
* 作者:佟礼
* 时间:2025-12-04
*/
@Data
public
class
OperationDependency
{
private
int
Id
;
private
int
prevOperationId
;
// 前置工序ID
private
int
nextOperationId
;
// 后继工序ID
private
DependencyType
dependencyType
=
DependencyType
.
FinishToStart
;
// 依赖类型
}
src/main/java/com/aps/entity/Algorithm/ScheduleResultDetail.java
View file @
1bed79d7
...
@@ -9,6 +9,40 @@ import lombok.Data;
...
@@ -9,6 +9,40 @@ import lombok.Data;
@Data
@Data
public
class
ScheduleResultDetail
{
public
class
ScheduleResultDetail
{
private
String
Key
;
private
String
Key
;
private
int
StartTime
;
// 相对开始时间(分钟)
private
int
StartTime
;
// 相对开始时间(秒)
private
int
EndTime
;
// 相对结束时间(分钟)
private
int
EndTime
;
// 相对结束时间(秒)
private
double
OneTime
;
// 单件工时
private
double
Quantity
;
// 时间段
// Key 的 getter/setter
public
String
getKey
()
{
return
Key
;
}
public
void
setKey
(
String
key
)
{
this
.
Key
=
key
;
}
// StartTime 的 getter/setter
public
int
getStartTime
()
{
return
StartTime
;
}
public
void
setStartTime
(
int
startTime
)
{
this
.
StartTime
=
startTime
;
}
// EndTime 的 getter/setter
public
int
getEndTime
()
{
return
EndTime
;
}
public
void
setEndTime
(
int
endTime
)
{
this
.
EndTime
=
endTime
;
}
// 对应C#的计算属性 processingTime(通过方法实现)
public
int
getProcessingTime
()
{
return
EndTime
-
StartTime
;
// 绝对处理时间(分钟)
}
}
}
src/main/java/com/aps/entity/basic/Entry.java
View file @
1bed79d7
package
com
.
aps
.
entity
.
basic
;
package
com
.
aps
.
entity
.
basic
;
import
com.aps.entity.Algorithm.OperationDependency
;
import
lombok.Data
;
import
lombok.Data
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
...
@@ -12,7 +13,7 @@ import java.util.List;
...
@@ -12,7 +13,7 @@ import java.util.List;
@Data
@Data
public
class
Entry
{
public
class
Entry
{
public
Entry
()
{
public
Entry
()
{
PrevEntryIds
=
new
ArrayList
<
Integer
>();
PrevEntryIds
=
new
ArrayList
<
OperationDependency
>();
}
}
/**
/**
...
@@ -74,12 +75,12 @@ public class Entry {
...
@@ -74,12 +75,12 @@ public class Entry {
/**
/**
* 前工单ID
* 前工单ID
*/
*/
public
List
<
Integer
>
PrevEntryIds
;
//前工序
public
List
<
OperationDependency
>
PrevEntryIds
;
//前工序
/**
/**
*
前
工单ID
*
后
工单ID
*/
*/
public
List
<
Integer
>
NextEntryIds
;
//后工序
public
List
<
OperationDependency
>
NextEntryIds
;
//后工序
/**
/**
* 数据状态 1 拆分 2 新建
* 数据状态 1 拆分 2 新建
...
...
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
1bed79d7
...
@@ -5,6 +5,7 @@ import com.aps.entity.Algorithm.*;
...
@@ -5,6 +5,7 @@ import com.aps.entity.Algorithm.*;
import
com.aps.entity.ProdEquipment
;
import
com.aps.entity.ProdEquipment
;
import
com.aps.entity.basic.*
;
import
com.aps.entity.basic.*
;
import
com.aps.service.plan.MachineSchedulerService
;
import
com.aps.service.plan.MachineSchedulerService
;
import
org.springframework.http.server.DelegatingServerHttpResponse
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
...
@@ -31,6 +32,7 @@ public class GeneticDecoder {
...
@@ -31,6 +32,7 @@ public class GeneticDecoder {
private
final
List
<
Material
>
materials
;
private
final
List
<
Material
>
materials
;
private
List
<
Entry
>
_allOperations
;
private
List
<
Entry
>
_allOperations
;
private
GlobalParam
_globalParam
;
private
GlobalParam
_globalParam
;
private
MachineCalculator
machineCalculator
;
public
GeneticDecoder
(
GlobalParam
globalParam
,
LocalDateTime
baseTime
,
List
<
Machine
>
machines
,
List
<
Order
>
orders
,
public
GeneticDecoder
(
GlobalParam
globalParam
,
LocalDateTime
baseTime
,
List
<
Machine
>
machines
,
List
<
Order
>
orders
,
List
<
Material
>
materials
,
MachineSchedulerService
machineScheduler
)
{
List
<
Material
>
materials
,
MachineSchedulerService
machineScheduler
)
{
this
.
baseTime
=
baseTime
;
this
.
baseTime
=
baseTime
;
...
@@ -40,6 +42,7 @@ public class GeneticDecoder {
...
@@ -40,6 +42,7 @@ public class GeneticDecoder {
this
.
materials
=
materials
;
this
.
materials
=
materials
;
this
.
machineScheduler
=
machineScheduler
;
this
.
machineScheduler
=
machineScheduler
;
_globalParam
=
globalParam
;
_globalParam
=
globalParam
;
machineCalculator
=
new
MachineCalculator
(
baseTime
,
machines
,
machineScheduler
);
// this.orderMaxID = orders.stream().mapToInt(Order::getId).max().orElse(0);
// this.orderMaxID = orders.stream().mapToInt(Order::getId).max().orElse(0);
}
}
public
Chromosome
decodeChromosomeWithCache
(
Chromosome
chromosome
)
{
public
Chromosome
decodeChromosomeWithCache
(
Chromosome
chromosome
)
{
...
@@ -195,15 +198,7 @@ public class GeneticDecoder {
...
@@ -195,15 +198,7 @@ public class GeneticDecoder {
if
(!
currentOp
.
getPrevEntryIds
().
isEmpty
())
{
if
(!
currentOp
.
getPrevEntryIds
().
isEmpty
())
{
// 处理多个前工序
// 处理多个前工序
for
(
int
opid
:
currentOp
.
getPrevEntryIds
())
{
prevtime
=
CalPrevtime
(
prevtime
,
currentOp
,
chromosome
,
processTime
,
targetMachine
);
List
<
GAScheduleResult
>
prevOperations
=
chromosome
.
getResult
().
stream
()
.
filter
(
t
->
t
.
getGroupId
()
==
groupId
&&
t
.
getOperationId
()
==
opid
)
.
collect
(
Collectors
.
toList
());
for
(
GAScheduleResult
prevOp
:
prevOperations
)
{
prevtime
=
Math
.
max
(
prevtime
,
prevOp
.
getEndTime
()+
prevOp
.
getTeardownTime
());
}
}
}
}
// 上个离散参数
// 上个离散参数
...
@@ -303,9 +298,10 @@ public class GeneticDecoder {
...
@@ -303,9 +298,10 @@ public class GeneticDecoder {
}
}
MachineCalculator
machineCalculator
=
new
MachineCalculator
(
baseTime
,
machines
,
machineScheduler
);
List
<
ScheduleResultDetail
>
geneDetails
=
machineCalculator
.
getNextAvailableTime
(
machine
,
earliestStartTime
,
-
1
,
List
<
ScheduleResultDetail
>
geneDetails
=
machineCalculator
.
getNextAvailableTime
(
machine
,
earliestStartTime
,
-
1
,
processingTimeTotal
,
chromosome
.
getResult
(),
false
,
true
,
true
);
processingTimeTotal
,
chromosome
.
getResult
(),
false
,
true
,
processingTime
,
operation
.
getQuantity
(),
true
);
...
@@ -337,7 +333,7 @@ public class GeneticDecoder {
...
@@ -337,7 +333,7 @@ public class GeneticDecoder {
machineCalculator
.
AddMachineAvailable
(
machine
,
geneDetails
);
machineCalculator
.
AddMachineAvailable
(
machine
,
geneDetails
);
geneDetails
=
machineCalculator
.
getNextAvailableTime
(
machine
,
conflictEarliestStartTime
,
-
1
,
geneDetails
=
machineCalculator
.
getNextAvailableTime
(
machine
,
conflictEarliestStartTime
,
-
1
,
processingTimeTotal
,
chromosome
.
getResult
(),
false
,
true
,
true
);
processingTimeTotal
,
chromosome
.
getResult
(),
false
,
true
,
processingTime
,
operation
.
getQuantity
(),
true
);
if
(!
geneDetails
.
isEmpty
())
{
if
(!
geneDetails
.
isEmpty
())
{
startTime
=
geneDetails
.
stream
()
startTime
=
geneDetails
.
stream
()
...
@@ -361,9 +357,11 @@ public class GeneticDecoder {
...
@@ -361,9 +357,11 @@ public class GeneticDecoder {
result
.
setProductId
(
operation
.
getProductId
());
result
.
setProductId
(
operation
.
getProductId
());
result
.
setMachineId
(
machine
.
getId
());
result
.
setMachineId
(
machine
.
getId
());
operation
.
setSelectMachineID
(
machine
.
getId
());
operation
.
setSelectMachineID
(
machine
.
getId
());
result
.
setQuantity
(
operation
.
getQuantity
());
result
.
setStartTime
(
startTime
);
result
.
setStartTime
(
startTime
);
result
.
setEndTime
(
endTime
);
result
.
setEndTime
(
endTime
);
result
.
setOneTime
(
processingTime
);
result
.
setQuantity
(
operation
.
getQuantity
());
result
.
setTeardownTime
(
teardownTime
);
result
.
setTeardownTime
(
teardownTime
);
if
(
existingResult
!=
null
)
{
if
(
existingResult
!=
null
)
{
result
.
setDesignatedStartTime
(
existingResult
.
getDesignatedStartTime
());
result
.
setDesignatedStartTime
(
existingResult
.
getDesignatedStartTime
());
...
@@ -376,6 +374,256 @@ public class GeneticDecoder {
...
@@ -376,6 +374,256 @@ public class GeneticDecoder {
chromosome
.
getResult
().
add
(
result
);
chromosome
.
getResult
().
add
(
result
);
return
endTime
;
return
endTime
;
}
}
/**
* 计算前序结束时间
* @param prevtime
* @param currentOp
* @param chromosome
* @return
*/
private
int
CalPrevtime
(
int
prevtime
,
Entry
currentOp
,
Chromosome
chromosome
,
double
processTime
,
Machine
machine
)
{
List
<
OperationDependency
>
FsOperations
=
currentOp
.
getPrevEntryIds
().
stream
()
.
filter
(
t
->
t
.
getDependencyType
()
==
DependencyType
.
FinishToStart
)
.
collect
(
Collectors
.
toList
());
//串行
if
(
FsOperations
!=
null
&&
FsOperations
.
size
()
>
0
)
{
for
(
OperationDependency
opid
:
FsOperations
)
{
List
<
GAScheduleResult
>
prevOperations
=
chromosome
.
getResult
().
stream
()
.
filter
(
t
->
t
.
getGroupId
()
==
currentOp
.
GroupId
&&
t
.
getOperationId
()
==
opid
.
getPrevOperationId
())
.
collect
(
Collectors
.
toList
());
//多台
for
(
GAScheduleResult
prevOp
:
prevOperations
)
{
prevtime
=
Math
.
max
(
prevtime
,
prevOp
.
getEndTime
()
+
prevOp
.
getTeardownTime
());
}
}
}
List
<
OperationDependency
>
SSOperations
=
currentOp
.
getPrevEntryIds
().
stream
()
.
filter
(
t
->
t
.
getDependencyType
()
==
DependencyType
.
StartToStart
)
.
collect
(
Collectors
.
toList
());
//重叠
if
(
FsOperations
!=
null
&&
FsOperations
.
size
()
>
0
)
{
List
<
GAScheduleResult
>
newScheduleResult
=
new
ArrayList
<>();
List
<
ScheduleResultDetail
>
newScheduleResultDetails
=
new
ArrayList
<>();
for
(
OperationDependency
opid
:
SSOperations
)
{
List
<
GAScheduleResult
>
prevOperations
=
chromosome
.
getResult
().
stream
()
.
filter
(
t
->
t
.
getGroupId
()
==
currentOp
.
GroupId
&&
t
.
getOperationId
()
==
opid
.
getPrevOperationId
())
.
collect
(
Collectors
.
toList
());
//多台
for
(
GAScheduleResult
prevOp
:
prevOperations
)
{
newScheduleResult
.
add
(
prevOp
);
newScheduleResultDetails
.
addAll
(
prevOp
.
getGeneDetails
());
}
}
int
prevperationEndTime
=
newScheduleResult
.
stream
()
.
mapToInt
(
GAScheduleResult:
:
getEndTime
)
.
max
()
.
orElse
(
0
);
prevtime
=
calculateNextOperationStartTime
(
newScheduleResult
,
newScheduleResultDetails
,
0
,
processTime
);
// 下一工序结束时间需晚于上一工序结束时间一个产品加工时间
double
nextopplanend
=
prevperationEndTime
+
processTime
;
List
<
ScheduleResultDetail
>
geneDetails1
=
machineCalculator
.
checkMachineStartTime
(
machine
,
(
int
)
(
processTime
*
currentOp
.
getQuantity
()),
baseTime
.
plusSeconds
((
int
)
nextopplanend
),
baseTime
.
plusSeconds
(
prevtime
),
chromosome
.
getResult
());
if
(
geneDetails1
!=
null
&&
!
geneDetails1
.
isEmpty
())
{
prevtime
=
Math
.
max
(
prevtime
,
geneDetails1
.
stream
()
.
mapToInt
(
ScheduleResultDetail:
:
getStartTime
)
.
min
()
.
orElse
(
prevtime
)
);
}
}
return
prevtime
;
}
/**
* 计算在上一工序生产后什么时间可以开工
* @param details 工序详情列表
* @param startindex 起始索引
* @param time2 时间参数2
* @return 可开工时间
*/
private
int
calculateNextOperationStartTime
(
List
<
GAScheduleResult
>
results
,
List
<
ScheduleResultDetail
>
details
,
int
startindex
,
double
time2
)
{
double
qty
=
results
.
stream
().
mapToDouble
(
GAScheduleResult:
:
getQuantity
)
// 替换为实际字段名
.
sum
();
double
time1
=
0.0
;
for
(
GAScheduleResult
r
:
results
)
{
time1
+=
1.0
/
r
.
getOneTime
();
}
int
leadCount
=(
int
)
calculateLeadProductionItems
(
qty
,
time1
,
time2
);
if
(
leadCount
==
qty
)
{
return
details
.
stream
()
.
mapToInt
(
ScheduleResultDetail:
:
getEndTime
)
.
max
()
.
orElse
(
0
);
}
if
(
startindex
>
leadCount
)
{
leadCount
=
startindex
;
}
if
(
results
.
size
()>
1
)
{
//多前置工序
calculateWithMoreMachine
(
details
,
leadCount
);
}
// 单设备时使用原逻辑
return
(
int
)
calculateWithSingleMachine
(
details
,
leadCount
,
time1
);
}
/**
* 多设备并行时计算满足提前量的最早时间
*/
private
int
calculateWithParallelMachines
(
List
<
ScheduleResultDetail
>
details
,
int
leadCount
,
int
time1
)
{
// 收集所有设备的时间点(开始和结束)并去重排序
Set
<
Integer
>
timePoints
=
new
TreeSet
<>();
for
(
ScheduleResultDetail
detail
:
details
)
{
timePoints
.
add
(
detail
.
getStartTime
());
timePoints
.
add
(
detail
.
getEndTime
());
}
List
<
Integer
>
sortedTimes
=
new
ArrayList
<>(
timePoints
);
int
accumulatedQty
=
0
;
int
prevTime
=
0
;
for
(
int
currTime
:
sortedTimes
)
{
if
(
prevTime
>=
currTime
)
{
prevTime
=
currTime
;
continue
;
}
// 计算当前时间区间[prevTime, currTime)内的有效产能
int
duration
=
currTime
-
prevTime
;
int
machinesWorking
=
0
;
for
(
ScheduleResultDetail
detail
:
details
)
{
// 设备在当前区间内是否处于工作状态
if
(
detail
.
getStartTime
()
<=
prevTime
&&
detail
.
getEndTime
()
>=
currTime
)
{
machinesWorking
++;
}
}
// 区间内的产量(每台设备单位时间产能为1/time1,多设备累加)
int
qtyInInterval
=
(
duration
/
time1
)
*
machinesWorking
;
accumulatedQty
+=
qtyInInterval
;
// 检查是否满足提前量
if
(
accumulatedQty
>=
leadCount
)
{
// 反推精确满足提前量的时间点
int
excess
=
accumulatedQty
-
leadCount
;
int
timeNeeded
=
leadCount
*
time1
-
(
accumulatedQty
-
qtyInInterval
)
*
time1
;
return
prevTime
+
timeNeeded
;
}
prevTime
=
currTime
;
}
// 若所有时间点仍未满足,返回最后结束时间
return
details
.
stream
().
mapToInt
(
ScheduleResultDetail:
:
getEndTime
).
max
().
orElse
(
0
);
}
/**
* 前置多工序多台,合并时间片段并计算满足前置产量的时间点
* @param details 排产详情列表(包含开始时间、结束时间、单件工时)
* @param leadCount 需要提前生产的数量
* @return 满足前置产量的时间点
*/
private
int
calculateWithMoreMachine
(
List
<
ScheduleResultDetail
>
details
,
int
leadCount
)
{
if
(
details
==
null
||
details
.
isEmpty
()
||
leadCount
<=
0
)
{
return
0
;
// 边界条件处理
}
// 1. 收集所有时间点(开始和结束)并去重排序
Set
<
Integer
>
timePoints
=
new
TreeSet
<>();
for
(
ScheduleResultDetail
detail
:
details
)
{
timePoints
.
add
(
detail
.
getStartTime
());
timePoints
.
add
(
detail
.
getEndTime
());
}
List
<
Integer
>
sortedTimes
=
new
ArrayList
<>(
timePoints
);
if
(
sortedTimes
.
size
()
<
2
)
{
return
details
.
get
(
0
).
getEndTime
();
// 无有效时间片段
}
// 2. 按时间片段计算累计产量
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
;
// 跳过无效时间段
}
// 计算当前时间段内所有运行的设备总效率(件/单位时间)
//1秒生产的数量
double
totalEfficiency
=
details
.
stream
()
.
filter
(
detail
->
detail
.
getStartTime
()
<=
startTime
&&
detail
.
getEndTime
()
>=
endTime
)
.
mapToDouble
(
detail
->
1.0
/
detail
.
getOneTime
())
// 单件工时的倒数即效率
.
sum
();
// 当前时间段可生产的数量
double
segmentQty
=
totalEfficiency
*
duration
;
// 检查是否在当前时间段内满足前置产量
if
(
accumulatedQty
+
segmentQty
>=
leadCount
)
{
// 计算精确时间点(向上取整避免小数精度问题)
double
remainingQty
=
leadCount
-
accumulatedQty
;
int
requiredTime
=
(
int
)
Math
.
ceil
(
remainingQty
/
totalEfficiency
);
//数量除以每秒的数量, 每秒生产多少个,生产X用几秒
return
startTime
+
requiredTime
;
}
accumulatedQty
+=
segmentQty
;
}
// 3. 所有片段累计仍未满足(返回最后结束时间)
return
details
.
stream
()
.
mapToInt
(
ScheduleResultDetail:
:
getEndTime
)
.
max
()
.
orElse
(
0
);
}
/**
* 单设备时使用原逻辑(保持兼容)
*/
private
double
calculateWithSingleMachine
(
List
<
ScheduleResultDetail
>
details
,
int
leadCount
,
double
time1
)
{
//上一工序的排产详情 - 需要提前生产出来的数量花费的时间
double
alltime
=
leadCount
*
time1
;
for
(
ScheduleResultDetail
detail
:
details
)
{
double
time3
=
alltime
-
detail
.
getProcessingTime
();
if
(
time3
<
0
)
{
return
detail
.
getEndTime
()
+
time3
;
}
else
if
(
time3
==
0
)
{
return
detail
.
getEndTime
();
}
else
{
alltime
=
time3
;
}
}
return
details
.
get
(
details
.
size
()
-
1
).
getEndTime
();
}
/**
* 计算工序1需要提前生产的件数
* @param qty 总订单量
* @param time1 工序1单件工时
* @param time2 工序2单件工时
* @return 工序1需要提前生产的件数
*/
private
double
calculateLeadProductionItems
(
double
qty
,
double
time1
,
double
time2
)
{
if
(
time1
<
time2
)
{
return
1
;
}
if
(
qty
<=
0
||
time1
<=
0
||
time2
<=
0
)
{
throw
new
IllegalArgumentException
(
"参数必须为正整数"
);
}
double
totalTime1
=
qty
*
time1
;
double
totalTime2
=
qty
*
time2
;
double
timeDifference
=
totalTime2
-
totalTime1
;
return
(
timeDifference
/
time1
)
>
qty
?
qty
:
(
timeDifference
/
time1
);
}
private
String
ConvertTime
(
int
minute
)
{
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
(
"MM-dd HH:mm"
));
}
}
...
...
src/main/java/com/aps/service/Algorithm/MachineCalculator.java
View file @
1bed79d7
...
@@ -9,6 +9,7 @@ import com.aps.service.plan.MachineSchedulerService;
...
@@ -9,6 +9,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.time.Duration
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
java.time.format.DateTimeFormatter
;
import
java.time.format.DateTimeFormatter
;
import
java.time.temporal.ChronoUnit
;
import
java.time.temporal.ChronoUnit
;
...
@@ -41,6 +42,7 @@ public class MachineCalculator {
...
@@ -41,6 +42,7 @@ public class MachineCalculator {
int
prevtime
,
int
processingTime
,
int
prevtime
,
int
processingTime
,
List
<
GAScheduleResult
>
existingTasks
,
List
<
GAScheduleResult
>
existingTasks
,
boolean
isInterrupt
,
boolean
istask
,
boolean
isInterrupt
,
boolean
istask
,
double
oneTime
,
double
quantity
,
boolean
islockMachineTime
)
{
boolean
islockMachineTime
)
{
LocalDateTime
startTime
=
baseTime
.
plus
(
proposedStartTime
,
ChronoUnit
.
SECONDS
);
LocalDateTime
startTime
=
baseTime
.
plus
(
proposedStartTime
,
ChronoUnit
.
SECONDS
);
...
@@ -52,7 +54,7 @@ public class MachineCalculator {
...
@@ -52,7 +54,7 @@ public class MachineCalculator {
// 查找合适的班次窗口
// 查找合适的班次窗口
return
findEarliestStart
(
machine
,
processingTime
,
startTime
,
prevtimestr
,
return
findEarliestStart
(
machine
,
processingTime
,
startTime
,
prevtimestr
,
existingTasks
,
istask
,
islockMachineTime
);
existingTasks
,
oneTime
,
quantity
,
istask
,
islockMachineTime
);
}
}
...
@@ -60,7 +62,7 @@ public class MachineCalculator {
...
@@ -60,7 +62,7 @@ public class MachineCalculator {
private
List
<
ScheduleResultDetail
>
findEarliestStart
(
private
List
<
ScheduleResultDetail
>
findEarliestStart
(
Machine
machine
,
int
processingTime
,
LocalDateTime
currentTime
,
Machine
machine
,
int
processingTime
,
LocalDateTime
currentTime
,
String
prevtime
,
List
<
GAScheduleResult
>
existingTasks
,
boolean
checkprevtime
,
boolean
islockMachineTime
String
prevtime
,
List
<
GAScheduleResult
>
existingTasks
,
double
oneTime
,
double
quantity
,
boolean
checkprevtime
,
boolean
islockMachineTime
)
{
)
{
List
<
GAScheduleResult
>
machineTasks
=
existingTasks
.
stream
()
List
<
GAScheduleResult
>
machineTasks
=
existingTasks
.
stream
()
.
filter
(
t
->
t
.
getMachineId
()
==
machine
.
getId
())
.
filter
(
t
->
t
.
getMachineId
()
==
machine
.
getId
())
...
@@ -79,12 +81,14 @@ public class MachineCalculator {
...
@@ -79,12 +81,14 @@ public class MachineCalculator {
LocalDateTime
endCandidate
=
startCandidate
.
plusSeconds
(
processingTime
);
LocalDateTime
endCandidate
=
startCandidate
.
plusSeconds
(
processingTime
);
if
(
endCandidate
.
isAfter
(
slot
.
getEnd
()))
{
if
(
endCandidate
.
isAfter
(
slot
.
getEnd
()))
{
return
CaldEarliestStart
(
machine
,
processingTime
,
currentTime
,
prevtime
,
machineTasks
,
checkprevtime
,
islockMachineTime
);
return
CaldEarliestStart
(
machine
,
processingTime
,
currentTime
,
prevtime
,
machineTasks
,
oneTime
,
quantity
,
checkprevtime
,
islockMachineTime
);
}
else
{
}
else
{
ScheduleResultDetail
time
=
new
ScheduleResultDetail
();
ScheduleResultDetail
time
=
new
ScheduleResultDetail
();
time
.
setKey
(
slot
.
getKey
());
time
.
setKey
(
slot
.
getKey
());
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
startCandidate
));
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
startCandidate
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
endCandidate
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
endCandidate
));
time
.
setOneTime
(
oneTime
);
time
.
setQuantity
(
quantity
);
times
.
add
(
time
);
times
.
add
(
time
);
if
(
islockMachineTime
)
{
if
(
islockMachineTime
)
{
RemoveMachineAvailable
(
machine
,
time
);
RemoveMachineAvailable
(
machine
,
time
);
...
@@ -96,7 +100,7 @@ public class MachineCalculator {
...
@@ -96,7 +100,7 @@ public class MachineCalculator {
private
List
<
ScheduleResultDetail
>
CaldEarliestStart
(
private
List
<
ScheduleResultDetail
>
CaldEarliestStart
(
Machine
machine
,
int
processingTime
,
LocalDateTime
currentTime
,
Machine
machine
,
int
processingTime
,
LocalDateTime
currentTime
,
String
prevtime
,
List
<
GAScheduleResult
>
machineTasks
,
boolean
checkprevtime
,
boolean
islockMachineTime
String
prevtime
,
List
<
GAScheduleResult
>
machineTasks
,
double
oneTime
,
double
quantity
,
boolean
checkprevtime
,
boolean
islockMachineTime
)
{
)
{
int
remainingTime
=
processingTime
;
int
remainingTime
=
processingTime
;
LocalDateTime
st
=
StringUtils
.
isEmpty
(
prevtime
)
?
currentTime
:
LocalDateTime
.
parse
(
prevtime
);
LocalDateTime
st
=
StringUtils
.
isEmpty
(
prevtime
)
?
currentTime
:
LocalDateTime
.
parse
(
prevtime
);
...
@@ -166,6 +170,8 @@ public class MachineCalculator {
...
@@ -166,6 +170,8 @@ public class MachineCalculator {
time
.
setKey
(
shift
.
getKey
());
time
.
setKey
(
shift
.
getKey
());
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveStart
));
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveStart
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
currentTime
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
currentTime
));
time
.
setQuantity
((
int
)(
processable
/
oneTime
));
time
.
setOneTime
(
oneTime
);
times
.
add
(
time
);
times
.
add
(
time
);
if
(
islockMachineTime
)
{
if
(
islockMachineTime
)
{
// 还原未使用的时间段
// 还原未使用的时间段
...
@@ -216,7 +222,209 @@ public class MachineCalculator {
...
@@ -216,7 +222,209 @@ public class MachineCalculator {
return
start
;
return
start
;
}
}
/**
* 检查设备的可用开工时间
* @param machine 目标设备
* @param processingTime 加工时长(分钟)
* @param currentTime 当前时间
* @param startTime 开始时间
* @param existingTasks 已有任务列表
* @return 可用时间段列表,无可用时间返回null
*/
public
List
<
ScheduleResultDetail
>
checkMachineStartTime
(
Machine
machine
,
int
processingTime
,
LocalDateTime
currentTime
,
LocalDateTime
startTime
,
List
<
GAScheduleResult
>
existingTasks
)
{
// 获取设备上已有任务并按开始时间排序
List
<
GAScheduleResult
>
machineTasks
=
existingTasks
.
stream
()
.
filter
(
t
->
t
.
getMachineId
()
==
machine
.
getId
())
.
sorted
(
Comparator
.
comparing
(
GAScheduleResult:
:
getStartTime
))
.
collect
(
Collectors
.
toList
());
List
<
ScheduleResultDetail
>
times
=
new
ArrayList
<>();
// 获取当前/上一个班次
TimeSegment
slot
=
getCurrentOrPrevShift
(
machine
,
currentTime
);
if
(
slot
==
null
)
{
return
null
;
}
// 计算候选开始/结束时间(当前时间往前推加工时长)
LocalDateTime
startCandidate
=
currentTime
.
minusSeconds
(
processingTime
);
LocalDateTime
endCandidate
=
currentTime
;
// 检查是否在可用时间段内
if
(
startCandidate
.
isBefore
(
slot
.
getStart
()))
{
// 放不下,寻找后续可用时间
return
checkMachineShift
(
machine
,
processingTime
,
currentTime
,
startTime
,
machineTasks
);
}
else
{
// 生成可用时间段
ScheduleResultDetail
time
=
new
ScheduleResultDetail
();
time
.
setKey
(
slot
.
getKey
());
// 计算相对基准时间的分钟数(对应原代码TotalMinutes
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
startCandidate
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
endCandidate
));
times
.
add
(
time
);
return
times
;
}
}
/**
* 获取设备当前或上一个有效班次
* @param machine 目标设备
* @param time 目标时间
* @return 有效班次,无则递归生成后返回
*/
private
TimeSegment
getCurrentOrPrevShift
(
Machine
machine
,
LocalDateTime
time
)
{
TimeSegment
start
=
null
;
// 找到最后一个可用班次:未使用、非维护类型、开始时间早于目标时间
// 倒序遍历找最后一个符合条件的班次
List
<
TimeSegment
>
availability
=
machine
.
getAvailability
();
for
(
int
i
=
availability
.
size
()
-
1
;
i
>=
0
;
i
--)
{
TimeSegment
slot
=
availability
.
get
(
i
);
if
(!
slot
.
isUsed
()
&&
slot
.
getType
()
!=
SegmentType
.
MAINTENANCE
&&
slot
.
getStart
().
isBefore
(
time
))
{
start
=
slot
;
break
;
}
}
// 若未找到班次,且目标时间晚于所有班次的结束时间 → 生成新班次并递归
if
(
start
==
null
)
{
// 获取所有班次的最大结束时间
Optional
<
LocalDateTime
>
maxEndTime
=
availability
.
stream
()
.
map
(
TimeSegment:
:
getEnd
)
.
max
(
LocalDateTime:
:
compareTo
);
// 检查是否目标时间晚于最大结束时间(处理空列表情况)
boolean
isTimeAfterMaxEnd
=
maxEndTime
.
map
(
end
->
time
.
isAfter
(
end
)).
orElse
(
true
);
if
(
isTimeAfterMaxEnd
)
{
// 生成新的时间段并添加到设备可用班次中
LocalDateTime
generateStartTime
=
maxEndTime
.
orElse
(
LocalDateTime
.
now
());
List
<
TimeSegment
>
timeSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
generateStartTime
);
machine
.
getAvailability
().
addAll
(
timeSegments
);
// 更新机器列表中的对应机器
Machine
m
=
machines
.
stream
()
.
filter
(
t
->
t
.
getId
()
==
machine
.
getId
())
.
findFirst
()
.
orElse
(
null
);
if
(
m
!=
null
)
{
MachineTimeline
machineTimeline
=
machineScheduler
.
getOrCreateTimeline
(
m
);
// 原代码注释:m.Availability = machineTimeline.Segments;
// 如需启用请补充:m.setAvailability(machineTimeline.getSegments());
}
// 递归调用,重新获取有效班次
return
getCurrentOrPrevShift
(
machine
,
time
);
}
}
return
start
;
}
/**
* 检查设备班次,计算满足加工时长的可用时间段
* @param machine 目标设备
* @param processingTime 总加工时长(分钟)
* @param currentTime 当前时间
* @param startTime 开始时间阈值
* @param machineTasks 设备已有任务列表
* @return 分段的可用时间段列表,无可用时间返回null
*/
private
List
<
ScheduleResultDetail
>
checkMachineShift
(
Machine
machine
,
int
processingTime
,
LocalDateTime
currentTime
,
LocalDateTime
startTime
,
List
<
GAScheduleResult
>
machineTasks
)
{
int
remainingTime
=
processingTime
;
// 初始化上一班次结束时间(对应原2000-01-01的初始值)
LocalDateTime
prevEnd
=
LocalDateTime
.
of
(
2000
,
1
,
1
,
0
,
0
);
List
<
ScheduleResultDetail
>
times
=
new
ArrayList
<>();
while
(
remainingTime
>
0
)
{
// 开始时间阈值超过当前时间,无可用时间
if
(
startTime
.
isAfter
(
currentTime
))
{
return
null
;
}
// 获取当前/上一个有效班次
TimeSegment
shift
=
getCurrentOrPrevShift
(
machine
,
currentTime
);
if
(
shift
==
null
)
{
return
null
;
}
LocalDateTime
shiftStart
=
shift
.
getStart
();
LocalDateTime
shiftEnd
=
shift
.
getEnd
();
// 非初始状态(上一班次已存在),检查班次连续性
if
(
prevEnd
.
getYear
()!=
2000
)
{
// 检查上一班次和当前班次之间是否有任务
if
(
prevEnd
.
isAfter
(
shiftEnd
))
{
// 查找任务:任务开始时间在当前班次开始 ~ 上一班次结束之间
LocalDateTime
finalPrevEnd
=
prevEnd
;
Optional
<
GAScheduleResult
>
task
=
machineTasks
.
stream
()
.
filter
(
t
->
baseTime
.
plusSeconds
(
t
.
getStartTime
()).
isAfter
(
shiftStart
)
&&
baseTime
.
plusSeconds
(
t
.
getStartTime
()).
isBefore
(
finalPrevEnd
))
.
findFirst
();
if
(
task
.
isPresent
())
{
// 班次间有任务,重置状态重新查找
currentTime
=
shiftStart
;
remainingTime
=
processingTime
;
prevEnd
=
LocalDateTime
.
of
(
2000
,
1
,
1
,
0
,
0
);
times
.
clear
();
continue
;
}
}
// 检查维护窗口
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
;
}
}
}
// 调整班次有效结束时间(不超过当前时间)
LocalDateTime
effectiveEnd
=
shiftEnd
.
isAfter
(
currentTime
)
?
currentTime
:
shiftEnd
;
// 计算班次可用时长
Duration
availableDuration
=
Duration
.
between
(
shiftStart
,
effectiveEnd
);
long
availableMinutes
=
availableDuration
.
getSeconds
();
// 当前班次可处理的时长(不超过剩余需要的时长)
int
processableMinutes
=
(
int
)
Math
.
min
(
remainingTime
,
availableMinutes
);
// 计算当前班次的有效开始时间
LocalDateTime
effectiveStart
=
effectiveEnd
.
minusSeconds
(
processableMinutes
);
prevEnd
=
effectiveStart
;
// 更新上一班次结束时间
remainingTime
-=
processableMinutes
;
// 剩余时长递减
currentTime
=
effectiveStart
;
// 更新当前时间,继续循环
// 生成当前班次的时间片段
ScheduleResultDetail
time
=
new
ScheduleResultDetail
();
time
.
setKey
(
shift
.
getKey
());
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveStart
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveEnd
));
times
.
add
(
time
);
}
return
times
;
}
private
void
RemoveMachineAvailable
(
Machine
machine
,
ScheduleResultDetail
geneDetails
)
{
private
void
RemoveMachineAvailable
(
Machine
machine
,
ScheduleResultDetail
geneDetails
)
{
List
<
TimeSegment
>
timeSegments
=
new
ArrayList
<>();
List
<
TimeSegment
>
timeSegments
=
new
ArrayList
<>();
...
...
src/main/java/com/aps/service/Algorithm/ScheduleOperationService.java
View file @
1bed79d7
package
com
.
aps
.
service
.
Algorithm
;
package
com
.
aps
.
service
.
Algorithm
;
import
com.aps.common.util.ProductionDeepCopyUtil
;
import
com.aps.common.util.ProductionDeepCopyUtil
;
import
com.aps.entity.Algorithm.Chromosome
;
import
com.aps.entity.Algorithm.*
;
import
com.aps.entity.Algorithm.GAScheduleResult
;
import
com.aps.entity.Algorithm.GlobalOperationInfo
;
import
com.aps.entity.Algorithm.IDAndChildID.GroupResult
;
import
com.aps.entity.Algorithm.IDAndChildID.GroupResult
;
import
com.aps.entity.Algorithm.IDAndChildID.NodeInfo
;
import
com.aps.entity.Algorithm.IDAndChildID.NodeInfo
;
import
com.aps.entity.Algorithm.ScheduleResultDetail
;
import
com.aps.entity.basic.Entry
;
import
com.aps.entity.basic.Entry
;
import
com.aps.entity.basic.GlobalParam
;
import
com.aps.entity.basic.GlobalParam
;
import
com.aps.entity.basic.MachineOption
;
import
com.aps.entity.basic.MachineOption
;
...
@@ -173,9 +170,28 @@ public class ScheduleOperationService {
...
@@ -173,9 +170,28 @@ public class ScheduleOperationService {
{
{
//存在则修改顺和前后序
//存在则修改顺和前后序
entry
.
setSequence
(
nodeInfo
.
getGroupSerial
());
entry
.
setSequence
(
nodeInfo
.
getGroupSerial
());
entry
.
setPrevEntryIds
(
nodeInfo
.
getNewParentIds
());
// entry.setPrevEntryIds(nodeInfo.getNewParentIds());
entry
.
setNextEntryIds
(
nodeInfo
.
getNewChildIds
());
// entry.setNextEntryIds(nodeInfo.getNewChildIds());
if
(
nodeInfo
.
getNewParentIds
()!=
null
)
{
List
<
OperationDependency
>
OperationDependency
=
new
ArrayList
<>();
for
(
int
id
:
nodeInfo
.
getNewParentIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setPrevOperationId
(
id
);
OperationDependency
.
add
(
od
);
}
entry
.
setPrevEntryIds
(
OperationDependency
);
}
if
(
nodeInfo
.
getNewChildIds
()!=
null
)
{
List
<
OperationDependency
>
OperationDependency
=
new
ArrayList
<>();
for
(
int
id
:
nodeInfo
.
getNewChildIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setNextOperationId
(
id
);
OperationDependency
.
add
(
od
);
}
entry
.
setNextEntryIds
(
OperationDependency
);
}
GlobalOperationInfo
info
=
chromosome
.
getGlobalOpList
().
stream
()
GlobalOperationInfo
info
=
chromosome
.
getGlobalOpList
().
stream
()
.
filter
(
t
->
t
.
getOp
().
getId
()==
entry
.
getId
())
.
filter
(
t
->
t
.
getOp
().
getId
()==
entry
.
getId
())
.
findFirst
()
.
findFirst
()
...
@@ -196,8 +212,28 @@ public class ScheduleOperationService {
...
@@ -196,8 +212,28 @@ public class ScheduleOperationService {
newOp
.
setId
(
nodeInfo
.
getGlobalSerial
());
newOp
.
setId
(
nodeInfo
.
getGlobalSerial
());
newOp
.
setSequence
(
nodeInfo
.
getGroupSerial
());
newOp
.
setSequence
(
nodeInfo
.
getGroupSerial
());
newOp
.
setExecId
(
nodeInfo
.
getOriginalId
());
newOp
.
setExecId
(
nodeInfo
.
getOriginalId
());
newOp
.
setPrevEntryIds
(
nodeInfo
.
getNewParentIds
());
// newOp.setPrevEntryIds(nodeInfo.getNewParentIds());
newOp
.
setNextEntryIds
(
nodeInfo
.
getNewChildIds
());
// newOp.setNextEntryIds(nodeInfo.getNewChildIds());
if
(
nodeInfo
.
getNewParentIds
()!=
null
)
{
List
<
OperationDependency
>
OperationDependency
=
new
ArrayList
<>();
for
(
int
id
:
nodeInfo
.
getNewParentIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setPrevOperationId
(
id
);
OperationDependency
.
add
(
od
);
}
entry
.
setPrevEntryIds
(
OperationDependency
);
}
if
(
nodeInfo
.
getNewChildIds
()!=
null
)
{
List
<
OperationDependency
>
OperationDependency
=
new
ArrayList
<>();
for
(
int
id
:
nodeInfo
.
getNewChildIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setNextOperationId
(
id
);
OperationDependency
.
add
(
od
);
}
entry
.
setNextEntryIds
(
OperationDependency
);
}
newOp
.
setQuantity
(
newids
.
get
(
nodeInfo
.
getOriginalId
()));
newOp
.
setQuantity
(
newids
.
get
(
nodeInfo
.
getOriginalId
()));
newOp
.
setMainId
(
MainId
);
newOp
.
setMainId
(
MainId
);
newOp
.
setState
(
2
);
newOp
.
setState
(
2
);
...
@@ -281,10 +317,10 @@ public class ScheduleOperationService {
...
@@ -281,10 +317,10 @@ public class ScheduleOperationService {
for
(
Entry
entry
:
newEntrys
)
{
for
(
Entry
entry
:
newEntrys
)
{
if
(
entry
.
getNextEntryIds
().
size
()>
0
)
if
(
entry
.
getNextEntryIds
().
size
()>
0
)
{
{
for
(
Integer
i
d
:
entry
.
getNextEntryIds
())
{
for
(
OperationDependency
o
d
:
entry
.
getNextEntryIds
())
{
Entry
nextentry
=
newEntrys
.
stream
()
Entry
nextentry
=
newEntrys
.
stream
()
.
filter
(
t
->
t
.
getGroupId
()==
entry
.
getGroupId
()&&
t
.
getId
()==
id
)
.
filter
(
t
->
t
.
getGroupId
()==
entry
.
getGroupId
()&&
t
.
getId
()==
od
.
getNextOperationId
()
)
.
findFirst
()
.
findFirst
()
.
orElse
(
null
);
.
orElse
(
null
);
if
(
nextentry
!=
null
)
{
if
(
nextentry
!=
null
)
{
...
@@ -325,8 +361,28 @@ public class ScheduleOperationService {
...
@@ -325,8 +361,28 @@ public class ScheduleOperationService {
entry
.
setGroupId
(
i
+
1
);
entry
.
setGroupId
(
i
+
1
);
entry
.
setSequence
(
nodeInfo
.
getGroupSerial
());
entry
.
setSequence
(
nodeInfo
.
getGroupSerial
());
entry
.
setExecId
(
nodeInfo
.
getOriginalId
());
entry
.
setExecId
(
nodeInfo
.
getOriginalId
());
entry
.
setPrevEntryIds
(
nodeInfo
.
getNewParentIds
());
// entry.setPrevEntryIds(nodeInfo.getNewParentIds());
entry
.
setNextEntryIds
(
nodeInfo
.
getNewChildIds
());
// entry.setNextEntryIds(nodeInfo.getNewChildIds());
if
(
nodeInfo
.
getNewParentIds
()!=
null
)
{
List
<
OperationDependency
>
OperationDependency
=
new
ArrayList
<>();
for
(
int
id
:
nodeInfo
.
getNewParentIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setPrevOperationId
(
id
);
OperationDependency
.
add
(
od
);
}
entry
.
setPrevEntryIds
(
OperationDependency
);
}
if
(
nodeInfo
.
getNewChildIds
()!=
null
)
{
List
<
OperationDependency
>
OperationDependency
=
new
ArrayList
<>();
for
(
int
id
:
nodeInfo
.
getNewChildIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setNextOperationId
(
id
);
OperationDependency
.
add
(
od
);
}
entry
.
setNextEntryIds
(
OperationDependency
);
}
entry
.
setMainId
(
""
);
entry
.
setMainId
(
""
);
entry
.
setState
(
2
);
entry
.
setState
(
2
);
//工序基本信息
//工序基本信息
...
@@ -487,8 +543,28 @@ public class ScheduleOperationService {
...
@@ -487,8 +543,28 @@ public class ScheduleOperationService {
if
(
node
!=
null
)
if
(
node
!=
null
)
{
{
entry
.
setSequence
(
node
.
getGroupSerial
());
entry
.
setSequence
(
node
.
getGroupSerial
());
entry
.
setPrevEntryIds
(
node
.
getNewParentIds
());
// entry.setPrevEntryIds(node.getNewParentIds());
entry
.
setNextEntryIds
(
node
.
getNewChildIds
());
// entry.setNextEntryIds(node.getNewChildIds());
if
(
node
.
getNewParentIds
()!=
null
)
{
List
<
OperationDependency
>
OperationDependency
=
new
ArrayList
<>();
for
(
int
id
:
node
.
getNewParentIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setPrevOperationId
(
id
);
OperationDependency
.
add
(
od
);
}
entry
.
setPrevEntryIds
(
OperationDependency
);
}
if
(
node
.
getNewChildIds
()!=
null
)
{
List
<
OperationDependency
>
OperationDependency
=
new
ArrayList
<>();
for
(
int
id
:
node
.
getNewChildIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setNextOperationId
(
id
);
OperationDependency
.
add
(
od
);
}
entry
.
setNextEntryIds
(
OperationDependency
);
}
GlobalOperationInfo
info
=
chromosome
.
getGlobalOpList
().
stream
()
GlobalOperationInfo
info
=
chromosome
.
getGlobalOpList
().
stream
()
.
filter
(
t
->
t
.
getOp
().
getId
()==
entry
.
getId
())
.
filter
(
t
->
t
.
getOp
().
getId
()==
entry
.
getId
())
.
findFirst
()
.
findFirst
()
...
...
src/main/java/com/aps/service/plan/PlanResultService.java
View file @
1bed79d7
...
@@ -5,12 +5,9 @@ import com.aps.common.util.JsonFileReader;
...
@@ -5,12 +5,9 @@ import com.aps.common.util.JsonFileReader;
import
com.aps.common.util.ProductionDeepCopyUtil
;
import
com.aps.common.util.ProductionDeepCopyUtil
;
import
com.aps.controller.gantt.FileUploadController
;
import
com.aps.controller.gantt.FileUploadController
;
import
com.aps.entity.*
;
import
com.aps.entity.*
;
import
com.aps.entity.Algorithm.Chromosome
;
import
com.aps.entity.Algorithm.*
;
import
com.aps.entity.Algorithm.GAScheduleResult
;
import
com.aps.entity.Algorithm.IDAndChildID.GroupResult
;
import
com.aps.entity.Algorithm.IDAndChildID.GroupResult
;
import
com.aps.entity.Algorithm.IDAndChildID.NodeInfo
;
import
com.aps.entity.Algorithm.IDAndChildID.NodeInfo
;
import
com.aps.entity.Algorithm.ScheduleParams
;
import
com.aps.entity.Algorithm.ScheduleResultDetail
;
import
com.aps.entity.basic.ScheduleChromosome
;
import
com.aps.entity.basic.ScheduleChromosome
;
import
com.aps.entity.Schedule.GenVO
;
import
com.aps.entity.Schedule.GenVO
;
import
com.aps.entity.Schedule.MachineVO
;
import
com.aps.entity.Schedule.MachineVO
;
...
@@ -140,10 +137,25 @@ public class PlanResultService {
...
@@ -140,10 +137,25 @@ public class PlanResultService {
}
}
}
}
public
Chromosome
execute1
()
{
public
Chromosome
execute1
()
{
try
{
try
{
//List<ScheduleResultDetail> details=new ArrayList<>();
// ScheduleResultDetail detail1=new ScheduleResultDetail();
//
// detail1.setOneTime(100);//单件工时
//
//
// ScheduleResultDetail detail2=new ScheduleResultDetail();
//
// detail2.setOneTime(200);//单件工时
// details.add(detail1);
// details.add(detail2);
// mergeSegmentsWithDifferentOneTime(details, 50);
// 1. 读取数据
// 1. 读取数据
List
<
Machine
>
machines
=
loadData
(
"machines.json"
,
Machine
.
class
);
List
<
Machine
>
machines
=
loadData
(
"machines.json"
,
Machine
.
class
);
List
<
Product
>
products
=
loadData
(
"products.json"
,
Product
.
class
);
List
<
Product
>
products
=
loadData
(
"products.json"
,
Product
.
class
);
...
@@ -171,23 +183,20 @@ public class PlanResultService {
...
@@ -171,23 +183,20 @@ public class PlanResultService {
}
}
ScheduleParams
param
=
new
ScheduleParams
();
ScheduleParams
param
=
new
ScheduleParams
();
param
.
setBaseTime
(
LocalDateTime
.
of
(
2025
,
11
,
1
,
0
,
0
,
0
));
param
.
setBaseTime
(
LocalDateTime
.
of
(
2025
,
11
,
1
,
0
,
0
,
0
));
param
.
setPopulationSize
(
50
);
param
.
setPopulationSize
(
1
);
param
.
setMaxIterations
(
100
);
param
.
setMaxIterations
(
2
);
// List<MesHoliday> holidays= _MesHolidayService.list();
// List<MesHoliday> holidays= _MesHolidayService.list();
// 创建节假日
// 创建节假日
List
<
Holiday
>
holidays
=
Arrays
.
asList
(
new
Holiday
(
LocalDateTime
.
of
(
2025
,
10
,
1
,
0
,
0
),
LocalDateTime
.
of
(
2025
,
10
,
7
,
23
,
59
))
);
// 将节假日添加到所有设备中
// 将节假日添加到所有设备中
addHolidaysToAllMachines
(
machines
,
holiday
s
);
// addHolidaysToAllMachines(machine
s);
// 3. 创建调度服务
// 3. 创建调度服务
MachineSchedulerService
machineScheduler
=
new
MachineSchedulerService
(
MachineSchedulerService
machineScheduler
=
new
MachineSchedulerService
(
holidays
,
param
.
getBaseTime
());
param
.
getBaseTime
());
// 4. 初始化机器时间线
// 4. 初始化机器时间线
for
(
Machine
machine
:
machines
)
{
for
(
Machine
machine
:
machines
)
{
...
@@ -219,7 +228,10 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
...
@@ -219,7 +228,10 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
// entry.setMaterialRequirements(o.getMaterialRequirements()); // 假设Operation类有获取物料需求的方法
// entry.setMaterialRequirements(o.getMaterialRequirements()); // 假设Operation类有获取物料需求的方法
if
(
sequence
!=
1
)
{
if
(
sequence
!=
1
)
{
entry
.
getPrevEntryIds
().
add
(
id
-
1
);
// 假设Entry类有getPrevEntryIds()返回List<Integer>
OperationDependency
od
=
new
OperationDependency
();
od
.
setPrevOperationId
(
id
-
1
);
entry
.
getPrevEntryIds
().
add
(
od
);
// 假设Entry类有getPrevEntryIds()返回List<Integer>
}
}
allOperations
.
add
(
entry
);
allOperations
.
add
(
entry
);
...
@@ -799,8 +811,27 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
...
@@ -799,8 +811,27 @@ order.setDueDate(LocalDateTime.of(2025, 12, 1,0,0,0));
entry
.
setGroupId
(
i
+
1
);
entry
.
setGroupId
(
i
+
1
);
entry
.
setSequence
(
nodeInfo
.
getGroupSerial
());
entry
.
setSequence
(
nodeInfo
.
getGroupSerial
());
entry
.
setExecId
(
nodeInfo
.
getOriginalId
());
entry
.
setExecId
(
nodeInfo
.
getOriginalId
());
entry
.
setPrevEntryIds
(
nodeInfo
.
getNewParentIds
());
entry
.
setNextEntryIds
(
nodeInfo
.
getNewChildIds
());
if
(
nodeInfo
.
getNewParentIds
()!=
null
)
{
List
<
OperationDependency
>
OperationDependency
=
new
ArrayList
<>();
for
(
int
id
:
nodeInfo
.
getNewParentIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setPrevOperationId
(
id
);
OperationDependency
.
add
(
od
);
}
entry
.
setPrevEntryIds
(
OperationDependency
);
}
if
(
nodeInfo
.
getNewChildIds
()!=
null
)
{
List
<
OperationDependency
>
OperationDependency
=
new
ArrayList
<>();
for
(
int
id
:
nodeInfo
.
getNewChildIds
())
{
OperationDependency
od
=
new
OperationDependency
();
od
.
setNextOperationId
(
id
);
OperationDependency
.
add
(
od
);
}
entry
.
setNextEntryIds
(
OperationDependency
);
}
ProdProcessExec
op
=
ProdProcessExecs
.
stream
()
ProdProcessExec
op
=
ProdProcessExecs
.
stream
()
.
filter
(
t
->
t
.
getExecId
().
equals
(
entry
.
getExecId
()))
.
filter
(
t
->
t
.
getExecId
().
equals
(
entry
.
getExecId
()))
.
findFirst
().
orElse
(
null
);
.
findFirst
().
orElse
(
null
);
...
...
src/main/resources/machines.json
View file @
1bed79d7
...
@@ -5,42 +5,12 @@
...
@@ -5,42 +5,12 @@
"startTime"
:
"08:00:00"
,
"startTime"
:
"08:00:00"
,
"endTime"
:
"18:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"startDate"
:
"20
25-10-10
T00:00:00"
,
"startDate"
:
"20
00-01-01
T00:00:00"
,
"endDate"
:
"20
25-11-10
T00:00:00"
,
"endDate"
:
"20
00-01-01
T00:00:00"
,
"shiftDate"
:
"0001-01-01T00:00:00"
,
"shiftDate"
:
"0001-01-01T00:00:00"
,
"temporaryShift"
:
false
,
"temporaryShift"
:
false
,
"priority"
:
0
,
"priority"
:
0
,
"status"
:
0
"status"
:
0
},{
"startTime"
:
"18:00:00"
,
"endTime"
:
"20:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"startDate"
:
"2025-10-10T00:00:00"
,
"endDate"
:
"0001-01-01T00:00:00"
,
"temporaryShift"
:
true
,
"priority"
:
0
,
"status"
:
1
},{
"startTime"
:
"08:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
0
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"startDate"
:
"2025-10-10T00:00:00"
,
"endDate"
:
"2025-11-10T00:00:00"
,
"temporaryShift"
:
true
,
"priority"
:
0
,
"status"
:
1
},{
"startTime"
:
"08:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
null
,
"shiftDate"
:
"2025-10-01T00:00:00"
,
"startDate"
:
"2025-10-10T00:00:00"
,
"endDate"
:
"2025-11-10T00:00:00"
,
"temporaryShift"
:
true
,
"priority"
:
0
,
"status"
:
1
}],
}],
"maintenanceWindows"
:
[{
"maintenanceWindows"
:
[{
"startTime"
:
"2025-10-08T10:00:00"
,
"startTime"
:
"2025-10-08T10:00:00"
,
...
@@ -55,8 +25,8 @@
...
@@ -55,8 +25,8 @@
"endTime"
:
"18:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"shiftDate"
:
"0001-01-01T00:00:00"
,
"startDate"
:
"20
25-10-10
T00:00:00"
,
"startDate"
:
"20
00-01-01
T00:00:00"
,
"endDate"
:
"20
25-11-10
T00:00:00"
,
"endDate"
:
"20
00-01-01
T00:00:00"
,
"temporaryShift"
:
false
,
"temporaryShift"
:
false
,
"priority"
:
0
,
"priority"
:
0
,
"status"
:
0
"status"
:
0
...
@@ -70,8 +40,8 @@
...
@@ -70,8 +40,8 @@
"endTime"
:
"18:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"shiftDate"
:
"0001-01-01T00:00:00"
,
"startDate"
:
"20
25-10-10
T00:00:00"
,
"startDate"
:
"20
00-01-01
T00:00:00"
,
"endDate"
:
"20
25-11-10
T00:00:00"
,
"endDate"
:
"20
00-01-01
T00:00:00"
,
"temporaryShift"
:
false
,
"temporaryShift"
:
false
,
"priority"
:
0
,
"priority"
:
0
,
"status"
:
0
"status"
:
0
...
@@ -85,8 +55,8 @@
...
@@ -85,8 +55,8 @@
"endTime"
:
"18:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"shiftDate"
:
"0001-01-01T00:00:00"
,
"startDate"
:
"20
25-10-10
T00:00:00"
,
"startDate"
:
"20
00-01-01
T00:00:00"
,
"endDate"
:
"20
25-11-10
T00:00:00"
,
"endDate"
:
"20
00-01-01
T00:00:00"
,
"temporaryShift"
:
false
,
"temporaryShift"
:
false
,
"priority"
:
0
,
"priority"
:
0
,
"status"
:
0
"status"
:
0
...
@@ -100,8 +70,8 @@
...
@@ -100,8 +70,8 @@
"endTime"
:
"18:00:00"
,
"endTime"
:
"18:00:00"
,
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"days"
:
[
1
,
2
,
3
,
4
,
5
],
"shiftDate"
:
"0001-01-01T00:00:00"
,
"shiftDate"
:
"0001-01-01T00:00:00"
,
"startDate"
:
"20
25-10-10
T00:00:00"
,
"startDate"
:
"20
00-01-01
T00:00:00"
,
"endDate"
:
"20
25-11-10
T00:00:00"
,
"endDate"
:
"20
00-01-01
T00:00:00"
,
"temporaryShift"
:
false
,
"temporaryShift"
:
false
,
"priority"
:
0
,
"priority"
:
0
,
"status"
:
0
"status"
:
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