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

Zimpl中如何基于m*n维度参数构造含零的合并集合?

问题与解决方案

问题描述

我从文件中读取了两个mn(月份夜晚)维度的参数:A[m,n]和B[m,n]。如何基于这两个参数构造一个同样为m*n索引的集合/参数,使得每个位置的元素是包含对应A值、0、对应B值的集合?例如,若A["D", 5] = 35,B["D", 5] = 2,希望得到C["D", 5] = {35, 0, 2}。是否可以实现?另外,我想将其用于目标函数的最小化/最大化,曾尝试使用{A[a,b], 0, B[a,b]}[index]但失败,因此希望预定义集合来替代。

解决方案

1. 构造m*n维度的集合参数C

完全可以实现,具体实现方式取决于你使用的优化建模工具,以下是两种主流工具的实现示例:

Pyomo 实现

from pyomo.environ import ConcreteModel, Set, Param, IndexedParam

# 初始化模型与索引集
model = ConcreteModel()
model.months = Set(initialize=["D", "J", ...])  # 替换为你的实际月份集合
model.nights = Set(initialize=range(1, n+1))  # 替换为你的实际夜晚编号范围
model.mn_index = model.months * model.nights  # 生成二维索引集

# 假设A、B已从文件读取并完成初始化
model.A = Param(model.mn_index, initialize=...)
model.B = Param(model.mn_index, initialize=...)

# 定义C:每个索引位置对应包含A值、0、B值的集合
def c_init(model, m, n):
    return {model.A[m,n], 0, model.B[m,n]}
model.C = IndexedParam(model.mn_index, initialize=c_init)

Gurobi Python API 实现

import gurobipy as gp

# 假设months、nights已定义,A、B为字典形式存储的参数
months = ["D", "J", ...]
nights = range(1, n+1)
A = {(m,n): ... for m in months for n in nights}
B = {(m,n): ... for m in months for n in nights}

# 构造C字典
C = {}
for m in months:
    for n in nights:
        C[(m, n)] = {A[(m,n)], 0, B[(m,n)]}

2. 用于目标函数优化

之前直接使用{A[a,b],0,B[a,b]}[index]失败,核心原因是多数优化建模工具不支持这种动态集合的直接索引访问。预定义C后,你可以通过二进制选择变量来实现目标函数的最小化/最大化,示例如下:

Pyomo 目标函数实现

from pyomo.environ import Binary, Objective, Constraint

# 为每个C[m,n]的元素绑定索引(0对应A值,1对应0,2对应B值)
def c_elements_init(model, m, n):
    return [(0, model.A[m,n]), (1, 0), (2, model.B[m,n])]
model.C_elements = Set(model.mn_index, initialize=c_elements_init)

# 定义二进制选择变量:x[m,n,k]表示是否选中C[m,n]中第k个元素
model.x = Var(model.mn_index, [0,1,2], domain=Binary)

# 添加约束:每个(m,n)位置只能选择一个元素
def select_one_constraint(model, m, n):
    return sum(model.x[m,n,k] for k in [0,1,2]) == 1
model.select_one = Constraint(model.mn_index, rule=select_one_constraint)

# 定义目标函数(以最大化为例,如需最小化将sense改为MINIMIZE)
def objective_rule(model):
    return sum(model.x[m,n,k] * val for m,n in model.mn_index for k, val in model.C_elements[m,n])
model.obj = Objective(rule=objective_rule, sense=gp.GRB.MAXIMIZE)

Gurobi 目标函数实现

from gurobipy import GRB

model = gp.Model()

# 定义二进制选择变量
x = {}
for m in months:
    for n in nights:
        for k in range(3):
            x[(m,n,k)] = model.addVar(vtype=GRB.BINARY, name=f"x_{m}_{n}_{k}")

# 添加"每个位置仅选一个元素"的约束
for m in months:
    for n in nights:
        model.addConstr(gp.quicksum(x[(m,n,k)] for k in range(3)) == 1)

# 定义目标函数(以最大化为例)
obj_expr = gp.quicksum(x[(m,n,k)] * list(C[(m,n)])[k] for m in months for n in nights for k in range(3))
model.setObjective(obj_expr, GRB.MAXIMIZE)

# 求解模型
model.optimize()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:05:38