增加注释,变异实现逻辑修改,增加了企业层变异后的初始化
This commit is contained in:
parent
0849790f95
commit
5d5aaae2fc
|
|
@ -140,8 +140,9 @@ class ChromosomeUtils:
|
|||
max_total_cap = self.supplier.Cj_total_max[supplier_id] # 供应商总产能上限
|
||||
|
||||
if total_cap > max_total_cap: # 超出上限时缩放
|
||||
scale = max_total_cap / total_cap # 缩放比例
|
||||
scale = max_total_cap / total_cap # 缩放比例(会出现浮点)
|
||||
start = 0
|
||||
# 重新遍历,按比例缩小该企业所有物料的产能
|
||||
for i in range(self.I):
|
||||
end = split_points[i]
|
||||
ents = self.material_optional_enterprises[i]
|
||||
|
|
@ -160,8 +161,8 @@ class ChromosomeUtils:
|
|||
repaired = quantity_layer.copy()
|
||||
split_points = np.cumsum(self.material_enterprise_count)
|
||||
start = 0
|
||||
for i in range(self.I):
|
||||
qi = self.order.Q[i]
|
||||
for i in range(self.I): # 遍历每种物料
|
||||
qi = self.order.Q[i] # 物料i的需求量
|
||||
end = split_points[i]
|
||||
ents = self.material_optional_enterprises[i]
|
||||
segment = repaired[start:end]
|
||||
|
|
@ -184,7 +185,7 @@ class ChromosomeUtils:
|
|||
segment[idx] = min_q
|
||||
elif segment[idx] > max_q:
|
||||
segment[idx] = max_q
|
||||
# 步骤2:强制总量等于需求数量(核心修复)
|
||||
# 步骤2:强制总量等于需求数量
|
||||
current_total = np.sum(segment[selected_indices])
|
||||
if current_total <= 0:
|
||||
weights = np.random.rand(len(selected_indices))
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class Config:
|
|||
|
||||
def __init__(self):
|
||||
# 种群参数
|
||||
self.pop_size = 50 # 种群大小
|
||||
self.pop_size = 300 # 种群大小
|
||||
self.N1_ratio = 0.2 # 优先成本的种群比例
|
||||
self.N2_ratio = 0.2 # 优先延期的种群比例
|
||||
self.N3_ratio = 0.3 # 强制风险企业的种群比例
|
||||
|
|
@ -99,12 +99,12 @@ class Config:
|
|||
|
||||
# 遗传操作参数
|
||||
self.crossover_prob = 0.8 # 交叉概率
|
||||
self.mutation_prob = 0.3 # 变异概率
|
||||
self.max_generations = 100 # 最大进化代数
|
||||
self.mutation_prob = 0.2 # 变异概率
|
||||
self.max_generations = 800 # 最大进化代数
|
||||
|
||||
# 惩罚系数
|
||||
self.delta = 1.3 # 变更惩罚系数
|
||||
self.gamma = 0.8 # 提前交付惩罚系数
|
||||
self.gamma = 500 # 提前交付惩罚系数
|
||||
|
||||
# 早停参数
|
||||
self.early_stop_patience = 50 # 连续多少代无改进则早停
|
||||
|
|
|
|||
12
encoder.py
12
encoder.py
|
|
@ -1,9 +1,9 @@
|
|||
import random
|
||||
import numpy as np
|
||||
from data_structures import Config # 配置参数类
|
||||
from chromosome_utils import ChromosomeUtils # 染色体工具类
|
||||
from objective_calculator import ObjectiveCalculator # 目标函数计算器
|
||||
from nsga2 import NSGA2 # NSGA-II算法类
|
||||
from data_structures import Config
|
||||
from chromosome_utils import ChromosomeUtils
|
||||
from objective_calculator import ObjectiveCalculator
|
||||
from nsga2 import NSGA2
|
||||
|
||||
|
||||
class Encoder:
|
||||
|
|
@ -109,8 +109,8 @@ class Encoder:
|
|||
if count <= 0: # 数量为0时返回空数组
|
||||
return np.array([])
|
||||
|
||||
# 生成候选解(数量为count的2倍或至少20个,确保有足够选择空间)
|
||||
candidate_count = max(2 * count, 20)
|
||||
# 生成候选解(数量为count的3倍或至少20个,确保有足够选择空间)
|
||||
candidate_count = max(3 * count, 20)
|
||||
candidates = [self._generate_random_chromosome() for _ in range(candidate_count)]
|
||||
|
||||
# 计算候选解的目标函数值
|
||||
|
|
|
|||
|
|
@ -52,67 +52,113 @@ class GeneticOperator:
|
|||
|
||||
# 拆分染色体为三层
|
||||
enterprise_layer, capacity_layer, quantity_layer = self.utils._split_chromosome(mutated)
|
||||
# 计算各物料的企业编码在染色体中的分割点(用于分层处理)
|
||||
split_points = np.cumsum(self.utils.material_enterprise_count)
|
||||
|
||||
# 1. 企业层变异(0/1翻转,即是否选择该企业)
|
||||
start = 0 # 起始索引
|
||||
for i in range(self.utils.I): # 遍历每种物料
|
||||
end = split_points[i] # 当前物料的企业编码结束索引
|
||||
# 遍历该物料的所有可选企业
|
||||
for idx in range(start, end):
|
||||
# 以设定的变异概率进行翻转
|
||||
if random.random() < self.config.mutation_prob:
|
||||
enterprise_layer[idx] = 1 - enterprise_layer[idx] # 0→1或1→0
|
||||
start = end # 更新起始索引为下一个物料
|
||||
# 修复企业层(确保每种物料至少选择一个企业)
|
||||
enterprise_layer = self.utils.repair_enterprise_layer(enterprise_layer)
|
||||
# ========== 第一步:记录原始企业层状态 ==========
|
||||
original_enterprise_layer = enterprise_layer.copy()
|
||||
|
||||
# 2. 能力层变异(调整选中企业的产能)
|
||||
# ========== 第二步:企业层变异 ==========
|
||||
start = 0
|
||||
for i in range(self.utils.I):
|
||||
end = split_points[i]
|
||||
ents = self.utils.material_optional_enterprises[i] # 当前物料的可选企业列表
|
||||
e_segment = enterprise_layer[start:end] # 当前物料的企业选择状态
|
||||
for idx in range(start, end):
|
||||
# 仅对被选中的企业(e_segment[idx-start]==1)进行变异
|
||||
if random.random() < self.config.mutation_prob and e_segment[idx - start] == 1:
|
||||
ent = ents[idx - start] # 企业ID(0为风险企业,1+为供应商)
|
||||
# 确定该企业的最大产能
|
||||
if ent == 0:
|
||||
max_cap = self.utils.risk.C0_i_std[i] # 风险企业的单物料产能
|
||||
else:
|
||||
supplier_id = ent - 1 # 供应商索引(转换为0基)
|
||||
max_cap = self.utils.supplier.Cj_i_std[supplier_id][i] # 供应商的单物料产能
|
||||
# 随机生成1到max_cap之间的新产能
|
||||
capacity_layer[idx] = random.uniform(1, max_cap)
|
||||
if random.random() < self.config.mutation_prob:
|
||||
enterprise_layer[idx] = 1 - enterprise_layer[idx]
|
||||
start = end
|
||||
# 修复能力层(确保不超过企业总产能约束)
|
||||
capacity_layer = self.utils.repair_capacity_layer(enterprise_layer, capacity_layer)
|
||||
|
||||
# 3. 数量层变异(调整选中企业的生产数量)
|
||||
# 修复企业层
|
||||
enterprise_layer = self.utils.repair_enterprise_layer(enterprise_layer)
|
||||
|
||||
# ========== 第三步:同步更新能力和数量层 ==========
|
||||
start = 0
|
||||
for i in range(self.utils.I):
|
||||
end = split_points[i]
|
||||
ents = self.utils.material_optional_enterprises[i]
|
||||
|
||||
for idx in range(start, end):
|
||||
current_ent_selected = enterprise_layer[idx] # 变异后的选择状态
|
||||
original_ent_selected = original_enterprise_layer[idx] # 变异前的选择状态
|
||||
|
||||
# 情况1:企业从选中变为未选中(1→0)
|
||||
if original_ent_selected == 1 and current_ent_selected == 0:
|
||||
capacity_layer[idx] = 0 # 产能设为0
|
||||
quantity_layer[idx] = 0 # 数量设为0
|
||||
|
||||
# 情况2:企业从未选中变为选中(0→1)
|
||||
elif original_ent_selected == 0 and current_ent_selected == 1:
|
||||
ent = ents[idx - start]
|
||||
|
||||
# 初始化产能
|
||||
if ent == 0:
|
||||
max_cap = self.utils.risk.C0_i_std[i]
|
||||
else:
|
||||
supplier_id = ent - 1
|
||||
max_cap = self.utils.supplier.Cj_i_std[supplier_id][i]
|
||||
capacity_layer[idx] = random.uniform(1, max_cap)
|
||||
|
||||
# 初始化数量
|
||||
qi = self.utils.order.Q[i]
|
||||
if ent == 0:
|
||||
max_q = qi
|
||||
else:
|
||||
supplier_id = ent - 1
|
||||
max_q = self.utils.supplier.MaxOrder[supplier_id][i]
|
||||
quantity_layer[idx] = random.uniform(1, max_q)
|
||||
|
||||
# 情况3:企业保持选中(1→1)或保持未选中(0→0)
|
||||
# 保持不变,后续的变异步骤会处理
|
||||
|
||||
start = end
|
||||
|
||||
# ========== 第四步:能力层变异(仅对保持选中的企业) ==========
|
||||
start = 0
|
||||
for i in range(self.utils.I):
|
||||
end = split_points[i]
|
||||
ents = self.utils.material_optional_enterprises[i]
|
||||
e_segment = enterprise_layer[start:end]
|
||||
|
||||
for idx in range(start, end):
|
||||
# 仅对被选中的企业进行变异
|
||||
if random.random() < self.config.mutation_prob and e_segment[idx - start] == 1:
|
||||
# 只对保持选中的企业进行变异(1→1的情况)
|
||||
if e_segment[idx - start] == 1 and original_enterprise_layer[idx] == 1:
|
||||
if random.random() < self.config.mutation_prob:
|
||||
ent = ents[idx - start]
|
||||
qi = self.utils.order.Q[i] # 当前物料的总需求
|
||||
# 确定该企业的最大可分配数量
|
||||
if ent == 0:
|
||||
max_q = qi # 风险企业最多分配全部需求
|
||||
max_cap = self.utils.risk.C0_i_std[i]
|
||||
else:
|
||||
supplier_id = ent - 1
|
||||
max_q = self.utils.supplier.MaxOrder[supplier_id][i] # 供应商的最大供应量
|
||||
# 随机生成1到max_q之间的新数量
|
||||
quantity_layer[idx] = random.uniform(1, max_q)
|
||||
max_cap = self.utils.supplier.Cj_i_std[supplier_id][i]
|
||||
capacity_layer[idx] = random.uniform(1, max_cap)
|
||||
|
||||
start = end
|
||||
# 修复数量层(确保总数量满足需求,且不超过企业最大供应)
|
||||
|
||||
# 修复能力层(考虑所有选中企业的产能)
|
||||
capacity_layer = self.utils.repair_capacity_layer(enterprise_layer, capacity_layer)
|
||||
|
||||
# ========== 第五步:数量层变异(仅对保持选中的企业) ==========
|
||||
start = 0
|
||||
for i in range(self.utils.I):
|
||||
end = split_points[i]
|
||||
ents = self.utils.material_optional_enterprises[i]
|
||||
e_segment = enterprise_layer[start:end]
|
||||
|
||||
for idx in range(start, end):
|
||||
# 只对保持选中的企业进行变异(1→1的情况)
|
||||
if e_segment[idx - start] == 1 and original_enterprise_layer[idx] == 1:
|
||||
if random.random() < self.config.mutation_prob:
|
||||
ent = ents[idx - start]
|
||||
qi = self.utils.order.Q[i]
|
||||
if ent == 0:
|
||||
max_q = qi
|
||||
else:
|
||||
supplier_id = ent - 1
|
||||
max_q = self.utils.supplier.MaxOrder[supplier_id][i]
|
||||
quantity_layer[idx] = random.uniform(1, max_q)
|
||||
|
||||
start = end
|
||||
|
||||
# 修复数量层(考虑所有选中企业的分配)
|
||||
quantity_layer = self.utils.repair_quantity_layer(enterprise_layer, quantity_layer)
|
||||
|
||||
# 合并三层并返回
|
||||
# 合并三层
|
||||
mutated = self.utils._merge_chromosome(enterprise_layer, capacity_layer, quantity_layer)
|
||||
return mutated
|
||||
Loading…
Reference in New Issue