Python 为什么在向约束函数传递参数时Pyomo行为会发生变化?

Python 为什么在向约束函数传递参数时Pyomo行为会发生变化?,python,optimization,pyomo,Python,Optimization,Pyomo,此代码工作正常 def m(model, i): return model.fd_amt[i] <= getattr(model, 'br_sa_ind')[i] * global_m setattr(model, ind+"_m",Constraint(model.br_standalone_I, rule=m)) defm(型号i): return model.fd_amt[i]您的代码不起作用,因为您使用函数调用rule=m(…)而不是函数引用rule=m 虽然此解决方案

此代码工作正常

def m(model, i):
    return model.fd_amt[i] <= getattr(model, 'br_sa_ind')[i] * global_m

setattr(model, ind+"_m",Constraint(model.br_standalone_I, rule=m))
defm(型号i):

return model.fd_amt[i]您的代码不起作用,因为您使用函数调用
rule=m(…)
而不是函数引用
rule=m

虽然此解决方案可能无法直接解决您的问题,但它可能会提供一个解决方案。我仍然不知道Pyomo是否允许您的请求(将参数传递给规则)

使用要作为唯一元素传递的参数创建一个新集。如果您能够充分处理规则函数中的参数,您可以在以后添加更多元素。为了简单起见,让我们只从一个元素开始

model.S = Set(initialize=['br_sa_ind'])
然后将此集合用作规则的参数。这就像使用一个表示所有元素的符号,只有一个元素。(对于集合S和集合br_独立_I中的所有元素,应用规则m)。您应该使用以下命令创建约束:

Constraint(model.br_standalone_I, model.S, rule=m)
所以你的整个代码看起来像

def m(model, i, ind_name):
    return model.fd_amt[i] <= getattr(model, ind_name)[i] * global_m

setattr(model, ind+"_m",Constraint(model.br_standalone_I, model.S, rule=m))
defm(型号、i、标识名):

return model.fd_amt[i]您的代码不起作用,因为您使用函数调用
rule=m(…)
而不是函数引用
rule=m

虽然此解决方案可能无法直接解决您的问题,但它可能会提供一个解决方案。我仍然不知道Pyomo是否允许您的请求(将参数传递给规则)

使用要作为唯一元素传递的参数创建一个新集。如果您能够充分处理规则函数中的参数,您可以在以后添加更多元素。为了简单起见,让我们只从一个元素开始

model.S = Set(initialize=['br_sa_ind'])
然后将此集合用作规则的参数。这就像使用一个表示所有元素的符号,只有一个元素。(对于集合S和集合br_独立_I中的所有元素,应用规则m)。您应该使用以下命令创建约束:

Constraint(model.br_standalone_I, model.S, rule=m)
所以你的整个代码看起来像

def m(model, i, ind_name):
    return model.fd_amt[i] <= getattr(model, ind_name)[i] * global_m

setattr(model, ind+"_m",Constraint(model.br_standalone_I, model.S, rule=m))
defm(型号、i、标识名):

return model.fd_amt[i]您可以通过将
规则=
替换为
expr=
来实现所需的行为:

setattr(model, ind+"_m",Constraint(model.br_standalone_I))
for i in model.br_standalone_I:
    getattr(model, ind+"_m")[i].set_value(expr=m(model, i, 'br_sa_ind'))

规则
的目的是使用通用规则构造索引约束表达式。如果有单例约束,可以使用
expr

指定表达式。您可以通过将
规则=
替换为
expr=
来实现所需的行为:

setattr(model, ind+"_m",Constraint(model.br_standalone_I))
for i in model.br_standalone_I:
    getattr(model, ind+"_m")[i].set_value(expr=m(model, i, 'br_sa_ind'))

规则
的目的是使用通用规则构造索引约束表达式。如果有单例约束,可以使用
expr

指定表达式要指定约束,需要使用引用而不是函数调用指定规则(请参见代码的最后一行)。然而,要将一个参数传递给这个约束,我想不出任何精巧的方法。看看你的代码,我想说也许你应该看看你的集合。“br_sa_ind”可能是集合中用于构建约束的唯一元素。但我宁愿等着看你的问题是否有正确答案。要指定约束,你需要用引用而不是函数调用来指定规则(请参阅代码的最后一行)。然而,要将一个参数传递给这个约束,我想不出任何精巧的方法。看看你的代码,我想说也许你应该看看你的集合。“br_sa_ind”可能是集合中用于构建约束的唯一元素。但是我宁愿等着看你的问题是否有一个正确的答案。因此,我想澄清一下,如果传递给第三个参数的集合中有多个变量名,它将循环遍历每个变量?简言之,是的。将这些集合作为参数来创建一个新的约束组件,使得Pyomo循环遍历这些集合中的所有元素,事实上,在集合中的每个元素组合中创建一个约束。这相当于说“对于集合s中的所有元素”。但要小心,因为这更像是一个黑客。我不知道这将如何随着代码的未来部分而扩展。通常,约束中的集合应用于为约束规则中的变量或参数提供索引。感谢您的澄清。我应该能够将一个索引列表传递给一个指示符变量,而不是传递一个指示符变量列表以保持此可伸缩性。感谢您的反馈。因此,请澄清一下,如果传递给第三个参数的集合中有多个变量名,它将循环遍历每个变量?简言之,是的。将这些集合作为参数来创建一个新的约束组件,使得Pyomo循环遍历这些集合中的所有元素,事实上,在集合中的每个元素组合中创建一个约束。这相当于说“对于集合s中的所有元素”。但要小心,因为这更像是一个黑客。我不知道这将如何随着代码的未来部分而扩展。通常,约束中的集合应用于为约束规则中的变量或参数提供索引。感谢您的澄清。我应该能够将一个索引列表传递给一个指示符变量,而不是传递一个指示符变量列表以保持此可伸缩性。感谢您的反馈。这确实让我正确地通过了VAR。未来用户注意:如果您使用“expr”,您还需要编写迭代器,而不是让“rule”为您执行。这确实允许我正确地传递变量。未来用户注意:如果您使用“expr”,您还需要编写一个迭代器,而不是让“rule”为您编写迭代器。