Pyomo函数,每当发生索引错误时返回默认值

时间:2017-06-16 12:01:20

标签: python pyomo

每当我尝试访问索引无效的索引变量时,我想创建一个返回默认值(= 0)的函数。这是我到目前为止所做的。

def SafeguardIdx(object, index_set):
    print("Guarded {} with index {}".format(object.name, index_set), index_set in object.index_set())
    return base.expr.Expr_if(IF=index_set in object.index_set(), THEN=object[index_set], ELSE=0)

这就是我得到的:

Guarded ENDINVW_jwt with index (1, 1, 0) False
KeyError: "Error accessing indexed component: Index '(1, 1, 0)' is not valid for array component 'ENDINVW_jwt'"

为什么即使" IF ="也要访问索引。评估为False?

编辑:我也想问一下我的min()函数的实现是否正确:

def PyomoMin(a, b):
    return base.expr.Expr_if(IF=(a > b), THEN=(a), ELSE=(b))

提前致谢!

2 个答案:

答案 0 :(得分:2)

你想要什么并没有多大意义。 Expr_if构造将3参数节点添加到表达式图中。也就是说,要定义表达式,IF,THEN和ELSE子句都必须都是有效的Pyomo表达式。如果在生成模型时可以评估表达式(例如,索引不存在),则不应使用Expr_if。可以使用简单的python SafeguardIdx实现if

至于实施min(),您的实施

def PyomoMin(a, b):
    return base.expr.Expr_if(IF=(a > b), THEN=(a), ELSE=(b))

实际上实现了max()。如果您需要min(),则需要反转比较或指定THEN=b, ELSE=a。也就是说,这通常不是实施min()的推荐方法。这个公式有几个问题(另见Constraints involving max in a linear program?):

  1. Expr_if仅可通过NL接口使用(因此您无法将其发送给LP / MIP解算器)。
  2. min()不平滑(大多数NL解算器需要),因此NL解算器可能存在收敛问题(特别是如果解决方案靠近a == b的地方)
  3. 还有其他方法来制定min,但它们都涉及添加额外的变量/约束,“最佳”取决于你的其他模型。最简单的是引入一个额外的变量(例如minab),然后将其约束为小于ab。如果客观压力试图最大化minab,那么你没事。但是,如果目标想要最小化minab,那么您的问题可能会变得无限制或返回无意义的答案。在这种情况下,您还需要实现约束minab >= min(a,b),这很棘手。对于MIP,一个常见的解决方案是引入二进制变量并放宽约束,例如:

    minab >= a - M*y
    minab >= b - M*(1-y)
    

    对于非线性模型,如果您的模型还没有它们,您经常要避免引入二进制文件。有些选项可以通过诸如互补性约束或通过abs()的平滑近似来完成。

答案 1 :(得分:0)

我找到了原始帖子的工作解决方案。

def SafeIdx(item, *index_set, default=0):
    return item[index_set] if index_set in item.index_set() else default