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
0f35c8f4
Commit
0f35c8f4
authored
Apr 16, 2026
by
DESKTOP-VKRD9QF\Administration
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
http://39.100.78.207:1213/tongli/hyh.apsj
parents
d632519e
111874b6
Expand all
Show 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 @
0f35c8f4
...
@@ -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,6 +174,7 @@ public class RedisUtils {
...
@@ -164,6 +174,7 @@ public class RedisUtils {
* @param key 可以传一个值 或多个
* @param key 可以传一个值 或多个
*/
*/
public
void
del
(
String
...
key
)
{
public
void
del
(
String
...
key
)
{
executeWithRetry
(()
->
{
if
(
key
!=
null
&&
key
.
length
>
0
)
{
if
(
key
!=
null
&&
key
.
length
>
0
)
{
if
(
key
.
length
==
1
)
{
if
(
key
.
length
==
1
)
{
redisTemplate
.
delete
(
prefix
+
key
[
0
]);
redisTemplate
.
delete
(
prefix
+
key
[
0
]);
...
@@ -171,6 +182,7 @@ public class RedisUtils {
...
@@ -171,6 +182,7 @@ public class RedisUtils {
redisTemplate
.
delete
(
Arrays
.
asList
(
key
).
stream
().
map
(
e
->
prefix
+
e
).
collect
(
Collectors
.
toList
()));
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,6 +219,7 @@ public class RedisUtils {
...
@@ -207,6 +219,7 @@ public class RedisUtils {
* @return true成功 false失败
* @return true成功 false失败
*/
*/
public
Boolean
set
(
String
key
,
Object
value
)
{
public
Boolean
set
(
String
key
,
Object
value
)
{
return
executeWithRetry
(()
->
{
try
{
try
{
redisTemplate
.
opsForValue
().
set
(
prefix
+
key
,
value
);
redisTemplate
.
opsForValue
().
set
(
prefix
+
key
,
value
);
return
true
;
return
true
;
...
@@ -214,6 +227,7 @@ public class RedisUtils {
...
@@ -214,6 +227,7 @@ public class RedisUtils {
log
.
error
(
"Exception: {}"
,
e
.
getMessage
());
log
.
error
(
"Exception: {}"
,
e
.
getMessage
());
return
false
;
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 @
0f35c8f4
...
@@ -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 @
0f35c8f4
...
@@ -165,15 +165,30 @@ public class FitnessCalculator {
...
@@ -165,15 +165,30 @@ 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或空数组的情况
return
true
;
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
;
}
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 @
0f35c8f4
...
@@ -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 @
0f35c8f4
This diff is collapsed.
Click to expand it.
src/main/java/com/aps/service/Algorithm/HillClimbing.java
View file @
0f35c8f4
...
@@ -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
])
{
return
true
;
}
}
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
;
}
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 @
0f35c8f4
...
@@ -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 @
0f35c8f4
...
@@ -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 @
0f35c8f4
...
@@ -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 @
0f35c8f4
...
@@ -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,10 +361,17 @@ public class SimulatedAnnealing {
...
@@ -361,10 +361,17 @@ 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或空数组的情况
if
(
currentFitness
!=
null
&&
currentFitness
.
length
>
0
&&
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
];
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(+%.4f) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
improvement
));
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
;
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(+%.4f)"
,
initialFitness
,
best
.
getFitness
(),
totalImprovement
));
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(+%.4f)"
,
initialFitness
,
best
.
getFitness
(),
totalImprovement
));
...
@@ -392,11 +399,18 @@ public class SimulatedAnnealing {
...
@@ -392,11 +399,18 @@ 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或空数组的情况
if
(
currentFitness
!=
null
&&
currentFitness
.
length
>
0
&&
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
];
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
}
}
}
else
{
sb
.
append
(
"(KPI数据不可用) "
);
}
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(%.2f%%)"
,
initialFitness
,
best
.
getFitness
(),
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(%.2f%%)"
,
initialFitness
,
best
.
getFitness
(),
...
@@ -408,10 +422,13 @@ public class SimulatedAnnealing {
...
@@ -408,10 +422,13 @@ 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
();
if
(
fitness1
!=
null
)
{
for
(
int
i
=
0
;
i
<
fitness1
.
length
;
i
++)
{
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 @
0f35c8f4
...
@@ -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
();
if
(
fitness1
!=
null
)
{
for
(
int
i
=
0
;
i
<
fitness1
.
length
;
i
++)
{
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,10 +231,17 @@ writeKpi(best);
...
@@ -228,10 +231,17 @@ 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或空数组的情况
if
(
currentFitness
!=
null
&&
currentFitness
.
length
>
0
&&
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
];
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(+%.4f) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
improvement
));
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
;
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(+%.4f)"
,
initialFitness
,
best
.
getFitness
(),
totalImprovement
));
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(+%.4f)"
,
initialFitness
,
best
.
getFitness
(),
totalImprovement
));
...
@@ -260,11 +270,18 @@ writeKpi(best);
...
@@ -260,11 +270,18 @@ 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或空数组的情况
if
(
currentFitness
!=
null
&&
currentFitness
.
length
>
0
&&
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
];
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
}
}
}
else
{
sb
.
append
(
"(KPI数据不可用) "
);
}
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(%.2f%%)"
,
initialFitness
,
best
.
getFitness
(),
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(%.2f%%)"
,
initialFitness
,
best
.
getFitness
(),
...
...
src/main/java/com/aps/service/Algorithm/VariableNeighborhoodSearch.java
View file @
0f35c8f4
...
@@ -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,10 +378,17 @@ public class VariableNeighborhoodSearch {
...
@@ -378,10 +378,17 @@ 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或空数组的情况
if
(
currentFitness
!=
null
&&
currentFitness
.
length
>
0
&&
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
];
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(+%.4f) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
improvement
));
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
;
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(+%.4f)"
,
initialFitness
,
best
.
getFitness
(),
totalImprovement
));
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(+%.4f)"
,
initialFitness
,
best
.
getFitness
(),
totalImprovement
));
...
@@ -409,11 +416,17 @@ public class VariableNeighborhoodSearch {
...
@@ -409,11 +416,17 @@ 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
&&
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
];
double
improvement
=
currentFitness
[
i
]
-
initialFitnessLevel
[
i
];
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
sb
.
append
(
String
.
format
(
"KPI%d: %.4f→%.4f(%.2f%%) "
,
i
+
1
,
initialFitnessLevel
[
i
],
currentFitness
[
i
],
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
initialFitnessLevel
[
i
]
>
0
?
improvement
/
initialFitnessLevel
[
i
]
*
100
:
0
));
}
}
}
else
{
sb
.
append
(
"(KPI数据不可用) "
);
}
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
double
totalImprovement
=
best
.
getFitness
()
-
initialFitness
;
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(%.2f%%)"
,
initialFitness
,
best
.
getFitness
(),
sb
.
append
(
String
.
format
(
"总Fitness: %.4f→%.4f(%.2f%%)"
,
initialFitness
,
best
.
getFitness
(),
...
@@ -424,10 +437,13 @@ public class VariableNeighborhoodSearch {
...
@@ -424,10 +437,13 @@ 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
();
if
(
fitness1
!=
null
)
{
for
(
int
i
=
0
;
i
<
fitness1
.
length
;
i
++)
{
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 @
0f35c8f4
...
@@ -39,8 +39,11 @@ public class PlanResultServiceTest {
...
@@ -39,8 +39,11 @@ 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");
...
...
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