我是 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 的大小。
我做了一些假设,因为规范有点不完整,但我认为你正在寻求做这样的事情。当然,这很快就会变得很大,因为你有一个 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()
# 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]