带单约束的一维数组优化问题:生产成本最值求解方案咨询
问题分析与最优解法
你的问题本质是带约束的离散优化问题:在总生产数量固定的前提下,调整每小时的机器功率(0-500kW,且功率低于15%时无生产),找到单位生产成本的极值。
先拆解核心逻辑:
- 单位生产成本
cost_of_item = (总电费) / (总生产数量) - 总生产数量固定时,最小化/最大化
cost_of_item等价于最小化/最大化总电费,而总电费直接和所有小时的功率总和成正比。 - 约束条件:所有小时的
(功率/对应能耗)之和固定(因为总生产数量=时间分辨率×该总和)。
最优策略推导
关键定义(针对有效负载,即功率≥75kW/15%负载)
对每个负载水平(15%-100%,对应功率75-500kW),计算两个核心指标:
production_per_hour = 功率 / 对应能耗:每小时生产的产品数量power_per_production = 能耗:生产1单位产品需要消耗的功率(等价于每单位生产对应的功率投入)
1. 最小化单位生产成本
要最小化总电费(即功率总和),需优先选择单位生产投入功率最低的负载水平(也就是power_per_production最小的负载),因为同样生产1单位产品,该负载的功率消耗最少。
步骤:
- 将所有有效负载按
power_per_production从小到大排序 - 依次给时间步分配该负载,直到累计生产数量达到目标值
- 剩余不需要生产的时间步,功率设为0(进一步降低总功率)
2. 最大化单位生产成本
要最大化总电费,需优先选择单位生产投入功率最高的负载水平(power_per_production最大的负载),同样生产1单位产品,该负载的功率消耗最多。
步骤:
- 将所有有效负载按
power_per_production从大到小排序 - 依次给时间步分配该负载,直到累计生产数量达到目标值
- 剩余不需要生产的时间步,功率设为72kW(最大的不触发生产的功率:
round(72/500,2)=0.14<0.15,不会贡献生产数量,但能最大化功率总和)
代码实现
import numpy as np import csv # 原始参数 machine_power_kW = 500 electricity_cost_Eur_kW = 0.10 time_resolution_hours = 1 total_hours = 8760 # 读取原始数据(替换为你的实际文件路径) file_name_1='**.csv' with open(file_name_1, 'r') as f: next(csv.reader(f)) data = list(csv.reader(f)) original_power_array = np.array(data[:-1], dtype=float) file_name_2='**.csv' with open(file_name_2, 'r') as f: next(csv.reader(f)) data = list(csv.reader(f)) Consumption_lookup_table = np.array(data, dtype=float).flatten() # 转为一维数组 # 预处理负载与对应指标 load_pcts = np.arange(0.15, 1.01, 0.01) # 15%到100%,步长1% powers = load_pcts * machine_power_kW consumptions = Consumption_lookup_table # 计算核心指标 production_per_hour = powers / consumptions power_per_production = consumptions # 等价于生产1单位的功率投入 # 计算目标总生产数量(从原始数据获取) # 先计算原始生产数量 original_consumption = np.empty_like(original_power_array) for i in range(len(original_power_array)): p = round(original_power_array.item(i)/machine_power_kW,2) if p >=0.15: pos = int(p*100 -15) original_consumption[i] = Consumption_lookup_table[pos] else: original_consumption[i] = 1e9999999 X = time_resolution_hours * (original_power_array / original_consumption).sum() total_required_prod = X / time_resolution_hours # ---------------------- 计算最小单位成本 ---------------------- sorted_idx_min = np.argsort(power_per_production) remaining_prod = total_required_prod remaining_hours = total_hours min_sum_power = 0.0 for idx in sorted_idx_min: if remaining_prod <= 0 or remaining_hours <=0: break prod_per_hour = production_per_hour[idx] p = powers[idx] max_hours = min(remaining_prod / prod_per_hour, remaining_hours) min_sum_power += max_hours * p remaining_prod -= max_hours * prod_per_hour remaining_hours -= max_hours min_sum_power += remaining_hours * 0 # 剩余时间功率设为0 min_cost = (min_sum_power * time_resolution_hours * electricity_cost_Eur_kW) / X # ---------------------- 计算最大单位成本 ---------------------- sorted_idx_max = np.argsort(-power_per_production) remaining_prod = total_required_prod remaining_hours = total_hours max_sum_power = 0.0 for idx in sorted_idx_max: if remaining_prod <=0 or remaining_hours <=0: break prod_per_hour = production_per_hour[idx] p = powers[idx] max_hours = min(remaining_prod / prod_per_hour, remaining_hours) max_sum_power += max_hours * p remaining_prod -= max_hours * prod_per_hour remaining_hours -= max_hours max_non_prod_power = 72.0 # 最大不触发生产的功率 max_sum_power += remaining_hours * max_non_prod_power max_cost = (max_sum_power * time_resolution_hours * electricity_cost_Eur_kW) / X # 输出结果 print(f"最小单位生产成本: {min_cost:.4f} Eur/unit") print(f"最大单位生产成本: {max_cost:.4f} Eur/unit")
注意事项
- 确保能耗 lookup 表的顺序与15%-100%负载的顺序完全对应
- 代码中仅考虑离散的1%步长负载,因为原始逻辑中
round(power/machine_power_kW,2)会将任意功率映射到最近的1%负载,无需考虑连续值 - 若目标生产数量为0(极端情况),直接返回0作为最小成本,72×8760×电价作为最大成本
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

