diff --git a/doc/_toc.yml b/doc/_toc.yml index b2077f06..682cf379 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -24,6 +24,7 @@ parts: - caption: "OMMX Ecosystem" chapters: - file: ommx_ecosystem/links + - file: ommx_ecosystem/adapter - caption: "API Reference" chapters: - url: https://jij-inc.github.io/ommx/protobuf.html diff --git a/doc/ommx_ecosystem/adapter.ipynb b/doc/ommx_ecosystem/adapter.ipynb new file mode 100644 index 00000000..b5a17afc --- /dev/null +++ b/doc/ommx_ecosystem/adapter.ipynb @@ -0,0 +1,198 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b578922f-02f2-4169-b16b-d3b5db062d40", + "metadata": {}, + "source": [ + "# 抽象基底クラスの定義およびOMMX Adapterの実装ガイド\n", + "\n", + "## 抽象基底クラスの定義\n", + "\n", + "抽象基底クラス SolverAdapter は、OMMXからSolverを利用するためのAdapterのインターフェイスを規格化するためのものである。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e0c34eb2-8eda-4f6a-9ee8-008222fc654f", + "metadata": {}, + "outputs": [], + "source": [ + "from abc import ABC, abstractmethod\n", + "from typing import Any\n", + "from ommx.v1 import Instance, Solution\n", + "\n", + "\n", + "SolverInput = Any\n", + "SolverOutput = Any\n", + "\n", + "class SolverAdapter(ABC):\n", + " \"\"\"\n", + " OMMXからSolverを利用するためのAdapterの抽象基底クラスです。\n", + " 詳しいアダプターの実装方法は (TODO: ドキュメントへのリンク) を参照してください。\n", + " \"\"\"\n", + "\n", + " @abstractmethod\n", + " def __init__(self, ommx_instance: Instance):\n", + " pass\n", + "\n", + " @staticmethod\n", + " @abstractmethod\n", + " def solve(ommx_instance: Instance) -> Solution:\n", + " pass\n", + "\n", + " @property\n", + " @abstractmethod\n", + " def solver_input(self) -> SolverInput:\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def decode(self, data: SolverOutput) -> Solution:\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "id": "47584ec2-d47e-4ab8-945b-9add00a84fee", + "metadata": {}, + "source": [ + "## OMMX Adapter実装ガイド\n", + "\n", + "本ドキュメントは、OMMXからSolverを実行するためのAdapterを実装する際の推奨事項を記載したものである。下記の内容に従いOMMX Adapterを実装することで、他のOMMX Adapterと一定程度の一貫性を保つことができ、複数のOMMX Adapterを利用するユーザーにとってよりよいユーザー体験の提供に繋がる。そのため、OMMXコミュニティとしては以下の内容に従うことを推奨したい。" + ] + }, + { + "cell_type": "markdown", + "id": "b78df1ee-2de3-4804-900c-3120158635cd", + "metadata": {}, + "source": [ + "### 推奨事項\n", + "\n", + "- OMMXからSolverを利用するためのアダプター `OMMXxxxAdapter`は、抽象基底クラス `SolverAdapter`を継承して実装することを推奨する\n", + "- `SolverAdapter`に実装されているメソッドの引数以外のものを引数として定義する場合は、キーワード限定引数を利用し、デフォルト値を設定するものとする\n", + "- `OMMXxxxAdapter.solve` メソッドは、OMMXからSolverを簡単に使うための静的メソッドとして提供されるべきである\n", + " - Solverのパラメーターを全て引数として実装する必要はない。そのようなユースケースは `OMMXxxxAdapter` クラスを直接使うことで実現できれば十分である\n", + "- `OMMXxxxAdapter` のコンストラクタ内で、以下の処理を行うようにすることを推奨する\n", + " - `ommx.v1.Instance` からSolverの入力形式(データやオブジェクト)を生成する処理\n", + " - `OMMXxxxAdapter.decode` に必要となるデータの生成する処理\n", + "- `OMMXxxxAdapter.solver_input` プロパティは、OMMXからSolverの入力形式(データやオブジェクト)を取得するプロパティとして提供されるべきである\n", + "- `OMMXxxxAdapter.decode` メソッドは、Solverの出力形式(データやオブジェクト)を `ommx.v1.Instance` へと変換するメソッドとして提供されるべきである" + ] + }, + { + "cell_type": "markdown", + "id": "a6a04d73-7413-4d26-8f3f-40b45bb552cb", + "metadata": {}, + "source": [ + "### 検討事項\n", + "\n", + "以下では、推奨するほどではないが実装を検討すると良いものを列挙する。\n", + "\n", + "- `OMMXxxxAdapter.decode_to_state` メソッド: Solverの出力形式(データやオブジェクト)を `ommx.v1.State` に変換するためのメソッド" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c1439963-4d0f-4e62-ac7f-4a7960fa44a3", + "metadata": {}, + "outputs": [], + "source": [ + "class OMMXxxxAdapter(SolverAdapter):\n", + "\t\t...\n", + "\t\tdef decode_to_state(self, data: SolverOutput) -> ommx.v1.State:\n", + "\t\t\t..." + ] + }, + { + "cell_type": "markdown", + "id": "430f540e-f244-422e-9800-31440a6342a9", + "metadata": {}, + "source": [ + "- yyy_to_instance 関数: Solverの入力形式を ommx.v1.Instance に変換する関数" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42ee3b8e-6cb0-497e-a334-16ee421ace72", + "metadata": {}, + "outputs": [], + "source": [ + "def xxx_to_instance(data: Any) -> ommmx.v1.Instance:\n", + "\t\t..." + ] + }, + { + "cell_type": "markdown", + "id": "5996e8a7-5e3b-46a8-bff3-56495a50a064", + "metadata": {}, + "source": [ + "### 推奨事項を満たすOMMX Adapterが保証するユーザー体験\n", + "\n", + "上記の推奨事項を満たすOMMX Adapterは、以下の一貫したユーザー体験を与えることができる。\n", + "\n", + "- Solverを気軽に利用したいユーザー(Solverの入出力方法やパラメーターを把握したくないユーザー)は、共通で提供されている静的メソッド solve で簡単にSolverを実行できる" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d37f44b-ad3d-46d8-a637-30e984597f4e", + "metadata": {}, + "outputs": [], + "source": [ + "from ommx_xxx_adapter import OMMXxxxAdapter\n", + "\n", + "ommx_solution = OMMXxxxAdapter.solve(ommx_instance)" + ] + }, + { + "cell_type": "markdown", + "id": "5ea9a36d-2fa8-42f2-b57a-c2a6882ec61b", + "metadata": {}, + "source": [ + "- Solverをチューニングして利用したいユーザーは、直接 OMMXxxxAdapter クラスを使うことでSolverのパラメーター等を設定して実行できる" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b1d141a2-23e7-4ff0-a29f-5e581133275d", + "metadata": {}, + "outputs": [], + "source": [ + "from ommx_xxx_adapter import OMMXxxxAdapter\n", + "\n", + "adapter = OMMXxxxAdapter(ommx_instance)\n", + "solver_input = adapter.solver_input\n", + "\n", + "... # この部分でSolverのチューニングを行ってから実行し、solver_outputを得る\n", + "\n", + "ommx_solution = adapter.decode(solver_output)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.12.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}