You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Pyomo的Python批量过程优化:如何设置批次恒定运行功率?

工业批量生产过程的Pyomo优化:批次恒定功率约束实现问题

我正在用Python的Pyomo工具优化工业批量生产过程,目标是最小化系统成本,生产成本采用随机值定义。该批量过程有两个核心特性:

  • 系统启动后必须连续运行4个或4的倍数个时间步长(此功能已实现)
  • 批次启动后,该批次的运行功率需保持恒定(这是目前未解决的问题)

尝试过的约束代码

我曾尝试添加以下约束,但这些约束只能保证运行功率不会在过程中降低,无法实现功率恒定的要求:

# 尝试确保工厂启动后,当前及后续三个时段功率相等
def block_production_rule_1(model, t):
    if t <= T-3:
        return model.production[t+1]  >= model.production[t] * model.start[t]
    return pyo.Constraint.Skip
model.block_production_rule_1 = pyo.Constraint(model.timesteps, rule=block_production_rule_1)

def block_production_rule_2(model,t):
    if t <= T-3:
        return model.production[t+2] >= model.production[t] * model.start[t]
    return pyo.Constraint.Skip
model.block_production_rule_2 = pyo.Constraint(model.timesteps, rule=block_production_rule_2)

def block_production_rule_3(model,t):
    if t <= T-3:
        return model.production[t+3] >= model.production[t] * model.start[t]
    return pyo.Constraint.Skip
model.block_production_rule_3 = pyo.Constraint(model.timesteps, rule=block_production_rule_3)

更新:问题解决

我修改了目标函数,同时调整了代码其他部分,目前功能已正常运行。

修改后的目标函数

def obj_rule(model):
    return sum((production_cost[t-1] + production_cost[t] + production_cost[t+1] + production_cost[t+2]) * model.run_power[t] for t in model.timesteps)
model.obj = pyo.Objective(rule=obj_rule, sense=pyo.minimize)

完整代码

import pyomo.environ as pyo
import numpy as np
import random 


# 定义模型
model = pyo.ConcreteModel()

# 1. 定义模型集合与参数
T = 56  # 时间步长总数
production_goal = 32
maxPower = 2
minPower = 0
model.timesteps = pyo.RangeSet(1, T)

# 生产成本函数
# production_cost = [1, 2, 0, 3, 4, 1, 0, 2, 4, 1, 3, 2, 0, 4, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1,0,3,3,3]
production_cost = (np.sin(np.linspace(0, 8*np.pi, T)) + 1) * 50
production_cost = [_ for _ in range(T+3)]
production_cost = [random.randint(0,4) for _ in range(T+3)]
production_cost_sum = []
for i in range(len(production_cost)):
    total = 0
    for j in range(i, min(i + 4, len(production_cost))):  # 处理末尾边界问题
        total += production_cost[j]
    production_cost_sum.append(total)

# 2. 定义决策变量
model.start = pyo.Var(model.timesteps, within=pyo.Binary)  # 工厂启动标志
model.run_power = pyo.Var(model.timesteps, within=pyo.Integers)  # 工厂运行功率

# 3. 定义目标函数
def obj_rule(model):
    return sum((production_cost[t-1] + production_cost[t] + production_cost[t+1] + production_cost[t+2]) * model.run_power[t] for t in model.timesteps)
model.obj = pyo.Objective(rule=obj_rule, sense=pyo.minimize)

# 4. 定义约束条件
# 总产量约束
def total_production_rule(model):
    return sum(model.run_power[t] for t in model.timesteps) == production_goal/4
model.total_production_con = pyo.Constraint(rule=total_production_rule)

# 仅当工厂启动时才能生产
def production_on_rule_1(model, t):
    return model.run_power[t] <= model.start[t] * maxPower
model.production_on_con_1 = pyo.Constraint(model.timesteps, rule=production_on_rule_1)

def production_on_rule_2(model, t):
    return model.run_power[t] >= model.start[t] 
model.production_on_con_2 = pyo.Constraint(model.timesteps, rule=production_on_rule_2)


# 启动约束:前3个时段未启动才能启动
def start_rule(model, t):
    return model.start[t] <= 1 - sum(model.start[tt] for tt in range(t-3, t) if tt > 0)
model.start_con = pyo.Constraint(model.timesteps, rule=start_rule)




# 5. 使用Gurobi求解模型
solver = pyo.SolverFactory('gurobi')
results = solver.solve(model)






import matplotlib.pyplot as plt
# 6. 绘制结果
x_values = [model.run_power[t]() for t in model.timesteps]
i = 0
while i < len(x_values):
    if x_values[i] > 0:
        value_to_propagate = x_values[i]
        for j in range(i, min(i + 4, len(x_values))):
            x_values[j] = value_to_propagate
        i += 4
    else:
        i += 1
y_values = [model.run_power[t]() for t in model.timesteps]
batch_over_values = [model.start[t]() for t in model.timesteps]

# 创建3个子图
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex=True, figsize=(15, 10))

# 绘制生产决策
ax1.step(range(1, T+1), x_values, where='post', label="Production (x)", color='blue')
ax1.set_ylabel("数值")
ax1.legend()
ax1.grid(True)

# 绘制工厂状态
ax2.step(range(1, T+1), y_values, where='post', label="工厂运行中", color='red', linestyle='--')
ax2.step(range(1, T+1), batch_over_values, where='post', label="工厂启动", color='blue', linestyle=':')
ax2.set_ylabel("数值")
ax2.legend()
ax2.grid(True)

# 统一x轴范围
ax3.step(range(1, T+4), production_cost, where='post', label="生产成本", color='green', linestyle=':')
ax3.set_ylabel("数值")
ax3.set_xlabel("时间步长")
ax3.legend()
ax3.grid(True)
ax3.set_xlim(1, T+4)  # 设置x轴范围

# 添加每个时间步长的刻度
ax3.set_xticks(range(1, T+5))  # 用5而非4,确保包含最后一个时间步长

# 绘制累计生产成本
ax3.step(range(1, T+4), production_cost_sum, where='post', label="累计生产成本", color='red', linestyle=':')
ax3.set_ylabel("数值")
ax3.set_xlabel("时间步长")
ax3.legend()
ax3.grid(True)

for t in range(1, T+4):
    value = production_cost_sum[t-1]
    ax3.text(t, value, str(value), ha='center', va='bottom')

# 显示图形
plt.show()

内容的提问来源于stack exchange,提问作者Programmdrik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:05:54