Utilities ========= .. _io-with-lp-format: ファイル入出力 -------------- Amplify SDK の :class:`~amplify.BinaryQuadraticModel` を、 LP ファイル形式もしくは QPLIB ファイル形式で読み書きすることができます。 LP ファイルフォーマット ^^^^^^^^^^^^^^^^^^^^^^^ LP ファイルのフォーマットは、 `Gurobi LP Format `_ に従います。 ただし、以下の制限があります。 * すべての変数がバイナリ変数である必要があります。 * 以下のセクションおよびサブセクションは未定義あるいは空である必要があります。 * Bounds Section * Variable Type Section のうち Binary 以外のもの * 以下の形式およびセクションには対応していません。 * Multi-Objective * Indicator Constraint * Lazy Constraints Section * SOS Section * PWLObj Section * General Constraint Section * Scenario Section QPLIB ファイルフォーマット ^^^^^^^^^^^^^^^^^^^^^^^^^^ QPLIB ファイルのフォーマットは、 `QPLIB `_ に従います。 ただし、変数はすべてバイナリ変数である必要があります。つまり、Problem Type の 2 つ目の文字は ``B`` である必要があります。 ファイルへの出力 ^^^^^^^^^^^^^^^^ Amplify SDK で作成した論理模型をファイルに出力するには、 :func:`~amplify.save_lp` または :func:`~amplify.save_qplib` の第一引数に :class:`~amplify.BinaryQuadraticModel` を、第二引数にファイルパスを与えます。 .. code-block:: python from amplify import BinarySymbolGenerator, BinaryQuadraticModel, save_lp from amplify.constraint import one_hot gen = BinarySymbolGenerator() q = gen.array(4) # 長さ 4 の変数配列を生成 f = 2 * q[0] * q[1] * q[2] + q[0] * q[1] + q[0] + q[1] + q[2] - 1 c1 = one_hot(q[:3]) # q_0 + q_1 + q_2 == 1 c2 = one_hot(q[1:]) # q_1 + q_2 + q_3 == 1 model = BinaryQuadraticModel(f, c1 + c2) save_lp(model, "model.lp") このとき、 ``model.lp`` は以下のようになります。 :: Minimize x_0 + x_1 + x_2 + 2 x_3 + [ 6 x_0 * x_1 + 4 x_0 * x_2 - 4 x_0 * x_3 + 4 x_1 * x_2 - 4 x_1 * x_3 - 4 x_2 * x_3 ] / 2 - 1 Subject To x_0 + x_1 + x_2 = 1 x_1 + x_2 + x_4 = 1 Binaries x_0 x_1 x_2 x_3 x_4 End LP ファイルまたは QPLIB ファイルに記述される多項式は二次以下である必要があります。そのため、次数下げ等を行った後の論理模型の論理レイヤの式が保存されます。したがって、入力変数とは変数変換が行われている可能性があり、これは :attr:`~amplify.BinaryQuadraticModel.logical_mapping` で取得できます。また、制約条件の制約式が自然に 2 次以下の式で表される場合はその式が書き出され、そうでない場合は「二次に次数下げを行ったペナルティ関数 :math:`= 0`」の式が書き出されます。 ファイルからの読み込み ^^^^^^^^^^^^^^^^^^^^^^ LP ファイルまたは QPLIB ファイルを :class:`~amplify.BinaryQuadraticModel` に変換するには、 :func:`~amplify.load_lp` または :func:`~amplify.load_qplib` の引数にファイルパスを与えます。 戻り値は、 論理模型と、変数名をキーとしインデックスを値とする辞書のタプルとなります。 たとえば、上の :func:`~amplify.save_lp` の例で作成した ``model.lp`` は、以下のように読み込むことができます。 .. code-block:: python from amplify import load_lp model, variables = load_lp("model.lp") >>> model.input_poly 3 q_0 q_1 + 2 q_0 q_2 - 2 q_0 q_3 + 2 q_1 q_2 - 2 q_1 q_3 - 2 q_2 q_3 + q_0 + q_1 + q_2 + 2 q_3 - 1 >>> variables {'x_4': 4, 'x_3': 3, 'x_2': 2, 'x_1': 1, 'x_0': 0} 制約条件の読み込みについては、 内部的に :func:`~amplify.constraint.equal_to` や :func:`~amplify.constraint.less_equal` などが呼び出されます。ここで、 :func:`~amplify.constraint.penalty` は使われないことに注意してください。また、:func:`~amplify.load_lp` または :func:`~amplify.load_qplib` のキーワード引数 ``inequality_formulation_method``, ``quadratization_method`` にそれぞれ :class:`~amplify.InequalityFormulation` クラス, :class:`~amplify.QuadratizationMethod` クラスを与えることで、論理模型の構築の際に使用される不等式制約の定式化方法と次数下げアルゴリズムを指定することができます。これらの詳細な使い方については、:ref:`不等式制約の実現方法 ` および :ref:`次数下げアルゴリズムの指定 ` を参照してください。 .. note:: :class:`~amplify.BinaryQuadraticModel` のファイルへの保存と読み込みを目的として LP ファイルや QPLIB ファイルを用いると、元となる論理模型を完全には再現することが出来ない場合があることに注意してください。これは、制約条件の構築に用いた関数の情報や、ペナルティ関数の重みに関する情報は LP ファイルや QPLIB ファイルに保存することが出来ないためです。 .. note:: :class:`~amplify.BinaryQuadraticModel` は目的関数や制約式が凸であるかどうかの情報を持つことができないため、:func:`~amplify.save_qplib` 関数により作成される QPLIB ファイルの Prolem Type の 1 文字目および 3 文字目が ``C`` や ``D`` となることはありません。同様に、変数および双対変数、制約条件のラグランジュ係数の初期値の情報や変数名も保存されません。