对由另一个范围集索引的集合有约束

问题描述 投票:0回答:1

我是 pyomo 的新手,我很好奇如何开始在 pyomo 中实施以下约束。

我的约束是在一个集合上,这个集合也是在范围集 k 上索引的。没有假设特定 k 值的集合中元素的数量在所有 k 中是一致的。我在文档中找不到与此类似的示例,这让我怀疑这在 pyomo 中是否可行。

对于示例代码的任何建议和/或指导将不胜感激。或者关于如何重新设置此约束以使其“对 pyomo 友好”的建议也很棒!

编辑:正如用户所问 - d 是一个已知数字,对于给定的 k 值,对于 A_k 中的给定元组是唯一的。准确地说,对于给定的 k,A_k 可以定义为 {(p_n_1,q_n_1,d_n_1), ....., (p_n_k,q_n_k,q_n_k)}。给定的 k 值将决定 A_k 的大小。

pyomo
1个回答
0
投票

我做了一些假设,因为规范有点不完整,但我认为你正在寻求做这样的事情。当然,这很快就会变得很大,因为你有一个 6 元组索引变量。

编辑...

第二次看这个,我想我在下面的第一个选项中做出了错误的假设,即

y
k
索引。如果您打算只收集与
k
k + 1
相关联的元组,那么第二个选项可能就是您想要的。

选项一:

# constraint over members of indexed set

import pyomo.environ as pyo

m = pyo.ConcreteModel()

m.T = pyo.Set(initialize=[1, 2, 3])
m.K = pyo.Set(initialize=[1, 2, 3])
m.I = pyo.Set(initialize=[4, 5, 6])
m.J = pyo.Set(initialize=[7, 8, 9])
m.P = pyo.Set(initialize=[10, 13, 22])
m.Q = pyo.Set(initialize=[11, 14, 24])
m.D = pyo.Set(initialize=[12, 15, 19])
m.A = pyo.Set(m.K, within=m.P*m.Q*m.D, initialize={ 1: [(10, 11, 12), (13, 14, 15)], 
                                                    2: [(22, 24, 19),],
                                                    3: [(10, 11, 15),]})

m.y = pyo.Var(m.K, m.P, m.Q, m.I, m.J, m.T, domain=pyo.Binary)

# flatten out the nested reference to A_k...
m.A_k_flat = pyo.Set(dimen=4, initialize=[(k, p, q, d) for k in m.K for (p, q, d) in m.A[k] ])

@m.Constraint(m.A_k_flat)
def nested_constraint(m, k, p, q, d):
    if k == m.K.last():
        return pyo.Constraint.Skip
    sum_1 = sum(m.y[k, p, q, i, j, t]*t + 1 for i in m.I for j in m.J for t in m.T)
    sum_2 = sum(m.y[m.K.next(k), p, q, i, j, t]*t for i in m.I for j in m.J for t in m.T)
    return sum_1 <= sum_2

m.pprint()

选项2:

# constraint over members of indexed set

import pyomo.environ as pyo

m = pyo.ConcreteModel()

m.T = pyo.Set(initialize=[1, 2, 3])
m.K = pyo.Set(initialize=[1, 2, 3])
m.I = pyo.Set(initialize=[4, 5, 6])
m.J = pyo.Set(initialize=[7, 8, 9])
m.P = pyo.Set(initialize=[10, 13, 22])
m.Q = pyo.Set(initialize=[11, 14, 24])
m.D = pyo.Set(initialize=[12, 15, 19])
m.A = pyo.Set(m.K, within=m.P*m.Q*m.D, initialize={ 1: [(10, 11, 12), (13, 14, 15)], 
                                                    2: [(22, 24, 19),],
                                                    3: [(10, 11, 15),]})

m.y = pyo.Var(m.P, m.Q, m.I, m.J, m.T, domain=pyo.Binary)

# flatten out the nested reference to A_k... and flatten again for k, k+1 capture
m.A_k_pairs_flat = pyo.Set(dimen=6, initialize=[(p, q, d, pp, qq, dd) 
    for k in m.K-{m.K.last(), }                 # subset of m.K without last element
    for (p, q, d) in m.A[k]                     # the tuple for k
    for (pp, qq, dd) in m.A[m.K.next(k)] ])     # the tuple for k+1

@m.Constraint(m.A_k_pairs_flat)
def nested_constraint(m, p, q, d, pp, qq, dd):
    sum_1 = sum(m.y[p, q, i, j, t]*t + 1 for i in m.I for j in m.J for t in m.T)
    sum_2 = sum(m.y[pp, qq, i, j, t]*t   for i in m.I for j in m.J for t in m.T)
    return sum_1 <= sum_2

m.A_k_pairs_flat.pprint()

产量:

A_k_pairs_flat : Size=1, Index=None, Ordered=Insertion
    Key  : Dimen : Domain : Size : Members
    None :     6 :    Any :    3 : {(10, 11, 12, 22, 24, 19), (13, 14, 15, 22, 24, 19), (22, 24, 19, 10, 11, 15)}
[Finished in 361ms]
© www.soinside.com 2019 - 2024. All rights reserved.