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
111874b6
Commit
111874b6
authored
Apr 15, 2026
by
Tong Li
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化
parent
40085732
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
545 additions
and
158 deletions
+545
-158
RedisUtils.java
src/main/java/com/aps/common/util/redis/RedisUtils.java
+145
-15
Chromosome.java
src/main/java/com/aps/entity/Algorithm/Chromosome.java
+24
-24
FitnessCalculator.java
...ain/java/com/aps/service/Algorithm/FitnessCalculator.java
+20
-5
GeneticDecoder.java
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
+2
-1
GeneticOperations.java
...ain/java/com/aps/service/Algorithm/GeneticOperations.java
+202
-34
HillClimbing.java
src/main/java/com/aps/service/Algorithm/HillClimbing.java
+19
-6
HybridAlgorithm.java
src/main/java/com/aps/service/Algorithm/HybridAlgorithm.java
+20
-21
MaterialRequirementService.java
...com/aps/service/Algorithm/MaterialRequirementService.java
+10
-4
RoutingDataService.java
...in/java/com/aps/service/Algorithm/RoutingDataService.java
+1
-0
SimulatedAnnealing.java
...in/java/com/aps/service/Algorithm/SimulatedAnnealing.java
+37
-20
TabuSearch.java
src/main/java/com/aps/service/Algorithm/TabuSearch.java
+31
-14
VariableNeighborhoodSearch.java
...com/aps/service/Algorithm/VariableNeighborhoodSearch.java
+28
-11
PlanResultServiceTest.java
src/test/java/com/aps/demo/PlanResultServiceTest.java
+6
-3
No files found.
src/main/java/com/aps/common/util/redis/RedisUtils.java
View file @
111874b6
...
@@ -45,6 +45,16 @@ public class RedisUtils {
...
@@ -45,6 +45,16 @@ public class RedisUtils {
@Getter
@Getter
public
static
String
prefix
=
"aps:"
;
public
static
String
prefix
=
"aps:"
;
/**
* 最大重试次数
*/
private
static
final
int
MAX_RETRY_TIMES
=
3
;
/**
* 重试间隔(毫秒)
*/
private
static
final
long
RETRY_DELAY_MS
=
500
;
/**
/**
* 设置redis前缀进行操作
* 设置redis前缀进行操作
*
*
...
@@ -62,7 +72,7 @@ public class RedisUtils {
...
@@ -62,7 +72,7 @@ public class RedisUtils {
* @return: boolean
* @return: boolean
*/
*/
public
boolean
exists
(
final
String
key
)
{
public
boolean
exists
(
final
String
key
)
{
return
redisTemplate
.
hasKey
(
prefix
+
key
);
return
executeWithRetry
(()
->
redisTemplate
.
hasKey
(
prefix
+
key
),
"exists("
+
key
+
")"
);
}
}
public
Set
<
String
>
keys
(
final
String
pattern
)
{
public
Set
<
String
>
keys
(
final
String
pattern
)
{
...
@@ -164,13 +174,15 @@ public class RedisUtils {
...
@@ -164,13 +174,15 @@ public class RedisUtils {
* @param key 可以传一个值 或多个
* @param key 可以传一个值 或多个
*/
*/
public
void
del
(
String
...
key
)
{
public
void
del
(
String
...
key
)
{
if
(
key
!=
null
&&
key
.
length
>
0
)
{
executeWithRetry
(()
->
{
if
(
key
.
length
==
1
)
{
if
(
key
!=
null
&&
key
.
length
>
0
)
{
redisTemplate
.
delete
(
prefix
+
key
[
0
]);
if
(
key
.
length
==
1
)
{
}
else
{
redisTemplate
.
delete
(
prefix
+
key
[
0
]);
redisTemplate
.
delete
(
Arrays
.
asList
(
key
).
stream
().
map
(
e
->
prefix
+
e
).
collect
(
Collectors
.
toList
()));
}
else
{
redisTemplate
.
delete
(
Arrays
.
asList
(
key
).
stream
().
map
(
e
->
prefix
+
e
).
collect
(
Collectors
.
toList
()));
}
}
}
}
}
,
"del("
+
Arrays
.
toString
(
key
)
+
")"
);
}
}
public
void
del
(
Collection
<
String
>
keys
)
{
public
void
del
(
Collection
<
String
>
keys
)
{
...
@@ -184,7 +196,7 @@ public class RedisUtils {
...
@@ -184,7 +196,7 @@ public class RedisUtils {
* @return 值
* @return 值
*/
*/
public
Object
get
(
String
key
)
{
public
Object
get
(
String
key
)
{
return
key
==
null
?
null
:
redisTemplate
.
opsForValue
().
get
(
prefix
+
key
);
return
executeWithRetry
(()
->
key
==
null
?
null
:
redisTemplate
.
opsForValue
().
get
(
prefix
+
key
),
"get("
+
key
+
")"
);
}
}
/**
/**
...
@@ -207,13 +219,15 @@ public class RedisUtils {
...
@@ -207,13 +219,15 @@ public class RedisUtils {
* @return true成功 false失败
* @return true成功 false失败
*/
*/
public
Boolean
set
(
String
key
,
Object
value
)
{
public
Boolean
set
(
String
key
,
Object
value
)
{
try
{
return
executeWithRetry
(()
->
{
redisTemplate
.
opsForValue
().
set
(
prefix
+
key
,
value
);
try
{
return
true
;
redisTemplate
.
opsForValue
().
set
(
prefix
+
key
,
value
);
}
catch
(
Exception
e
)
{
return
true
;
log
.
error
(
"Exception: {}"
,
e
.
getMessage
());
}
catch
(
Exception
e
)
{
return
false
;
log
.
error
(
"Exception: {}"
,
e
.
getMessage
());
}
return
false
;
}
},
"set("
+
key
+
")"
);
}
}
/**
/**
...
@@ -814,4 +828,120 @@ public class RedisUtils {
...
@@ -814,4 +828,120 @@ public class RedisUtils {
redisLockUtil
.
releaseLock
(
prefix
+
key
,
""
);
redisLockUtil
.
releaseLock
(
prefix
+
key
,
""
);
}
}
/**
* 通用重试执行器:用于处理 Redis 连接异常
* @param operation Redis 操作函数
* @param operationName 操作名称(用于日志)
* @param <T> 返回值类型
* @return 操作结果
*/
private
<
T
>
T
executeWithRetry
(
java
.
util
.
function
.
Supplier
<
T
>
operation
,
String
operationName
)
{
Exception
lastException
=
null
;
for
(
int
attempt
=
1
;
attempt
<=
MAX_RETRY_TIMES
;
attempt
++)
{
try
{
if
(
attempt
>
1
)
{
log
.
warn
(
"Redis 操作重试 {}/{}: {}"
,
attempt
,
MAX_RETRY_TIMES
,
operationName
);
}
return
operation
.
get
();
}
catch
(
Exception
e
)
{
lastException
=
e
;
log
.
error
(
"Redis 操作失败 {}/{}: {}, 错误: {}"
,
attempt
,
MAX_RETRY_TIMES
,
operationName
,
e
.
getMessage
());
if
(
attempt
<
MAX_RETRY_TIMES
)
{
try
{
log
.
warn
(
"等待 {}ms 后重试..."
,
RETRY_DELAY_MS
);
Thread
.
sleep
(
RETRY_DELAY_MS
);
}
catch
(
InterruptedException
ie
)
{
Thread
.
currentThread
().
interrupt
();
throw
new
RuntimeException
(
"Redis 操作重试被中断"
,
ie
);
}
}
}
}
throw
new
RuntimeException
(
"Redis 操作失败,已重试 "
+
MAX_RETRY_TIMES
+
" 次: "
+
operationName
,
lastException
);
}
/**
* 无返回值的重试执行器
* @param operation Redis 操作函数
* @param operationName 操作名称(用于日志)
*/
private
void
executeWithRetry
(
Runnable
operation
,
String
operationName
)
{
executeWithRetry
(()
->
{
operation
.
run
();
return
null
;
},
operationName
);
}
// ==================== 以下是添加了重试机制的方法 ====================
/**
* 判断是否有这个缓存key(带重试)
* @param key 缓存key
* @return boolean
*/
public
boolean
existsWithRetry
(
final
String
key
)
{
return
executeWithRetry
(()
->
exists
(
key
),
"exists("
+
key
+
")"
);
}
/**
* 普通缓存获取(带重试)
* @param key 键
* @return 值
*/
public
Object
getWithRetry
(
String
key
)
{
return
executeWithRetry
(()
->
get
(
key
),
"get("
+
key
+
")"
);
}
/**
* 普通缓存放入(带重试)
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public
Boolean
setWithRetry
(
String
key
,
Object
value
)
{
return
executeWithRetry
(()
->
set
(
key
,
value
),
"set("
+
key
+
")"
);
}
/**
* 普通缓存放入并设置时间(带重试)
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return true成功 false失败
*/
public
Boolean
setWithRetry
(
String
key
,
Object
value
,
Long
time
)
{
return
executeWithRetry
(()
->
set
(
key
,
value
,
time
),
"set("
+
key
+
", "
+
time
+
"s)"
);
}
/**
* 删除缓存(带重试)
* @param key 可以传一个值 或多个
*/
public
void
delWithRetry
(
String
...
key
)
{
executeWithRetry
(()
->
del
(
key
),
"del("
+
Arrays
.
toString
(
key
)
+
")"
);
}
/**
* HashGet(带重试)
* @param key 键 不能为 null
* @param item 项 不能为 null
* @return 值
*/
public
Object
hgetWithRetry
(
String
key
,
String
item
)
{
return
executeWithRetry
(()
->
hget
(
key
,
item
),
"hget("
+
key
+
", "
+
item
+
")"
);
}
/**
* HashSet(带重试)
* @param key 键
* @param map 对应多个键值
* @return true成功 false失败
*/
public
Boolean
hmsetWithRetry
(
String
key
,
Map
<
String
,
Object
>
map
)
{
return
executeWithRetry
(()
->
hmset
(
key
,
map
),
"hmset("
+
key
+
")"
);
}
}
}
src/main/java/com/aps/entity/Algorithm/Chromosome.java
View file @
111874b6
...
@@ -116,53 +116,53 @@ public class Chromosome {
...
@@ -116,53 +116,53 @@ public class Chromosome {
private
List
<
GlobalOperationInfo
>
globalOpList
;
private
List
<
GlobalOperationInfo
>
globalOpList
=
new
ArrayList
<>()
;
private
CopyOnWriteArrayList
<
Entry
>
allOperations
;
private
CopyOnWriteArrayList
<
Entry
>
allOperations
=
new
CopyOnWriteArrayList
<>()
;
private
CopyOnWriteArrayList
<
Order
>
orders
;
private
CopyOnWriteArrayList
<
Order
>
orders
=
new
CopyOnWriteArrayList
<>()
;
private
List
<
Machine
>
InitMachines
;
private
List
<
Machine
>
InitMachines
=
new
ArrayList
<>()
;
private
List
<
OrderMaterialRequirement
>
orderMaterials
;
private
List
<
OrderMaterialRequirement
>
orderMaterials
=
new
ArrayList
<>()
;
private
CopyOnWriteArrayList
<
GroupResult
>
OperatRel
;
private
CopyOnWriteArrayList
<
GroupResult
>
OperatRel
=
new
CopyOnWriteArrayList
<>()
;
private
ObjectiveWeights
objectiveWeights
;
private
ObjectiveWeights
objectiveWeights
;
private
List
<
Material
>
materials
;
private
List
<
Material
>
materials
=
new
ArrayList
<>()
;
private
List
<
String
>
materialIds
;
private
List
<
String
>
materialIds
=
new
ArrayList
<>()
;
/*
/*
* 最早完工时间(最小化) 最小化总加工时间 最小总换型时间
* 最早完工时间(最小化) 最小化总加工时间 最小总换型时间
*/
*/
private
double
[]
Objectives
;
// 多目标值:[Makespan, TotalFlowTime, TotalChangeover, LoadStd, Delay]
private
double
[]
Objectives
=
new
double
[
0
]
;
// 多目标值:[Makespan, TotalFlowTime, TotalChangeover, LoadStd, Delay]
private
double
[]
MaxObjectives
;
//
private
double
[]
MaxObjectives
=
new
double
[
0
]
;
//
private
double
[]
MinObjectives
;
//
private
double
[]
MinObjectives
=
new
double
[
0
]
;
//
private
int
Rank
;
// 非支配排序等级(1最优)
private
int
Rank
;
// 非支配排序等级(1最优)
private
double
CrowdingDistance
=
0
;
// 拥挤距离 越小越优
private
double
CrowdingDistance
=
0
;
// 拥挤距离 越小越优
/*
/*
*(Objectives - min) / (max - min);
*(Objectives - min) / (max - min);
*/
*/
private
double
[]
WeightedObjectives
;
//越靠近1越优
private
double
[]
WeightedObjectives
=
new
double
[
0
]
;
//越靠近1越优
private
double
WeightedObjective
=
0
;
// 加权目标值(用于自定义权重)
private
double
WeightedObjective
=
0
;
// 加权目标值(用于自定义权重)
/// <summary>
/// <summary>
/// 适应度值
/// 适应度值
/// </summary>
/// </summary>
private
double
[]
fitnessLevel
;
private
double
[]
fitnessLevel
=
new
double
[
0
]
;
/// <summary>
/// <summary>
/// 适应度值
/// 适应度值
/// </summary>
/// </summary>
private
double
Fitness
;
private
double
Fitness
=
0.0
;
/// <summary>
/// <summary>
/// 机器
/// 机器
/// </summary>
/// </summary>
private
List
<
Machine
>
Machines
;
private
List
<
Machine
>
Machines
=
new
ArrayList
<>()
;
/// <summary>
/// <summary>
/// 解码后的调度结果
/// 解码后的调度结果
/// </summary>
/// </summary>
private
CopyOnWriteArrayList
<
GAScheduleResult
>
Result
;
private
CopyOnWriteArrayList
<
GAScheduleResult
>
Result
=
new
CopyOnWriteArrayList
<>()
;
/// <summary>
/// <summary>
/// 解码后的调度结果
/// 解码后的调度结果
...
@@ -172,33 +172,33 @@ public class Chromosome {
...
@@ -172,33 +172,33 @@ public class Chromosome {
/// <summary>
/// <summary>
/// 最早完工时间
/// 最早完工时间
/// </summary>
/// </summary>
private
double
Makespan
;
private
double
Makespan
=
0.0
;
/// <summary>
/// <summary>
/// 总流程时间
/// 总流程时间
/// </summary>
/// </summary>
private
double
TotalFlowTime
;
private
double
TotalFlowTime
=
0.0
;
/// <summary>
/// <summary>
/// 总换型时间
/// 总换型时间
/// </summary>
/// </summary>
private
double
TotalChangeoverTime
;
private
double
TotalChangeoverTime
=
0.0
;
/// <summary>
/// <summary>
/// 机器负载标准差(越小越均衡)
/// 机器负载标准差(越小越均衡)
/// </summary>
/// </summary>
private
double
MachineLoadStd
;
private
double
MachineLoadStd
=
0.0
;
/// <summary>
/// <summary>
/// 交付期延迟时间
/// 交付期延迟时间
/// </summary>
/// </summary>
private
double
DelayTime
;
private
double
DelayTime
=
0.0
;
private
String
ScenarioID
;
private
String
ScenarioID
=
""
;
private
String
ScenarioName
;
private
String
ScenarioName
=
""
;
private
LocalDateTime
BaseTime
;
// 当前基准时间
private
LocalDateTime
BaseTime
;
// 当前基准时间
private
List
<
Integer
>
reOrderids
=
new
ArrayList
<>();
private
List
<
Integer
>
reOrderids
=
new
ArrayList
<>();
...
...
src/main/java/com/aps/service/Algorithm/FitnessCalculator.java
View file @
111874b6
...
@@ -165,14 +165,29 @@ public class FitnessCalculator {
...
@@ -165,14 +165,29 @@ public class FitnessCalculator {
* 比较两个染色体的优劣(基于fitnessLevel多层次比较)
* 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/
*/
public
boolean
isBetter
(
Chromosome
c1
,
Chromosome
c2
)
{
public
boolean
isBetter
(
Chromosome
c1
,
Chromosome
c2
)
{
for
(
int
i
=
0
;
i
<
c1
.
getFitnessLevel
().
length
;
i
++)
{
double
[]
fitness1
=
c1
.
getFitnessLevel
();
double
[]
Fitness1
=
c1
.
getFitnessLevel
();
double
[]
fitness2
=
c2
.
getFitnessLevel
();
double
[]
Fitness2
=
c2
.
getFitnessLevel
();
if
(
Fitness1
[
i
]
>
Fitness2
[
i
])
{
// 处理null或空数组的情况
if
(
fitness1
==
null
||
fitness1
.
length
==
0
)
{
return
false
;
// c1没有fitness,认为c2更优
}
if
(
fitness2
==
null
||
fitness2
.
length
==
0
)
{
return
true
;
// c2没有fitness,认为c1更优
}
// 取两个数组中较小的长度进行比较
int
minLength
=
Math
.
min
(
fitness1
.
length
,
fitness2
.
length
);
for
(
int
i
=
0
;
i
<
minLength
;
i
++)
{
if
(
fitness1
[
i
]
>
fitness2
[
i
])
{
return
true
;
return
true
;
}
else
if
(
fitness1
[
i
]
<
fitness2
[
i
])
{
return
false
;
}
}
}
}
return
false
;
// 如果前面都相等,长度更长的视为更优(有更多维度)
return
fitness1
.
length
>
fitness2
.
length
;
}
}
...
...
src/main/java/com/aps/service/Algorithm/GeneticDecoder.java
View file @
111874b6
...
@@ -193,7 +193,8 @@ public class GeneticDecoder {
...
@@ -193,7 +193,8 @@ public class GeneticDecoder {
// 缓存命中:复用缓存结果
// 缓存命中:复用缓存结果
// 赋值给染色体
// 赋值给染色体
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(cachedResult.getInitMachines(),Machine.class));
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(cachedResult.getInitMachines(),Machine.class));
chromosome
.
setFitnessLevel
(
cachedResult
.
getFitnessLevel
());
chromosome
.
setFitness
(
cachedResult
.
getFitness
());
chromosome
.
setObjectives
(
cachedResult
.
getObjectives
());
chromosome
.
setObjectives
(
cachedResult
.
getObjectives
());
chromosome
.
setMakespan
(
cachedResult
.
getMakespan
());
chromosome
.
setMakespan
(
cachedResult
.
getMakespan
());
chromosome
.
setTotalFlowTime
(
cachedResult
.
getTotalFlowTime
());
chromosome
.
setTotalFlowTime
(
cachedResult
.
getTotalFlowTime
());
...
...
src/main/java/com/aps/service/Algorithm/GeneticOperations.java
View file @
111874b6
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/service/Algorithm/HillClimbing.java
View file @
111874b6
...
@@ -643,16 +643,29 @@ public class HillClimbing {
...
@@ -643,16 +643,29 @@ public class HillClimbing {
/**
/**
* 比较两个染色体的优劣
* 比较两个染色体的优劣
*/
*/
private
boolean
isBetter
(
Chromosome
c1
,
Chromosome
c2
)
{
public
boolean
isBetter
(
Chromosome
c1
,
Chromosome
c2
)
{
double
[]
fitness1
=
c1
.
getFitnessLevel
();
double
[]
fitness2
=
c2
.
getFitnessLevel
();
for
(
int
i
=
0
;
i
<
c1
.
getFitnessLevel
().
length
;
i
++)
{
// 处理null或空数组的情况
double
[]
Fitness1
=
c1
.
getFitnessLevel
();
if
(
fitness1
==
null
||
fitness1
.
length
==
0
)
{
double
[]
Fitness2
=
c2
.
getFitnessLevel
();
return
false
;
// c1没有fitness,认为c2更优
if
(
Fitness1
[
i
]
>
Fitness2
[
i
])
{
}
if
(
fitness2
==
null
||
fitness2
.
length
==
0
)
{
return
true
;
// c2没有fitness,认为c1更优
}
// 取两个数组中较小的长度进行比较
int
minLength
=
Math
.
min
(
fitness1
.
length
,
fitness2
.
length
);
for
(
int
i
=
0
;
i
<
minLength
;
i
++)
{
if
(
fitness1
[
i
]
>
fitness2
[
i
])
{
return
true
;
return
true
;
}
else
if
(
fitness1
[
i
]
<
fitness2
[
i
])
{
return
false
;
}
}
}
}
return
false
;
// 如果前面都相等,长度更长的视为更优(有更多维度)
return
fitness1
.
length
>
fitness2
.
length
;
}
}
}
}
\ No newline at end of file
src/main/java/com/aps/service/Algorithm/HybridAlgorithm.java
View file @
111874b6
...
@@ -104,7 +104,7 @@ public class HybridAlgorithm {
...
@@ -104,7 +104,7 @@ public class HybridAlgorithm {
GeneticOperations
geneticOps
=
new
GeneticOperations
(
_GlobalParam
,
allOperations
,
param
);
GeneticOperations
geneticOps
=
new
GeneticOperations
(
_GlobalParam
,
allOperations
,
param
);
int
opcount
=
allOperations
.
size
();
int
opcount
=
allOperations
.
size
();
// 预生成全局工序列表(所有初始化方法共享同一顺序)
// 预生成全局工序列表(所有初始化方法共享同一顺序)
List
<
GlobalOperationInfo
>
globalOpList
=
initialization
.
generateGlobalOpList
();
List
<
GlobalOperationInfo
>
globalOpList
=
new
ArrayList
<>();
//
initialization.generateGlobalOpList();
// 初始化变邻域搜索
// 初始化变邻域搜索
_vns
=
new
VariableNeighborhoodSearch
(
allOperations
,
orders
,
materials
,
_entryRel
,
_fitnessCalculator
);
_vns
=
new
VariableNeighborhoodSearch
(
allOperations
,
orders
,
materials
,
_entryRel
,
_fitnessCalculator
);
_hillClimbing
=
new
HillClimbing
(
allOperations
,
orders
,
materials
,
_entryRel
,
_fitnessCalculator
);
_hillClimbing
=
new
HillClimbing
(
allOperations
,
orders
,
materials
,
_entryRel
,
_fitnessCalculator
);
...
@@ -137,11 +137,13 @@ int opcount=allOperations.size();
...
@@ -137,11 +137,13 @@ int opcount=allOperations.size();
// return getBestChromosome(population.get(0), param.getBaseTime(), starttime);
// return getBestChromosome(population.get(0), param.getBaseTime(), starttime);
// 步骤2:对初始种群进行爬山法局部优化
// 步骤2:对初始种群进行爬山法局部优化
if
(
opcount
<
20
)
{
if
(
opcount
<
100
)
{
Chromosome
best
=
population
.
get
(
0
);
geneticOps
.
DelOrder
(
best
);
FileHelper
.
writeLogFile
(
"爬山法局部优化-----------开始-------"
);
FileHelper
.
writeLogFile
(
"爬山法局部优化-----------开始-------"
);
GeneticDecoder
hillClimbingDecoder
=
new
GeneticDecoder
(
_GlobalParam
,
param
.
getBaseTime
(),
machines
,
orders
,
materials
,
machineScheduler
,
materialRequirementService
,
sceneId
);
GeneticDecoder
hillClimbingDecoder
=
new
GeneticDecoder
(
_GlobalParam
,
param
.
getBaseTime
(),
machines
,
orders
,
materials
,
machineScheduler
,
materialRequirementService
,
sceneId
);
Chromosome
optimized
=
_hillClimbing
.
search
(
population
.
get
(
0
),
hillClimbingDecoder
,
machines
);
Chromosome
optimized
=
_hillClimbing
.
search
All
(
best
,
machines
,
hillClimbingDecoder
);
FileHelper
.
writeLogFile
(
"爬山法局部优化-----------结束-------"
);
FileHelper
.
writeLogFile
(
"爬山法局部优化-----------结束-------"
);
return
getBestChromosome
(
optimized
,
param
.
getBaseTime
(),
starttime
);
return
getBestChromosome
(
optimized
,
param
.
getBaseTime
(),
starttime
);
}
}
...
@@ -158,14 +160,17 @@ int opcount=allOperations.size();
...
@@ -158,14 +160,17 @@ int opcount=allOperations.size();
if
(
opcount
<
800
)
{
if
(
opcount
<
800
)
{
Chromosome
best
=
population
.
get
(
0
);
geneticOps
.
DelOrder
(
best
);
FileHelper
.
writeLogFile
(
"模拟退火+爬山法优化-----------开始-------"
);
FileHelper
.
writeLogFile
(
"模拟退火+爬山法优化-----------开始-------"
);
Chromosome
saHcOptimized
=
_simulatedAnnealing
.
searchWithHillClimbing
(
population
.
get
(
0
)
,
_vns
,
saDecoder1
,
machines
);
Chromosome
saHcOptimized
=
_simulatedAnnealing
.
searchWithHillClimbing
(
best
,
_vns
,
saDecoder1
,
machines
);
FileHelper
.
writeLogFile
(
"模拟退火+爬山法优化-----------结束-------"
);
FileHelper
.
writeLogFile
(
"模拟退火+爬山法优化-----------结束-------"
);
return
getBestChromosome
(
saHcOptimized
,
param
.
getBaseTime
(),
starttime
);
return
getBestChromosome
(
saHcOptimized
,
param
.
getBaseTime
(),
starttime
);
}
}
if
(
opcount
>=
800
)
{
if
(
opcount
>=
800
)
{
Chromosome
best
=
population
.
get
(
0
);
Chromosome
best
=
population
.
get
(
0
);
geneticOps
.
DelOrder
(
best
);
best
=
_simulatedAnnealing
.
search
(
best
,
_tabuSearch
,
_vns
,
saDecoder1
,
machines
);
best
=
_simulatedAnnealing
.
search
(
best
,
_tabuSearch
,
_vns
,
saDecoder1
,
machines
);
best
=
_vns
.
search
(
best
,
vnsDecoder1
,
machines
);
best
=
_vns
.
search
(
best
,
vnsDecoder1
,
machines
);
best
=
_tabuSearch
.
search
(
best
,
_vns
,
tabuDecoder1
,
machines
);
best
=
_tabuSearch
.
search
(
best
,
_vns
,
tabuDecoder1
,
machines
);
...
@@ -194,6 +199,7 @@ int opcount=allOperations.size();
...
@@ -194,6 +199,7 @@ int opcount=allOperations.size();
int
maxNoImprove
=
10
;
int
maxNoImprove
=
10
;
// 步骤2:迭代进化
// 步骤2:迭代进化
FileHelper
.
writeLogFile
(
"迭代进化-----------开始-------"
+
param
.
getMaxIterations
());
FileHelper
.
writeLogFile
(
"迭代进化-----------开始-------"
+
param
.
getMaxIterations
());
for
(
int
iter
=
0
;
iter
<
param
.
getMaxIterations
();
iter
++)
{
for
(
int
iter
=
0
;
iter
<
param
.
getMaxIterations
();
iter
++)
{
// 解码并计算适应度
// 解码并计算适应度
FileHelper
.
writeLogFile
(
"迭代进化------"
+
iter
+
"-----开始-------"
);
FileHelper
.
writeLogFile
(
"迭代进化------"
+
iter
+
"-----开始-------"
);
...
@@ -212,7 +218,7 @@ int opcount=allOperations.size();
...
@@ -212,7 +218,7 @@ int opcount=allOperations.size();
FileHelper
.
writeLogFile
(
"选择操作-----------开始-------"
);
FileHelper
.
writeLogFile
(
"选择操作-----------开始-------"
);
// 选择操作
// 选择操作
List
<
Chromosome
>
selected
=
geneticOps
.
tournamentSelection
(
population
);
List
<
Chromosome
>
selected
=
geneticOps
.
tournamentSelection
2
(
population
);
FileHelper
.
writeLogFile
(
"选择操作-----------结束-------"
);
FileHelper
.
writeLogFile
(
"选择操作-----------结束-------"
);
...
@@ -230,13 +236,13 @@ int opcount=allOperations.size();
...
@@ -230,13 +236,13 @@ int opcount=allOperations.size();
Chromosome
parent2
=
selected
.
get
(
rnd
.
nextInt
(
selected
.
size
()));
Chromosome
parent2
=
selected
.
get
(
rnd
.
nextInt
(
selected
.
size
()));
// 交叉
// 交叉
Chromosome
child
=
parent1
;
Chromosome
child
=
parent1
;
//
if (rnd.nextDouble() < param.getCrossoverProb()) {
if
(
rnd
.
nextDouble
()
<
param
.
getCrossoverProb
())
{
//
// 假设PoxCrossover返回包含两个子染色体的数组
// 假设PoxCrossover返回包含两个子染色体的数组
//
Pair<Chromosome, Chromosome> children = geneticOps.poxCrossover(parent1, parent2, ordercount);
Pair
<
Chromosome
,
Chromosome
>
children
=
geneticOps
.
poxCrossover
(
parent1
,
parent2
,
ordercount
);
//
child=children.getFirst();
child
=
children
.
getFirst
();
//
initDataToChromosome(child,param, allOperations,globalOpList);
//
initDataToChromosome(child,param, allOperations,globalOpList);
//
child.setID(UUID.randomUUID().toString());
child
.
setID
(
UUID
.
randomUUID
().
toString
());
//
}
}
// // 变异
// // 变异
// if (rnd.nextDouble() < param.getMutationProb()) {
// if (rnd.nextDouble() < param.getMutationProb()) {
// geneticOps.mutate(child, globalOpList);
// geneticOps.mutate(child, globalOpList);
...
@@ -249,7 +255,7 @@ int opcount=allOperations.size();
...
@@ -249,7 +255,7 @@ int opcount=allOperations.size();
newPopulation
.
add
(
child
);
newPopulation
.
add
(
child
);
FileHelper
.
writeLogFile
(
"交叉-----------结束-------"
+
n
);
FileHelper
.
writeLogFile
(
"交叉-----------结束-------"
+
n
);
n
++;
}
}
population
=
chromosomeDistinctByObjectives
(
newPopulation
);;
population
=
chromosomeDistinctByObjectives
(
newPopulation
);;
...
@@ -375,14 +381,7 @@ int opcount=allOperations.size();
...
@@ -375,14 +381,7 @@ int opcount=allOperations.size();
* 比较两个染色体的优劣(基于fitnessLevel多层次比较)
* 比较两个染色体的优劣(基于fitnessLevel多层次比较)
*/
*/
private
boolean
isBetter
(
Chromosome
c1
,
Chromosome
c2
)
{
private
boolean
isBetter
(
Chromosome
c1
,
Chromosome
c2
)
{
for
(
int
i
=
0
;
i
<
c1
.
getFitnessLevel
().
length
;
i
++)
{
return
_fitnessCalculator
.
isBetter
(
c1
,
c2
);
double
[]
Fitness1
=
c1
.
getFitnessLevel
();
double
[]
Fitness2
=
c2
.
getFitnessLevel
();
if
(
Fitness1
[
i
]
>
Fitness2
[
i
])
{
return
true
;
}
}
return
false
;
}
}
...
...
src/main/java/com/aps/service/Algorithm/MaterialRequirementService.java
View file @
111874b6
...
@@ -149,10 +149,13 @@ public class MaterialRequirementService {
...
@@ -149,10 +149,13 @@ public class MaterialRequirementService {
if
(
MaterialRequirements
!=
null
)
if
(
MaterialRequirements
!=
null
)
{
{
List
<
Entry
>
Operations
=
_allOperations
.
stream
()
List
<
Entry
>
Operations
=
_allOperations
.
stream
()
.
filter
(
t
->
t
.
getOrderId
()
!=
null
)
.
filter
(
t
->
t
.
getOrderId
().
equals
(
orderId
))
.
filter
(
t
->
t
.
getOrderId
().
equals
(
orderId
))
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
if
(
Operations
==
null
)
{
int
i
=
1
;
}
for
(
Entry
operation
:
Operations
)
{
for
(
Entry
operation
:
Operations
)
{
List
<
Routingsupporting
>
MaterialRequirement_entrys
=
routingsupportings
.
stream
()
List
<
Routingsupporting
>
MaterialRequirement_entrys
=
routingsupportings
.
stream
()
.
filter
(
t
->
t
.
getRoutingDetailId
().
equals
(
operation
.
getRoutingDetailId
()))
.
filter
(
t
->
t
.
getRoutingDetailId
().
equals
(
operation
.
getRoutingDetailId
()))
...
@@ -524,7 +527,10 @@ public class MaterialRequirementService {
...
@@ -524,7 +527,10 @@ public class MaterialRequirementService {
for
(
Integer
groupId
:
operationSequencing
)
for
(
Integer
groupId
:
operationSequencing
)
{
{
Order
demand
=
orders
.
stream
().
filter
(
t
->
t
.
getId
()==
groupId
).
findFirst
().
orElse
(
null
);
Order
demand
=
orders
.
stream
().
filter
(
t
->
t
.
getId
()==
groupId
).
findFirst
().
orElse
(
null
);
if
(
demand
==
null
)
{
continue
;
}
if
(
demand
.
getFinishOrderId
()
!=
null
&&
!
demand
.
getFinishOrderId
().
isEmpty
())
{
if
(
demand
.
getFinishOrderId
()
!=
null
&&
!
demand
.
getFinishOrderId
().
isEmpty
())
{
continue
;
continue
;
}
}
...
@@ -606,7 +612,7 @@ public class MaterialRequirementService {
...
@@ -606,7 +612,7 @@ public class MaterialRequirementService {
List
<
Entry
>
_allOperations
=
chromosome
.
getAllOperations
();
List
<
Entry
>
_allOperations
=
chromosome
.
getAllOperations
();
List
<
Entry
>
Operations
=
_allOperations
.
stream
()
List
<
Entry
>
Operations
=
_allOperations
.
stream
()
.
filter
(
t
->
t
.
getOrderId
()
!=
null
)
.
filter
(
t
->
t
.
getOrderId
().
equals
(
childorderId
))
.
filter
(
t
->
t
.
getOrderId
().
equals
(
childorderId
))
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
...
...
src/main/java/com/aps/service/Algorithm/RoutingDataService.java
View file @
111874b6
...
@@ -232,6 +232,7 @@ public class RoutingDataService {
...
@@ -232,6 +232,7 @@ public class RoutingDataService {
entry
.
setProductCode
(
order
.
getMaterialCode
());
entry
.
setProductCode
(
order
.
getMaterialCode
());
entry
.
setProductName
(
order
.
getMaterialName
());
entry
.
setProductName
(
order
.
getMaterialName
());
entry
.
setPriority
(
order
.
getActualPriority
());
entry
.
setPriority
(
order
.
getActualPriority
());
order
.
setId
(
entry
.
getGroupId
());
order
.
setId
(
entry
.
getGroupId
());
}
}
List
<
ProdEquipment
>
Equipments
=
ProdEquipments
.
stream
()
List
<
ProdEquipment
>
Equipments
=
ProdEquipments
.
stream
()
...
...
src/main/java/com/aps/service/Algorithm/SimulatedAnnealing.java
View file @
111874b6
...
@@ -106,13 +106,13 @@ public class SimulatedAnnealing {
...
@@ -106,13 +106,13 @@ public class SimulatedAnnealing {
// log("模拟退火+爬山法 - 初始化解码完成");
// log("模拟退火+爬山法 - 初始化解码完成");
// 初始化温度
// 初始化温度
(优化:更快收敛)
double
temperature
=
100.0
;
double
temperature
=
100.0
;
double
coolingRate
=
0.9
5
;
double
coolingRate
=
0.9
0
;
// 优化:降温更快
double
temperatureThreshold
=
1.0
;
double
temperatureThreshold
=
5.0
;
// 优化:温度阈值更高
int
maxIterations
=
300
;
int
maxIterations
=
100
;
// 优化:从300减少到100次
int
noImproveCount
=
0
;
int
noImproveCount
=
0
;
int
maxNoImprove
=
30
;
// 降低最大无改进次数
int
maxNoImprove
=
15
;
// 优化:从30减少到15次
// 新增:改进率监控参数
// 新增:改进率监控参数
int
stagnantWindow
=
15
;
// 观察窗口大小
int
stagnantWindow
=
15
;
// 观察窗口大小
...
@@ -239,13 +239,13 @@ public class SimulatedAnnealing {
...
@@ -239,13 +239,13 @@ public class SimulatedAnnealing {
// log("模拟退火+爬山法 - 初始化解码完成");
// log("模拟退火+爬山法 - 初始化解码完成");
// 初始化温度
// 初始化温度
(优化:更快收敛)
double
temperature
=
100.0
;
double
temperature
=
100.0
;
double
coolingRate
=
0.9
5
;
double
coolingRate
=
0.9
0
;
// 优化:降温更快
double
temperatureThreshold
=
1.0
;
double
temperatureThreshold
=
5.0
;
// 优化:温度阈值更高
int
maxIterations
=
300
;
int
maxIterations
=
80
;
// 优化:从300减少到80次
int
noImproveCount
=
0
;
int
noImproveCount
=
0
;
int
maxNoImprove
=
20
;
// 降低最大无改进次数,更快提前结束
int
maxNoImprove
=
10
;
// 优化:从20减少到10次
// 新增:改进率监控参数
// 新增:改进率监控参数
int
stagnantWindow
=
10
;
// 观察窗口大小
int
stagnantWindow
=
10
;
// 观察窗口大小
...
@@ -361,9 +361,16 @@ public class SimulatedAnnealing {
...
@@ -361,9 +361,16 @@ public class SimulatedAnnealing {
StringBuilder
sb
=
new
StringBuilder
(
"模拟退火 - 改进详情: 迭代"
+
iteration
+
", "
);
StringBuilder
sb
=
new
StringBuilder
(
"模拟退火 - 改进详情: 迭代"
+
iteration
+
", "
);
double
[]
currentFitness
=
best
.
getFitnessLevel
();
double
[]
currentFitness
=
best
.
getFitnessLevel
();
for
(
int
i
=
0
;
i
<
currentFitness
.
length
;
i
++)
{
// 处理null或空数组的情况
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
if
(
currentFitness
!=
null
&&
currentFitness
.
length
>
0
&&
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(+%.4f) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
improvement
));
initialFitnessLevel
!=
null
&&
initialFitnessLevel
.
length
>
0
)
{
int
minLength
=
Math
.
min
(
currentFitness
.
length
,
initialFitnessLevel
.
length
);
for
(
int
i
=
0
;
i
<
minLength
;
i
++)
{
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(+%.4f) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
improvement
));
}
}
else
{
sb
.
append
(
"(KPI数据不可用) "
);
}
}
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
...
@@ -392,10 +399,17 @@ public class SimulatedAnnealing {
...
@@ -392,10 +399,17 @@ public class SimulatedAnnealing {
sb
.
append
(
String
.
format
(
"总迭代%d次, 成功改进%d次, 改进率%.2f%%. "
,
sb
.
append
(
String
.
format
(
"总迭代%d次, 成功改进%d次, 改进率%.2f%%. "
,
totalIterations
,
improveCount
,
totalIterations
>
0
?
(
double
)
improveCount
/
totalIterations
*
100
:
0
));
totalIterations
,
improveCount
,
totalIterations
>
0
?
(
double
)
improveCount
/
totalIterations
*
100
:
0
));
for
(
int
i
=
0
;
i
<
currentFitness
.
length
;
i
++)
{
// 处理null或空数组的情况
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
if
(
currentFitness
!=
null
&&
currentFitness
.
length
>
0
&&
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
initialFitnessLevel
!=
null
&&
initialFitnessLevel
.
length
>
0
)
{
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
int
minLength
=
Math
.
min
(
currentFitness
.
length
,
initialFitnessLevel
.
length
);
for
(
int
i
=
0
;
i
<
minLength
;
i
++)
{
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
}
}
else
{
sb
.
append
(
"(KPI数据不可用) "
);
}
}
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
...
@@ -408,9 +422,12 @@ public class SimulatedAnnealing {
...
@@ -408,9 +422,12 @@ public class SimulatedAnnealing {
private
void
writeKpi
(
Chromosome
chromosome
)
{
private
void
writeKpi
(
Chromosome
chromosome
)
{
String
fitness
=
""
;
String
fitness
=
""
;
double
[]
fitness1
=
chromosome
.
getFitnessLevel
();
double
[]
fitness1
=
chromosome
.
getFitnessLevel
();
for
(
int
i
=
0
;
i
<
fitness1
.
length
;
i
++)
{
if
(
fitness1
!=
null
)
{
for
(
int
i
=
0
;
i
<
fitness1
.
length
;
i
++)
{
fitness
+=
fitness1
[
i
]
+
","
;
fitness
+=
fitness1
[
i
]
+
","
;
}
}
else
{
fitness
=
"null (未计算)"
;
}
}
log
(
String
.
format
(
"模拟退火 - kpi:%s"
,
fitness
),
true
);
log
(
String
.
format
(
"模拟退火 - kpi:%s"
,
fitness
),
true
);
...
...
src/main/java/com/aps/service/Algorithm/TabuSearch.java
View file @
111874b6
...
@@ -65,7 +65,7 @@ public class TabuSearch {
...
@@ -65,7 +65,7 @@ public class TabuSearch {
Chromosome
current
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
Chromosome
current
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
Chromosome
best
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
Chromosome
best
=
ProductionDeepCopyUtil
.
deepCopy
(
chromosome
,
Chromosome
.
class
);
this
.
bestFitness
=
best
.
getFitnessLevel
().
clone
();
this
.
bestFitness
=
best
.
getFitnessLevel
().
clone
();
writeKpi
(
best
);
writeKpi
(
best
);
// 记录初始KPI用于计算改进率
// 记录初始KPI用于计算改进率
double
[]
initialFitnessLevel
=
best
.
getFitnessLevel
().
clone
();
double
[]
initialFitnessLevel
=
best
.
getFitnessLevel
().
clone
();
double
initialFitness
=
best
.
getFitness
();
double
initialFitness
=
best
.
getFitness
();
...
@@ -73,8 +73,8 @@ writeKpi(best);
...
@@ -73,8 +73,8 @@ writeKpi(best);
int
iterations
=
0
;
int
iterations
=
0
;
int
improveCount
=
0
;
int
improveCount
=
0
;
int
noImprovementCount
=
0
;
int
noImprovementCount
=
0
;
int
maxNoImprovement
=
15
;
// 降低到1
5次无改进则停止
int
maxNoImprovement
=
5
;
// 优化:
5次无改进则停止
int
maxIterations
=
Math
.
min
(
cachedAllOperations
.
size
(),
80
);
// 降低到最多80次
int
maxIterations
=
Math
.
min
(
cachedAllOperations
.
size
(),
20
);
// 优化:最多20次迭代
// 改进率监控
// 改进率监控
int
stagnantWindow
=
10
;
int
stagnantWindow
=
10
;
...
@@ -213,12 +213,15 @@ writeKpi(best);
...
@@ -213,12 +213,15 @@ writeKpi(best);
private
void
writeKpi
(
Chromosome
chromosome
)
{
private
void
writeKpi
(
Chromosome
chromosome
)
{
String
fitness
=
""
;
String
fitness
=
""
;
double
[]
fitness1
=
chromosome
.
getFitnessLevel
();
double
[]
fitness1
=
chromosome
.
getFitnessLevel
();
for
(
int
i
=
0
;
i
<
fitness1
.
length
;
i
++)
{
if
(
fitness1
!=
null
)
{
for
(
int
i
=
0
;
i
<
fitness1
.
length
;
i
++)
{
fitness
+=
fitness1
[
i
]
+
","
;
fitness
+=
fitness1
[
i
]
+
","
;
}
}
else
{
fitness
=
"null (未计算)"
;
}
}
log
(
String
.
format
(
"
变邻域
搜索 - kpi:%s"
,
fitness
),
true
);
log
(
String
.
format
(
"
禁忌
搜索 - kpi:%s"
,
fitness
),
true
);
}
}
/**
/**
...
@@ -228,9 +231,16 @@ writeKpi(best);
...
@@ -228,9 +231,16 @@ writeKpi(best);
StringBuilder
sb
=
new
StringBuilder
(
"禁忌搜索 - 改进详情: 迭代"
+
iteration
+
", "
);
StringBuilder
sb
=
new
StringBuilder
(
"禁忌搜索 - 改进详情: 迭代"
+
iteration
+
", "
);
double
[]
currentFitness
=
best
.
getFitnessLevel
();
double
[]
currentFitness
=
best
.
getFitnessLevel
();
for
(
int
i
=
0
;
i
<
currentFitness
.
length
;
i
++)
{
// 处理null或空数组的情况
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
if
(
currentFitness
!=
null
&&
currentFitness
.
length
>
0
&&
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(+%.4f) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
improvement
));
initialFitnessLevel
!=
null
&&
initialFitnessLevel
.
length
>
0
)
{
int
minLength
=
Math
.
min
(
currentFitness
.
length
,
initialFitnessLevel
.
length
);
for
(
int
i
=
0
;
i
<
minLength
;
i
++)
{
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(+%.4f) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
improvement
));
}
}
else
{
sb
.
append
(
"(KPI数据不可用) "
);
}
}
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
...
@@ -260,10 +270,17 @@ writeKpi(best);
...
@@ -260,10 +270,17 @@ writeKpi(best);
sb
.
append
(
String
.
format
(
"总迭代%d次, 成功改进%d次, 改进率%.2f%%. "
,
sb
.
append
(
String
.
format
(
"总迭代%d次, 成功改进%d次, 改进率%.2f%%. "
,
totalIterations
,
improveCount
,
totalIterations
>
0
?
(
double
)
improveCount
/
totalIterations
*
100
:
0
));
totalIterations
,
improveCount
,
totalIterations
>
0
?
(
double
)
improveCount
/
totalIterations
*
100
:
0
));
for
(
int
i
=
0
;
i
<
currentFitness
.
length
;
i
++)
{
// 处理null或空数组的情况
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
if
(
currentFitness
!=
null
&&
currentFitness
.
length
>
0
&&
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
initialFitnessLevel
!=
null
&&
initialFitnessLevel
.
length
>
0
)
{
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
int
minLength
=
Math
.
min
(
currentFitness
.
length
,
initialFitnessLevel
.
length
);
for
(
int
i
=
0
;
i
<
minLength
;
i
++)
{
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
}
}
else
{
sb
.
append
(
"(KPI数据不可用) "
);
}
}
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
...
...
src/main/java/com/aps/service/Algorithm/VariableNeighborhoodSearch.java
View file @
111874b6
...
@@ -21,7 +21,7 @@ public class VariableNeighborhoodSearch {
...
@@ -21,7 +21,7 @@ public class VariableNeighborhoodSearch {
// ==================== 常量定义 ====================
// ==================== 常量定义 ====================
private
static
final
int
MAX_CONSECUTIVE_SAME_STRATEGY
=
3
;
private
static
final
int
MAX_CONSECUTIVE_SAME_STRATEGY
=
3
;
private
static
final
int
MAX_NEIGHBORHOODS
=
7
;
private
static
final
int
MAX_NEIGHBORHOODS
=
4
;
// 优化:从7减少到4个邻域
private
static
final
double
HIGH_PRIORITY_GROUP_PROBABILITY
=
0.7
;
private
static
final
double
HIGH_PRIORITY_GROUP_PROBABILITY
=
0.7
;
private
static
final
int
MAX_ATTEMPTS
=
50
;
private
static
final
int
MAX_ATTEMPTS
=
50
;
private
static
final
int
NEIGHBOR_SELECTION_TOP_K
=
3
;
private
static
final
int
NEIGHBOR_SELECTION_TOP_K
=
3
;
...
@@ -378,9 +378,16 @@ public class VariableNeighborhoodSearch {
...
@@ -378,9 +378,16 @@ public class VariableNeighborhoodSearch {
StringBuilder
sb
=
new
StringBuilder
(
"变邻域搜索 - 改进详情: 轮次"
+
round
+
", 邻域="
+
neighborhoodName
+
", "
);
StringBuilder
sb
=
new
StringBuilder
(
"变邻域搜索 - 改进详情: 轮次"
+
round
+
", 邻域="
+
neighborhoodName
+
", "
);
double
[]
currentFitness
=
best
.
getFitnessLevel
();
double
[]
currentFitness
=
best
.
getFitnessLevel
();
for
(
int
i
=
0
;
i
<
currentFitness
.
length
;
i
++)
{
// 处理null或空数组的情况
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
if
(
currentFitness
!=
null
&&
currentFitness
.
length
>
0
&&
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(+%.4f) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
improvement
));
initialFitnessLevel
!=
null
&&
initialFitnessLevel
.
length
>
0
)
{
int
minLength
=
Math
.
min
(
currentFitness
.
length
,
initialFitnessLevel
.
length
);
for
(
int
i
=
0
;
i
<
minLength
;
i
++)
{
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(+%.4f) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
improvement
));
}
}
else
{
sb
.
append
(
"(KPI数据不可用) "
);
}
}
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
...
@@ -409,10 +416,16 @@ public class VariableNeighborhoodSearch {
...
@@ -409,10 +416,16 @@ public class VariableNeighborhoodSearch {
sb
.
append
(
"\n"
);
sb
.
append
(
"\n"
);
// 记录KPI改进
// 记录KPI改进
for
(
int
i
=
0
;
i
<
currentFitness
.
length
;
i
++)
{
if
(
currentFitness
!=
null
&&
currentFitness
.
length
>
0
&&
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
initialFitnessLevel
!=
null
&&
initialFitnessLevel
.
length
>
0
)
{
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
int
minLength
=
Math
.
min
(
currentFitness
.
length
,
initialFitnessLevel
.
length
);
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
for
(
int
i
=
0
;
i
<
minLength
;
i
++)
{
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
}
}
else
{
sb
.
append
(
"(KPI数据不可用) "
);
}
}
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
...
@@ -424,9 +437,12 @@ public class VariableNeighborhoodSearch {
...
@@ -424,9 +437,12 @@ public class VariableNeighborhoodSearch {
private
void
writeKpi
(
Chromosome
chromosome
)
{
private
void
writeKpi
(
Chromosome
chromosome
)
{
String
fitness
=
""
;
String
fitness
=
""
;
double
[]
fitness1
=
chromosome
.
getFitnessLevel
();
double
[]
fitness1
=
chromosome
.
getFitnessLevel
();
for
(
int
i
=
0
;
i
<
fitness1
.
length
;
i
++)
{
if
(
fitness1
!=
null
)
{
for
(
int
i
=
0
;
i
<
fitness1
.
length
;
i
++)
{
fitness
+=
fitness1
[
i
]
+
","
;
fitness
+=
fitness1
[
i
]
+
","
;
}
}
else
{
fitness
=
"null (未计算)"
;
}
}
log
(
String
.
format
(
"变邻域搜索 - kpi:%s"
,
fitness
),
true
);
log
(
String
.
format
(
"变邻域搜索 - kpi:%s"
,
fitness
),
true
);
...
@@ -2024,6 +2040,7 @@ public class VariableNeighborhoodSearch {
...
@@ -2024,6 +2040,7 @@ public class VariableNeighborhoodSearch {
}
else
{
}
else
{
chromosome
.
setResultOld
(
new
CopyOnWriteArrayList
<>());
chromosome
.
setResultOld
(
new
CopyOnWriteArrayList
<>());
}
}
//decoder.decodeChromosomeWithCache(chromosome,true);
});
});
log
(
String
.
format
(
"变邻域搜索 -复制对象E"
));
log
(
String
.
format
(
"变邻域搜索 -复制对象E"
));
...
...
src/test/java/com/aps/demo/PlanResultServiceTest.java
View file @
111874b6
...
@@ -39,10 +39,13 @@ public class PlanResultServiceTest {
...
@@ -39,10 +39,13 @@ public class PlanResultServiceTest {
// TestSortService sortService=new TestSortService();
// TestSortService sortService=new TestSortService();
// sortService.test1();
// sortService.test1();
// nsgaiiUtils.Test();
// nsgaiiUtils.Test();
planResultService
.
execute2
(
"08B1D87FE1B84ECDBAC2E546DDB6FB81"
);
//2000
// planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4");//2000
planResultService
.
execute2
(
"F6747C64865D4609989D943709939331"
);
//2000
// planResultService.execute2("08B1D87FE1B84ECDBAC2E546DDB6FB81");//2000
// planResultService.execute2("0428340BB4F540938F1FB5599F03E8A4");//5000
// planResultService.execute2("C8B533BD8944405B9A2F8823C575C204");//500
// planResultService.execute2("C8B533BD8944405B9A2F8823C575C204");//500
//
planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");//20
//
planResultService.execute2("EFDD34E4B5BC434BAEAE6A84DFCD4E7B");//20
// planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D");
// planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D");
// planResultService.execute2("92BB773E1E2447C99D8176C991D5C9D2");
// planResultService.execute2("92BB773E1E2447C99D8176C991D5C9D2");
...
...
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