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
dd36e456
Commit
dd36e456
authored
Jan 15, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化非分配排序
parent
4965288c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
188 additions
and
29 deletions
+188
-29
GeneticAlgorithm.java
...main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
+9
-16
NSGAIIUtils.java
src/main/java/com/aps/service/Algorithm/NSGAIIUtils.java
+178
-12
PlanResultServiceTest.java
src/test/java/com/aps/demo/PlanResultServiceTest.java
+1
-1
No files found.
src/main/java/com/aps/service/Algorithm/GeneticAlgorithm.java
View file @
dd36e456
...
...
@@ -110,12 +110,12 @@ public class GeneticAlgorithm {
FileHelper
.
writeLogFile
(
"初始化批量解码-----------开始-------"
);
Chromosomedecode
(
param
,
allOperations
,
globalOpList
,
population
);
FileHelper
.
writeLogFile
(
"初始化批量解码-----------结束-------"
);
List
<
List
<
Chromosome
>>
f
ronts
=
_nsgaIIUtils
.
parallelFastNonDominatedSort
(
population
);
List
<
List
<
Chromosome
>>
combinedF
ronts
=
_nsgaIIUtils
.
parallelFastNonDominatedSort
(
population
);
int
ordercount
=
globalOpList
.
stream
()
.
mapToInt
(
GlobalOperationInfo:
:
getGroupId
)
.
max
()
.
orElse
(
0
);
Chromosome
best
=
GetBest
(
f
ronts
,
"初始"
);
Chromosome
best
=
GetBest
(
combinedF
ronts
,
"初始"
);
// best=fronts.get(0).stream()
// .max(Comparator.comparingDouble(Chromosome::getFitness))
...
...
@@ -165,6 +165,7 @@ public class GeneticAlgorithm {
List
<
Chromosome
>
nextPopulation
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
selected
.
size
();
i
+=
2
)
{
if
(
i
+
1
>=
selected
.
size
())
{
selected
.
get
(
i
).
setID
(
UUID
.
randomUUID
().
toString
());
nextPopulation
.
add
(
selected
.
get
(
i
));
break
;
}
...
...
@@ -188,6 +189,7 @@ public class GeneticAlgorithm {
for
(
Chromosome
chromosome
:
nextPopulation
)
{
if
(
rnd
.
nextDouble
()
<
param
.
getMutationProb
())
{
Chromosome
chromosome1
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
chromosome1
.
setID
(
UUID
.
randomUUID
().
toString
());
geneticOps
.
mutate
(
chromosome1
,
globalOpList
);
nextPopulation1
.
add
(
chromosome1
);
}
...
...
@@ -209,12 +211,15 @@ public class GeneticAlgorithm {
// List<Chromosome> elites = population1.subList(0, param.getElitismCount());
List
<
Chromosome
>
newPopulation
=
new
ArrayList
<>();
newPopulation
.
addAll
(
population
);
//保留一定数量的上一代
List
<
Chromosome
>
populationcopy
=
_nsgaIIUtils
.
selectNextPopulation
(
combinedFronts
,
param
.
getPopulationSize
()/
5
);
newPopulation
.
addAll
(
populationcopy
);
newPopulation
.
addAll
(
nextPopulation
);
newPopulation
=
chromosomeDistinct1
(
newPopulation
);
FileHelper
.
writeLogFile
(
"非支配排序-----------开始-------"
);
// 2.7 非支配排序
List
<
List
<
Chromosome
>>
combinedFronts
=
_nsgaIIUtils
.
parallelFastNonDominatedSort
(
newPopulation
);
combinedFronts
=
_nsgaIIUtils
.
parallelFastNonDominatedSort
(
newPopulation
);
FileHelper
.
writeLogFile
(
"非支配排序-----------结束-------"
);
// 2.8 选择下一代种群
population
=
_nsgaIIUtils
.
selectNextPopulation
(
combinedFronts
,
param
.
getPopulationSize
());
...
...
@@ -291,14 +296,9 @@ return population;
}
FileHelper
.
writeLogFile
(
String
.
format
(
"排产-----------方案数量---%d-------"
,
population
.
size
()
));
List
<
Chromosome
>
population1
=
population
.
stream
().
filter
(
t
->
t
.
getGeneStr
()==
null
).
collect
(
Collectors
.
toList
());
if
(
population1
!=
null
&&
population1
.
size
()>
0
)
{
FileHelper
.
writeLogFile
(
String
.
format
(
"排产-----------方案GeneStrnull数量---%d-------"
,
population1
.
size
()
));
}
population
=
population
.
stream
()
.
collect
(
Collectors
.
toMap
(
Chromosome:
:
getGeneStr
,
// key:去重的字段(GeneStr)
...
...
@@ -308,7 +308,6 @@ if(population1!=null&&population1.size()>0)
.
values
()
// 获取去重后的
.
stream
()
.
collect
(
Collectors
.
toList
());
FileHelper
.
writeLogFile
(
String
.
format
(
"排产-----------方案数量---%d-------"
,
population
.
size
()
));
return
population
;
}
...
...
@@ -321,14 +320,9 @@ if(population1!=null&&population1.size()>0)
}
FileHelper
.
writeLogFile
(
String
.
format
(
"排产-----------方案数量---%d-------"
,
population
.
size
()
));
List
<
Chromosome
>
population1
=
population
.
stream
().
filter
(
t
->
t
.
getGeneStr
()==
null
).
collect
(
Collectors
.
toList
());
if
(
population1
!=
null
&&
population1
.
size
()>
0
)
{
FileHelper
.
writeLogFile
(
String
.
format
(
"排产-----------方案GeneStrnull数量---%d-------"
,
population1
.
size
()
));
}
population
=
population
.
stream
()
.
collect
(
Collectors
.
toMap
(
Chromosome:
:
getGeneStr
,
// key:去重的字段(GeneStr)
...
...
@@ -338,7 +332,6 @@ if(population1!=null&&population1.size()>0)
.
values
()
// 获取去重后的
.
stream
()
.
collect
(
Collectors
.
toList
());
FileHelper
.
writeLogFile
(
String
.
format
(
"排产-----------方案数量---%d-------"
,
population
.
size
()
));
return
population
;
}
...
...
src/main/java/com/aps/service/Algorithm/NSGAIIUtils.java
View file @
dd36e456
...
...
@@ -24,7 +24,7 @@ public class NSGAIIUtils {
public
void
init
(
ObjectiveWeights
weights
,
int
taskCount
,
boolean
[]
isMinimize
)
{
this
.
objectiveWeights
=
(
weights
!=
null
)
?
weights
:
new
ObjectiveWeights
();
this
.
taskCount
=
(
taskCount
>
0
)
?
taskCount
:
Runtime
.
getRuntime
().
availableProcessors
();
this
.
taskCount
=
(
taskCount
>
0
)
?
taskCount
:
Runtime
.
getRuntime
().
availableProcessors
()
-
1
;
this
.
isMinimize
=
isMinimize
;
}
...
...
@@ -33,7 +33,7 @@ public class NSGAIIUtils {
*/
public
void
init
(
ObjectiveWeights
weights
,
int
taskCount
)
{
this
.
objectiveWeights
=
(
weights
!=
null
)
?
weights
:
new
ObjectiveWeights
();
this
.
taskCount
=
(
taskCount
>
0
)
?
taskCount
:
Runtime
.
getRuntime
().
availableProcessors
();
this
.
taskCount
=
(
taskCount
>
0
)
?
taskCount
:
Runtime
.
getRuntime
().
availableProcessors
()
-
1
;
}
/**
...
...
@@ -53,22 +53,171 @@ public class NSGAIIUtils {
// 步骤1:预处理 - 计算归一化目标值和加权目标值
preprocessObjectives
(
population
);
if
(
popSize
<=
taskCount
*
1
0
)
{
// 小规模种群直接串行
if
(
popSize
<=
taskCount
*
1
5
)
{
// 小规模种群直接串行 7*15
fronts
=
fastNonDominatedSort
(
population
);
}
else
{
int
chunkCount
=
Math
.
min
(
taskCount
,
popSize
);
// 步骤2:拆分种群为多个块,并行计算支配关系
List
<
List
<
Chromosome
>>
chunks
=
splitPopulation
(
population
,
taskCount
);
ConcurrentHashMap
<
Chromosome
,
ConcurrentLinkedQueue
<
Chromosome
>>
dominanceMatrix
=
new
ConcurrentHashMap
<>();
ConcurrentHashMap
<
Chromosome
,
AtomicInteger
>
dominatedCount
=
new
ConcurrentHashMap
<>();
List
<
List
<
Chromosome
>>
chunks
=
splitPopulation
(
population
,
chunkCount
);
Map
<
Chromosome
,
List
<
Chromosome
>>
dominanceMatrix
=
new
HashMap
<>();
Map
<
Chromosome
,
Integer
>
dominatedCount
=
new
HashMap
<>();
for
(
Chromosome
chromo
:
population
)
{
dominanceMatrix
.
put
(
chromo
,
new
ArrayList
<>());
dominatedCount
.
put
(
chromo
,
0
);
}
ExecutorService
executor
=
Executors
.
newFixedThreadPool
(
chunkCount
);
try
{
List
<
Future
<?>>
futures
=
new
ArrayList
<>();
// 存储任务Future,确保全量等待
for
(
List
<
Chromosome
>
chunk
:
chunks
)
{
futures
.
add
(
executor
.
submit
(()
->
{
for
(
Chromosome
p
:
chunk
)
{
for
(
Chromosome
q
:
population
)
{
if
(
p
==
q
)
continue
;
if
(
dominates
(
p
,
q
))
{
synchronized
(
dominanceMatrix
.
get
(
p
))
{
// 细粒度锁
dominanceMatrix
.
get
(
p
).
add
(
q
);
}
}
else
if
(
dominates
(
q
,
p
))
{
synchronized
(
dominatedCount
)
{
dominatedCount
.
put
(
p
,
dominatedCount
.
get
(
p
)
+
1
);
}
}
}
}
}));
}
// 核心修复2:等待所有任务完成,避免提前终止导致的计算不完整
for
(
Future
<?>
future
:
futures
)
{
try
{
future
.
get
();
// 等待单个任务完成,抛出异常则终止
}
catch
(
ExecutionException
e
)
{
throw
new
RuntimeException
(
"并行计算支配关系失败"
,
e
.
getCause
());
}
}
executor
.
shutdown
();
}
catch
(
InterruptedException
e
)
{
Thread
.
currentThread
().
interrupt
();
throw
new
RuntimeException
(
"并行计算支配关系中断"
,
e
);
}
finally
{
if
(!
executor
.
isShutdown
())
{
executor
.
shutdownNow
();
// 确保线程池关闭
}
}
// 生成前沿
// 染色体 -> 数组下标的映射表
Map
<
Chromosome
,
Integer
>
chromosomeIndexMap
=
new
HashMap
<>(
popSize
);
int
[]
dominatedCounts
=
new
int
[
popSize
];
// 新增:支配矩阵数组化 - 每个p的下标,对应一个存储q下标的List
List
<
List
<
Integer
>>
dominanceMatrixArr
=
new
ArrayList
<>(
popSize
);
// ======== 修复空指针的核心行:循环popSize次,给每个索引塞一个空的ArrayList ========
for
(
int
idx
=
0
;
idx
<
popSize
;
idx
++)
{
dominanceMatrixArr
.
add
(
new
ArrayList
<>());
// 必须加这行,初始化每个位置的空列表
Chromosome
c
=
population
.
get
(
idx
);
chromosomeIndexMap
.
put
(
c
,
idx
);
}
// 5. 填充映射表、被支配数数组、支配矩阵数组
for
(
int
idx
=
0
;
idx
<
popSize
;
idx
++)
{
Chromosome
c
=
population
.
get
(
idx
);
dominatedCounts
[
idx
]
=
dominatedCount
.
get
(
c
);
// 把HashMap的支配列表,转成q的下标列表,存入数组
List
<
Chromosome
>
qList
=
dominanceMatrix
.
get
(
c
);
List
<
Integer
>
qIdxList
=
dominanceMatrixArr
.
get
(
idx
);
// 此时get(idx)绝对非空!
for
(
Chromosome
q
:
qList
)
{
Integer
qIdx
=
chromosomeIndexMap
.
get
(
q
);
if
(
qIdx
!=
null
){
// 额外兜底:防止q是null导致的空指针
qIdxList
.
add
(
qIdx
);
}
}
}
// ========== 初始化前沿列表,必须先添加F1(第一个前沿) ==========
List
<
Chromosome
>
firstFront
=
new
ArrayList
<>();
// 遍历种群,找到所有被支配数=0的个体 → 这就是F1,绝对不被任何个体支配的最优解
for
(
Chromosome
chromosome
:
population
)
{
if
(
chromosome
==
null
)
continue
;
int
count
=
dominatedCount
.
getOrDefault
(
chromosome
,
0
);
if
(
count
==
0
)
{
firstFront
.
add
(
chromosome
);
}
}
fronts
.
add
(
firstFront
);
boolean
[]
addedFlag
=
new
boolean
[
popSize
];
int
i
=
0
;
while
(
i
<
fronts
.
size
()
&&
!
fronts
.
get
(
i
).
isEmpty
())
{
List
<
Chromosome
>
currentFront
=
fronts
.
get
(
i
);
List
<
Chromosome
>
nextFront
=
new
ArrayList
<>();
Arrays
.
fill
(
addedFlag
,
false
);
for
(
Chromosome
p
:
currentFront
)
{
if
(
p
==
null
)
continue
;
Integer
pIdxObj
=
chromosomeIndexMap
.
get
(
p
);
if
(
pIdxObj
==
null
||
pIdxObj
>=
popSize
||
pIdxObj
<
0
)
continue
;
int
pIdx
=
pIdxObj
;
// 拿到p能支配的所有q的下标,无空指针
List
<
Integer
>
qIdxList
=
dominanceMatrixArr
.
get
(
pIdx
);
for
(
int
qIdx
:
qIdxList
)
{
// 核心逻辑:被支配数-1
if
(
dominatedCounts
[
qIdx
]
<=
0
)
{
continue
;
}
dominatedCounts
[
qIdx
]--;
// 当被支配数=0时,加入下一个前沿,去重
if
(
dominatedCounts
[
qIdx
]
==
0
&&
!
addedFlag
[
qIdx
])
{
addedFlag
[
qIdx
]
=
true
;
nextFront
.
add
(
population
.
get
(
qIdx
));
}
}
}
// 把下一个前沿加入列表,继续循环
if
(!
nextFront
.
isEmpty
())
{
fronts
.
add
(
nextFront
);
}
i
++;
}
}
assignRankToSolutions
(
fronts
);
return
fronts
;
}
public
List
<
List
<
Chromosome
>>
parallelFastNonDominatedSort1
(
List
<
Chromosome
>
population
)
{
int
popSize
=
population
.
size
();
List
<
List
<
Chromosome
>>
fronts
=
new
ArrayList
<>();
// 步骤1:预处理 - 计算归一化目标值和加权目标值
preprocessObjectives
(
population
);
if
(
popSize
<=
taskCount
*
15
)
{
// 小规模种群直接串行 7*15
fronts
=
fastNonDominatedSort
(
population
);
}
else
{
int
chunkCount
=
Math
.
min
(
taskCount
,
popSize
);
// 步骤2:拆分种群为多个块,并行计算支配关系
List
<
List
<
Chromosome
>>
chunks
=
splitPopulation
(
population
,
chunkCount
);
ConcurrentHashMap
<
Chromosome
,
ConcurrentLinkedQueue
<
Chromosome
>>
dominanceMatrix
=
new
ConcurrentHashMap
<>();
ConcurrentHashMap
<
Chromosome
,
AtomicInteger
>
dominatedCount
=
new
ConcurrentHashMap
<>();
// 初始化字典
for
(
Chromosome
chromo
:
population
)
{
dominanceMatrix
.
putIfAbsent
(
chromo
,
new
ConcurrentLinkedQueue
<>());
dominatedCount
.
putIfAbsent
(
chromo
,
new
AtomicInteger
(
0
));
}
// 并行计算支配关系
chunks
.
parallelStream
().
forEach
(
chunk
->
{
for
(
Chromosome
p
:
chunk
)
{
...
...
@@ -84,6 +233,8 @@ public class NSGAIIUtils {
}
});
// 步骤3:生成前沿
List
<
Chromosome
>
front1
=
new
ArrayList
<>();
...
...
@@ -111,14 +262,18 @@ public class NSGAIIUtils {
}
i
++;
fronts
.
add
(
nextFront
);
fronts
.
add
(
nextFront
);
}
List
<
List
<
Chromosome
>>
fronts1
=
fastNonDominatedSort
(
population
);
}
assignRankToSolutions
(
fronts
);
return
fronts
;
}
/**
* 用Stream API为分层后的解批量赋值Rank
*/
...
...
@@ -220,10 +375,21 @@ public class NSGAIIUtils {
// 计算每个目标的最大/最小值
double
[]
minValues
=
new
double
[
kpisize
];
double
[]
maxValues
=
new
double
[
kpisize
];
// for (int i = 0; i < kpisize; i++) {
// final int idx = i;
// minValues[i] = population.stream().mapToDouble(c -> c.getObjectives()[idx]).min().orElse(0);
// maxValues[i] = population.stream().mapToDouble(c -> c.getObjectives()[idx]).max().orElse(0);
// }
for
(
int
i
=
0
;
i
<
kpisize
;
i
++)
{
final
int
idx
=
i
;
minValues
[
i
]
=
population
.
stream
().
mapToDouble
(
c
->
c
.
getObjectives
()[
idx
]).
min
().
orElse
(
0
);
maxValues
[
i
]
=
population
.
stream
().
mapToDouble
(
c
->
c
.
getObjectives
()[
idx
]).
max
().
orElse
(
0
);
minValues
[
i
]
=
Double
.
MAX_VALUE
;
maxValues
[
i
]
=
Double
.
MIN_VALUE
;
}
for
(
Chromosome
chromo
:
population
)
{
double
[]
obj
=
chromo
.
getObjectives
();
for
(
int
i
=
0
;
i
<
kpisize
;
i
++)
{
minValues
[
i
]
=
Math
.
min
(
minValues
[
i
],
obj
[
i
]);
maxValues
[
i
]
=
Math
.
max
(
maxValues
[
i
],
obj
[
i
]);
}
}
// 并行计算归一化和加权目标值
...
...
@@ -337,7 +503,7 @@ public class NSGAIIUtils {
}
}
if
(
popSize
>
taskCount
*
1
0
)
if
(
popSize
>
taskCount
*
1
5
)
{
// 对每个目标维度并行计算距离
IntStream
.
range
(
0
,
popSize
).
parallel
().
forEach
(
m
->
{
...
...
src/test/java/com/aps/demo/PlanResultServiceTest.java
View file @
dd36e456
...
...
@@ -39,7 +39,7 @@ public class PlanResultServiceTest {
// nsgaiiUtils.Test();
//planResultService.execute2("C5FB5EF2A7334A0A92F826F4937E1008");
// planResultService.execute2("726D4C1A712B4B1393175BD44B775B66");
planResultService
.
execute2
(
"
13CC1CF783CE40D7AE3264D09FAA6378
"
);
planResultService
.
execute2
(
"
265F24B6DF3C40E4B17D193B0CC8AAF2
"
);
// LocalDateTime t= LocalDateTime.of(2025, 11, 15, 6, 51, 11);
// List<Integer> opids=new ArrayList<>();BCA6FA43FFA444D3952CF8F6E1EA291B
// 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