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
f081f29e
Commit
f081f29e
authored
Jan 12, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/tl'
parents
99817cb4
34d7e700
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
505 additions
and
99 deletions
+505
-99
ScheduleParams.java
src/main/java/com/aps/entity/Algorithm/ScheduleParams.java
+29
-2
ScheduleResultDetail.java
...n/java/com/aps/entity/Algorithm/ScheduleResultDetail.java
+6
-0
GeneticAlgorithm.java
...main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
+85
-30
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+1
-0
GeneticOperations.java
...ain/java/com/aps/service/Algorithm/GeneticOperations.java
+79
-6
IdGroupingWithDualSerial.java
...a/com/aps/service/Algorithm/IdGroupingWithDualSerial.java
+1
-1
Initialization.java
src/main/java/com/aps/service/Algorithm/Initialization.java
+1
-1
MachineCalculator.java
...ain/java/com/aps/service/Algorithm/MachineCalculator.java
+289
-50
RoutingDataService.java
...in/java/com/aps/service/Algorithm/RoutingDataService.java
+1
-2
ScheduleOperationService.java
...a/com/aps/service/Algorithm/ScheduleOperationService.java
+2
-2
PlanResultService.java
src/main/java/com/aps/service/plan/PlanResultService.java
+8
-2
PlanResultServiceTest.java
src/test/java/com/aps/demo/PlanResultServiceTest.java
+3
-3
No files found.
src/main/java/com/aps/entity/Algorithm/ScheduleParams.java
View file @
f081f29e
...
@@ -20,8 +20,8 @@ public class ScheduleParams {
...
@@ -20,8 +20,8 @@ public class ScheduleParams {
private
static
final
int
MAX_MAX_ITERATIONS
=
200
;
private
static
final
int
MAX_MAX_ITERATIONS
=
200
;
private
static
final
float
MIN_CROSSOVER_PROB
=
0.6f
;
private
static
final
float
MIN_CROSSOVER_PROB
=
0.6f
;
private
static
final
float
MAX_CROSSOVER_PROB
=
0.9f
;
private
static
final
float
MAX_CROSSOVER_PROB
=
0.9f
;
private
static
final
float
MIN_MUTATION_PROB
=
0.
3
f
;
private
static
final
float
MIN_MUTATION_PROB
=
0.
2
f
;
private
static
final
float
MAX_MUTATION_PROB
=
0.
7
f
;
private
static
final
float
MAX_MUTATION_PROB
=
0.
5
f
;
private
static
final
int
MIN_TOURNAMENT_SIZE
=
3
;
private
static
final
int
MIN_TOURNAMENT_SIZE
=
3
;
private
static
final
int
MAX_TOURNAMENT_SIZE
=
7
;
private
static
final
int
MAX_TOURNAMENT_SIZE
=
7
;
...
@@ -81,6 +81,13 @@ public class ScheduleParams {
...
@@ -81,6 +81,13 @@ public class ScheduleParams {
return
maxIterations
;
return
maxIterations
;
}
}
/// <summary>
/// 交叉概率
/// </summary>
public
float
setCrossoverProb
(
float
crossoverProb
)
{
return
this
.
crossoverProb
=
crossoverProb
;
}
/// <summary>
/// <summary>
/// 交叉概率
/// 交叉概率
/// </summary>
/// </summary>
...
@@ -235,6 +242,26 @@ public class ScheduleParams {
...
@@ -235,6 +242,26 @@ public class ScheduleParams {
}
}
}
}
public
void
fineTuneParams
()
{
// 适应度标准差阈值(可调整):小于0.05视为收敛过慢,大于0.2视为收敛过快
final
float
LOW_STD_THRESHOLD
=
0.05f
;
final
float
HIGH_STD_THRESHOLD
=
0.2f
;
final
float
ADJUST_STEP
=
0.05f
;
// 调整步长
DecimalFormat
df
=
new
DecimalFormat
(
"#.000"
);
// 1. 收敛过慢(适应度方差小):增加变异概率,降低交叉概率
mutationProb
=
Math
.
max
(
MIN_MUTATION_PROB
,
Math
.
min
(
MAX_MUTATION_PROB
,
mutationProb
+
0.05f
));
crossoverProb
=
Math
.
max
(
MIN_CROSSOVER_PROB
,
Math
.
min
(
MAX_CROSSOVER_PROB
,
crossoverProb
-
0.1f
));
}
// 测试示例
// 测试示例
public
void
test
()
{
public
void
test
()
{
ScheduleParams
params
=
new
ScheduleParams
();
ScheduleParams
params
=
new
ScheduleParams
();
...
...
src/main/java/com/aps/entity/Algorithm/ScheduleResultDetail.java
View file @
f081f29e
package
com
.
aps
.
entity
.
Algorithm
;
package
com
.
aps
.
entity
.
Algorithm
;
import
com.aps.entity.basic.TimeSegment
;
import
lombok.Data
;
import
lombok.Data
;
import
java.util.List
;
/**
/**
* 作者:佟礼
* 作者:佟礼
* 时间:2025-11-21
* 时间:2025-11-21
...
@@ -14,6 +17,9 @@ public class ScheduleResultDetail {
...
@@ -14,6 +17,9 @@ public class ScheduleResultDetail {
private
double
OneTime
;
// 单件工时
private
double
OneTime
;
// 单件工时
private
double
Quantity
;
// 时间段
private
double
Quantity
;
// 时间段
private
List
<
TimeSegment
>
usedSegment
;
// Key 的 getter/setter
// Key 的 getter/setter
public
String
getKey
()
{
public
String
getKey
()
{
return
Key
;
return
Key
;
...
...
src/main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
View file @
f081f29e
...
@@ -13,6 +13,9 @@ import org.springframework.beans.factory.annotation.Autowired;
...
@@ -13,6 +13,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.*
;
import
java.util.concurrent.CompletableFuture
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
/**
/**
...
@@ -98,7 +101,7 @@ public class GeneticAlgorithm {
...
@@ -98,7 +101,7 @@ public class GeneticAlgorithm {
List
<
Chromosome
>
population
=
initialization
.
generateInitialPopulation
(
param
,
globalOpList
);
List
<
Chromosome
>
population
=
initialization
.
generateInitialPopulation
(
param
,
globalOpList
);
//
population= chromosomeDistinct(population);
population
=
chromosomeDistinct
(
population
);
...
@@ -137,8 +140,14 @@ public class GeneticAlgorithm {
...
@@ -137,8 +140,14 @@ public class GeneticAlgorithm {
}
}
FileHelper
.
writeLogFile
(
"选择操作-----------开始-------"
);
FileHelper
.
writeLogFile
(
"选择操作-----------开始-------"
);
// 选择前移除适应度为 0 或明显劣于当前最优解的个体,减少选择池规模:
double
minValidFitness
=
bestFitness
*
0.5
;
// 保留最优解50%以上的个体
List
<
Chromosome
>
validPopulation
=
population
.
stream
()
.
filter
(
c
->
c
.
getFitness
()
>=
minValidFitness
)
.
collect
(
Collectors
.
toList
());
// 选择操作
// 选择操作
List
<
Chromosome
>
selected
=
geneticOps
.
tournamentSelection
(
p
opulation
);
List
<
Chromosome
>
selected
=
geneticOps
.
tournamentSelection
(
validP
opulation
);
FileHelper
.
writeLogFile
(
"选择操作-----------结束-------"
);
FileHelper
.
writeLogFile
(
"选择操作-----------结束-------"
);
// 交叉操作
// 交叉操作
FileHelper
.
writeLogFile
(
"交叉操作-----------开始-------"
);
FileHelper
.
writeLogFile
(
"交叉操作-----------开始-------"
);
...
@@ -178,7 +187,7 @@ public class GeneticAlgorithm {
...
@@ -178,7 +187,7 @@ public class GeneticAlgorithm {
FileHelper
.
writeLogFile
(
"变异批量解码-----------开始-------"
);
FileHelper
.
writeLogFile
(
"变异批量解码-----------开始-------"
);
nextPopulation
=
chromosomeDistinct
(
nextPopulation
);
Chromosomedecode
(
param
,
allOperations
,
globalOpList
,
nextPopulation
);
Chromosomedecode
(
param
,
allOperations
,
globalOpList
,
nextPopulation
);
FileHelper
.
writeLogFile
(
"变异批量解码-----------结束-------"
);
FileHelper
.
writeLogFile
(
"变异批量解码-----------结束-------"
);
// // 精英保留
// // 精英保留
...
@@ -192,7 +201,7 @@ public class GeneticAlgorithm {
...
@@ -192,7 +201,7 @@ public class GeneticAlgorithm {
List
<
Chromosome
>
newPopulation
=
new
ArrayList
<>();
List
<
Chromosome
>
newPopulation
=
new
ArrayList
<>();
newPopulation
.
addAll
(
population
);
newPopulation
.
addAll
(
population
);
newPopulation
.
addAll
(
nextPopulation
);
newPopulation
.
addAll
(
nextPopulation
);
newPopulation
=
chromosomeDistinct
(
newPopulation
);
newPopulation
=
chromosomeDistinct
1
(
newPopulation
);
FileHelper
.
writeLogFile
(
"非支配排序-----------开始-------"
);
FileHelper
.
writeLogFile
(
"非支配排序-----------开始-------"
);
// 2.7 非支配排序
// 2.7 非支配排序
List
<
List
<
Chromosome
>>
combinedFronts
=
_nsgaIIUtils
.
parallelFastNonDominatedSort
(
newPopulation
);
List
<
List
<
Chromosome
>>
combinedFronts
=
_nsgaIIUtils
.
parallelFastNonDominatedSort
(
newPopulation
);
...
@@ -208,19 +217,26 @@ public class GeneticAlgorithm {
...
@@ -208,19 +217,26 @@ public class GeneticAlgorithm {
best
=
GetBest
(
combinedFronts
,
String
.
valueOf
(
iter
));
best
=
GetBest
(
combinedFronts
,
String
.
valueOf
(
iter
));
if
(
bestFitness
<
best
.
getFitness
())
if
(
bestFitness
<
best
.
getFitness
())
{
{
bestFitness
=
best
.
getFitness
();
bestFitness
=
best
.
getFitness
();
Iteration
=
1
;
Iteration
=
1
;
}
else
{
}
else
{
Iteration
++;
Iteration
++;
if
(
Iteration
>
5
)
{
// 当连续 5 代无最优解提升时,降低交叉概率(如从 0.8 降至 0.5)、提高变异概率(如从 0.1 升至 0.2)
param
.
fineTuneParams
();
}
}
}
if
(
Iteration
>
10
)
if
(
Iteration
>
10
)
{
{
break
;
break
;
}
}
// 当种群适应度标准差小于阈值(如 0.001)时,说明种群已收敛,提前终止迭代
fitnessStd
=
_fitnessCalculator
.
calculateFitnessStd
(
population
);
if
(
fitnessStd
<
0.001
)
{
FileHelper
.
writeLogFile
(
"种群已收敛,提前终止迭代"
);
break
;
}
FileHelper
.
writeLogFile
(
"迭代进化------"
+
iter
+
"-----结束-------"
);
FileHelper
.
writeLogFile
(
"迭代进化------"
+
iter
+
"-----结束-------"
);
}
}
...
@@ -256,21 +272,34 @@ public class GeneticAlgorithm {
...
@@ -256,21 +272,34 @@ public class GeneticAlgorithm {
// WriteKpi(best,"最大");
// WriteKpi(best,"最大");
return
best
;
return
best
;
}
}
private
List
<
Chromosome
>
chromosomeDistinct
(
List
<
Chromosome
>
population
)
private
List
<
Chromosome
>
chromosomeDistinct
(
List
<
Chromosome
>
population
)
{
{
if
(
orders
.
size
()<
10
)
{
population
=
population
.
stream
()
.
collect
(
Collectors
.
toMap
(
Chromosome:
:
getGeneStr
,
// key:去重的字段(GeneStr)
u
->
u
,
// value:Chromosome对象
(
u1
,
u2
)
->
u1
// 重复时保留第一个元素
))
.
values
()
// 获取去重后的
.
stream
()
.
collect
(
Collectors
.
toList
());
return
population
;
}
private
List
<
Chromosome
>
chromosomeDistinct1
(
List
<
Chromosome
>
population
)
{
population
=
population
.
stream
()
population
=
population
.
stream
()
.
collect
(
Collectors
.
toMap
(
.
collect
(
Collectors
.
toMap
(
Chromosome:
:
getGeneStr
,
// key:去重的字段(GeneStr)
Chromosome:
:
getGeneStr
,
// key:去重的字段(GeneStr)
u
->
u
,
// value:Chromosome对象
u
->
u
,
// value:Chromosome对象
(
u1
,
u2
)
->
u1
// 重复时保留第一个元素
(
u1
,
u2
)
->
u1
.
getFitness
()
>
u2
.
getFitness
()
?
u1
:
u2
// 重复时保留第一个元素
))
))
.
values
()
// 获取去重后的
.
values
()
// 获取去重后的
.
stream
()
.
stream
()
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
}
return
population
;
return
population
;
}
}
...
@@ -292,6 +321,7 @@ public class GeneticAlgorithm {
...
@@ -292,6 +321,7 @@ public class GeneticAlgorithm {
FileHelper
.
writeLogFile
(
String
.
format
(
" KPI---%f-------"
,
d
));
FileHelper
.
writeLogFile
(
String
.
format
(
" KPI---%f-------"
,
d
));
}
}
}
}
private
ExecutorService
decodeExecutor
=
Executors
.
newFixedThreadPool
(
Runtime
.
getRuntime
().
availableProcessors
()
*
2
);
private
void
Chromosomedecode
(
ScheduleParams
param
,
List
<
Entry
>
allOperations
,
List
<
GlobalOperationInfo
>
globalOpList
,
List
<
Chromosome
>
population
)
private
void
Chromosomedecode
(
ScheduleParams
param
,
List
<
Entry
>
allOperations
,
List
<
GlobalOperationInfo
>
globalOpList
,
List
<
Chromosome
>
population
)
{
{
...
@@ -299,26 +329,51 @@ public class GeneticAlgorithm {
...
@@ -299,26 +329,51 @@ public class GeneticAlgorithm {
GeneticDecoder
decoder
=
new
GeneticDecoder
(
_GlobalParam
,
param
.
getBaseTime
(),
machines
,
orders
,
materials
,
machineScheduler
,
orderMaterials
);
GeneticDecoder
decoder
=
new
GeneticDecoder
(
_GlobalParam
,
param
.
getBaseTime
(),
machines
,
orders
,
materials
,
machineScheduler
,
orderMaterials
);
if
(
population
!=
null
&&
population
.
size
()>
0
)
{
CompletableFuture
.
allOf
(
population
.
stream
()
population
.
parallelStream
().
forEach
(
chromosome
->
{
.
map
(
chromosome
->
CompletableFuture
.
runAsync
(()
->
decode
(
decoder
,
chromosome
,
param
,
allOperations
,
globalOpList
),
decodeExecutor
))
chromosome
.
setResult
(
new
ArrayList
<>());
.
toArray
(
CompletableFuture
[]::
new
))
.
join
();
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
if
(
1
==
2
)
{
chromosome
.
setMachines
(
ProductionDeepCopyUtil
.
deepCopyList
(
machines
));
// 简单拷贝,实际可能需要深拷贝
if
(
population
!=
null
&&
population
.
size
()
>
0
)
{
chromosome
.
setAllOperations
(
allOperations
);
// 简单拷贝,实际可能需要深拷贝
population
.
parallelStream
().
forEach
(
chromosome
->
{
chromosome
.
setGlobalOpList
(
globalOpList
);
// 简单拷贝,实际可能需要深拷贝
chromosome
.
setResult
(
new
ArrayList
<>());
//chromosome.setObjectiveWeights(_objectiveWeights);
chromosome
.
setBaseTime
(
param
.
getBaseTime
());
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder
.
decodeChromosomeWithCache
(
chromosome
);
if
(
chromosome
.
getFitness
()
==
0
)
{
chromosome
.
setFitness
(
_fitnessCalculator
.
calculateFitness
(
chromosome
,
_objectiveWeights
));
}
});
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome
.
setMachines
(
ProductionDeepCopyUtil
.
deepCopyList
(
machines
,
Machine
.
class
));
// 简单拷贝,实际可能需要深拷贝
chromosome
.
setAllOperations
(
allOperations
);
// 简单拷贝,实际可能需要深拷贝
chromosome
.
setGlobalOpList
(
globalOpList
);
// 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
chromosome
.
setBaseTime
(
param
.
getBaseTime
());
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder
.
decodeChromosomeWithCache
(
chromosome
);
if
(
chromosome
.
getFitness
()
==
0
)
{
chromosome
.
setFitness
(
_fitnessCalculator
.
calculateFitness
(
chromosome
,
_objectiveWeights
));
}
});
}
}
}
private
void
decode
(
GeneticDecoder
decoder
,
Chromosome
chromosome
,
ScheduleParams
param
,
List
<
Entry
>
allOperations
,
List
<
GlobalOperationInfo
>
globalOpList
)
{
chromosome
.
setResult
(
new
ArrayList
<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
chromosome
.
setMachines
(
ProductionDeepCopyUtil
.
deepCopyList
(
machines
,
Machine
.
class
));
// 简单拷贝,实际可能需要深拷贝
chromosome
.
setAllOperations
(
allOperations
);
// 简单拷贝,实际可能需要深拷贝
chromosome
.
setGlobalOpList
(
globalOpList
);
// 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights);
chromosome
.
setBaseTime
(
param
.
getBaseTime
());
// _sceneService.saveChromosomeToFile(chromosome, "12345679");
decoder
.
decodeChromosomeWithCache
(
chromosome
);
if
(
chromosome
.
getFitness
()
==
0
)
{
chromosome
.
setFitness
(
_fitnessCalculator
.
calculateFitness
(
chromosome
,
_objectiveWeights
));
}
}
}
}
...
...
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
f081f29e
...
@@ -374,6 +374,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
...
@@ -374,6 +374,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
int
teardownTime
=
machineOption
.
getTeardownTime
();
int
teardownTime
=
machineOption
.
getTeardownTime
();
int
preTime
=
machineOption
.
getPreTime
();
int
preTime
=
machineOption
.
getPreTime
();
int
setupTime
=
calculateSetupTime
(
chromosome
.
getResult
(),
operation
,
machine
,
machineOption
);
int
setupTime
=
calculateSetupTime
(
chromosome
.
getResult
(),
operation
,
machine
,
machineOption
);
...
...
src/main/java/com/aps/service/Algorithm/GeneticOperations.java
View file @
f081f29e
...
@@ -33,11 +33,80 @@ public class GeneticOperations {
...
@@ -33,11 +33,80 @@ public class GeneticOperations {
* 锦标赛选择
* 锦标赛选择
*/
*/
public
List
<
Chromosome
>
tournamentSelection
(
List
<
Chromosome
>
population
,
int
tournamentSize
)
{
public
List
<
Chromosome
>
tournamentSelection
(
List
<
Chromosome
>
population
,
int
tournamentSize
)
{
// 前置边界校验(避免NPE和无效计算)
if
(
population
==
null
||
population
.
isEmpty
())
{
return
new
ArrayList
<>();
}
int
populationSize
=
population
.
size
();
int
populationSize
=
population
.
size
();
// 预计算需要选中的个体数量,避免动态判断
int
needSelectCount
=
populationSize
-
Math
.
max
(
1
,
Math
.
min
(
tournamentSize
,
populationSize
));
List
<
Chromosome
>
selected
=
new
ArrayList
<>(
needSelectCount
);
// 预初始化容量
// 边界值处理:锦标赛规模不能超过种群规模,且至少为1
int
effectiveTournamentSize
=
Math
.
max
(
1
,
Math
.
min
(
tournamentSize
,
populationSize
));
List
<
Chromosome
>
selectedtemp
=
new
ArrayList
<>(
needSelectCount
);
// 预初始化容量
// 预生成随机索引,减少Random对象创建开销
Random
random
=
this
.
rnd
;
// 固定次数循环,替代动态终止条件
for
(
int
selectIdx
=
0
;
selectIdx
<
needSelectCount
;
selectIdx
++)
{
// 优化1:Fisher-Yates抽样(无重复、无冲突,比HashSet高效)
List
<
Integer
>
indices
=
new
ArrayList
<>(
populationSize
);
for
(
int
i
=
0
;
i
<
populationSize
;
i
++)
{
indices
.
add
(
i
);
}
// 仅打乱前effectiveTournamentSize个索引,减少计算量
for
(
int
i
=
0
;
i
<
effectiveTournamentSize
;
i
++)
{
int
swapIdx
=
i
+
random
.
nextInt
(
populationSize
-
i
);
Collections
.
swap
(
indices
,
i
,
swapIdx
);
}
Chromosome
bestCandidate
=
null
;
for
(
int
i
=
0
;
i
<
effectiveTournamentSize
;
i
++)
{
int
idx
=
indices
.
get
(
i
);
Chromosome
curr
=
population
.
get
(
idx
);
if
(
bestCandidate
!=
null
)
{
int
rankCompare
=
Integer
.
compare
(
curr
.
getRank
(),
bestCandidate
.
getRank
());
if
(
rankCompare
==
0
)
{
int
crowdingCompare
=
Double
.
compare
(
curr
.
getCrowdingDistance
(),
bestCandidate
.
getCrowdingDistance
());
if
(
crowdingCompare
<
0
)
{
bestCandidate
=
curr
;
}
}
else
{
if
(
rankCompare
<
0
)
{
bestCandidate
=
curr
;
}
}
}
else
{
bestCandidate
=
curr
;
}
}
if
(
bestCandidate
!=
null
)
{
selected
.
add
(
bestCandidate
);
}
}
return
selected
;
// ProductionDeepCopyUtil.deepCopyList(selected, Chromosome.class);
}
/**
* 锦标赛选择
*/
public
List
<
Chromosome
>
tournamentSelection1
(
List
<
Chromosome
>
population
,
int
tournamentSize
)
{
int
populationSize
=
population
.
size
();
List
<
Chromosome
>
selected
=
new
ArrayList
<>();
// 预初始化容量
List
<
Chromosome
>
selected
=
new
ArrayList
<>();
// 预初始化容量
// 边界值处理:锦标赛规模不能超过种群规模,且至少为1
// 边界值处理:锦标赛规模不能超过种群规模,且至少为1
int
effectiveTournamentSize
=
Math
.
max
(
1
,
Math
.
min
(
tournamentSize
,
populationSize
));
int
effectiveTournamentSize
=
Math
.
max
(
1
,
Math
.
min
(
tournamentSize
,
populationSize
));
while
(
selected
.
size
()
<
populationSize
-
tournamentSize
)
{
while
(
selected
.
size
()
<
populationSize
-
tournamentSize
)
{
// 优化1:不复制整个种群,直接随机抽取有效锦标赛规模的个体,避免大量内存拷贝和shuffle开销
// 优化1:不复制整个种群,直接随机抽取有效锦标赛规模的个体,避免大量内存拷贝和shuffle开销
...
@@ -46,9 +115,9 @@ public class GeneticOperations {
...
@@ -46,9 +115,9 @@ public class GeneticOperations {
List
<
Chromosome
>
chromosomes
=
population
.
subList
(
0
,
endIndex
);
List
<
Chromosome
>
chromosomes
=
population
.
subList
(
0
,
endIndex
);
chromosomes
.
sort
((
c1
,
c2
)
->
{
chromosomes
.
sort
((
c1
,
c2
)
->
{
int
rankCompare
=
Integer
.
compare
(
c1
.
getRank
(),
c2
.
getRank
());
int
rankCompare
=
Integer
.
compare
(
c1
.
getRank
(),
c2
.
getRank
());
return
rankCompare
!=
0
?
rankCompare
:
Double
.
compare
(
c1
.
getCrowdingDistance
(),
c2
.
getCrowdingDistance
());
return
rankCompare
!=
0
?
rankCompare
:
Double
.
compare
(
c1
.
getCrowdingDistance
(),
c2
.
getCrowdingDistance
());
});
});
Chromosome
bestCandidate
=
chromosomes
.
get
(
0
);
Chromosome
bestCandidate
=
chromosomes
.
get
(
0
);
...
@@ -60,6 +129,7 @@ public class GeneticOperations {
...
@@ -60,6 +129,7 @@ public class GeneticOperations {
return
selected
;
return
selected
;
}
}
// 重载,使用默认锦标赛大小3
// 重载,使用默认锦标赛大小3
public
List
<
Chromosome
>
tournamentSelection
(
List
<
Chromosome
>
population
)
{
public
List
<
Chromosome
>
tournamentSelection
(
List
<
Chromosome
>
population
)
{
return
tournamentSelection
(
population
,
param
.
getTournamentSize
());
return
tournamentSelection
(
population
,
param
.
getTournamentSize
());
...
@@ -259,8 +329,8 @@ public class GeneticOperations {
...
@@ -259,8 +329,8 @@ public class GeneticOperations {
.
findFirst
().
orElse
(
0
);
.
findFirst
().
orElse
(
0
);
List
<
Integer
>
MachineSelections
=
chromosome
.
getMachineSelection
();
int
machineSeq
=
chromosome
.
getMachineSelection
()
.
get
(
pos
);
int
machineSeq
=
MachineSelections
.
get
(
pos
);
// 选择当前所选设备外最短加工时间的机器
// 选择当前所选设备外最短加工时间的机器
...
@@ -274,7 +344,8 @@ public class GeneticOperations {
...
@@ -274,7 +344,8 @@ public class GeneticOperations {
.
orElse
(
currentMachine
);
// 如果没有其他机器,保持当前
.
orElse
(
currentMachine
);
// 如果没有其他机器,保持当前
machineSeq
=
optionalMachines
.
indexOf
(
minLoadMachine
)
+
1
;
machineSeq
=
optionalMachines
.
indexOf
(
minLoadMachine
)
+
1
;
chromosome
.
getMachineSelection
().
set
(
pos
,
machineSeq
);
MachineSelections
.
set
(
pos
,
machineSeq
);
chromosome
.
setMachineSelection
(
MachineSelections
);
i
++;
i
++;
}
}
...
@@ -298,6 +369,7 @@ public class GeneticOperations {
...
@@ -298,6 +369,7 @@ public class GeneticOperations {
// 交换位置
// 交换位置
List
<
Integer
>
os
=
chromosome
.
getOperationSequencing
();
List
<
Integer
>
os
=
chromosome
.
getOperationSequencing
();
Collections
.
swap
(
os
,
idx1
,
idx2
);
Collections
.
swap
(
os
,
idx1
,
idx2
);
chromosome
.
setOperationSequencing
(
os
);
}
else
{
}
else
{
// 反转:仅对高优先级工序集中的子序列反转
// 反转:仅对高优先级工序集中的子序列反转
OperationSequencingWeight
osStart
=
selectHighPriorityIndex
(
chromosome
.
getOperationSequencing
(),
0
);
OperationSequencingWeight
osStart
=
selectHighPriorityIndex
(
chromosome
.
getOperationSequencing
(),
0
);
...
@@ -318,6 +390,7 @@ public class GeneticOperations {
...
@@ -318,6 +390,7 @@ public class GeneticOperations {
int
pos2
=
end
-
i
;
int
pos2
=
end
-
i
;
Collections
.
swap
(
os
,
pos1
,
pos2
);
Collections
.
swap
(
os
,
pos1
,
pos2
);
}
}
chromosome
.
setOperationSequencing
(
os
);
}
}
}
}
...
...
src/main/java/com/aps/service/Algorithm/IdGroupingWithDualSerial.java
View file @
f081f29e
...
@@ -668,7 +668,7 @@ public class IdGroupingWithDualSerial {
...
@@ -668,7 +668,7 @@ public class IdGroupingWithDualSerial {
nodeInfo
.
getNewParentIds
().
isEmpty
()
?
"无"
:
nodeInfo
.
getNewParentIds
(),
nodeInfo
.
getNewParentIds
().
isEmpty
()
?
"无"
:
nodeInfo
.
getNewParentIds
(),
nodeInfo
.
getNewChildIds
());
nodeInfo
.
getNewChildIds
());
}
}
System
.
out
.
println
(
"------------------------"
);
//
System.out.println("------------------------");
}
}
}
}
}
}
src/main/java/com/aps/service/Algorithm/Initialization.java
View file @
f081f29e
...
@@ -65,7 +65,7 @@ int populationSize=param.getPopulationSize();
...
@@ -65,7 +65,7 @@ int populationSize=param.getPopulationSize();
.
forEach
(
i
->
{
.
forEach
(
i
->
{
Chromosome
chromo
=
new
Chromosome
();
// 初始化染色体
Chromosome
chromo
=
new
Chromosome
();
// 初始化染色体
// chromo.setObjectiveWeights(_objectiveWeights);
// chromo.setObjectiveWeights(_objectiveWeights);
chromo
.
setInitMachines
(
ProductionDeepCopyUtil
.
deepCopyList
(
machines
));
//
chromo.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines));
chromo
.
setOrders
(
orders
);
chromo
.
setOrders
(
orders
);
// 全局选择(GS):按GlobalOpId顺序生成MachineSelection
// 全局选择(GS):按GlobalOpId顺序生成MachineSelection
if
(
i
<
gsCount
)
{
if
(
i
<
gsCount
)
{
...
...
src/main/java/com/aps/service/Algorithm/MachineCalculator.java
View file @
f081f29e
...
@@ -92,7 +92,7 @@ public class MachineCalculator {
...
@@ -92,7 +92,7 @@ public class MachineCalculator {
time
.
setQuantity
(
quantity
);
time
.
setQuantity
(
quantity
);
times
.
add
(
time
);
times
.
add
(
time
);
if
(
islockMachineTime
)
{
if
(
islockMachineTime
)
{
RemoveMachineAvailable
(
machine
,
time
);
RemoveMachineAvailable
(
machine
,
time
,
slot
);
}
}
return
times
;
return
times
;
}
}
...
@@ -129,7 +129,7 @@ public class MachineCalculator {
...
@@ -129,7 +129,7 @@ public class MachineCalculator {
st
=
shiftStart
;
st
=
shiftStart
;
remainingTime
=
processingTime
;
remainingTime
=
processingTime
;
prevEnd
=
LocalDateTime
.
of
(
2000
,
1
,
1
,
0
,
0
,
0
);
prevEnd
=
LocalDateTime
.
of
(
2000
,
1
,
1
,
0
,
0
,
0
);
oldTimes
.
addAll
(
ProductionDeepCopyUtil
.
deepCopyList
(
times
));
oldTimes
.
addAll
(
ProductionDeepCopyUtil
.
deepCopyList
(
times
,
ScheduleResultDetail
.
class
));
times
.
clear
();
times
.
clear
();
continue
;
continue
;
}
}
...
@@ -159,7 +159,7 @@ public class MachineCalculator {
...
@@ -159,7 +159,7 @@ public class MachineCalculator {
times
.
add
(
time
);
times
.
add
(
time
);
if
(
islockMachineTime
)
{
if
(
islockMachineTime
)
{
// 还原未使用的时间段
// 还原未使用的时间段
RemoveMachineAvailable
(
machine
,
time
);
RemoveMachineAvailable
(
machine
,
time
,
shift
);
}
}
}
}
...
@@ -182,47 +182,112 @@ public class MachineCalculator {
...
@@ -182,47 +182,112 @@ public class MachineCalculator {
List
<
ScheduleResultDetail
>
times
=
new
ArrayList
<>();
List
<
ScheduleResultDetail
>
times
=
new
ArrayList
<>();
List
<
ScheduleResultDetail
>
oldTimes
=
new
ArrayList
<>();
List
<
ScheduleResultDetail
>
oldTimes
=
new
ArrayList
<>();
List
<
TimeSegment
>
timeSegments
=
findAvailableSegments
(
machine
,
currentTime
,
machineTasks
,
remainingTime
,
isInterrupt
);
int
estimateIndex
=
(
int
)
Math
.
ceil
(
remainingTime
/
(
double
)
ONE_DAY_MINUTES
);
List
<
TimeSegment
>
timeSegments1
=
null
;
if
(
estimateIndex
>
10
)
{
timeSegments1
=
getEnoughSegmentsByEstimateIndex
(
timeSegments
,
currentTime
,
remainingTime
);
}
if
(
timeSegments1
==
null
)
{
int
i
=
0
;
while
(
remainingTime
>
0
)
{
TimeSegment
shift
=
timeSegments
.
get
(
i
);
List
<
TimeSegment
>
timeSegments
=
findAvailableSegments
(
machine
,
currentTime
,
machineTasks
,
remainingTime
,
isInterrupt
);
Map
<
Integer
,
Object
>
outMap
=
CreateScheduleResultDetail
(
shift
,
st
,
remainingTime
,
oneTime
);
remainingTime
=
(
int
)
outMap
.
get
(
1
);
ScheduleResultDetail
time
=
(
ScheduleResultDetail
)
outMap
.
get
(
2
);
times
.
add
(
time
);
// 还原未使用的时间段
RemoveMachineAvailable
(
machine
,
time
,
shift
);
i
++;
}
}
else
{
times
=
CaldScheduleResultDetail
(
timeSegments1
,
machine
,
st
,
remainingTime
,
oneTime
);
}
return
times
;
}
private
List
<
ScheduleResultDetail
>
CaldScheduleResultDetail
(
List
<
TimeSegment
>
timeSegments
,
Machine
machine
,
LocalDateTime
st
,
int
remainingTime
,
double
oneTime
)
{
int
i
=
0
;
int
processable1
=(
int
)
calculateTotalAvailableSecond
(
timeSegments
,
st
);
while
(
remainingTime
>
0
)
{
TimeSegment
shift
=
timeSegments
.
get
(
i
);
LocalDateTime
shiftStart
=
shift
.
getStart
();
LocalDateTime
shiftEnd
=
shift
.
getEnd
();
// 计算有效时间
List
<
ScheduleResultDetail
>
times
=
new
ArrayList
<>();
LocalDateTime
effectiveStart
=
st
.
isAfter
(
shiftStart
)
?
st
:
shiftStart
;
long
availableSeconds
=
ChronoUnit
.
SECONDS
.
between
(
effectiveStart
,
shiftEnd
);
long
availableSeconds_e
=
Math
.
round
(
availableSeconds
*
shift
.
getEfficiency
())
;
// 处理当前班次
TimeSegment
shiftfrist
=
timeSegments
.
get
(
0
);
int
processable
=
Math
.
min
(
remainingTime
,
(
int
)
availableSeconds_e
);
remainingTime
-=
processable
;
currentTime
=
effectiveStart
.
plusSeconds
(
availableSeconds
/
availableSeconds_e
*
processable
);
// 添加时间详情
Map
<
Integer
,
Object
>
outMap
=
CreateScheduleResultDetail
(
shiftfrist
,
st
,
remainingTime
,
oneTime
);
ScheduleResultDetail
time
=
new
ScheduleResultDetail
();
remainingTime
=(
int
)
outMap
.
get
(
1
);
time
.
setKey
(
shift
.
getKey
());
ScheduleResultDetail
time1
=(
ScheduleResultDetail
)
outMap
.
get
(
2
);
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveStart
));
times
.
add
(
time1
);
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
currentTime
));
RemoveMachineAvailable
(
machine
,
time1
,
shiftfrist
);
time
.
setQuantity
((
int
)(
processable
/
oneTime
));
time
.
setOneTime
(
oneTime
);
times
.
add
(
time
);
// 还原未使用的时间段
// 计算有效时间
RemoveMachineAvailable
(
machine
,
time
);
i
++;
List
<
TimeSegment
>
timeSegments2
=
timeSegments
.
subList
(
1
,
timeSegments
.
size
()-
1
);
}
LocalDateTime
effectiveStart
=
timeSegments2
.
get
(
0
).
getStart
();
LocalDateTime
effectiveend
=
timeSegments2
.
get
(
timeSegments2
.
size
()-
1
).
getEnd
();
int
processable
=(
int
)
calculateTotalAvailableSecond
(
timeSegments2
,
st
);
ScheduleResultDetail
time
=
new
ScheduleResultDetail
();
time
.
setKey
(
UUID
.
randomUUID
().
toString
());
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveStart
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveend
));
time
.
setQuantity
((
int
)(
processable
/
oneTime
));
time
.
setOneTime
(
oneTime
);
time
.
setUsedSegment
(
timeSegments2
);
timeSegments2
.
forEach
(
t
->
t
.
setUsed
(
true
));
remainingTime
-=
processable
;
times
.
add
(
time
);
TimeSegment
shiftlast
=
timeSegments
.
get
(
timeSegments
.
size
()-
1
);
Map
<
Integer
,
Object
>
outMaplast
=
CreateScheduleResultDetail
(
shiftlast
,
st
,
remainingTime
,
oneTime
);
remainingTime
=(
int
)
outMaplast
.
get
(
1
);
ScheduleResultDetail
timelast
=(
ScheduleResultDetail
)
outMaplast
.
get
(
2
);
times
.
add
(
timelast
);
RemoveMachineAvailable
(
machine
,
timelast
,
shiftlast
);
return
times
;
return
times
;
}
}
private
Map
<
Integer
,
Object
>
CreateScheduleResultDetail
(
TimeSegment
shift
,
LocalDateTime
st
,
int
remainingTime
,
double
oneTime
)
{
LocalDateTime
shiftStart
=
shift
.
getStart
();
LocalDateTime
shiftEnd
=
shift
.
getEnd
();
// 计算有效时间
LocalDateTime
effectiveStart
=
st
.
isAfter
(
shiftStart
)
?
st
:
shiftStart
;
long
availableSeconds
=
ChronoUnit
.
SECONDS
.
between
(
effectiveStart
,
shiftEnd
);
long
availableSeconds_e
=
Math
.
round
(
availableSeconds
*
shift
.
getEfficiency
())
;
// 处理当前班次
int
processable
=
Math
.
min
(
remainingTime
,
(
int
)
availableSeconds_e
);
remainingTime
-=
processable
;
double
e
=
(
double
)
availableSeconds
/
availableSeconds_e
*
processable
;
LocalDateTime
currentTime
=
effectiveStart
.
plusSeconds
((
int
)
Math
.
ceil
(
e
));
// 添加时间详情
ScheduleResultDetail
time
=
new
ScheduleResultDetail
();
time
.
setKey
(
shift
.
getKey
());
time
.
setStartTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
effectiveStart
));
time
.
setEndTime
((
int
)
ChronoUnit
.
SECONDS
.
between
(
baseTime
,
currentTime
));
time
.
setQuantity
((
int
)(
processable
/
oneTime
));
time
.
setOneTime
(
oneTime
);
Map
<
Integer
,
Object
>
outMap
=
new
HashMap
<>();
outMap
.
put
(
1
,
remainingTime
);
outMap
.
put
(
2
,
time
);
return
outMap
;
}
/**
/**
* 查找满足时长要求的无冲突可用时段
* 查找满足时长要求的无冲突可用时段
* @param machine 设备
* @param machine 设备
...
@@ -323,6 +388,100 @@ i++;
...
@@ -323,6 +388,100 @@ i++;
}
}
}
}
}
}
private
static
final
int
ONE_DAY_MINUTES
=
24
*
60
*
60
;
// 固定锚点:一天1440分钟,永不改变
/**
* 按预估索引快速获取满足时长的时段数组
* @param availableSegments 有序的可用时段列表(必须按Start升序,业务中天然满足)
* @param currentTime 排程开始时间
* @param requiredMinutes 需要的总分钟数(支持超大值:几万/几十万分钟)
* @return 刚好满足时长的片段数组
* @throws IllegalArgumentException 总时长不足时抛出
*/
public
List
<
TimeSegment
>
getEnoughSegmentsByEstimateIndex
(
List
<
TimeSegment
>
availableSegments
,
LocalDateTime
currentTime
,
int
requiredMinutes
)
{
// 基础校验
if
(
availableSegments
==
null
||
availableSegments
.
isEmpty
())
{
throw
new
IllegalArgumentException
(
"可用时段列表不能为空"
);
}
if
(
requiredMinutes
<=
0
)
{
return
null
;
}
int
totalSegmentCount
=
availableSegments
.
size
();
// ========== 步骤1:核心!快速预估索引,一步到位,跳过几千个片段 ==========
// 预估逻辑:需求时长/每天分钟数 + 5(冗余值,防止预估不足,可根据业务调整,实际班次不是24小时),
int
estimateIndex
=
(
int
)
Math
.
ceil
(
requiredMinutes
/
(
double
)
ONE_DAY_MINUTES
);
estimateIndex
=
estimateIndex
+
5
;
// 边界保护:预估索引不能超过总片段数,也不能小于0
estimateIndex
=
Math
.
min
(
estimateIndex
,
totalSegmentCount
-
1
);
estimateIndex
=
Math
.
max
(
estimateIndex
,
0
);
// ========== 步骤2:双向逼近,小范围循环增减索引,循环次数≤20次 ==========
int
targetIndex
=
estimateIndex
;
while
(
true
)
{
// 计算当前索引的总有效时长
double
currentTotal
=
calculateTotalMinutesByIndex
(
availableSegments
,
currentTime
,
targetIndex
);
if
(
currentTotal
>=
requiredMinutes
)
{
// ✔️ 总时长满足,尝试往前减索引,找「最小满足索引」(减少后续裁剪的工作量)
if
(
targetIndex
>
0
)
{
double
prevTotal
=
calculateTotalMinutesByIndex
(
availableSegments
,
currentTime
,
targetIndex
-
1
);
if
(
prevTotal
>=
requiredMinutes
)
{
targetIndex
--;
continue
;
}
}
break
;
// 找到最小满足索引,退出循环
}
else
{
double
syday
=
(
int
)
Math
.
ceil
((
requiredMinutes
-
currentTotal
)/(
double
)
ONE_DAY_MINUTES
);
// ❌ 总时长不足,往后加索引(每次加5,大步前进,加快逼近速度)
targetIndex
+=
Math
.
max
(
syday
,
5
);
if
(
targetIndex
>=
totalSegmentCount
)
{
// 所有片段总时长不足,抛出异常
double
allTotal
=
calculateTotalMinutesByIndex
(
availableSegments
,
currentTime
,
totalSegmentCount
-
1
);
if
(
allTotal
>
requiredMinutes
)
{
double
prevTotal
=
calculateTotalMinutesByIndex
(
availableSegments
,
currentTime
,
targetIndex
-
1
);
if
(
prevTotal
>=
requiredMinutes
)
{
targetIndex
--;
continue
;
}
break
;
}
else
if
(
allTotal
==
requiredMinutes
)
{
return
availableSegments
;
}
else
{
return
null
;
}
}
}
}
// ========== 步骤3:精准裁剪片段,返回最终结果 ==========
List
<
TimeSegment
>
resultList
=
availableSegments
.
subList
(
0
,
targetIndex
);
return
resultList
;
}
/**
* 计算从0到指定索引的所有时段的总有效分钟数
*/
private
double
calculateTotalMinutesByIndex
(
List
<
TimeSegment
>
segments
,
LocalDateTime
currentTime
,
int
endIndex
)
{
return
calculateTotalAvailableSecond
(
segments
.
subList
(
0
,
endIndex
),
currentTime
);
}
/**
/**
* 统一过滤有效可用片段
* 统一过滤有效可用片段
*/
*/
...
@@ -538,13 +697,17 @@ i++;
...
@@ -538,13 +697,17 @@ i++;
if
(
newSegments
==
null
||
newSegments
.
isEmpty
())
{
if
(
newSegments
==
null
||
newSegments
.
isEmpty
())
{
return
;
return
;
}
}
List
<
TimeSegment
>
availabilitySnapshot
=
new
ArrayList
<>(
machine
.
getAvailability
());
availabilitySnapshot
.
addAll
(
newSegments
);
List
<
TimeSegment
>
mergedSegments
=
MergeSegments
(
availabilitySnapshot
);
synchronized
(
machine
.
getAvailability
())
{
// 合并片段(去重+排序),
machine
.
setAvailability
(
mergedSegments
);
}
// 追加新片段,对应C#的 machine.Availability.AddRange(newSegments)
machine
.
getAvailability
().
addAll
(
newSegments
);
// 合并片段(去重+排序),并重新赋值给设备的可用片段列表,对应C#的 machine.Availability = MergeSegments(...)
List
<
TimeSegment
>
mergedSegments
=
MergeSegments
(
machine
.
getAvailability
());
machine
.
setAvailability
(
mergedSegments
);
}
}
private
boolean
CheckTask
(
Machine
machine
,
List
<
GAScheduleResult
>
machineTasks
,
LocalDateTime
prevEnd
,
LocalDateTime
shiftStart
)
{
private
boolean
CheckTask
(
Machine
machine
,
List
<
GAScheduleResult
>
machineTasks
,
LocalDateTime
prevEnd
,
LocalDateTime
shiftStart
)
{
...
@@ -572,10 +735,10 @@ i++;
...
@@ -572,10 +735,10 @@ i++;
*/
*/
private
TimeSegment
GetCurrentOrNextShift
(
Machine
machine
,
LocalDateTime
time
,
String
prevtime
,
boolean
checkprevtime
)
{
private
TimeSegment
GetCurrentOrNextShift
(
Machine
machine
,
LocalDateTime
time
,
String
prevtime
,
boolean
checkprevtime
)
{
TimeSegment
start
=
null
;
TimeSegment
start
=
null
;
List
<
TimeSegment
>
availabilitySnapshot
=
new
ArrayList
<>(
machine
.
getAvailability
());
if
(
machine
.
getAvailability
()!=
null
)
if
(!
availabilitySnapshot
.
isEmpty
()
)
{
{
start
=
machine
.
getAvailability
()
.
stream
()
start
=
availabilitySnapshot
.
stream
()
.
filter
(
slot
->
!
slot
.
isUsed
()
&&
slot
.
getType
()
!=
SegmentType
.
MAINTENANCE
)
.
filter
(
slot
->
!
slot
.
isUsed
()
&&
slot
.
getType
()
!=
SegmentType
.
MAINTENANCE
)
.
filter
(
slot
->
slot
.
getStart
().
isAfter
(
time
)
||
slot
.
getEnd
().
isAfter
(
time
))
.
filter
(
slot
->
slot
.
getStart
().
isAfter
(
time
)
||
slot
.
getEnd
().
isAfter
(
time
))
.
findFirst
()
.
findFirst
()
...
@@ -590,8 +753,9 @@ i++;
...
@@ -590,8 +753,9 @@ i++;
// 生成新时间段
// 生成新时间段
List
<
TimeSegment
>
timeSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
time
.
plusDays
(
1
),
0
);
List
<
TimeSegment
>
timeSegments
=
machineScheduler
.
generateTimeSegment
(
machine
,
time
.
plusDays
(
1
),
0
);
machine
.
getAvailability
().
addAll
(
timeSegments
);
synchronized
(
machine
.
getAvailability
())
{
machine
.
getAvailability
().
addAll
(
timeSegments
);
}
// 更新设备时间线
// 更新设备时间线
Machine
originalMachine
=
machines
.
stream
()
Machine
originalMachine
=
machines
.
stream
()
.
filter
(
t
->
t
.
getId
()
==
machine
.
getId
())
.
filter
(
t
->
t
.
getId
()
==
machine
.
getId
())
...
@@ -812,17 +976,54 @@ i++;
...
@@ -812,17 +976,54 @@ i++;
return
times
;
return
times
;
}
}
private
void
RemoveMachineAvailable
(
Machine
machine
,
ScheduleResultDetail
geneDetails
)
{
private
void
RemoveMachineAvailable
(
Machine
machine
,
ScheduleResultDetail
geneDetails
,
TimeSegment
targetSegment
)
{
// 关键修复2:加锁(若多线程访问),避免并发修改
synchronized
(
machine
.
getAvailability
())
{
List
<
TimeSegment
>
availabilitySnapshot
=
new
ArrayList
<>(
machine
.
getAvailability
());
LocalDateTime
geneEndTime
=
baseTime
.
plusSeconds
(
geneDetails
.
getEndTime
());
if
(
targetSegment
.
getEnd
().
isAfter
(
geneEndTime
))
{
TimeSegment
usedSegment
=
new
TimeSegment
();
usedSegment
.
setStart
(
baseTime
.
plusSeconds
(
geneDetails
.
getStartTime
()));
usedSegment
.
setEnd
(
geneEndTime
);
usedSegment
.
setHoliday
(
false
);
usedSegment
.
setKey
(
UUID
.
randomUUID
().
toString
());
usedSegment
.
setType
(
SegmentType
.
REGULAR
);
usedSegment
.
setUsed
(
true
);
availabilitySnapshot
.
add
(
usedSegment
);
geneDetails
.
setKey
(
usedSegment
.
getKey
());
targetSegment
.
setStart
(
geneEndTime
);
}
else
{
targetSegment
.
setUsed
(
true
);
}
availabilitySnapshot
.
sort
(
Comparator
.
comparing
(
TimeSegment:
:
getStart
));
machine
.
setAvailability
(
availabilitySnapshot
);
}
}
private
void
RemoveMachineAvailable1
(
Machine
machine
,
ScheduleResultDetail
geneDetails
)
{
List
<
TimeSegment
>
timeSegments
=
new
ArrayList
<>();
List
<
TimeSegment
>
timeSegments
=
new
ArrayList
<>();
int
index
=
machine
.
getAvailability
().
stream
()
List
<
TimeSegment
>
availabilitySnapshot
=
new
ArrayList
<>(
machine
.
getAvailability
());
int
index
=
availabilitySnapshot
.
stream
()
.
filter
(
t
->
t
.
getKey
().
equals
(
geneDetails
.
getKey
()))
.
filter
(
t
->
t
.
getKey
().
equals
(
geneDetails
.
getKey
()))
.
findFirst
()
.
findFirst
()
.
map
(
machine
.
getAvailability
()::
indexOf
)
.
map
(
machine
.
getAvailability
()::
indexOf
)
.
orElse
(-
1
);
.
orElse
(-
1
);
if
(
index
>
-
1
)
{
if
(
index
>
-
1
)
{
TimeSegment
targetSegment
=
machine
.
getAvailability
()
.
get
(
index
);
TimeSegment
targetSegment
=
availabilitySnapshot
.
get
(
index
);
LocalDateTime
geneEndTime
=
baseTime
.
plusSeconds
(
geneDetails
.
getEndTime
());
LocalDateTime
geneEndTime
=
baseTime
.
plusSeconds
(
geneDetails
.
getEndTime
());
if
(
targetSegment
.
getEnd
().
isAfter
(
geneEndTime
))
{
if
(
targetSegment
.
getEnd
().
isAfter
(
geneEndTime
))
{
...
@@ -843,22 +1044,60 @@ i++;
...
@@ -843,22 +1044,60 @@ i++;
}
}
if
(!
timeSegments
.
isEmpty
())
{
if
(!
timeSegments
.
isEmpty
())
{
machine
.
getAvailability
().
addAll
(
timeSegments
);
availabilitySnapshot
.
addAll
(
timeSegments
);
}
availabilitySnapshot
.
sort
(
Comparator
.
comparing
(
TimeSegment:
:
getStart
));
// 关键修复2:加锁(若多线程访问),避免并发修改
synchronized
(
machine
.
getAvailability
())
{
machine
.
setAvailability
(
availabilitySnapshot
);
}
}
machine
.
getAvailability
().
sort
(
Comparator
.
comparing
(
TimeSegment:
:
getStart
));
}
}
public
void
AddMachineAvailable
(
Machine
machine
,
List
<
ScheduleResultDetail
>
geneDetails
)
{
public
void
AddMachineAvailable
(
Machine
machine
,
List
<
ScheduleResultDetail
>
geneDetails
)
{
if
(
geneDetails
==
null
||
geneDetails
.
isEmpty
())
return
;
if
(
geneDetails
==
null
||
geneDetails
.
isEmpty
())
return
;
synchronized
(
machine
.
getAvailability
())
{
List
<
String
>
keys
=
geneDetails
.
stream
().
filter
(
t
->
t
.
getUsedSegment
()==
null
||
t
.
getUsedSegment
().
size
()==
0
)
.
map
(
ScheduleResultDetail:
:
getKey
)
.
collect
(
Collectors
.
toList
());
List
<
String
>
keys1
=
geneDetails
.
stream
().
filter
(
t
->
t
.
getUsedSegment
()!=
null
)
.
flatMap
(
detail
->
detail
.
getUsedSegment
().
stream
())
.
map
(
TimeSegment:
:
getKey
).
collect
(
Collectors
.
toList
());
if
(
keys1
!=
null
&&
keys1
.
size
()>
0
)
{
keys
.
addAll
(
keys1
);
}
machine
.
getAvailability
().
stream
()
.
filter
(
t
->
keys
.
contains
(
t
.
getKey
()))
.
forEach
(
t
->
t
.
setUsed
(
false
));
for
(
ScheduleResultDetail
detail
:
geneDetails
)
{
machine
.
getAvailability
().
stream
()
.
filter
(
t
->
t
.
getKey
().
equals
(
detail
.
getKey
()))
.
findFirst
()
.
ifPresent
(
t
->
t
.
setUsed
(
false
));
}
}
}
machine
.
setAvailability
(
MergeSegments
(
machine
.
getAvailability
()));
public
void
AddMachineAvailable1
(
Machine
machine
,
List
<
ScheduleResultDetail
>
geneDetails
)
{
if
(
geneDetails
==
null
||
geneDetails
.
isEmpty
())
return
;
List
<
TimeSegment
>
availabilitySnapshot
=
new
ArrayList
<>(
machine
.
getAvailability
());
for
(
ScheduleResultDetail
detail
:
geneDetails
)
{
if
(
detail
.
getUsedSegment
()!=
null
&&
detail
.
getUsedSegment
().
size
()>
0
)
{
List
<
TimeSegment
>
availabilitySnapshot1
=
detail
.
getUsedSegment
();
availabilitySnapshot1
.
forEach
(
t
->
t
.
setUsed
(
false
));
}
else
{
availabilitySnapshot
.
stream
()
.
filter
(
t
->
t
.
getKey
().
equals
(
detail
.
getKey
()))
.
findFirst
()
.
ifPresent
(
t
->
t
.
setUsed
(
false
));
}
}
availabilitySnapshot
=
MergeSegments
(
availabilitySnapshot
);
synchronized
(
machine
.
getAvailability
())
{
machine
.
setAvailability
(
availabilitySnapshot
);
}
}
}
/**
/**
* 分割设备可用时间段
* 分割设备可用时间段
...
...
src/main/java/com/aps/service/Algorithm/RoutingDataService.java
View file @
f081f29e
...
@@ -272,9 +272,8 @@ public class RoutingDataService {
...
@@ -272,9 +272,8 @@ public class RoutingDataService {
entrys
.
add
(
entry
);
entrys
.
add
(
entry
);
}
}
// 输出每个节点的详细信息
System
.
out
.
println
(
"------------------------"
);
}
}
list
.
put
(
1
,
entrys
);
list
.
put
(
1
,
entrys
);
list
.
put
(
2
,
results
);
list
.
put
(
2
,
results
);
...
...
src/main/java/com/aps/service/Algorithm/ScheduleOperationService.java
View file @
f081f29e
...
@@ -928,13 +928,13 @@ Integer newMachineId1=newMachineId.intValue();
...
@@ -928,13 +928,13 @@ Integer newMachineId1=newMachineId.intValue();
GeneticDecoder
decoder
=
new
GeneticDecoder
(
globalParam
,
baseTime
,
chromosome
.
getMachines
(),
GeneticDecoder
decoder
=
new
GeneticDecoder
(
globalParam
,
baseTime
,
chromosome
.
getMachines
(),
chromosome
.
getOrders
(),
null
,
machineScheduler
,
chromosome
.
getOrderMaterials
());
chromosome
.
getOrders
(),
null
,
machineScheduler
,
chromosome
.
getOrderMaterials
());
chromosome
.
setResultOld
(
ProductionDeepCopyUtil
.
deepCopyList
(
chromosome
.
getResult
()));
chromosome
.
setResultOld
(
ProductionDeepCopyUtil
.
deepCopyList
(
chromosome
.
getResult
()
,
GAScheduleResult
.
class
));
chromosome
.
getResult
().
clear
();
chromosome
.
getResult
().
clear
();
List
<
GAScheduleResult
>
Resultlock
=
chromosome
.
getResult
().
stream
()
List
<
GAScheduleResult
>
Resultlock
=
chromosome
.
getResult
().
stream
()
.
filter
(
o
->
o
.
isIsLocked
()
==
true
)
.
filter
(
o
->
o
.
isIsLocked
()
==
true
)
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
chromosome
.
setResult
(
ProductionDeepCopyUtil
.
deepCopyList
(
Resultlock
));
chromosome
.
setResult
(
ProductionDeepCopyUtil
.
deepCopyList
(
Resultlock
,
GAScheduleResult
.
class
));
decoder
.
decode
(
chromosome
);
decoder
.
decode
(
chromosome
);
...
...
src/main/java/com/aps/service/plan/PlanResultService.java
View file @
f081f29e
...
@@ -98,7 +98,8 @@ public class PlanResultService {
...
@@ -98,7 +98,8 @@ public class PlanResultService {
@Autowired
@Autowired
private
MaterialInfoMapper
materialInfoMapper
;
private
MaterialInfoMapper
materialInfoMapper
;
@Autowired
private
MaterialPurchaseMapper
materialPurchaseMapper
;
@Autowired
@Autowired
private
StockMapper
stockMapper
;
private
StockMapper
stockMapper
;
...
@@ -1139,14 +1140,19 @@ private GlobalParam InitGlobalParam()
...
@@ -1139,14 +1140,19 @@ private GlobalParam InitGlobalParam()
public
List
<
Material
>
getMaterials
(){
public
List
<
Material
>
getMaterials
(){
List
<
Material
>
materials
=
new
ArrayList
<>();
List
<
Material
>
materials
=
new
ArrayList
<>();
System
.
out
.
println
(
"开始初始化物料数据"
);
LambdaQueryWrapper
<
MaterialInfo
>
MaterialInfoWrapper
=
new
LambdaQueryWrapper
<>();
LambdaQueryWrapper
<
MaterialInfo
>
MaterialInfoWrapper
=
new
LambdaQueryWrapper
<>();
MaterialInfoWrapper
.
eq
(
MaterialInfo:
:
getIsdeleted
,
0
);
MaterialInfoWrapper
.
eq
(
MaterialInfo:
:
getIsdeleted
,
0
);
List
<
MaterialInfo
>
materiallist
=
materialInfoMapper
.
selectList
(
MaterialInfoWrapper
);
List
<
MaterialInfo
>
materiallist
=
materialInfoMapper
.
selectList
(
MaterialInfoWrapper
);
LambdaQueryWrapper
<
MaterialPurchase
>
materialPurchaseWrapper
=
new
LambdaQueryWrapper
<>();
materialPurchaseWrapper
.
eq
(
MaterialPurchase:
:
getIsdeleted
,
0
);
List
<
MaterialPurchase
>
MaterialPurchaselist
=
materialPurchaseMapper
.
selectList
(
materialPurchaseWrapper
);
System
.
out
.
println
(
"开始初始化物料数据"
);
LambdaQueryWrapper
<
Stock
>
StockWrapper
=
new
LambdaQueryWrapper
<>();
LambdaQueryWrapper
<
Stock
>
StockWrapper
=
new
LambdaQueryWrapper
<>();
StockWrapper
.
eq
(
Stock:
:
getIsdeleted
,
0
);
StockWrapper
.
eq
(
Stock:
:
getIsdeleted
,
0
);
...
...
src/test/java/com/aps/demo/PlanResultServiceTest.java
View file @
f081f29e
...
@@ -38,13 +38,13 @@ public class PlanResultServiceTest {
...
@@ -38,13 +38,13 @@ public class PlanResultServiceTest {
// nsgaiiUtils.Test();
// nsgaiiUtils.Test();
//planResultService.execute2("C5FB5EF2A7334A0A92F826F4937E1008");
//planResultService.execute2("C5FB5EF2A7334A0A92F826F4937E1008");
//
planResultService.execute2("726D4C1A712B4B1393175BD44B775B66");
planResultService
.
execute2
(
"726D4C1A712B4B1393175BD44B775B66"
);
planResultService
.
execute2
(
"BCA6FA43FFA444D3952CF8F6E1EA291B"
);
//
planResultService.execute2("BCA6FA43FFA444D3952CF8F6E1EA291B");
// LocalDateTime t= LocalDateTime.of(2025, 11, 15, 6, 51, 11);
// LocalDateTime t= LocalDateTime.of(2025, 11, 15, 6, 51, 11);
// List<Integer> opids=new ArrayList<>();
// List<Integer> opids=new ArrayList<>();
// opids.add(1);
// opids.add(1);
// planResultService.Move("B571EF6682DB463AB2977B1055A74112",opids,t,3403L);
// planResultService.Move("B571EF6682DB463AB2977B1055A74112",opids,t,3403L);
//
planResultService.Redecode("12345679");
planResultService
.
Redecode
(
"12345679"
);
// MaintenanceWindow maintenanceWindow=new MaintenanceWindow();
// MaintenanceWindow maintenanceWindow=new MaintenanceWindow();
// maintenanceWindow.setStartTime(LocalDateTime.of(2025, 10, 21, 0, 0, 0));
// maintenanceWindow.setStartTime(LocalDateTime.of(2025, 10, 21, 0, 0, 0));
// maintenanceWindow.setEndTime(LocalDateTime.of(2025, 10, 31, 0, 0, 0));
// maintenanceWindow.setEndTime(LocalDateTime.of(2025, 10, 31, 0, 0, 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