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
d0c355df
Commit
d0c355df
authored
Dec 24, 2025
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
遗传算法-优化
parent
dd5f7afc
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
537 additions
and
50 deletions
+537
-50
DateTimeUtil.java
src/main/java/com/aps/common/util/DateTimeUtil.java
+253
-0
FileHelper.java
src/main/java/com/aps/common/util/FileHelper.java
+7
-2
GlobalCacheUtil.java
src/main/java/com/aps/common/util/GlobalCacheUtil.java
+135
-0
ResourceGanttController.java
...ava/com/aps/controller/gantt/ResourceGanttController.java
+10
-0
GeneticAlgorithm.java
...main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
+31
-7
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+13
-7
MaterialRequirementService.java
...com/aps/service/Algorithm/MaterialRequirementService.java
+59
-22
RoutingDataService.java
...in/java/com/aps/service/Algorithm/RoutingDataService.java
+4
-2
MachineSchedulerService.java
...in/java/com/aps/service/plan/MachineSchedulerService.java
+13
-3
PlanResultService.java
src/main/java/com/aps/service/plan/PlanResultService.java
+10
-5
PlanResultServiceTest.java
src/test/java/com/aps/demo/PlanResultServiceTest.java
+2
-2
No files found.
src/main/java/com/aps/common/util/DateTimeUtil.java
0 → 100644
View file @
d0c355df
package
com
.
aps
.
common
.
util
;
import
java.time.*
;
import
java.time.format.DateTimeFormatter
;
import
java.time.temporal.ChronoUnit
;
import
java.time.temporal.TemporalAdjusters
;
import
java.util.Date
;
import
java.util.Locale
;
/**
* 通用时间工具类
* 覆盖:格式化/解析、类型转换、日期增减、节假日判断、时间戳转换、工作日校验等核心场景
*/
public
class
DateTimeUtil
{
// ======================== 常用时间格式常量 ========================
public
static
final
String
FORMAT_YMD
=
"yyyy-MM-dd"
;
public
static
final
String
FORMAT_YMD_HMS
=
"yyyy-MM-dd HH:mm:ss"
;
public
static
final
String
FORMAT_YMD_HM
=
"yyyy-MM-dd HH:mm"
;
public
static
final
String
FORMAT_HMS
=
"HH:mm:ss"
;
public
static
final
String
FORMAT_YMD_CN
=
"yyyy年MM月dd日"
;
// 默认时区(可根据业务调整为UTC/Asia/Shanghai等)
public
static
final
ZoneId
DEFAULT_ZONE
=
ZoneId
.
systemDefault
();
// ======================== 格式化:时间对象 → 字符串 ========================
/**
* LocalDateTime 格式化为字符串
* @param localDateTime 待格式化时间(null返回空串)
* @param pattern 格式模板(如 FORMAT_YMD_HMS)
*/
public
static
String
format
(
LocalDateTime
localDateTime
,
String
pattern
)
{
if
(
localDateTime
==
null
||
pattern
==
null
)
{
return
""
;
}
DateTimeFormatter
formatter
=
DateTimeFormatter
.
ofPattern
(
pattern
);
return
localDateTime
.
format
(
formatter
);
}
/**
* Date 格式化为字符串
*/
public
static
String
format
(
Date
date
,
String
pattern
)
{
if
(
date
==
null
)
{
return
""
;
}
LocalDateTime
localDateTime
=
dateToLocalDateTime
(
date
);
return
format
(
localDateTime
,
pattern
);
}
/**
* 时间戳(毫秒)格式化为字符串
*/
public
static
String
format
(
long
timestamp
,
String
pattern
)
{
LocalDateTime
localDateTime
=
LocalDateTime
.
ofInstant
(
Instant
.
ofEpochMilli
(
timestamp
),
DEFAULT_ZONE
);
return
format
(
localDateTime
,
pattern
);
}
// ======================== 解析:字符串 → 时间对象 ========================
/**
* 字符串解析为 LocalDateTime
* @param dateStr 时间字符串(如 "2025-12-24 10:00:00")
* @param pattern 格式模板(需与字符串匹配)
* @return 解析失败返回 null
*/
public
static
LocalDateTime
parseLocalDateTime
(
String
dateStr
,
String
pattern
)
{
if
(
dateStr
==
null
||
pattern
==
null
)
{
return
null
;
}
try
{
DateTimeFormatter
formatter
=
DateTimeFormatter
.
ofPattern
(
pattern
);
return
LocalDateTime
.
parse
(
dateStr
,
formatter
);
}
catch
(
Exception
e
)
{
return
null
;
}
}
/**
* 字符串解析为 Date
*/
public
static
Date
parseDate
(
String
dateStr
,
String
pattern
)
{
LocalDateTime
localDateTime
=
parseLocalDateTime
(
dateStr
,
pattern
);
return
localDateTime
==
null
?
null
:
localDateTimeToDate
(
localDateTime
);
}
// ======================== 类型转换:Date ↔ LocalDateTime ========================
/**
* Date 转 LocalDateTime
*/
public
static
LocalDateTime
dateToLocalDateTime
(
Date
date
)
{
if
(
date
==
null
)
{
return
null
;
}
return
date
.
toInstant
().
atZone
(
DEFAULT_ZONE
).
toLocalDateTime
();
}
/**
* LocalDateTime 转 Date
*/
public
static
Date
localDateTimeToDate
(
LocalDateTime
localDateTime
)
{
if
(
localDateTime
==
null
)
{
return
null
;
}
return
Date
.
from
(
localDateTime
.
atZone
(
DEFAULT_ZONE
).
toInstant
());
}
// ======================== 日期增减:年/月/日/时/分/秒 ========================
/**
* LocalDateTime 增减指定时间单位
* @param localDateTime 基准时间
* @param amount 增减数量(正数加,负数减)
* @param unit 时间单位(ChronoUnit.DAYS/HOURS等)
*/
public
static
LocalDateTime
plus
(
LocalDateTime
localDateTime
,
long
amount
,
ChronoUnit
unit
)
{
if
(
localDateTime
==
null
||
unit
==
null
)
{
return
null
;
}
return
localDateTime
.
plus
(
amount
,
unit
);
}
/**
* Date 增减指定时间单位
*/
public
static
Date
plus
(
Date
date
,
long
amount
,
ChronoUnit
unit
)
{
LocalDateTime
localDateTime
=
dateToLocalDateTime
(
date
);
LocalDateTime
newLdt
=
plus
(
localDateTime
,
amount
,
unit
);
return
localDateTimeToDate
(
newLdt
);
}
// ======================== 常用日期获取:当天开始/结束、本月第一天/最后一天 ========================
/**
* 获取当天开始时间(如 2025-12-24 00:00:00)
*/
public
static
LocalDateTime
getStartOfDay
(
LocalDateTime
localDateTime
)
{
return
localDateTime
==
null
?
null
:
localDateTime
.
with
(
LocalTime
.
MIN
);
}
/**
* 获取当天结束时间(如 2025-12-24 23:59:59.999999999)
*/
public
static
LocalDateTime
getEndOfDay
(
LocalDateTime
localDateTime
)
{
return
localDateTime
==
null
?
null
:
localDateTime
.
with
(
LocalTime
.
MAX
);
}
/**
* 获取本月第一天(如 2025-12-01 00:00:00)
*/
public
static
LocalDateTime
getFirstDayOfMonth
(
LocalDateTime
localDateTime
)
{
if
(
localDateTime
==
null
)
{
return
null
;
}
return
localDateTime
.
with
(
TemporalAdjusters
.
firstDayOfMonth
()).
with
(
LocalTime
.
MIN
);
}
/**
* 获取本月最后一天(如 2025-12-31 23:59:59.999999999)
*/
public
static
LocalDateTime
getLastDayOfMonth
(
LocalDateTime
localDateTime
)
{
if
(
localDateTime
==
null
)
{
return
null
;
}
return
localDateTime
.
with
(
TemporalAdjusters
.
lastDayOfMonth
()).
with
(
LocalTime
.
MAX
);
}
// ======================== 时间戳转换 ========================
/**
* LocalDateTime 转时间戳(毫秒)
*/
public
static
long
toTimestamp
(
LocalDateTime
localDateTime
)
{
if
(
localDateTime
==
null
)
{
return
0L
;
}
return
localDateTime
.
atZone
(
DEFAULT_ZONE
).
toInstant
().
toEpochMilli
();
}
/**
* 时间戳(毫秒)转 LocalDateTime
*/
public
static
LocalDateTime
fromTimestamp
(
long
timestamp
)
{
if
(
timestamp
<=
0
)
{
return
null
;
}
return
LocalDateTime
.
ofInstant
(
Instant
.
ofEpochMilli
(
timestamp
),
DEFAULT_ZONE
);
}
// ======================== 工作日/节假日判断(基础版,可扩展) ========================
/**
* 判断是否为工作日(周一到周五)
*/
public
static
boolean
isWorkDay
(
LocalDateTime
localDateTime
)
{
if
(
localDateTime
==
null
)
{
return
false
;
}
DayOfWeek
dayOfWeek
=
localDateTime
.
getDayOfWeek
();
return
dayOfWeek
!=
DayOfWeek
.
SATURDAY
&&
dayOfWeek
!=
DayOfWeek
.
SUNDAY
;
}
/**
* 判断是否为周末(周六/周日)
*/
public
static
boolean
isWeekend
(
LocalDateTime
localDateTime
)
{
return
!
isWorkDay
(
localDateTime
);
}
// ======================== 扩展:获取指定日期是周几(中文) ========================
/**
* 获取周几(如 "周一"、"周日")
*/
public
static
String
getWeekName
(
LocalDateTime
localDateTime
)
{
if
(
localDateTime
==
null
)
{
return
""
;
}
String
[]
weekNames
=
{
"周日"
,
"周一"
,
"周二"
,
"周三"
,
"周四"
,
"周五"
,
"周六"
};
DayOfWeek
dayOfWeek
=
localDateTime
.
getDayOfWeek
();
return
weekNames
[
dayOfWeek
.
getValue
()
%
7
];
}
public
static
Duration
diffDuration
(
LocalDateTime
start
,
LocalDateTime
end
)
{
if
(
start
==
null
||
end
==
null
)
{
return
Duration
.
ZERO
;
}
return
Duration
.
between
(
start
,
end
);
}
// ======================== 测试示例 ========================
public
void
test
()
{
// 1. 格式化
LocalDateTime
now
=
LocalDateTime
.
now
();
System
.
out
.
println
(
"当前时间(yyyy-MM-dd HH:mm:ss):"
+
format
(
now
,
FORMAT_YMD_HMS
));
// 2. 解析
String
dateStr
=
"2025-12-24 10:30:00"
;
LocalDateTime
parseLdt
=
parseLocalDateTime
(
dateStr
,
FORMAT_YMD_HMS
);
System
.
out
.
println
(
"解析后的时间:"
+
parseLdt
);
// 3. 类型转换
Date
date
=
localDateTimeToDate
(
now
);
LocalDateTime
ldt
=
dateToLocalDateTime
(
date
);
System
.
out
.
println
(
"Date转LocalDateTime:"
+
ldt
);
// 4. 日期增减
LocalDateTime
nextDay
=
plus
(
now
,
1
,
ChronoUnit
.
DAYS
);
System
.
out
.
println
(
"明天此时:"
+
format
(
nextDay
,
FORMAT_YMD_HMS
));
// 5. 当天开始/结束
LocalDateTime
startOfDay
=
getStartOfDay
(
now
);
System
.
out
.
println
(
"当天开始时间:"
+
format
(
startOfDay
,
FORMAT_YMD_HMS
));
// 6. 工作日判断
System
.
out
.
println
(
"今天是否为工作日:"
+
isWorkDay
(
now
));
// 7. 周几
System
.
out
.
println
(
"今天是:"
+
getWeekName
(
now
));
}
}
src/main/java/com/aps/common/util/FileHelper.java
View file @
d0c355df
...
...
@@ -7,12 +7,17 @@ import java.time.LocalDateTime;
import
java.time.format.DateTimeFormatter
;
public
class
FileHelper
{
private
static
final
String
LOG_FILE_PATH
=
"schedule_log.txt"
;
private
static
final
String
LOG_FILE
=
"schedule_log.txt"
;
private
static
final
String
LOG_FILE_PATH
=
"log/"
;
public
static
void
writeLogFile
(
String
message
)
{
try
(
PrintWriter
writer
=
new
PrintWriter
(
new
FileWriter
(
LOG_FILE_PATH
,
true
)))
{
String
date
=
LocalDateTime
.
now
().
format
(
DateTimeFormatter
.
ofPattern
(
"yyyyMMdd"
))+
"-"
;
try
(
PrintWriter
writer
=
new
PrintWriter
(
new
FileWriter
(
LOG_FILE_PATH
+
date
+
LOG_FILE
,
true
)))
{
String
timestamp
=
LocalDateTime
.
now
().
format
(
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
));
writer
.
println
(
"["
+
timestamp
+
"] "
+
message
);
System
.
out
.
println
(
"["
+
timestamp
+
"] "
+
message
);
}
catch
(
IOException
e
)
{
System
.
err
.
println
(
"Failed to write log: "
+
e
.
getMessage
());
}
...
...
src/main/java/com/aps/common/util/GlobalCacheUtil.java
0 → 100644
View file @
d0c355df
package
com
.
aps
.
common
.
util
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.TimeUnit
;
/**
* 轻量级全局缓存工具类(基于ConcurrentHashMap)
* 支持:过期时间、自动清理过期缓存、线程安全、批量删除
*/
public
class
GlobalCacheUtil
{
// 核心缓存容器(ConcurrentHashMap保证线程安全)
private
static
final
Map
<
String
,
CacheEntry
>
CACHE_MAP
=
new
ConcurrentHashMap
<>();
// 定时清理过期缓存的线程池(单线程即可)
private
static
final
ScheduledExecutorService
CLEAN_EXECUTOR
=
Executors
.
newSingleThreadScheduledExecutor
(
r
->
{
Thread
t
=
new
Thread
(
r
,
"cache-clean-thread"
);
t
.
setDaemon
(
true
);
// 守护线程,不阻塞程序退出
return
t
;
});
// 缓存条目:封装值 + 过期时间
private
static
class
CacheEntry
{
Object
value
;
// 缓存值
long
expireTime
;
// 过期时间戳(毫秒):0表示永不过期
public
CacheEntry
(
Object
value
,
long
expireTime
)
{
this
.
value
=
value
;
this
.
expireTime
=
expireTime
;
}
}
// 静态初始化:启动定时清理任务(每5分钟清理一次过期缓存)
static
{
CLEAN_EXECUTOR
.
scheduleAtFixedRate
(
()
->
CACHE_MAP
.
entrySet
().
removeIf
(
entry
->
{
long
expireTime
=
entry
.
getValue
().
expireTime
;
return
expireTime
!=
0
&&
System
.
currentTimeMillis
()
>
expireTime
;
}),
5
,
5
,
TimeUnit
.
MINUTES
);
}
// ======================== 核心方法 ========================
/**
* 存入缓存(永不过期)
* @param key 缓存键
* @param value 缓存值
*/
public
static
void
put
(
String
key
,
Object
value
)
{
put
(
key
,
value
,
0
,
TimeUnit
.
MILLISECONDS
);
}
/**
* 存入缓存(指定过期时间)
* @param key 缓存键
* @param value 缓存值
* @param timeout 过期时长
* @param timeUnit 时间单位
*/
public
static
void
put
(
String
key
,
Object
value
,
long
timeout
,
TimeUnit
timeUnit
)
{
if
(
key
==
null
||
value
==
null
)
{
return
;
}
long
expireTime
=
timeout
<=
0
?
0
:
System
.
currentTimeMillis
()
+
timeUnit
.
toMillis
(
timeout
);
CACHE_MAP
.
put
(
key
,
new
CacheEntry
(
value
,
expireTime
));
}
/**
* 获取缓存值(自动过滤过期值)
* @param key 缓存键
* @param <T> 泛型,避免强制类型转换
* @return 缓存值(过期/不存在返回null)
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
T
get
(
String
key
)
{
CacheEntry
entry
=
CACHE_MAP
.
get
(
key
);
if
(
entry
==
null
)
{
return
null
;
}
// 检查是否过期
if
(
entry
.
expireTime
!=
0
&&
System
.
currentTimeMillis
()
>
entry
.
expireTime
)
{
CACHE_MAP
.
remove
(
key
);
// 主动移除过期缓存
return
null
;
}
return
(
T
)
entry
.
value
;
}
/**
* 删除指定缓存
* @param key 缓存键
*/
public
static
void
remove
(
String
key
)
{
CACHE_MAP
.
remove
(
key
);
}
/**
* 清空所有缓存
*/
public
static
void
clear
()
{
CACHE_MAP
.
clear
();
}
/**
* 获取缓存大小
*/
public
static
int
size
()
{
return
CACHE_MAP
.
size
();
}
// 关闭定时任务(程序退出时调用)
public
static
void
shutdown
()
{
CLEAN_EXECUTOR
.
shutdown
();
}
// ======================== 测试示例 ========================
public
void
test
()
throws
InterruptedException
{
// 1. 存入永不过期缓存
GlobalCacheUtil
.
put
(
"user:1"
,
"张三"
);
System
.
out
.
println
(
"获取user:1:"
+
GlobalCacheUtil
.
get
(
"user:1"
));
// 输出:张三
// 2. 存入1秒后过期的缓存
GlobalCacheUtil
.
put
(
"code:123"
,
"666666"
,
1
,
TimeUnit
.
SECONDS
);
System
.
out
.
println
(
"立即获取code:123:"
+
GlobalCacheUtil
.
get
(
"code:123"
));
// 输出:666666
// 3. 等待2秒后获取(已过期)
Thread
.
sleep
(
2000
);
System
.
out
.
println
(
"2秒后获取code:123:"
+
GlobalCacheUtil
.
get
(
"code:123"
));
// 输出:null
// 4. 清空缓存
GlobalCacheUtil
.
clear
();
System
.
out
.
println
(
"清空后缓存大小:"
+
GlobalCacheUtil
.
size
());
// 输出:0
}
}
src/main/java/com/aps/controller/gantt/ResourceGanttController.java
View file @
d0c355df
...
...
@@ -138,6 +138,16 @@ public class ResourceGanttController {
return
scheduleChromosomes
;
}
@GetMapping
(
"/SyncMaterials"
)
@Operation
(
summary
=
"更新物料信息缓存"
,
description
=
"更新物料信息缓存"
)
public
void
SyncMaterials
()
{
// 调用 PlanResultService 获取 ScheduleChromosome 列表
planResultService
.
getMaterials
();
}
@PostMapping
(
"/operationMove"
)
@Operation
(
summary
=
"操作移动"
,
description
=
"操作移动"
)
public
R
<
String
>
operationMove
(
@RequestBody
Map
<
String
,
Object
>
params
)
{
...
...
src/main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
View file @
d0c355df
package
com
.
aps
.
service
.
Algorithm
;
import
com.aps.common.util.DateTimeUtil
;
import
com.aps.common.util.DeepCopyUtil
;
import
com.aps.common.util.FileHelper
;
import
com.aps.common.util.ProductionDeepCopyUtil
;
import
com.aps.entity.Algorithm.*
;
import
com.aps.entity.Algorithm.IDAndChildID.GroupResult
;
...
...
@@ -8,6 +10,7 @@ import com.aps.entity.basic.*;
import
com.aps.service.plan.MachineSchedulerService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.stream.Collectors
;
...
...
@@ -64,7 +67,8 @@ public class GeneticAlgorithm {
orderMaterials
=
materialRequirementService
.
buildMultiLevelRequirementNetwork
(
param
.
getBaseTime
());
}
System
.
out
.
println
(
"开始"
);
LocalDateTime
starttime
=
LocalDateTime
.
now
();
FileHelper
.
writeLogFile
(
"排产-----------开始-----------"
);
Initialization
initialization
=
new
Initialization
(
_GlobalParam
,
allOperations
,
orders
,
machines
);
...
...
@@ -72,11 +76,14 @@ public class GeneticAlgorithm {
// 预生成全局工序列表(所有初始化方法共享同一顺序)
List
<
GlobalOperationInfo
>
globalOpList
=
initialization
.
generateGlobalOpList
();
FileHelper
.
writeLogFile
(
"初始化种群-----------开始-------"
);
// 步骤1:初始化种群
List
<
Chromosome
>
population
=
initialization
.
generateInitialPopulation
(
param
,
globalOpList
);
FileHelper
.
writeLogFile
(
"初始化种群-----------结束-------"
);
FileHelper
.
writeLogFile
(
"初始化批量解码-----------开始-------"
);
Chromosomedecode
(
param
,
allOperations
,
globalOpList
,
population
);
FileHelper
.
writeLogFile
(
"初始化批量解码-----------结束-------"
);
List
<
List
<
Chromosome
>>
fronts
=
_nsgaIIUtils
.
parallelFastNonDominatedSort
(
population
);
int
ordercount
=
globalOpList
.
stream
()
.
mapToInt
(
GlobalOperationInfo:
:
getGroupId
)
...
...
@@ -96,9 +103,10 @@ public class GeneticAlgorithm {
double
bestFitness
=
0
;
int
Iteration
=
0
;
// 步骤2:迭代进化
FileHelper
.
writeLogFile
(
"迭代进化-----------开始-------"
+
param
.
getMaxIterations
());
for
(
int
iter
=
0
;
iter
<
param
.
getMaxIterations
();
iter
++)
{
// 解码并计算适应度
FileHelper
.
writeLogFile
(
"迭代进化------"
+
iter
+
"-----开始-------"
);
// 计算种群适应度标准差,微调参数
...
...
@@ -110,11 +118,14 @@ public class GeneticAlgorithm {
if
(
iter
==
param
.
getMaxIterations
()
-
1
)
{
break
;
}
FileHelper
.
writeLogFile
(
"选择操作-----------开始-------"
);
// 选择操作
List
<
Chromosome
>
selected
=
geneticOps
.
tournamentSelection
(
population
);
FileHelper
.
writeLogFile
(
"选择操作-----------结束-------"
);
// 交叉操作
FileHelper
.
writeLogFile
(
"交叉操作-----------开始-------"
);
List
<
Chromosome
>
nextPopulation
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
selected
.
size
();
i
+=
2
)
{
if
(
i
+
1
>=
selected
.
size
())
{
...
...
@@ -134,14 +145,18 @@ public class GeneticAlgorithm {
nextPopulation
.
add
(
parent2
);
}
}
FileHelper
.
writeLogFile
(
"交叉操作-----------结束-------"
);
FileHelper
.
writeLogFile
(
"变异操作-----------开始-------"
);
// 变异操作
for
(
Chromosome
chromosome
:
nextPopulation
)
{
if
(
rnd
.
nextDouble
()
<
param
.
getMutationProb
())
{
geneticOps
.
mutate
(
chromosome
,
globalOpList
);
}
}
FileHelper
.
writeLogFile
(
"变异操作-----------结束-------"
);
FileHelper
.
writeLogFile
(
"变异批量解码-----------开始-------"
);
Chromosomedecode
(
param
,
allOperations
,
globalOpList
,
nextPopulation
);
FileHelper
.
writeLogFile
(
"变异批量解码-----------开始-------"
);
// // 精英保留
// List<Chromosome> population1 = population.stream()
// .sorted((c1, c2) -> Double.compare(c2.getFitness(), c1.getFitness()))
...
...
@@ -153,10 +168,10 @@ public class GeneticAlgorithm {
List
<
Chromosome
>
newPopulation
=
new
ArrayList
<>();
newPopulation
.
addAll
(
population
);
newPopulation
.
addAll
(
nextPopulation
);
FileHelper
.
writeLogFile
(
"非支配排序-----------开始-------"
);
// 2.7 非支配排序
List
<
List
<
Chromosome
>>
combinedFronts
=
_nsgaIIUtils
.
parallelFastNonDominatedSort
(
newPopulation
);
FileHelper
.
writeLogFile
(
"非支配排序-----------结束-------"
);
// 2.8 选择下一代种群
population
=
_nsgaIIUtils
.
selectNextPopulation
(
combinedFronts
,
param
.
getPopulationSize
());
// 更新种群
...
...
@@ -181,11 +196,20 @@ public class GeneticAlgorithm {
{
break
;
}
FileHelper
.
writeLogFile
(
"迭代进化------"
+
iter
+
"-----结束-------"
);
}
FileHelper
.
writeLogFile
(
"迭代进化-----------结束-------"
);
best
.
setBaseTime
(
param
.
getBaseTime
());
best
.
setOrderMaterials
(
orderMaterials
);
best
.
setOperatRel
(
_entryRel
);
LocalDateTime
endtime
=
LocalDateTime
.
now
();
FileHelper
.
writeLogFile
(
String
.
format
(
"排产-----------结束-------耗时%d----"
,
DateTimeUtil
.
diffDuration
(
starttime
,
endtime
).
getSeconds
())
);
// 步骤3:返回最优解
return
best
;
...
...
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
d0c355df
package
com
.
aps
.
service
.
Algorithm
;
import
com.aps.common.util.FileHelper
;
import
com.aps.common.util.ProductionDeepCopyUtil
;
import
com.aps.entity.Algorithm.*
;
import
com.aps.entity.DiscreteParameterDuration
;
...
...
@@ -56,14 +57,18 @@ public class GeneticDecoder {
orderMaterials
=
_orderMaterials
;
// this.orderMaxID = orders.stream().mapToInt(Order::getId).max().orElse(0);
}
public
Chromosome
decodeChromosomeWithCache
(
Chromosome
chromosome
)
{
String
cacheKey
=
createCacheKey
(
chromosome
);
FileHelper
.
writeLogFile
(
"解码-----------开始-------"
+
chromosome
.
getID
()+
":"
+
cacheKey
);
_allOperations
=
chromosome
.
getAllOperations
();
if
(
_globalParam
.
isIsCheckBom
()&&
orderMaterials
!=
null
&&
orderMaterials
.
size
()>
0
)
{
CreateNewOpSequence
(
chromosome
);
}
// 1. 创建缓存键
String
cacheKey
=
createCacheKey
(
chromosome
);
// 2. 尝试从缓存获取(加锁保证线程安全)
cacheLock
.
lock
();
...
...
@@ -110,6 +115,7 @@ public class GeneticDecoder {
}
finally
{
cacheLock
.
unlock
();
}
FileHelper
.
writeLogFile
(
"解码-----------结束-------"
+
chromosome
.
getID
());
return
chromosome
;
}
...
...
@@ -359,7 +365,7 @@ public class GeneticDecoder {
int
setupTime
=
calculateSetupTime
(
chromosome
.
getResult
(),
operation
,
machine
,
machineOption
);
System
.
out
.
println
(
" 处理时间: "
+
processingTime
+
", 后处理: "
+
teardownTime
+
", 前处理: "
+
preTime
+
", 换型: "
+
setupTime
);
", 前处理: "
+
preTime
+
", 换型: "
+
setupTime
+
", 数量: "
+
operation
.
getQuantity
()
);
// 确定任务的最早开始时间(基于前一道工序的完整结束时间,包含后处理)
...
...
@@ -399,10 +405,10 @@ public class GeneticDecoder {
earliestStartTime
=
Math
.
max
(
earliestStartTime
,
machineAvailableTime
);
}
System
.
out
.
println
(
" 最终最早开始时间: "
+
earliestStartTime
+
" (前序工序结束含后处理: "
+
prevOperationEndTime
+
", 设备可用: "
+
(
lastGeneOnMachine
!=
null
?
lastGeneOnMachine
.
getEndTime
()
:
0
)
+
", 换型: "
+
setupTime
+
")"
);
//
System.out.println(" 最终最早开始时间: " + earliestStartTime +
//
" (前序工序结束含后处理: " + prevOperationEndTime + ", 设备可用: " +
//
(lastGeneOnMachine != null ? lastGeneOnMachine.getEndTime() : 0) +
//
", 换型: " + setupTime + ")");
// 根据换型模式调整处理时间
// int processingTimeForScheduling;
...
...
@@ -413,7 +419,7 @@ public class GeneticDecoder {
}
else
{
// 标准模式:需要安排主处理时间+换型时间
processingTimeTotal
=
processingTimeTotal
+
setupTime
;
System
.
out
.
println
(
" 标准模式:安排主处理+"
+
setupTime
+
"分钟换型="
+
processingTimeTotal
+
"分钟"
);
//
System.out.println(" 标准模式:安排主处理+" + setupTime + "分钟换型=" + processingTimeTotal + "分钟");
}
GAScheduleResult
existingResult
=
chromosome
.
getResultOld
().
stream
().
filter
(
r
->
r
.
getOperationId
()
==
operation
.
Id
).
findFirst
().
orElse
(
null
);
...
...
src/main/java/com/aps/service/Algorithm/MaterialRequirementService.java
View file @
d0c355df
...
...
@@ -210,12 +210,14 @@ if(routingIds.size()==0)
BOMBuildResult
operationResult
=
buildOperationBOM
(
mainorderId
,
childorderId
,
parentQuantity
,
operation
,
level
,
forder
);
// // 合并物料需求和子订单
if
(
operationResult
!=
null
)
{
materialRequirements
.
addAll
(
operationResult
.
getMaterialRequirements
());
childorders2
.
addAll
(
operationResult
.
getChildOrders
());
_newEntrys
.
addAll
(
operationResult
.
getNewEntrys
());
_newMachines
.
addAll
(
operationResult
.
getNewMachines
());
}
}
}
return
new
BOMBuildResult
(
materialRequirements
,
childorders2
,
_newEntrys
,
_newMachines
);
...
...
@@ -247,11 +249,14 @@ if(routingIds.size()==0)
routingsupportings1
=
routingsupportingMapper
.
selectList
(
routingsupportingwrapper
);
routingsupportings
.
addAll
(
routingsupportings1
);
List
<
String
>
routingsupportingids
=
routingsupportings
.
stream
()
List
<
String
>
routingsupportingids
=
routingsupportings1
.
stream
()
.
filter
(
t
->
t
.
getStrId
()!=
null
)
.
map
(
Routingsupporting:
:
getStrId
)
.
distinct
()
.
collect
(
Collectors
.
toList
());
if
(
routingsupportingids
.
size
()>
0
)
{
LambdaQueryWrapper
<
RoutingSupportingReplace
>
routingsupportingreplacewrapper
=
new
LambdaQueryWrapper
<>();
routingsupportingreplacewrapper
.
in
(
RoutingSupportingReplace:
:
getStrsupid
,
routingsupportingids
)
.
eq
(
RoutingSupportingReplace:
:
getIsdeleted
,
0
);
...
...
@@ -260,6 +265,8 @@ if(routingIds.size()==0)
routingsupportingreplaces
.
addAll
(
routingsupportingreplaces1
);
}
}
}
else
{
routingIds
=
headers1
.
getId
().
longValue
();
...
...
@@ -271,8 +278,32 @@ if(routingIds.size()==0)
{
return
null
;
}
List
<
RoutingDetail
>
RoutingDetails
=
lanuchService
.
getRoutingDetails
(
headers1
.
getId
());
List
<
RoutingDetailEquip
>
routingDetailEquips
=
lanuchService
.
getRoutingDetailEquip
(
headers1
.
getId
(),
headers1
.
getCode
());
Long
headersid
=
routingIds
;
List
<
RoutingDetail
>
RoutingDetails
=
allRoutingDetails
.
stream
()
.
filter
(
t
->
t
.
getRoutingHeaderId
()==
headersid
)
.
collect
(
Collectors
.
toList
());
List
<
RoutingDetailEquip
>
routingDetailEquips
=
null
;
List
<
RoutingDetailConnect
>
connections
=
null
;
if
(
RoutingDetails
==
null
||
RoutingDetails
.
size
()==
0
)
{
RoutingDetails
=
lanuchService
.
getRoutingDetails
(
headers1
.
getId
());
allRoutingDetails
.
addAll
(
RoutingDetails
);
routingDetailEquips
=
lanuchService
.
getRoutingDetailEquip
(
headers1
.
getId
(),
headers1
.
getCode
());
allroutingDetailEquips
.
addAll
(
routingDetailEquips
);
LambdaQueryWrapper
<
RoutingDetailConnect
>
routingDetailConnectwrapper
=
new
LambdaQueryWrapper
<>();
routingDetailConnectwrapper
.
eq
(
RoutingDetailConnect:
:
getRoutingHeaderId
,
routingIds
)
.
eq
(
RoutingDetailConnect:
:
getIsdeleted
,
0
);
// 添加 isdeleted=0 过滤条件
connections
=
routingDetailConnectService
.
list
(
routingDetailConnectwrapper
);
allroutingDetailconnections
.
addAll
(
connections
);
}
if
(
routingDetailEquips
==
null
)
{
routingDetailEquips
=
allroutingDetailEquips
.
stream
()
.
filter
(
t
->
t
.
getRoutingHeaderId
()==
headersid
)
.
collect
(
Collectors
.
toList
());
}
order
.
setRoutingId
(
headers1
.
getId
());
ProdLaunchOrder
prodOrderMain
=
convertToLaunchOrder
(
order
,
""
);
...
...
@@ -291,12 +322,12 @@ if(routingIds.size()==0)
ProdProcessExec:
:
getExecId
,
(
existing
,
replacement
)
->
existing
));
LambdaQueryWrapper
<
RoutingDetailConnect
>
routingDetailConnectwrapper
=
new
LambdaQueryWrapper
<>();
routingDetailConnectwrapper
.
eq
(
RoutingDetailConnect:
:
getRoutingHeaderId
,
routingIds
)
.
eq
(
RoutingDetailConnect:
:
getIsdeleted
,
0
);
// 添加 isdeleted=0 过滤条件
List
<
RoutingDetailConnect
>
connections
=
routingDetailConnectService
.
list
(
routingDetailConnectwrapper
);
if
(
connections
==
null
)
{
connections
=
allroutingDetailconnections
.
stream
()
.
filter
(
t
->
t
.
getRoutingHeaderId
()==
headersid
)
.
collect
(
Collectors
.
toList
()
);
}
List
<
ProdOrderProcess
>
ProdOrderProcesslist
=
connections
.
stream
()
.
map
(
connection
->
lanuchService
.
createProcessRelation
(
prodOrderMain
,
connection
,
sceneId
,
routingDetailIdToExecIdMap
))
...
...
@@ -307,10 +338,16 @@ if(routingIds.size()==0)
.
distinct
()
.
collect
(
Collectors
.
toList
());
List
<
RoutingDiscreteParam
>
routingDiscreteParams
=
_routingDiscreteParamService
.
lambdaQuery
()
List
<
RoutingDiscreteParam
>
routingDiscreteParams
=
allroutingDiscreteParams
.
stream
()
.
filter
(
t
->
routingDetailIds
.
contains
(
t
.
getRoutingDetailId
()))
.
collect
(
Collectors
.
toList
());
if
(
routingDiscreteParams
==
null
||
routingDiscreteParams
.
size
()==
0
)
{
routingDiscreteParams
=
_routingDiscreteParamService
.
lambdaQuery
()
.
in
(
RoutingDiscreteParam:
:
getRoutingDetailId
,
routingDetailIds
)
.
eq
(
RoutingDiscreteParam:
:
getIsDeleted
,
0
)
.
list
();
allroutingDiscreteParams
.
addAll
(
routingDiscreteParams
);
}
...
...
src/main/java/com/aps/service/Algorithm/RoutingDataService.java
View file @
d0c355df
...
...
@@ -281,7 +281,7 @@ public class RoutingDataService {
machine
.
setMaintenanceWindows
(
new
ArrayList
<>());
}
List
<
ProdEquipSpecialCal
>
machineProdEquipSpecialCals
=
ProdEquipSpecialCals
.
stream
()
.
filter
(
t
->
t
.
getPlanResourceId
()
==
machine
.
getId
()&&
t
.
getReferenceType
()==
1
)
.
filter
(
t
->
t
.
getPlanResourceId
()!=
null
&&
t
.
getPlanResourceId
()
==
machine
.
getId
()&&
t
.
getReferenceType
()==
1
)
.
collect
(
Collectors
.
toList
());
List
<
Shift
>
shifts1
=
new
ArrayList
<>();
for
(
ProdEquipSpecialCal
machineProdEquipSpecialCal
:
machineProdEquipSpecialCals
)
{
...
...
@@ -318,8 +318,10 @@ public class RoutingDataService {
}
}
else
{
machine
.
setCode
(
Long
.
toString
(
machine
.
getId
())
);
}
if
(
shifts1
==
null
)
if
(
shifts1
==
null
||
shifts1
.
size
()==
0
)
{
throw
new
RuntimeException
(
String
.
format
(
"设备%s没有工作日历"
,
machine
.
getCode
().
concat
(
"_"
).
concat
(
machine
.
getName
()))
);
}
...
...
src/main/java/com/aps/service/plan/MachineSchedulerService.java
View file @
d0c355df
...
...
@@ -3,6 +3,7 @@ package com.aps.service.plan;
import
com.aps.common.util.ProductionDeepCopyUtil
;
import
com.aps.entity.basic.*
;
import
java.time.DayOfWeek
;
...
...
@@ -252,19 +253,28 @@ if(shifts==null||shifts.size()==0) {
return
shiftDays
.
contains
(
targetDayValue
);
}
private
List
<
TimeSegment
>
mergeSegments
(
List
<
TimeSegment
>
segments
)
{
private
List
<
TimeSegment
>
mergeSegments
(
List
<
TimeSegment
>
segments
1
)
{
List
<
TimeSegment
>
segments
=
ProductionDeepCopyUtil
.
deepCopyList
(
segments1
,
TimeSegment
.
class
);
if
(
segments
==
null
||
segments
.
size
()==
0
)
{
return
null
;
}
List
<
TimeSegment
>
maintenanceSegments1
=
segments
.
stream
()
.
filter
(
t
->
t
.
getType
()==
null
)
.
collect
(
Collectors
.
toList
());
if
(
maintenanceSegments1
.
size
()>
0
)
{
int
i
=
0
;
}
List
<
TimeSegment
>
maintenanceSegments
=
segments
.
stream
()
.
filter
(
t
->
t
.
getType
()
==
SegmentType
.
MAINTENANCE
)
.
filter
(
t
->
t
.
getType
()!=
null
&&
t
.
getType
()
==
SegmentType
.
MAINTENANCE
)
.
collect
(
Collectors
.
toList
());
List
<
TimeSegment
>
otherSegments
=
segments
.
stream
()
.
filter
(
t
->
t
.
getType
()
!=
SegmentType
.
MAINTENANCE
)
.
filter
(
t
->
t
.
getType
()!=
null
&&
t
.
getType
()
!=
SegmentType
.
MAINTENANCE
)
.
collect
(
Collectors
.
toList
());
// 按开始时间排序
...
...
src/main/java/com/aps/service/plan/PlanResultService.java
View file @
d0c355df
...
...
@@ -27,6 +27,7 @@ import java.time.LocalTime;
import
java.time.format.DateTimeFormatter
;
import
java.time.temporal.ChronoUnit
;
import
java.util.*
;
import
java.util.concurrent.TimeUnit
;
import
java.util.stream.Collectors
;
import
java.util.stream.IntStream
;
...
...
@@ -911,7 +912,7 @@ private GlobalParam InitGlobalParam()
}
}
private
final
Map
<
String
,
Object
>
CommonCache
=
new
HashMap
<>();
private
List
<
Material
>
InitMaterial
()
{
List
<
Material
>
materials
=
new
ArrayList
<>();
...
...
@@ -919,7 +920,7 @@ private GlobalParam InitGlobalParam()
// .eq(MaterialInfo::getIsdeleted,0)
// .list();
List
<
Material
>
cmaterials
=
(
List
<
Material
>)
CommonCache
.
get
(
"material"
);
List
<
Material
>
cmaterials
=
(
List
<
Material
>)
GlobalCacheUtil
.
get
(
"material"
);
if
(
cmaterials
!=
null
)
{
...
...
@@ -935,12 +936,15 @@ private GlobalParam InitGlobalParam()
}
materials
=
getMaterials
();
CommonCache
.
put
(
"material"
,
materials
);
redisUtils
.
set
(
"material"
,
materials
);
GlobalCacheUtil
.
put
(
"material"
,
materials
,
10
,
TimeUnit
.
MINUTES
);
return
materials
;
}
private
List
<
Material
>
getMaterials
(){
public
List
<
Material
>
getMaterials
(){
List
<
Material
>
materials
=
new
ArrayList
<>();
LambdaQueryWrapper
<
MaterialInfo
>
MaterialInfoWrapper
=
new
LambdaQueryWrapper
<>();
MaterialInfoWrapper
.
eq
(
MaterialInfo:
:
getIsdeleted
,
0
);
...
...
@@ -1039,6 +1043,7 @@ private GlobalParam InitGlobalParam()
materials
.
add
(
material
);
// });
}
redisUtils
.
set
(
"material"
,
materials
);
return
materials
;
}
...
...
src/test/java/com/aps/demo/PlanResultServiceTest.java
View file @
d0c355df
...
...
@@ -25,9 +25,9 @@ public class PlanResultServiceTest {
@Test
public
void
testExecute
()
{
// planResultService.getMaterials();
planResultService
.
execute2
(
"6DB2311203C44FABBAE966A42D0A5C8E"
);
// planResultService.execute2("BE037838EF074B07B87D7DE763107398");
// LocalDateTime t= LocalDateTime.of(2025, 11, 15, 6, 51, 11);
// List<Integer> opids=new ArrayList<>();
// opids.add(1);
...
...
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