修改了目标C的计算逻辑(但仍需要补充)

This commit is contained in:
Hgq 2025-12-06 19:42:46 +08:00
parent 6d4aa70df6
commit c21683083d
2 changed files with 86 additions and 60 deletions

View File

@ -1,6 +1,5 @@
import random import random
import numpy as np import numpy as np
# 导入数据结构和工具类(根据实际项目结构调整导入路径)
from data_structures import OrderData, RiskEnterpriseData, SupplierData, Config from data_structures import OrderData, RiskEnterpriseData, SupplierData, Config
from chromosome_utils import ChromosomeUtils from chromosome_utils import ChromosomeUtils
from objective_calculator import ObjectiveCalculator from objective_calculator import ObjectiveCalculator
@ -36,7 +35,7 @@ def main():
# 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 ''}")
# 若种群初始化失败(为空),直接退出 # 若种群初始化失败(为空),直接退出
if population.size == 0: if population.size == 0:
print("错误:种群初始化失败,无法继续进化") print("错误:种群初始化失败,无法继续进化")

View File

@ -40,26 +40,32 @@ class ObjectiveCalculator:
def _calculate_change_cost(self, enterprise_layer: np.ndarray, capacity_layer: np.ndarray, def _calculate_change_cost(self, enterprise_layer: np.ndarray, capacity_layer: np.ndarray,
quantity_layer: np.ndarray) -> float: quantity_layer: np.ndarray) -> float:
""" """
计算变更成本 C = C1 + C2 + C3 + C4 计算变更成本 C = C1 + C2 + C3 + C4按新规则实现
- C1: 变更惩罚成本使用供应商替代风险企业的惩罚 - C1: 变更惩罚成本含α系数
- C2: 采购成本差异变更后 - 原始 - C2: 采购成本差异保持原有逻辑
- C3: 运输成本差异变更后 - 原始 - C3: 运输成本差异保持原有逻辑
- C4: 提前交付惩罚成本 - C4: 提前交付惩罚成本新公式
""" """
C1 = 0.0 C1 = 0.0
C2 = 0.0 C2 = 0.0
C3 = 0.0 C3 = 0.0
C4 = 0.0 C4 = 0.0
# 原始成本(全部由风险企业生产时的成本) # -------------------------- 基础数据计算(复用+新增)--------------------------
# 1. 原始成本(全风险企业生产时的成本)
original_purchase_cost = sum(self.order.Q[i] * self.order.P0[i] for i in range(self.order.I)) original_purchase_cost = sum(self.order.Q[i] * self.order.P0[i] for i in range(self.order.I))
original_transport_cost = sum(self.order.Q[i] * self.order.T0[i] for i in range(self.order.I)) original_transport_cost = sum(self.order.Q[i] * self.order.T0[i] for i in range(self.order.I))
original_total_cost = original_purchase_cost + original_transport_cost # 全风险生产总成本用于C4
# 变更后成本(当前解的成本) # 2. 变更后成本(当前解的成本)
new_purchase_cost = 0.0 new_purchase_cost = 0.0
new_transport_cost = 0.0 new_transport_cost = 0.0
risk_production = np.zeros(self.order.I) # 风险企业生产的数量
supplier_production = np.zeros(self.order.I) # 供应商生产的数量 # 3. 关键变量收集(风险企业/供应商的产量、交货时间)
risk_production = np.zeros(self.order.I) # 风险企业生产的各物料数量xi0
supplier_production = np.zeros(self.order.I) # 供应商生产的各物料数量Qi - xi0
risk_delivery_times = [] # 风险企业的各物料交货时间Di0 = 生产时间 + 运输时间)
supplier_delivery_times = {} # 供应商的各物料交货时间 {供应商ID: [Dij1, Dij2, ...]}
start = 0 start = 0
for i in range(self.order.I): # 遍历每种物料 for i in range(self.order.I): # 遍历每种物料
@ -67,73 +73,94 @@ class ObjectiveCalculator:
ents = self.utils.material_optional_enterprises[i] # 可选企业 ents = self.utils.material_optional_enterprises[i] # 可选企业
e_segment = enterprise_layer[start:end] # 企业选择状态 e_segment = enterprise_layer[start:end] # 企业选择状态
q_segment = quantity_layer[start:end] # 数量分配 q_segment = quantity_layer[start:end] # 数量分配
c_segment = capacity_layer[start:end] # 产能(用于计算生产时间)
for idx, ent in enumerate(ents): for idx, ent in enumerate(ents):
if e_segment[idx] == 1: # 仅处理被选中的企业 if e_segment[idx] == 1: # 仅处理被选中的企业
q = q_segment[idx] # 分配的数量 q = q_segment[idx] # 分配的数量
c = c_segment[idx] # 产能
production_time = q / c if c != 0 else 0 # 生产时间
if ent == 0: # 风险企业 if ent == 0: # 风险企业
risk_production[i] += q risk_production[i] += q
new_purchase_cost += q * self.order.P0[i] # 采购成本 # 风险企业的采购/运输成本
new_transport_cost += q * self.order.T0[i] # 运输成本 new_purchase_cost += q * self.order.P0[i]
new_transport_cost += q * self.order.T0[i]
# 风险企业的交货时间Di0
transport_time = self.risk.distance / self.order.transport_speed
risk_delivery_times.append(production_time + transport_time)
else: # 供应商 else: # 供应商
supplier_id = ent - 1 supplier_id = ent - 1
supplier_production[i] += q supplier_production[i] += q
new_purchase_cost += q * self.supplier.P_ij[supplier_id][i] # 采购成本 # 供应商的采购/运输成本
new_transport_cost += q * self.supplier.T_ij[supplier_id][i] # 运输成本 new_purchase_cost += q * self.supplier.P_ij[supplier_id][i]
new_transport_cost += q * self.supplier.T_ij[supplier_id][i]
# 供应商的交货时间Dij
transport_time = self.supplier.distance[supplier_id] / self.order.transport_speed
if supplier_id not in supplier_delivery_times:
supplier_delivery_times[supplier_id] = []
supplier_delivery_times[supplier_id].append(production_time + transport_time)
start = end start = end
# 计算C1变更惩罚成本对供应商生产的部分收取惩罚 # -------------------------- C1变更惩罚成本计算新规则--------------------------
# 计算α的两个分子
sum_xi0 = np.sum(risk_production) # 所有物料的风险企业总产量
sum_Qi = np.sum(self.order.Q) # 所有物料的订单总需求
if sum_Qi == 0:
ratio_risk_q = 1.0 # 避免除零
else:
ratio_risk_q = sum_xi0 / sum_Qi
D_original = self.order.Dd # 原定交货时间Q1确认需求交货期
T_actual = self._calculate_actual_delivery_time(enterprise_layer, capacity_layer, quantity_layer) # 实际交货期Q2确认
if T_actual == 0:
ratio_delivery = 1.0 # 避免除零
else:
ratio_delivery = D_original / T_actual
# 计算α并应用约束0, 1]≤0取1
alpha = max(ratio_risk_q, ratio_delivery)
alpha = 1.0 if alpha > 1.0 else alpha # 超过1取1
alpha = 1.0 if alpha <= 0.0 else alpha # ≤0取1
# 计算C1按物料求和
for i in range(self.order.I): for i in range(self.order.I):
# 惩罚系数×供应商生产数量×(风险企业的单位采购+运输成本) supplier_q = supplier_production[i] # 物料i的供应商产量Qi - xi0
C1 += self.config.delta * supplier_production[i] * (self.order.P0[i] + self.order.T0[i]) risk_unit_cost = self.order.P0[i] + self.order.T0[i] # 风险企业单位采运成本
C1 += self.config.delta * alpha * supplier_q * risk_unit_cost
# 计算C2采购成本差异变更后 - 原始) # -------------------------- C2、C3保持原有逻辑--------------------------
C2 = new_purchase_cost - original_purchase_cost C2 = new_purchase_cost - original_purchase_cost # 采购成本差异
C3 = new_transport_cost - original_transport_cost # 运输成本差异
# 计算C3运输成本差异变更后 - 原始) # -------------------------- C4提前交付惩罚成本计算新规则--------------------------
C3 = new_transport_cost - original_transport_cost T_actual = self._calculate_actual_delivery_time(enterprise_layer, capacity_layer, quantity_layer)
if T_actual <= self.order.Dd: # 不延期时才计算Q7确认
# 步骤1计算基础值 = 四舍五入(全风险生产总成本 / 需求交货期)
Dd = self.order.Dd
if Dd == 0:
base_value = 0.0
else:
base_value = original_total_cost / Dd
base_value_rounded = round(base_value) # 四舍五入取整
# 计算C4提前交付惩罚成本若实际交货期早于需求交货期 # 步骤2计算风险企业提前天数 = max(0, Dd - D0)D0为风险企业最长交货时间
actual_delivery_time = self._calculate_actual_delivery_time(enterprise_layer, capacity_layer, quantity_layer) D0 = max(risk_delivery_times) if risk_delivery_times else 0.0
if actual_delivery_time < self.order.Dd: risk_early_days = max(0.0, Dd - D0)
# 计算风险企业和供应商的交货时间
risk_delivery = [] # 风险企业的各物料交货时间
supplier_deliveries = {} # {供应商ID: 各物料交货时间}
start = 0 # 步骤3计算供应商最大提前天数 = max(0, Dd - Dj)的最大值Dj为每个供应商的最长交货时间
for i in range(self.order.I): max_supplier_early = 0.0
end = self.split_points[i] for supplier_id, times in supplier_delivery_times.items():
ents = self.utils.material_optional_enterprises[i] Dj = max(times) if times else 0.0
e_segment = enterprise_layer[start:end] supplier_early = max(0.0, Dd - Dj)
c_segment = capacity_layer[start:end] # 产能(用于计算生产时间) if supplier_early > max_supplier_early:
q_segment = quantity_layer[start:end] # 数量 max_supplier_early = supplier_early
for idx, ent in enumerate(ents): # 步骤4计算C4
if e_segment[idx] == 1: C4 = base_value_rounded * 0.1 * (risk_early_days + max_supplier_early)
q = q_segment[idx] C4 = round(C4) # 最终结果四舍五入取整
c = c_segment[idx]
# 生产时间 = 数量 / 产能产能为0时按0处理
production_time = q / c if c != 0 else 0
# 运输时间 = 距离 / 运输速度
if ent == 0:
transport_time = self.risk.distance / self.order.transport_speed
risk_delivery.append(production_time + transport_time)
else:
supplier_id = ent - 1
transport_time = self.supplier.distance[supplier_id] / self.order.transport_speed
if supplier_id not in supplier_deliveries:
supplier_deliveries[supplier_id] = []
supplier_deliveries[supplier_id].append(production_time + transport_time)
start = end
# 风险企业的最大交货时间(取最长)
D0 = max(risk_delivery) if risk_delivery else 0
# 所有供应商的最大交货时间之和
Dj_sum = sum(max(times) for times in supplier_deliveries.values()) if supplier_deliveries else 0
# 提前交付惩罚 = 惩罚系数 ×(需求交货期 - 风险企业交货时间 + 供应商总交货时间)
C4 = self.config.gamma * ((self.order.Dd - D0) + Dj_sum)
# -------------------------- 总变更成本 --------------------------
return C1 + C2 + C3 + C4 return C1 + C2 + C3 + C4
def _calculate_actual_delivery_time(self, enterprise_layer: np.ndarray, capacity_layer: np.ndarray, def _calculate_actual_delivery_time(self, enterprise_layer: np.ndarray, capacity_layer: np.ndarray,