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

如何在Pyomo中创建支持可变RangeSet的Param以适配动态变化的二维输入数组

Pyomo动态传入可变长度轨迹数组的解决方案

你代码运行后m.x形状不变的核心原因是:RangeSet的边界在初始化时就已经静态计算完成,你定义m.x的第一个索引时,m.num[0]还是默认值0,所以RangeSet(0, value(m.num[0])-1)初始化为空集,后续修改m.num的值不会触发已创建RangeSet的边界更新,因此m.x的索引永远为空。

以下是两种可行的适配方案:

方案1:每个时间步重建模型(推荐用于滚动优化场景)

你做的是每个时间步求解的滚动优化任务,每个时间步直接根据当前车辆数动态构建模型是最简洁、不易出错的方案,完全适配动态变化的输入:

import pyomo.environ as pyo
import numpy as np

# 每个时间步获取当前周边车辆的预测轨迹数组
x_data = np.array([[1,2,3,4],[5,6,7,8]])
n_veh = x_data.shape[0]
pred_len = x_data.shape[1]

# 新建模型
m = pyo.ConcreteModel()
# 动态生成车辆索引和预测时域索引
m.veh_set = pyo.RangeSet(0, n_veh - 1)
m.pred_set = pyo.RangeSet(0, pred_len - 1)
# 直接传入轨迹数据初始化Param
m.x = pyo.Param(m.veh_set, m.pred_set, 
                initialize={(i,j): x_data[i,j] for i in range(n_veh) for j in range(pred_len)},
                mutable=True)

# 目标函数直接遍历集合求和,自动适配当前车辆数
def obj_rule(m):
    return sum(m.x[i,j] for i in m.veh_set for j in m.pred_set)
m.obj = pyo.Objective(rule=obj_rule)

方案2:复用模型,使用可变Set动态更新

如果需要复用同一个模型避免重复初始化的开销,可以将车辆索引定义为可变Set,每次更新轨迹时先修改Set成员,再更新Param的值:

import pyomo.environ as pyo
import numpy as np

# 初始化模型,预测时域固定的话可以提前定义
m = pyo.ConcreteModel()
m.pred_set = pyo.RangeSet(0, 3)
# 定义可变的车辆集合,支持动态增删成员
m.veh_set = pyo.Set(initialize=[], ordered=True, mutable=True)
# 定义依赖可变Set的Param
m.x = pyo.Param(m.veh_set, m.pred_set, mutable=True)

# 目标函数定义一次即可,会自动适配veh_set的当前成员
def obj_rule(m):
    return sum(m.x[i,j] for i in m.veh_set for j in m.pred_set)
m.obj = pyo.Objective(rule=obj_rule)

# ========== 每个时间步更新数据 ==========
x_new = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
n_veh_new = x_new.shape[0]
# 清空旧的车辆集合
m.veh_set.clear()
# 添加新的车辆索引
m.veh_set.update(range(n_veh_new))
# 给Param赋新值
for i in range(n_veh_new):
    for j in range(4):
        m.x[i,j] = x_new[i,j]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:57:00