1

pyomo.environ を使って LP モデルを作ってみました。しかし、セットを作るのに苦労しています。私の問題では、2 つのセットを作成する必要があります。1 つのセットは一連のノードからのもので、もう 1 つはノード間の複数のアークからのものです。Networkx を使用してネットワークを作成し、ノードとアークを保存します。ノードデータは (経度、緯度) のようにタプル形式で保存されます。アークは (nodeA, nodeB) として保存されます。ここで、nodeA と nodeB は両方ともタプルの座標です。

したがって、ノードは次のようなものです。

(-97.97516252657978、30.342243012086083)

そして、弧は次のようなものです:

((-97.97516252657978, 30.342243012086083), (-97.976196300350608, 30.34247219922803))

セットを作成しようとした方法は次のとおりです。

# import pyomo.envrion as pe
# create a model m 
m = pe.ConcreteModel()
# network is an object I created by Networkx module
m.node_set = pe.Set(initialize= self.network.nodes()) 
m.arc_set = pe.Set(initialize= self.network.edges())

しかし、arc_set でエラー メッセージが表示され続けました。

ValueError: The value=(-97.97516252657978, 30.342243012086083,
-97.976196300350608, 30.34247219922803) does not have dimension=2, 
which is needed for set=arc_set

どういうわけか私の arc_set が 2 つではなく 1 つのタプルになったのは奇妙だと思いました。次に、ノードとアークを文字列に変換しようとしましたが、それでもエラーが発生しました。誰かヒントを教えてくれませんか?または、このバグをどのように削除しますか? ありがとう!

4

1 に答える 1

4

ボンネットの下で、Pyomo はすべてのインデックス セットを「平坦化」します。つまり、ネストされたタプルを削除して、各セット メンバーがスカラー値の 1 つのタプルになるようにします。これは一般的に他の代数モデリング言語と一致しており、ユーザーがクエリを実行しようとした方法に関係なく、一貫して (そして正しく) コンポーネント メンバーを取得できるようにするのに役立ちます。

あなたの場合、Pyomo はアーク セットの各メンバーを単一の 4 メンバーのタプルとして必要とします。セットを構築するときにタプルをフラット化するために使用できる PyUtilib のユーティリティがあります。

from pyutilib.misc import flatten
m.arc_set = pe.Set(initialize=(tuple(flatten(x)) for x in self.network.edges())

また、いくつかのエラー チェックを実行することもできます。この場合、すべてのエッジが既知のノードで開始および終了することを確認します。

from pyutilib.misc import flatten
m.node_set = pe.Set( initialize=self.network.nodes() ) 
m.arc_set = pe.Set(
    within=m.node_set*m.node_set,
    initialize=(tuple(flatten(x)) for x in self.network.edges() )

これは、浮動小数点数をインデックスとして使用しているこのようなモデルでは特に重要であり、微妙な丸め誤差により、ほぼ同じでも数学的に等しくないインデックスが生成される可能性があります。

構造化されたインデックスとフラット化されたインデックスの両方をサポートするために開発者の間でいくつかの議論がありましたが、下位互換性のある方法でそれをサポートする最善の方法については完全には合意に達していません.

于 2016-10-25T09:02:34.260 に答える