修改了评价指标,新输入案例
This commit is contained in:
parent
3e6355be3d
commit
abd1544d6b
|
|
@ -83,7 +83,7 @@ class Config:
|
||||||
"""算法参数配置类:存储NSGA-II的各类参数"""
|
"""算法参数配置类:存储NSGA-II的各类参数"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# 种群参数
|
# 种群参数
|
||||||
self.pop_size = 200 # 种群大小
|
self.pop_size = 300 # 种群大小
|
||||||
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 # 强制风险企业的种群比例
|
||||||
|
|
@ -91,12 +91,12 @@ class Config:
|
||||||
# 遗传操作参数
|
# 遗传操作参数
|
||||||
self.crossover_prob = 0.8 # 交叉概率
|
self.crossover_prob = 0.8 # 交叉概率
|
||||||
self.mutation_prob = 0.3 # 变异概率
|
self.mutation_prob = 0.3 # 变异概率
|
||||||
self.max_generations = 500 # 最大进化代数
|
self.max_generations = 1000 # 最大进化代数
|
||||||
# 惩罚系数
|
# 惩罚系数
|
||||||
self.delta = 1.3 # 变更惩罚系数
|
self.delta = 1.3 # 变更惩罚系数
|
||||||
# 早停参数
|
# 早停参数
|
||||||
self.early_stop_patience = 20 # 连续多少代无改进则早停
|
self.early_stop_patience = 30 # 连续多少代无改进则早停
|
||||||
self.early_stop_threshold = 0.15 # 目标值变化阈值
|
self.early_stop_threshold = 0.1 # 目标值变化阈值
|
||||||
# 目标函数数量
|
# 目标函数数量
|
||||||
self.objective_num = 2 # 双目标(成本+延期)
|
self.objective_num = 2 # 双目标(成本+延期)
|
||||||
self.duplicate_threshold = 0.01 # 重复解保留数量
|
self.duplicate_threshold = 0.01 # 重复解保留数量
|
||||||
|
|
|
||||||
49
main.py
49
main.py
|
|
@ -8,9 +8,8 @@ from genetic_operators import GeneticOperator
|
||||||
from nsga2 import NSGA2
|
from nsga2 import NSGA2
|
||||||
from visualizer import ResultVisualizer
|
from visualizer import ResultVisualizer
|
||||||
from data_structures import DataStructures
|
from data_structures import DataStructures
|
||||||
"""主函数:执行NSGA-II算法求解多目标优化问题(整数化版本)"""
|
|
||||||
def main():
|
def main():
|
||||||
"""主函数:执行NSGA-II算法求解多目标优化问题(整数化版本)"""
|
"""主函数:执行NSGA-II算法求解多目标优化问题"""
|
||||||
try:
|
try:
|
||||||
# 1. 初始化随机种子(确保结果可复现)
|
# 1. 初始化随机种子(确保结果可复现)
|
||||||
random.seed(42)
|
random.seed(42)
|
||||||
|
|
@ -18,19 +17,19 @@ def main():
|
||||||
# 2. 初始化数据(订单、风险企业、供应商、算法配置)
|
# 2. 初始化数据(订单、风险企业、供应商、算法配置)
|
||||||
print("初始化数据结构...")
|
print("初始化数据结构...")
|
||||||
order_data = OrderData() # 订单数据(需求、交货期等,整数)
|
order_data = OrderData() # 订单数据(需求、交货期等,整数)
|
||||||
risk_data = RiskEnterpriseData() # 风险企业数据(整数)
|
risk_data = RiskEnterpriseData() # 风险企业数据
|
||||||
supplier_data = SupplierData() # 供应商数据(整数)
|
supplier_data = SupplierData() # 供应商数据
|
||||||
config = Config() # 算法参数配置
|
config = Config() # 算法参数配置
|
||||||
# 3. 初始化工具类和算法组件
|
# 3. 初始化工具类和算法组件
|
||||||
print("初始化算法组件...")
|
print("初始化算法组件...")
|
||||||
utils = ChromosomeUtils(order_data, risk_data, supplier_data) # 染色体工具(整数化)
|
utils = ChromosomeUtils(order_data, risk_data, supplier_data) # 染色体工具
|
||||||
calculator = ObjectiveCalculator(order_data, risk_data, supplier_data, utils, config) # 目标函数计算器(整数化)
|
calculator = ObjectiveCalculator(order_data, risk_data, supplier_data, utils, config) # 目标函数计算器
|
||||||
encoder = Encoder(config, utils) # 种群初始化编码器(整数化)
|
encoder = Encoder(config, utils) # 种群初始化编码器
|
||||||
genetic_op = GeneticOperator(config, utils) # 遗传操作器(整数化)
|
genetic_op = GeneticOperator(config, utils) # 遗传操作器
|
||||||
nsga2 = NSGA2(config.pop_size, config.objective_num) # NSGA-II算法实例
|
nsga2 = NSGA2(config.pop_size, config.objective_num) # NSGA-II算法实例
|
||||||
visualizer = ResultVisualizer(utils) # 结果可视化工具(适配整数化)
|
visualizer = ResultVisualizer(utils) # 结果可视化工具
|
||||||
# 4. 初始化种群
|
# 4. 初始化种群
|
||||||
print("初始化种群(整数化)...")
|
print("初始化种群...")
|
||||||
population = encoder.initialize_population()
|
population = encoder.initialize_population()
|
||||||
print(f"初始化种群完成,(种群大小,染色体长度): {population.shape if population.size > 0 else '空'}")
|
print(f"初始化种群完成,(种群大小,染色体长度): {population.shape if population.size > 0 else '空'}")
|
||||||
|
|
||||||
|
|
@ -39,11 +38,11 @@ def main():
|
||||||
if population.size == 0:
|
if population.size == 0:
|
||||||
print("错误:种群初始化失败,无法继续进化")
|
print("错误:种群初始化失败,无法继续进化")
|
||||||
return
|
return
|
||||||
# 5. 记录进化过程中的历史数据(整数化)
|
# 5. 记录进化过程中的历史数据
|
||||||
all_objectives = [] # 所有代的目标函数值(整数)
|
all_objectives = [] # 所有代的目标函数值
|
||||||
convergence_history = [] # 收敛趋势(每代最优前沿的平均目标值,整数)
|
convergence_history = [] # 收敛趋势(每代最优前沿的平均目标值,整数)
|
||||||
best_front = [] # 最终帕累托前沿解(整数)
|
best_front = [] # 最终帕累托前沿解
|
||||||
best_front_objs = [] # 最终帕累托前沿的目标值(整数)
|
best_front_objs = [] # 最终帕累托前沿的目标值
|
||||||
no_improve_count = 0 # 无改进计数器(用于早停)
|
no_improve_count = 0 # 无改进计数器(用于早停)
|
||||||
prev_avg_cost = None # 上一代的平均成本
|
prev_avg_cost = None # 上一代的平均成本
|
||||||
prev_avg_tardiness = None # 上一代的平均延期
|
prev_avg_tardiness = None # 上一代的平均延期
|
||||||
|
|
@ -52,17 +51,17 @@ def main():
|
||||||
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):
|
||||||
try:
|
try:
|
||||||
# 计算当前种群的目标函数值(整数)
|
# 计算当前种群的目标函数值
|
||||||
objectives = [calculator.calculate_objectives(chrom) for chrom in population]
|
objectives = [calculator.calculate_objectives(chrom) for chrom in population]
|
||||||
all_objectives.extend(objectives) # 记录所有目标值(整数)
|
all_objectives.extend(objectives) # 记录所有目标值
|
||||||
# 非支配排序,获取当前代的帕累托前沿
|
# 非支配排序,获取当前代的帕累托前沿
|
||||||
ranks, fronts = nsga2.fast_non_dominated_sort(objectives)
|
ranks, fronts = nsga2.fast_non_dominated_sort(objectives)
|
||||||
current_front = fronts[0] if fronts else [] # 第0层为最优前沿
|
current_front = fronts[0] if fronts else [] # 第0层为最优前沿
|
||||||
|
|
||||||
current_front_objs = [objectives[i] for i in current_front] if current_front else []
|
current_front_objs = [objectives[i] for i in current_front] if current_front else []
|
||||||
|
|
||||||
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:
|
||||||
|
|
@ -105,7 +104,7 @@ def main():
|
||||||
f"选择后的种群大小({len(selected)})与目标大小({config.pop_size})不符"
|
f"选择后的种群大小({len(selected)})与目标大小({config.pop_size})不符"
|
||||||
|
|
||||||
# 交叉操作(两点交叉)- 修复索引越界问题
|
# 交叉操作(两点交叉)- 修复索引越界问题
|
||||||
offspring = [] # 子代种群(整数)
|
offspring = [] # 子代种群
|
||||||
selected_len = len(selected) # selected的长度(等于pop_size)
|
selected_len = len(selected) # selected的长度(等于pop_size)
|
||||||
i = 0
|
i = 0
|
||||||
max_iter = 2 * config.pop_size # 最大迭代次数,避免无限循环
|
max_iter = 2 * config.pop_size # 最大迭代次数,避免无限循环
|
||||||
|
|
@ -144,8 +143,8 @@ def main():
|
||||||
]
|
]
|
||||||
offspring = np.array(offspring[:config.pop_size]).astype(int) # 确保子代大小和整数类型
|
offspring = np.array(offspring[:config.pop_size]).astype(int) # 确保子代大小和整数类型
|
||||||
# 合并父代和子代,准备环境选择
|
# 合并父代和子代,准备环境选择
|
||||||
combined = np.vstack([population, offspring]).astype(int) # 合并种群(整数)
|
combined = np.vstack([population, offspring]).astype(int) # 合并种群
|
||||||
# 计算合并种群的目标函数值(整数)
|
# 计算合并种群的目标函数值
|
||||||
combined_objs = objectives + [calculator.calculate_objectives(chrom) for chrom in offspring]
|
combined_objs = objectives + [calculator.calculate_objectives(chrom) for chrom in offspring]
|
||||||
# 环境选择(保留最优的pop_size个个体)
|
# 环境选择(保留最优的pop_size个个体)
|
||||||
population, objectives = nsga2.environmental_selection(combined, combined_objs)
|
population, objectives = nsga2.environmental_selection(combined, combined_objs)
|
||||||
|
|
@ -166,8 +165,8 @@ def main():
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"第{generation}代进化出错:{str(e)},跳过当前代")
|
print(f"第{generation}代进化出错:{str(e)},跳过当前代")
|
||||||
continue
|
continue
|
||||||
# 7. 结果可视化与输出(整数化)
|
# 7. 结果可视化与输出
|
||||||
print("进化完成,处理结果(整数化)...")
|
print("进化完成,处理结果...")
|
||||||
if len(best_front_objs) > 0:
|
if len(best_front_objs) > 0:
|
||||||
# 1. 过滤重复解(关键改进:基于目标值去重,确保相同目标值只保留一个解)
|
# 1. 过滤重复解(关键改进:基于目标值去重,确保相同目标值只保留一个解)
|
||||||
unique_front = []
|
unique_front = []
|
||||||
|
|
@ -217,8 +216,8 @@ def main():
|
||||||
top_objectives = []
|
top_objectives = []
|
||||||
|
|
||||||
# 保持原有图表绘制逻辑不变
|
# 保持原有图表绘制逻辑不变
|
||||||
visualizer.plot_pareto_front(all_objectives, best_front_objs) # 绘制帕累托前沿(整数)
|
visualizer.plot_pareto_front(all_objectives, best_front_objs) # 绘制帕累托前沿
|
||||||
visualizer.plot_convergence(convergence_history) # 绘制收敛趋势(整数)
|
visualizer.plot_convergence(convergence_history) # 绘制收敛趋势
|
||||||
|
|
||||||
# 打印处理后的最优解详情
|
# 打印处理后的最优解详情
|
||||||
if top_population:
|
if top_population:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue