From ff7be0f93d032a55fe887b864f310fa3aab7e152 Mon Sep 17 00:00:00 2001 From: Toshiki Teramura Date: Fri, 13 Dec 2024 22:10:05 +0900 Subject: [PATCH] About ommx.v1.Function --- doc/_toc.yml | 1 + doc/ommx_message/function.ipynb | 118 ++++++++++++++++++++++++++++++++ python/ommx/ommx/v1/__init__.py | 7 ++ 3 files changed, 126 insertions(+) create mode 100644 doc/ommx_message/function.ipynb diff --git a/doc/_toc.yml b/doc/_toc.yml index 3e4c5a20..31ee0a3a 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -15,6 +15,7 @@ parts: - caption: "OMMX Message" chapters: - file: ommx_message/architecture + - file: ommx_message/function - caption: "OMMX Artifact" chapters: - file: ommx_artifact/architecture diff --git a/doc/ommx_message/function.ipynb b/doc/ommx_message/function.ipynb new file mode 100644 index 00000000..77f17d9c --- /dev/null +++ b/doc/ommx_message/function.ipynb @@ -0,0 +1,118 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ommx.v1.Function\n", + "\n", + "数理最適化では目的関数や制約条件を表現するために(数学的な意味での)関数を扱う必要があります。OMMXでは特に多項式を中心に扱い、OMMX Messageには多項式を表すためのデータ構造として以下のものが存在します。\n", + "\n", + "| データ構造 | 説明 |\n", + "| --- | --- |\n", + "| [ommx.v1.Linear](https://jij-inc.github.io/ommx/python/ommx/autoapi/ommx/v1/index.html#ommx.v1.Linear) | 線形の関数。決定変数のIDとその係数のペアを持つ |\n", + "| [ommx.v1.Quadratic](https://jij-inc.github.io/ommx/python/ommx/autoapi/ommx/v1/index.html#ommx.v1.Quadratic) | 二次の関数。決定変数のIDのペアとその係数のペアを持つ |\n", + "| [ommx.v1.Polynomial](https://jij-inc.github.io/ommx/python/ommx/autoapi/ommx/v1/index.html#ommx.v1.Polynomial) | 多項式。決定変数のIDの組とその係数のペアを持つ |\n", + "| [ommx.v1.Function](https://jij-inc.github.io/ommx/python/ommx/autoapi/ommx/v1/index.html#ommx.v1.Function) | 上記のいずれかあるいは定数 |\n", + "\n", + "\n", + "Python SDKでこれらのデータ構造を作る場合、大きく分けて二つの方法があります。まずひとつ目は、各データ構造のコンストラクタを直接呼び出す方法です。たとえば、次のようにして`ommx.v1.Linear`を作ることができます。" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Linear(x1 + 2*x2 + 3)\n" + ] + } + ], + "source": [ + "from ommx.v1 import Linear\n", + "\n", + "linear = Linear(terms={1: 1.0, 2: 2.0}, constant=3.0)\n", + "print(linear)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "このように決定変数はIDで識別され、係数は実数で表されます。係数や定数値にアクセスするには `terms` `constant` プロパティを使います。" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "linear.terms=[(1, 1.0), (2, 2.0)], linear.constant=3.0\n" + ] + } + ], + "source": [ + "print(f\"{linear.terms=}, {linear.constant=}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "もう一つの方法は `ommx.v1.DecisionVariable` から作る方法です。`ommx.v1.DecisionVariable` は決定変数のIDを持つだけのデータ構造です。`ommx.v1.Linear` などの多項式を作る際には、`ommx.v1.DecisionVariable` を使って決定変数を作り、それを使って多項式を作ることができます。" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Linear(x1 + 2*x2 + 3)\n" + ] + } + ], + "source": [ + "from ommx.v1 import DecisionVariable\n", + "\n", + "x = DecisionVariable.binary(1, name=\"x\")\n", + "y = DecisionVariable.binary(2, name=\"y\")\n", + "\n", + "linear = x + 2.0 * y + 3.0\n", + "print(linear)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/python/ommx/ommx/v1/__init__.py b/python/ommx/ommx/v1/__init__.py index 24c8470c..b51fb16b 100644 --- a/python/ommx/ommx/v1/__init__.py +++ b/python/ommx/ommx/v1/__init__.py @@ -1040,6 +1040,13 @@ def terms(self) -> list[tuple[int, float]]: """ return [(term.id, term.coefficient) for term in self.raw.terms] + @property + def constant(self) -> float: + """ + Get the constant term of the linear function + """ + return self.raw.constant + @staticmethod def from_bytes(data: bytes) -> Linear: new = Linear(terms={})