2017-06-16 5 views
0

無効なインデックスを持つインデックス付き変数にアクセスしようとすると、デフォルト値(= 0)を返す関数を作成します。これは私が今までに得たものです。インデックスエラーが発生したときにデフォルト値を返すPyomo関数

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と評価しても?

EDIT:分()関数の私の実装が正しければ、私もお願いしたいと思います:

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

感謝を事前に!

答えて

2

本当に意味をなさないものです。 Expr_ifコンストラクトは、3引数のノードを式グラフに追加します。つまり、式を定義するには、IF、THEN、およびELSE句がすべて有効なPyomo式でなければなりません。モデルを生成しているときに式を評価できる場合(たとえば、インデックスが存在しない場合)は、Expr_ifを使用しないでください。 SafeguardIdxは単純なpython 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ソルバーにそれを送信することはできません)。 NLソルバが

(溶液がどこa == b近くにある場合は特に)、収束の問題を有することができるよう

  • min()することはありminを策定する選択肢がありますが、それらはすべて、(ほとんどのNLソルバーを必要とする)スムーズされていません追加の変数/制約を追加することが含まれ、「最良」は残りのモデルに依存します。最も簡単なのは、余分な変数(例えば、minab)を導入し、それをabより小さくすることです。客観的な圧力がminabを最大にしようとしている場合は、問題ありません。しかし、目的がminabを最小限に抑えたい場合は、問題が無制限になるか、無意味な回答が返される可能性があります。この場合は、制約があるminab >= min(a,b)も実装する必要があります。これは扱いにくいものです。 MIPのために、一般的な解決策は、バイナリ変数を導入し、制約を緩和することで、例えば:非線形モデルの場合

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

    あなたは頻繁にあなたのモデルは、すでにそれらを持っていない場合はバイナリを導入しないようにしたいです。相補性制約のようなものや、abs()の円滑な近似を通ることができるオプションがあります。

  • 0

    元の投稿のための解決策を見つけました。

    def SafeIdx(item, *index_set, default=0): 
        return item[index_set] if index_set in item.index_set() else default 
    
    関連する問題