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

基于Pyomo的批处理过程优化:如何设置批次固定运行时长?

工业批处理过程的Pyomo成本优化实现

需求概述

  • 目标:使用Python的Pyomo工具优化工业批处理过程,最小化系统成本
  • 成本定义:简化示例中采用随机值作为生产成本
  • 过程约束:
    • 系统启动后必须连续运行4个或4的倍数个时间步(支持连续执行多批次)
    • 停机时间需满足:要么不超过2个时间步,要么至少20个时间步

问题解决记录

曾尝试通过块规则确保运行时长为4的倍数,但约束设为>=4时仍出现运行时长大于4的情况;改为==4时优化完全无法进行,目前所有问题已解决

完整实现代码

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


# Define the model
model = pyo.ConcreteModel()

# 1. Define the model, sets, and parameters.
T = 56  # number of timesteps
production_goal = 32
maxPower = 2
minPower = 0
model.timesteps = pyo.RangeSet(1, T)

# Production cost function
production_cost = (np.sin(np.linspace(0, 8*np.pi, T)) + 1) * 50
production_cost = [_ for _ in range(T)]
production_cost = [random.randint(1,100) for _ in range(T)]

# 2. Define the decision variables.
model.production = pyo.Var(model.timesteps, within=pyo.Integers)  # production decision
model.running = pyo.Var(model.timesteps, within=pyo.Binary)  # plant status
model.start = pyo.Var(model.timesteps, within=pyo.Binary)  # start of the plant

# 3. Define the objective function.
def obj_rule(model):
    return sum(production_cost[t-1] * model.production[t] for t in model.timesteps)
model.obj = pyo.Objective(rule=obj_rule, sense=pyo.minimize)

# 4. Define the constraints.
# Total production constraint
def total_production_rule(model):
    return sum(model.production[t] for t in model.timesteps) == production_goal
model.total_production_con = pyo.Constraint(rule=total_production_rule)


# Production is only possible if plant is on
def production_on_rule_1(model, t):
    return model.production[t] <= model.running[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.production[t] >= model.running[t] 
model.production_on_con_2 = pyo.Constraint(model.timesteps, rule=production_on_rule_2)


# Running if started in current or preceding 3 periods
def running_rule(model, t):
    return model.running[t] <= sum(model.start[tt] for tt in range(t-3, t+1) if tt > 0)
model.running_con = pyo.Constraint(model.timesteps, rule=running_rule)

# Start if no start occurred in preceding 3 periods
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)

# Shut-down window constraint
M_starts = 5 # max possible starts in 20 periods
def shutdown_window_rule(model, t):
    if t > 3:  # Limiting timesteps to avoid out-of-bounds errors
        return sum(model.start[tt] for tt in range(t+3, t+21) if tt <= T) <= (1 - (model.running[t-1] - model.running[t])) * M_starts
    return pyo.Constraint.Skip
model.shutdown_window_con = pyo.Constraint(model.timesteps, rule=shutdown_window_rule)

# Ensure that when the plant starts, it runs for the current and next three periods.
def block_start_rule(model, t):
    if t <= T-3:
        return model.running[t] + model.running[t+1] + model.running[t+2] + model.running[t+3]>= 4 * model.start[t]
    return pyo.Constraint.Skip
model.block_start_con = pyo.Constraint(model.timesteps, rule=block_start_rule)




# 5. Solve the model using Gurobi.
solver = pyo.SolverFactory('gurobi')
results = solver.solve(model)

import matplotlib.pyplot as plt
# 6. Plot the results.
x_values = [model.production[t]() for t in model.timesteps]
y_values = [model.running[t]() for t in model.timesteps]
batch_over_values = [model.start[t]() for t in model.timesteps]

# Create a plot with 3 subplots
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(15, 6))

# Plot the production decision
ax1.step(range(1, T+1), x_values, where='post', label="Production (x)", color='blue')
ax1.set_xticks(range(1, T+1))
ax1.set_ylabel("Value")
ax1.legend()
ax1.grid(True)

# Plot the plant status
ax2.step(range(1, T+1), y_values, where='mid', label="Plant running", color='red', linestyle='--')
ax2.step(range(1, T+1), batch_over_values, where='mid', label="Plant started", color='blue', linestyle=':')
ax2.set_ylabel("Value")
ax2.legend()
ax2.grid(True)

# Plot the production cost
ax3.step(range(1, T+1), production_cost, where='mid', label="Production Cost", color='green', linestyle=':')
ax3.set_xlabel("Timesteps")
ax3.set_ylabel("Value")
ax3.legend()
ax3.grid(True)

# Add a title
plt.suptitle("Steel Plant Production Schedule")
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.10 17:25:02