优化早停和指标公式
This commit is contained in:
parent
dfdb10d207
commit
aba7dc18d3
|
|
@ -71,7 +71,7 @@ class Config:
|
||||||
"""算法参数配置类:存储NSGA-II的各类参数"""
|
"""算法参数配置类:存储NSGA-II的各类参数"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# 种群参数
|
# 种群参数
|
||||||
self.pop_size = 300 # 种群大小
|
self.pop_size = 100 # 种群大小
|
||||||
self.N1_ratio = 0.2 # 优先成本的种群比例
|
self.N1_ratio = 0.2 # 优先成本的种群比例
|
||||||
self.N2_ratio = 0.2 # 优先延期的种群比例
|
self.N2_ratio = 0.2 # 优先延期的种群比例
|
||||||
self.N3_ratio = 0.3 # 强制风险企业的种群比例
|
self.N3_ratio = 0.3 # 强制风险企业的种群比例
|
||||||
|
|
@ -83,11 +83,12 @@ class Config:
|
||||||
# 惩罚系数
|
# 惩罚系数
|
||||||
self.delta = 1.3 # 变更惩罚系数
|
self.delta = 1.3 # 变更惩罚系数
|
||||||
# 早停参数
|
# 早停参数
|
||||||
self.early_stop_patience = 50 # 连续多少代无改进则早停
|
self.early_stop_patience = 20 # 连续多少代无改进则早停
|
||||||
|
self.early_stop_threshold = 0.15 # 目标值变化阈值
|
||||||
# 目标函数数量
|
# 目标函数数量
|
||||||
self.objective_num = 2 # 双目标(成本+延期)
|
self.objective_num = 2 # 双目标(成本+延期)
|
||||||
self.duplicate_threshold = 0.1 # 重复解保留数量
|
self.duplicate_threshold = 0.05 # 重复解保留数量
|
||||||
self.print_top_n = 5 # 打印前N个最优解
|
self.print_top_n = 10 # 打印前N个最优解
|
||||||
|
|
||||||
class DataStructures:
|
class DataStructures:
|
||||||
"""数据结构工具类:提供评价指标计算等功能"""
|
"""数据结构工具类:提供评价指标计算等功能"""
|
||||||
|
|
@ -103,9 +104,9 @@ class DataStructures:
|
||||||
cost, tardiness = objectives
|
cost, tardiness = objectives
|
||||||
# 避免除以零(成本最优值为0时的保护)
|
# 避免除以零(成本最优值为0时的保护)
|
||||||
if optimal_cost == 0:
|
if optimal_cost == 0:
|
||||||
cost_ratio = 0 if cost == 0 else float('inf')
|
cost_ratio = cost
|
||||||
else:
|
else:
|
||||||
cost_ratio = cost / optimal_cost
|
cost_ratio = 2*(cost / optimal_cost)
|
||||||
# 延期处理(+1避免除以零)
|
# 延期处理(+1避免除以零)
|
||||||
tardiness_ratio = (tardiness + 1) / (optimal_tardiness + 1)
|
tardiness_ratio = 8*((tardiness + 1) / (optimal_tardiness + 1))
|
||||||
return cost_ratio + tardiness_ratio
|
return cost_ratio + tardiness_ratio
|
||||||
39
main.py
39
main.py
|
|
@ -44,7 +44,9 @@ def main():
|
||||||
best_front = [] # 最终帕累托前沿解(整数)
|
best_front = [] # 最终帕累托前沿解(整数)
|
||||||
best_front_objs = [] # 最终帕累托前沿的目标值(整数)
|
best_front_objs = [] # 最终帕累托前沿的目标值(整数)
|
||||||
no_improve_count = 0 # 无改进计数器(用于早停)
|
no_improve_count = 0 # 无改进计数器(用于早停)
|
||||||
prev_best_avg = float('inf') # 上一代的最优平均目标值(整数求和)
|
prev_avg_cost = None # 上一代的平均成本
|
||||||
|
prev_avg_tardiness = None # 上一代的平均延期
|
||||||
|
no_improve_count = 0 # 无改进计数器
|
||||||
# 6. 进化主循环
|
# 6. 进化主循环
|
||||||
print(f"开始进化(最大代数:{config.max_generations},早停耐心:{config.early_stop_patience})...")
|
print(f"开始进化(最大代数:{config.max_generations},早停耐心:{config.early_stop_patience})...")
|
||||||
for generation in range(config.max_generations):
|
for generation in range(config.max_generations):
|
||||||
|
|
@ -60,20 +62,39 @@ def main():
|
||||||
best_front = population[current_front] if current_front else [] # 更新当前最优前沿解(整数)
|
best_front = population[current_front] if current_front else [] # 更新当前最优前沿解(整数)
|
||||||
best_front_objs = current_front_objs # 更新当前最优前沿目标值(整数)
|
best_front_objs = current_front_objs # 更新当前最优前沿目标值(整数)
|
||||||
# 记录收敛趋势(基于最优前沿的平均目标值,整数)
|
# 记录收敛趋势(基于最优前沿的平均目标值,整数)
|
||||||
|
# 记录收敛趋势并判断早停条件
|
||||||
if len(current_front_objs) > 0:
|
if len(current_front_objs) > 0:
|
||||||
avg_cost = sum(obj[0] for obj in current_front_objs) // len(current_front_objs) # 整数平均
|
avg_cost = sum(obj[0] for obj in current_front_objs) // len(current_front_objs)
|
||||||
avg_tardiness = sum(obj[1] for obj in current_front_objs) // len(current_front_objs) # 整数平均
|
avg_tardiness = sum(obj[1] for obj in current_front_objs) // len(current_front_objs)
|
||||||
convergence_history.append((avg_cost, avg_tardiness))
|
convergence_history.append((avg_cost, avg_tardiness))
|
||||||
|
|
||||||
# 判断是否改进(用于早停)
|
# 早停判断逻辑
|
||||||
current_avg = avg_cost + avg_tardiness # 合并两个目标的平均值(整数)
|
if prev_avg_cost is not None and prev_avg_tardiness is not None:
|
||||||
if abs(current_avg - prev_best_avg) < 1e-4: # 变化小于阈值,视为无改进
|
# 计算两个目标的变化量
|
||||||
no_improve_count += 1
|
cost_change = abs(avg_cost - prev_avg_cost)
|
||||||
|
tardiness_change = abs(avg_tardiness - prev_avg_tardiness)
|
||||||
|
|
||||||
|
# 检查是否两个目标的变化都小于阈值
|
||||||
|
if (cost_change < config.early_stop_threshold and
|
||||||
|
tardiness_change < config.early_stop_threshold):
|
||||||
|
no_improve_count += 1
|
||||||
|
else:
|
||||||
|
no_improve_count = 0 # 有改进,重置计数器
|
||||||
|
prev_avg_cost = avg_cost
|
||||||
|
prev_avg_tardiness = avg_tardiness
|
||||||
else:
|
else:
|
||||||
no_improve_count = 0 # 有改进,重置计数器
|
# 初始化历史值(第一代)
|
||||||
prev_best_avg = current_avg
|
prev_avg_cost = avg_cost
|
||||||
|
prev_avg_tardiness = avg_tardiness
|
||||||
|
no_improve_count = 0
|
||||||
else:
|
else:
|
||||||
no_improve_count += 1 # 无前沿解,视为无改进
|
no_improve_count += 1 # 无前沿解,视为无改进
|
||||||
|
|
||||||
|
# 早停检查(连续多代无改进则停止)
|
||||||
|
if no_improve_count >= config.early_stop_patience:
|
||||||
|
print(
|
||||||
|
f"早停触发:连续{no_improve_count}代两个目标值变化均小于{config.early_stop_threshold},终止于第{generation}代")
|
||||||
|
break
|
||||||
# 选择操作(锦标赛选择)
|
# 选择操作(锦标赛选择)
|
||||||
selected = nsga2.selection(population, objectives)
|
selected = nsga2.selection(population, objectives)
|
||||||
# 校验选择后的种群大小
|
# 校验选择后的种群大小
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue