@ohtaman/washi 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +103 -386
- package/README.md +104 -387
- package/README.zh-CN.md +103 -386
- package/THIRD_PARTY_LICENSES.md +5 -4
- package/dist/browser/_washi-node-only-BvRk9kiK.js +0 -0
- package/dist/browser/browser-runtime-TLCY0hkc.js +1793 -0
- package/dist/browser/highs-worker.js +1 -1
- package/dist/browser/highs.wasm +0 -0
- package/dist/browser/highs.wasm.LICENSE +1 -2
- package/dist/browser/loader-DewlSho8.js +643 -0
- package/dist/browser/solvers/glpk.js +3 -3
- package/dist/browser/solvers/glpk.min.js +1 -1
- package/dist/browser/solvers/z3.js +7 -1
- package/dist/browser/solvers/z3.min.js +1 -1
- package/dist/browser/washi.js +1708 -540
- package/dist/browser/washi.min.js +3 -4
- package/dist/lib/_washi-node-only-BvRk9kiK.js +0 -0
- package/dist/lib/highs-browser-runtime.js +2120 -4124
- package/dist/lib/highs-node-runtime.js +24 -1
- package/dist/lib/highs-runtime.js +2 -0
- package/dist/lib/highs-worker.js +1 -1
- package/dist/lib/highs.wasm +0 -0
- package/dist/lib/highs.wasm.LICENSE +1 -2
- package/dist/lib/loader-BZUQNvh4.js +649 -0
- package/dist/lib/{registry-BEfvpZW3.js → registry-D7TZ3Wh_.js} +142 -59
- package/dist/lib/solvers/glpk.js +4 -4
- package/dist/lib/solvers/z3.js +1 -1
- package/dist/lib/washi.js +1576 -465
- package/dist/types/decomposition/benders.d.ts +32 -0
- package/dist/types/decomposition/benders.d.ts.map +1 -0
- package/dist/types/decomposition/column-generation.d.ts +34 -0
- package/dist/types/decomposition/column-generation.d.ts.map +1 -0
- package/dist/types/decomposition/index.d.ts +4 -0
- package/dist/types/decomposition/index.d.ts.map +1 -0
- package/dist/types/decomposition/types.d.ts +230 -0
- package/dist/types/decomposition/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modeler/boolean-expr.d.ts.map +1 -1
- package/dist/types/modeler/constraint.d.ts +11 -0
- package/dist/types/modeler/constraint.d.ts.map +1 -1
- package/dist/types/modeler/expression.d.ts +57 -26
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/index.d.ts +4 -3
- package/dist/types/modeler/index.d.ts.map +1 -1
- package/dist/types/modeler/linearizer.d.ts +15 -0
- package/dist/types/modeler/linearizer.d.ts.map +1 -0
- package/dist/types/modeler/lp-writer.d.ts +3 -1
- package/dist/types/modeler/lp-writer.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +159 -8
- package/dist/types/modeler/model.d.ts.map +1 -1
- package/dist/types/modeler/parser.d.ts +25 -5
- package/dist/types/modeler/parser.d.ts.map +1 -1
- package/dist/types/modeler/solvers/glpk/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/driver.d.ts +232 -0
- package/dist/types/modeler/solvers/highs/driver.d.ts.map +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/loader.d.ts +4 -4
- package/dist/types/modeler/solvers/highs/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/worker-client.d.ts.map +1 -1
- package/dist/types/modeler/solvers/types.d.ts +4 -0
- package/dist/types/modeler/solvers/types.d.ts.map +1 -1
- package/dist/types/modeler/types.d.ts +27 -0
- package/dist/types/modeler/types.d.ts.map +1 -1
- package/docs/examples/diet-sensitivity.md +15 -14
- package/docs/examples/ecommerce-coupons.md +15 -22
- package/docs/examples/index.md +18 -12
- package/docs/examples/knapsack.md +8 -7
- package/docs/examples/portfolio-qp.md +11 -4
- package/docs/examples/production.md +4 -4
- package/docs/examples/shift-scheduling.md +20 -7
- package/docs/examples/smt-security.md +16 -4
- package/docs/examples/transportation.md +46 -19
- package/docs/examples/traveling-salesperson.md +157 -0
- package/docs/examples/unsat-core.md +15 -5
- package/docs/examples/vehicle-routing.md +208 -0
- package/docs/getting-started/ai-agents.md +33 -18
- package/docs/getting-started/cross-origin.md +56 -28
- package/docs/getting-started/index.md +40 -69
- package/docs/getting-started/runtimes.md +66 -61
- package/docs/guide/constraints.md +47 -41
- package/docs/guide/decomposition.md +267 -0
- package/docs/guide/expressions.md +90 -39
- package/docs/guide/formulation-tips.md +212 -0
- package/docs/guide/objectives.md +7 -4
- package/docs/guide/unsat-core.md +28 -9
- package/docs/guide/variables.md +33 -38
- package/docs/ja/getting-started/ai-agents.md +32 -18
- package/docs/solvers/custom-solver.md +1 -1
- package/docs/solvers/highs.md +48 -5
- package/docs/solvers/index.md +4 -4
- package/docs/solvers/z3.md +3 -0
- package/docs/zh/getting-started/ai-agents.md +32 -18
- package/llms-full.txt +1536 -478
- package/llms.txt +28 -22
- package/package.json +19 -16
- package/skills/washi/SKILL.md +21 -17
- package/dist/browser/browser-runtime-D13gHOT5.js +0 -4189
- package/dist/browser/loader-CtaDHef_.js +0 -273
- package/dist/lib/loader-DmNC_UNk.js +0 -279
package/README.ja.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
<picture>
|
|
3
3
|
<source media="(prefers-color-scheme: dark)" srcset="./assets/washi-header-dark.png">
|
|
4
4
|
<source media="(prefers-color-scheme: light)" srcset="./assets/washi-header-light.png">
|
|
5
|
-
<img alt="WaSHI - TypeScript
|
|
5
|
+
<img alt="WaSHI - TypeScript 数理最適化モデラー" src="./assets/washi-header-light.png" width="420" />
|
|
6
6
|
</picture>
|
|
7
|
-
<p><strong>TypeScript
|
|
7
|
+
<p><strong>TypeScript 数理最適化モデラー</strong></p>
|
|
8
8
|
<p>
|
|
9
9
|
<em>線形計画 (LP) • 混合整数計画 (MIP) • 凸二次計画 (QP) • SMT論理制約 & 矛盾診断</em>
|
|
10
10
|
</p>
|
|
@@ -16,19 +16,45 @@
|
|
|
16
16
|
<p>
|
|
17
17
|
<a href="https://www.npmjs.com/package/@ohtaman/washi"><img src="https://img.shields.io/npm/v/@ohtaman/washi?color=crimson&label=npm" alt="npm version" /></a>
|
|
18
18
|
<a href="https://github.com/ohtaman/washi/actions/workflows/distribution.yml"><img src="https://github.com/ohtaman/washi/actions/workflows/distribution.yml/badge.svg" alt="CI Status" /></a>
|
|
19
|
-
<a href="https://ohtaman.
|
|
20
|
-
<a href="https://ohtaman.
|
|
19
|
+
<a href="https://washi.ohtaman.dev/ja/"><img src="https://img.shields.io/badge/docs-online-blue" alt="docs" /></a>
|
|
20
|
+
<a href="https://washi.ohtaman.dev/demo/"><img src="https://img.shields.io/badge/demo-playground-brightgreen" alt="live demo" /></a>
|
|
21
21
|
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="license" /></a>
|
|
22
22
|
</p>
|
|
23
23
|
</div>
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
**WaSHI**(WebAssembly-backed, Solver-independent, High-level modeling Interface)は、Python の **PuLP**
|
|
27
|
+
**WaSHI**(WebAssembly-backed, Solver-independent, High-level modeling Interface)は、Python の **PuLP** に着想を得た、数理最適化と制約プログラミングのための TypeScript / JavaScript 向け代数モデラーです。変数・目的関数・制約をアプリケーションコードで記述し、Node.js やブラウザ上で **HiGHS**(標準)・**Z3**・**GLPK** を使ってそのまま求解できます。
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
## ✨ 主な特徴
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
- **直感的な数式記述**: `` expr`30 * ${x} + 50 * ${y} <= 40` `` や総和・内積(`sum`, `dot`)で数式と制約を簡潔に書けます。
|
|
32
|
+
- **Node.js・ブラウザで完結**: WebAssembly ベースのため、Python サーバーや C/C++ のネイティブビルドなしで動作します。
|
|
33
|
+
- **ソルバー非依存**: 標準同梱の **HiGHS** に加え、オプションの **Z3**・**GLPK** や独自ソルバーへ切り替えられます。
|
|
34
|
+
- **充足判定と矛盾診断**: 論理・数値制約の充足可能性判定や、実行不能(Infeasible)になった原因制約の特定に対応しています。
|
|
35
|
+
- **大規模問題の分解法**: 列生成法やベンダーズ分解などの分解アルゴリズムをサポートしています。
|
|
36
|
+
|
|
37
|
+
## 📚 ドキュメント & リンク
|
|
38
|
+
|
|
39
|
+
- **[ドキュメント](https://washi.ohtaman.dev/ja/)**: モデリングガイド・ソルバー仕様・環境別の導入手順
|
|
40
|
+
- **[ショーケース](https://washi.ohtaman.dev/ja/showcase/) & [ブラウザデモ](https://washi.ohtaman.dev/demo/)**: ブラウザ上で動くデモアプリ集とプレイグラウンド
|
|
41
|
+
- **[サンプル集](https://washi.ohtaman.dev/ja/examples/)**: 課題別の実践レシピと実行可能なサンプルコード([`examples/`](examples/README.md))
|
|
42
|
+
- **[AIエージェント向けガイド](docs/ja/getting-started/ai-agents.md) · [Agent Skill (`SKILL.md`)](skills/washi/SKILL.md) · [`llms.txt`](https://washi.ohtaman.dev/llms.txt) / [`llms-full.txt`](https://washi.ohtaman.dev/llms-full.txt)**: AI コーディングエージェント向けのリファレンス・スキル定義・機械可読ドキュメント
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 📦 インストール & クイックスタート
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install @ohtaman/washi
|
|
50
|
+
|
|
51
|
+
# オプションのソルバープラグイン
|
|
52
|
+
npm install z3-solver # SMT 論理制約・Unsat Core 診断を使う場合
|
|
53
|
+
npm install glpk.js # GLPK ソルバーを使う場合 (GPL-3.0)
|
|
54
|
+
|
|
55
|
+
# AI コーディングエージェント用スキル (Claude Code, Cursor, Codex 等)
|
|
56
|
+
npx skills add ohtaman/washi
|
|
57
|
+
```
|
|
32
58
|
|
|
33
59
|
```ts
|
|
34
60
|
import { Model, expr, maximize } from "@ohtaman/washi";
|
|
@@ -47,446 +73,137 @@ console.log(`生産量: x=${x.value}, y=${y.value} (最大利益: $${m.objective
|
|
|
47
73
|
|
|
48
74
|
---
|
|
49
75
|
|
|
50
|
-
##
|
|
51
|
-
|
|
52
|
-
1. **代数的なモデル記述**: ドメイン変数メソッド(`m.binary`, `m.integer`, `m.continuous`)、タグ付きテンプレート(`expr`)、ベクトル集計関数(`dot`, `sum`)、およびファーストクラスの制約(`m.constraint`)によりモデルを記述します。JavaScript には演算子オーバーロードがないため、`` expr`...` `` は SQL のパラメータバインディングと同様に、中置記法の演算子(`+`, `-`, `*`, `^2`, `<=`, `>=`, `==`)を構文解析しつつ `${...}` に渡された値を型付きの `Var` や式のオブジェクト参照として直接バインドします。これにより、TypeScript の型検査、IDE のシンボルリネーム、多次元変数の添字参照(`${flow[i][j]}`)がそのまま機能します。
|
|
53
|
-
2. **ソルバーアダプター**: 共通のモデリング API から HiGHS・Z3・GLPK を利用でき、[独自アダプターも登録できます](https://github.com/ohtaman/washi/blob/main/docs/ja/solvers/custom-solver.md)。モデルの問題クラスを扱えるソルバーを選ぶ必要があり、対応機能はソルバーごとに異なります。
|
|
54
|
-
3. **ローカル実行と WebAssembly の配布**: ローカルソルバーのアダプターでは、別途 Python サービスや C/C++ のネイティブビルドを用意せずアプリケーション内で求解できるため、プロトタイプから Web ツールを公開する際のバックエンド構築のボトルネックを解消でき、ブラウザ内 LLM(WebGPU / WebLLM 等)とのクライアントサイド連携も容易です。ブラウザへの配布には生成された JS・Worker・WASM が必要です。オフライン利用には、これらをローカルに配置するかキャッシュしておく必要があります。Z3 には追加のブラウザ隔離設定があります。
|
|
55
|
-
4. **名前付き制約と SMT の結果**: Z3 を明示的に使って充足可能性を確認し、矛盾する制約の調査に競合制約(`conflicts` / `unsatCore`)を利用できます。返されるのは矛盾する制約の部分集合であり、最小の集合とは限りません。
|
|
76
|
+
## ⚙️ 対応ソルバー
|
|
56
77
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## ⚙️ ソルバーアダプターと対応範囲
|
|
62
|
-
|
|
63
|
-
| アダプター | エンジンのライセンス | 対応する問題クラス | エンジンの役割 | 提供形態 |
|
|
78
|
+
| ソルバー | ライセンス | 対応クラス | 主な用途 | 導入方法 |
|
|
64
79
|
| :--- | :--- | :--- | :--- | :--- |
|
|
65
|
-
| **HiGHS** |
|
|
66
|
-
| **Z3** |
|
|
67
|
-
| **GLPK** |
|
|
68
|
-
| **Mock** |
|
|
69
|
-
|
|
70
|
-
---
|
|
80
|
+
| **[HiGHS](https://github.com/ERGO-Code/HiGHS)** | MIT | LP, MIP, 凸QP | 数値最適化・エラスティック矛盾修復 | 標準搭載(設定不要) |
|
|
81
|
+
| **[Z3](https://github.com/Z3Prover/z3)** | MIT | SMT, SAT, 論理, MIP | 論理ルール・充足判定・厳密な `unsatCore` | `import "@ohtaman/washi/solvers/z3"` |
|
|
82
|
+
| **[GLPK](https://www.gnu.org/software/glpk/)** | GPL-3.0 | LP, MIP | 線形・混合整数最適化 | `import "@ohtaman/washi/solvers/glpk"` |
|
|
83
|
+
| **Mock** | MIT | — | テスト用の決定論的な模擬応答 | 標準搭載 (`MockSolver`) |
|
|
71
84
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
# npm
|
|
76
|
-
npm install @ohtaman/washi
|
|
77
|
-
|
|
78
|
-
# pnpm
|
|
79
|
-
pnpm add @ohtaman/washi
|
|
80
|
-
|
|
81
|
-
# yarn
|
|
82
|
-
yarn add @ohtaman/washi
|
|
83
|
-
|
|
84
|
-
# bun
|
|
85
|
-
bun add @ohtaman/washi
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
*(任意)* Z3 や GLPK を使用する場合は、各パッケージを追加インストールします:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
npm install z3-solver # SMT・矛盾診断を利用する場合
|
|
92
|
-
npm install glpk.js # GLPK ソルバーを利用する場合 (GPL-3.0)
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
*(任意)* AI コーディングエージェント(Claude Code, Antigravity, Cursor, Codex 等)向けに、[AIエージェント向けクイックリファレンス](docs/ja/getting-started/ai-agents.md)とあわせてポータブルな [`skills/washi/SKILL.md`](skills/washi/SKILL.md) を同梱しています:
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
mkdir -p .agents/skills/washi
|
|
99
|
-
cp node_modules/@ohtaman/washi/skills/washi/SKILL.md .agents/skills/washi/SKILL.md
|
|
100
|
-
```
|
|
85
|
+
プラグインを import した上で、`new Model(...)`・`m.solve(...)`・`m.check(...)` に `{ solver: "z3" }` または `{ solver: "glpk" }` を渡して切り替えます。
|
|
101
86
|
|
|
102
87
|
---
|
|
103
88
|
|
|
104
|
-
## 🚀
|
|
89
|
+
## 🚀 基本的な使い方
|
|
105
90
|
|
|
106
|
-
### 1.
|
|
91
|
+
### 1. 総和・内積(`sum` / `dot`)と条件付き制約
|
|
107
92
|
|
|
108
|
-
|
|
93
|
+
`dot` / `sum` による線形式の記述と、`m.indicator()` による条件付き制約:
|
|
109
94
|
|
|
110
95
|
```ts
|
|
111
|
-
import { Model, expr } from "@ohtaman/washi";
|
|
112
|
-
|
|
113
|
-
const m = new Model("FacilityPlanning");
|
|
114
|
-
|
|
115
|
-
// 1次元辞書形式のバイナリ変数群
|
|
116
|
-
const openCity = m.binary(["Tokyo", "Osaka", "Nagoya"]);
|
|
117
|
-
|
|
118
|
-
// 2次元輸送量行列: [工場] x [店舗]
|
|
119
|
-
const flow = m.continuous(["F1", "F2"], ["StoreA", "StoreB"], { lb: 0, ub: 1000 });
|
|
120
|
-
|
|
121
|
-
// 2次元グリッド (例: 8x8 チェス盤)
|
|
122
|
-
const board = m.binary(8, 8, { prefix: "queen" });
|
|
123
|
-
|
|
124
|
-
// 条件付き Big-M 制約: 東京拠点が閉鎖 (openCity['Tokyo'] == 0) なら flow <= 0
|
|
125
|
-
// (M を省略すると、変数の有限な上下限から安全な最小の Big-M が自動導出されます)
|
|
126
|
-
m.indicator(openCity["Tokyo"], expr`${flow["F1"]["StoreA"]} <= 0`, {
|
|
127
|
-
activeValue: 0,
|
|
128
|
-
name: "tokyo_closed_no_flow",
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
// 進捗コールバック (onProgress) と AbortSignal によるキャンセル制御
|
|
132
|
-
const controller = new AbortController();
|
|
133
|
-
await m.solve({
|
|
134
|
-
signal: controller.signal,
|
|
135
|
-
onProgress: (ev) => {
|
|
136
|
-
// 分枝限定法のライブ指標: ev.elapsedTime, ev.objectiveValue, ev.objectiveBound, ev.mipGap
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// 求解結果が境界・整数性・線形/論理制約を満たすか独立検証
|
|
141
|
-
const report = m.validateSolution();
|
|
142
|
-
console.log("解の検証結果:", report.valid);
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
---
|
|
96
|
+
import { Model, expr, minimize } from "@ohtaman/washi";
|
|
146
97
|
|
|
147
|
-
|
|
98
|
+
const m = new Model("TransportPlanning");
|
|
99
|
+
const factories = ["Tokyo", "Osaka"];
|
|
100
|
+
const stores = ["StoreA", "StoreB"];
|
|
101
|
+
const costs = {
|
|
102
|
+
Tokyo: { StoreA: 4, StoreB: 7 },
|
|
103
|
+
Osaka: { StoreA: 8, StoreB: 3 },
|
|
104
|
+
};
|
|
148
105
|
|
|
149
|
-
|
|
106
|
+
const open = m.binary(factories);
|
|
107
|
+
const ship = m.continuous(factories, stores, { lb: 0, ub: 500 });
|
|
150
108
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const m = new Model("MarkowitzPortfolio");
|
|
155
|
-
const assets = ["Tech", "Bonds", "RealEstate"];
|
|
156
|
-
const returns = [0.14, 0.04, 0.08];
|
|
157
|
-
|
|
158
|
-
// 決定変数: 投資比率 (0.0 〜 1.0)
|
|
159
|
-
const w = m.continuous(assets, { lb: 0, ub: 1 });
|
|
160
|
-
|
|
161
|
-
// 1. 予算制約: 合計 100%
|
|
162
|
-
m.constraint(expr`${sum(assets, (a) => w[a])} == 1.0`, "budget");
|
|
163
|
-
|
|
164
|
-
// 2. 目標リターン: 最低 8.5%
|
|
165
|
-
const retMap = Object.fromEntries(assets.map((a, i) => [a, returns[i]]));
|
|
166
|
-
m.constraint(expr`${dot(retMap, w)} >= 0.085`, "min_return");
|
|
167
|
-
|
|
168
|
-
// 3. 共分散行列 (リスク & 相関)
|
|
169
|
-
const cov = [
|
|
170
|
-
[0.040, 0.002, 0.015],
|
|
171
|
-
[0.002, 0.005, 0.002],
|
|
172
|
-
[0.015, 0.002, 0.025],
|
|
173
|
-
];
|
|
174
|
-
|
|
175
|
-
// 二次目的関数: w^T * Cov * w
|
|
176
|
-
let risk = new QuadExpr();
|
|
177
|
-
for (let i = 0; i < assets.length; i++) {
|
|
178
|
-
for (let j = 0; j < assets.length; j++) {
|
|
179
|
-
risk = risk.add(w[assets[i]].mul(w[assets[j]]).mul(cov[i][j]));
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
m.objective(minimize(risk));
|
|
109
|
+
// 東京工場が閉鎖 (open["Tokyo"] == 0) なら東京工場からの総輸送量は 0
|
|
110
|
+
m.indicator(open["Tokyo"], expr`sum(${ship["Tokyo"]}) <= 0`, { activeValue: 0 });
|
|
111
|
+
m.constraint(expr`${ship["Tokyo"]["StoreA"]} + ${ship["Osaka"]["StoreA"]} >= 100`, "demand_A");
|
|
183
112
|
|
|
113
|
+
m.objective(minimize(expr`dot(${costs}, ${ship})`));
|
|
184
114
|
await m.solve();
|
|
185
|
-
console.log(`最小分散: ${m.objectiveValue?.toFixed(6)}`);
|
|
186
|
-
assets.forEach((name) => {
|
|
187
|
-
console.log(` ${name}: ${((w[name].value || 0) * 100).toFixed(2)}%`);
|
|
188
|
-
});
|
|
189
|
-
```
|
|
190
115
|
|
|
191
|
-
|
|
116
|
+
console.log("Tokyo -> StoreA:", ship["Tokyo"]["StoreA"].value);
|
|
117
|
+
```
|
|
192
118
|
|
|
193
|
-
###
|
|
119
|
+
### 2. 凸二次計画 (QP)
|
|
194
120
|
|
|
195
|
-
|
|
121
|
+
線形制約のもとで二次の目的関数を最小化:
|
|
196
122
|
|
|
197
123
|
```ts
|
|
198
|
-
import { Model,
|
|
199
|
-
import "@ohtaman/washi/solvers/z3";
|
|
200
|
-
|
|
201
|
-
const m = new Model({ name: "SmartSecurityRules" });
|
|
202
|
-
|
|
203
|
-
const isNight = m.bool("isNight");
|
|
204
|
-
const motion = m.bool("motion");
|
|
205
|
-
const alarm = m.bool("alarm");
|
|
206
|
-
const siren = m.bool("siren");
|
|
207
|
-
const lux = m.integer("lux", { lb: 0 });
|
|
208
|
-
|
|
209
|
-
// 論理ルール
|
|
210
|
-
m.constraint(lux.le(50).implies(isNight), "dark_implies_night");
|
|
211
|
-
m.constraint(motion.and(isNight).and(alarm).implies(siren), "alarm_rule");
|
|
124
|
+
import { Model, expr, minimize } from "@ohtaman/washi";
|
|
212
125
|
|
|
213
|
-
|
|
214
|
-
m.
|
|
215
|
-
m.
|
|
216
|
-
m.constraint(alarm, "alarm_on");
|
|
126
|
+
const m = new Model("PortfolioQP");
|
|
127
|
+
const x = m.continuous("tech", { lb: 0, ub: 1 });
|
|
128
|
+
const y = m.continuous("bonds", { lb: 0, ub: 1 });
|
|
217
129
|
|
|
218
|
-
|
|
219
|
-
|
|
130
|
+
m.constraint(expr`${x} + ${y} == 1`, "budget");
|
|
131
|
+
m.constraint(expr`0.14 * ${x} + 0.04 * ${y} >= 0.08`, "min_return");
|
|
132
|
+
m.objective(minimize(expr`0.04 * ${x}^2 + 0.005 * ${y}^2`));
|
|
220
133
|
|
|
221
|
-
|
|
222
|
-
console.log(
|
|
134
|
+
await m.solve();
|
|
135
|
+
console.log(`Tech: ${x.value?.toFixed(2)}, Bonds: ${y.value?.toFixed(2)}`);
|
|
223
136
|
```
|
|
224
137
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
### 4. 矛盾原因の自動特定 (`conflicts` / `unsatCore`)
|
|
138
|
+
### 3. SMT 論理ルール & 矛盾診断 (`m.check`)
|
|
228
139
|
|
|
229
|
-
|
|
140
|
+
論理条件(`m.bool`, `implies`)を含むモデルの充足可能性を判定し、矛盾時の原因制約を特定します:
|
|
141
|
+
- **HiGHS(標準)**: 緩和すれば実行可能になる**修復集合**(`res.conflicts`)を特定します。
|
|
142
|
+
- **Z3**: 相互に矛盾している**充足不能コア**(`res.unsatCore` / `res.conflicts`)を抽出します。
|
|
230
143
|
|
|
231
144
|
```ts
|
|
232
|
-
import { Model, expr } from "@ohtaman/washi";
|
|
233
|
-
import "@ohtaman/washi/solvers/z3";
|
|
145
|
+
import { Model, implies, expr } from "@ohtaman/washi";
|
|
146
|
+
// import "@ohtaman/washi/solvers/z3"; // 厳密な SMT unsatCore を抽出する場合
|
|
234
147
|
|
|
235
|
-
const m = new Model(
|
|
148
|
+
const m = new Model("StaffingRules");
|
|
236
149
|
const engineers = m.integer("engineers", { lb: 0, ub: 20 });
|
|
237
150
|
const budget = m.continuous("budget", { lb: 0, ub: 100000 });
|
|
238
|
-
const
|
|
151
|
+
const rush = m.bool("rush");
|
|
239
152
|
|
|
240
|
-
// ルール 1: エンジニア1人あたり $8,000
|
|
241
153
|
m.constraint(expr`8000 * ${engineers} <= ${budget}`, "budget_limit");
|
|
154
|
+
m.constraint(rush, "rush_required");
|
|
155
|
+
m.constraint(implies(rush, expr`${engineers} >= 8`), "rush_staffing");
|
|
156
|
+
m.constraint(expr`${budget} <= 50000`, "budget_cap"); // 矛盾: 8人 * $8,000 > $50,000
|
|
157
|
+
m.constraint(expr`${engineers} >= 1`, "min_staff"); // 無関係な制約
|
|
242
158
|
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
// ルール 3: 特急納品には最低 8 人のエンジニアが必要
|
|
247
|
-
m.constraint(rushDelivery.implies(engineers.ge(8)), "rush_staffing_rule");
|
|
248
|
-
|
|
249
|
-
// ルール 4: 役員会の予算上限 $50,000 (矛盾: 8人 * $8000 = $64,000 > $50,000!)
|
|
250
|
-
m.constraint(expr`${budget} <= 50000`, "strict_board_budget_cap");
|
|
251
|
-
|
|
252
|
-
// ルール 5: 最低 1 人雇用の労働基準(無関係なルール)
|
|
253
|
-
m.constraint(expr`${engineers} >= 1`, "minimum_one_employee");
|
|
254
|
-
|
|
255
|
-
const res = await m.check({ solver: "z3" });
|
|
256
|
-
|
|
257
|
-
console.log(`ステータス: ${res.status}`); // "Unsat"
|
|
258
|
-
console.log("矛盾している制約:", res.conflicts);
|
|
259
|
-
// 出力: ["budget_limit", "rush_required", "rush_staffing_rule", "strict_board_budget_cap"]
|
|
260
|
-
// ※ 無関係な "minimum_one_employee" は的確に除外されます
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
---
|
|
264
|
-
|
|
265
|
-
### 5. GLPK ソルバーの利用 (GPL-3.0)
|
|
266
|
-
|
|
267
|
-
GNU Linear Programming Kit (GLPK) ソルバープラグインを利用する場合:
|
|
268
|
-
|
|
269
|
-
```ts
|
|
270
|
-
import { Model, expr, maximize } from "@ohtaman/washi";
|
|
271
|
-
import "@ohtaman/washi/solvers/glpk";
|
|
272
|
-
|
|
273
|
-
const m = new Model({ solver: "glpk" });
|
|
274
|
-
const x = m.integer("x", { lb: 0 });
|
|
275
|
-
const y = m.integer("y", { lb: 0 });
|
|
276
|
-
|
|
277
|
-
m.objective(maximize(expr`30 * ${x} + 50 * ${y}`));
|
|
278
|
-
m.constraint(expr`${x} + 2 * ${y} <= 40`, "wood_limit");
|
|
279
|
-
m.constraint(expr`2 * ${x} + ${y} <= 50`, "labor_limit");
|
|
280
|
-
|
|
281
|
-
const status = await m.solve();
|
|
282
|
-
console.log(`ステータス: ${status}`); // "Optimal"
|
|
283
|
-
console.log(`目的関数値: ${m.objectiveValue}`); // 1100
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
---
|
|
287
|
-
|
|
288
|
-
### 6. ベクトル演算と高速内積 (`dot`)
|
|
289
|
-
|
|
290
|
-
ネストしたループを書くことなく、1次元・2次元の線形結合を1行で記述:
|
|
291
|
-
|
|
292
|
-
```ts
|
|
293
|
-
import { Model, dot, minimize } from "@ohtaman/washi";
|
|
294
|
-
|
|
295
|
-
const m = new Model();
|
|
296
|
-
const factories = ["Tokyo", "Osaka"];
|
|
297
|
-
const stores = ["StoreA", "StoreB"];
|
|
298
|
-
|
|
299
|
-
const costs = {
|
|
300
|
-
Tokyo: { StoreA: 4, StoreB: 7 },
|
|
301
|
-
Osaka: { StoreA: 8, StoreB: 3 },
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
const ship = m.continuous(factories, stores);
|
|
305
|
-
|
|
306
|
-
// 総輸送コストを1行で最小化:
|
|
307
|
-
m.objective(minimize(dot(costs, ship)));
|
|
308
|
-
await m.solve();
|
|
309
|
-
|
|
310
|
-
// 最適解の全変数値を取得
|
|
311
|
-
const solution = m.getValues(ship);
|
|
312
|
-
console.log(solution);
|
|
159
|
+
const res = await m.check(); // または await m.check({ solver: "z3" })
|
|
160
|
+
console.log(res.status); // "Unsat"
|
|
161
|
+
console.log(res.conflicts); // HiGHS: ["rush_required"]
|
|
313
162
|
```
|
|
314
163
|
|
|
315
164
|
---
|
|
316
165
|
|
|
317
166
|
## 🌐 ブラウザ & Web Worker での利用方法
|
|
318
167
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
### npm とバンドラー
|
|
322
|
-
|
|
323
|
-
```typescript
|
|
324
|
-
import { Model } from "@ohtaman/washi";
|
|
325
|
-
const model = new Model();
|
|
326
|
-
// 変数・目的関数・制約を定義
|
|
327
|
-
await model.solve();
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
検証対象の Vite / webpack ビルドでは WASM の手動コピー・URL 指定は不要です。その他のバンドラーや SSR は個別に確認し、ブラウザの求解はクライアントで実行してください。ブラウザでは Worker をデフォルトで使用します。簡単なデモは `model.solve({ useWorker: false })` でも動きますが、長い計算中は UI が止まります。
|
|
331
|
-
|
|
332
|
-
### ブラウザ標準 ESM(利用者側のビルド不要)
|
|
333
|
-
|
|
334
|
-
`dist/browser` 一式(JS の分割ファイル・`highs.wasm`・Worker を含む)を HTTP 配信します。Import Maps は不要です。
|
|
168
|
+
- **バンドラー (Vite / webpack 5)**: `import { Model } from "@ohtaman/washi"` でそのまま動作します。ブラウザでは標準で Web Worker 上で実行されます(メインスレッドで実行する場合は `{ useWorker: false }` を指定)。
|
|
169
|
+
- **単体 ESM / script タグ / CDN**: `dist/browser/` 一式(`highs.wasm` や Worker を含む)を配信するか、CDN の URL を指定して読み込みます。
|
|
335
170
|
|
|
336
171
|
```html
|
|
172
|
+
<!-- ブラウザ ESM -->
|
|
337
173
|
<script type="module">
|
|
338
174
|
import { Model } from "./washi/washi.js";
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
await
|
|
342
|
-
</script>
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
### 通常の script / CodePen
|
|
346
|
-
|
|
347
|
-
`dist/browser/washi.min.js` はグローバル API `Washi` を公開します。CodePen の External Scripts にその URL を追加するか、次のように読み込みます。
|
|
348
|
-
|
|
349
|
-
```html
|
|
350
|
-
<script src="./washi/washi.min.js"></script>
|
|
351
|
-
<script>
|
|
352
|
-
const model = new Washi.Model();
|
|
353
|
-
// 変数・目的関数・制約を定義
|
|
354
|
-
model.solve({ useWorker: false }).then(status => console.log(status));
|
|
355
|
-
</script>
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
CDN から直接読み込む場合は、URL を `https://cdn.jsdelivr.net/npm/@ohtaman/washi@<version>/dist/browser/washi.min.js`(対応版リリースが公開された後にそのバージョンを指定)に指定できます。ESM は同じ版の `dist/browser/washi.js` を指定します。CDN の URL を選ぶことが明示的な CDN 利用になり、ローカル配信が勝手に CDN へ切り替わることはありません。
|
|
359
|
-
|
|
360
|
-
### ブラウザ環境でのソルバープラグイン(GLPK & Z3)
|
|
361
|
-
|
|
362
|
-
ブラウザ配布物には、`dist/browser/solvers/` 配下に事前バンドルされたスタンドアロンソルバープラグインが含まれています:
|
|
363
|
-
- **GLPK**: `dist/browser/solvers/glpk.js` (ESM) および `dist/browser/solvers/glpk.min.js` (IIFE、グローバル `WashiGLPK` を登録)
|
|
364
|
-
- **Z3**: `dist/browser/solvers/z3.js` (ESM) および `dist/browser/solvers/z3.min.js` (IIFE、グローバル `WashiZ3` を登録)、ならびに `z3-built.js` / `z3-built.wasm`
|
|
365
|
-
|
|
366
|
-
#### ブラウザ ESM での GLPK 利用
|
|
367
|
-
```html
|
|
368
|
-
<script type="module">
|
|
369
|
-
import { Model, maximize } from "./washi/washi.js";
|
|
370
|
-
import "./washi/solvers/glpk.js";
|
|
371
|
-
|
|
372
|
-
const model = new Model({ solver: "glpk" });
|
|
373
|
-
const x = model.continuous("x", { lb: 0, ub: 10 });
|
|
374
|
-
model.objective(maximize(x));
|
|
375
|
-
await model.solve();
|
|
376
|
-
console.log("GLPK ステータス:", model.status);
|
|
175
|
+
// オプションプラグイン: import "./washi/solvers/glpk.js" または "./washi/solvers/z3.js"
|
|
176
|
+
const m = new Model();
|
|
177
|
+
await m.solve();
|
|
377
178
|
</script>
|
|
378
|
-
```
|
|
379
179
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
<script src="./washi/washi.min.js"></script>
|
|
383
|
-
<script src="./washi/solvers/glpk.min.js"></script>
|
|
384
|
-
<script>
|
|
385
|
-
const model = new Washi.Model({ solver: "glpk" });
|
|
386
|
-
const x = model.continuous("x", { lb: 0, ub: 10 });
|
|
387
|
-
model.objective(Washi.maximize(x));
|
|
388
|
-
model.solve().then(status => console.log("GLPK ステータス:", status));
|
|
389
|
-
</script>
|
|
180
|
+
<!-- script タグ / CodePen (グローバル Washi を公開) -->
|
|
181
|
+
<script src="https://cdn.jsdelivr.net/npm/@ohtaman/washi/dist/browser/washi.min.js"></script>
|
|
390
182
|
```
|
|
391
183
|
|
|
392
184
|
> [!NOTE]
|
|
393
|
-
>
|
|
394
|
-
> Z3 の WebAssembly エンジンはマルチスレッド(`SharedArrayBuffer`)を必要とするため、`Cross-Origin-Opener-Policy: same-origin` および `Cross-Origin-Embedder-Policy: require-corp` ヘッダーによる Cross-Origin Isolation が必要です。静的ホスティング(`coi-serviceworker.js`)、イントラネット・オフライン配置、CSP(`worker-src blob:`)、カスタム WASM URL(`setHighsWasmUrl`)の詳細は [Cross-Origin Isolation 設定](docs/ja/getting-started/cross-origin.md) および [ランタイム環境とデプロイ構成](docs/ja/getting-started/runtimes.md) を参照してください。
|
|
395
|
-
|
|
396
|
-
完全なスタンドアロンサンプル(ESM、スクリプトタグ、CodePen)は [`examples/distribution/`](examples/distribution/README.md) に用意されています。
|
|
397
|
-
|
|
398
|
-
---
|
|
399
|
-
|
|
400
|
-
## 🛠️ カスタムソルバー開発と拡張性
|
|
401
|
-
|
|
402
|
-
WaSHI は疎結合なプラグイン方式のソルバーアーキテクチャを採用しています。独自の最適化エンジン(クラウド REST ソルバー、WebAssembly エンジン、商用ソルバーアダプターなど)を容易に構築・登録できます:
|
|
403
|
-
|
|
404
|
-
- 詳細な開発手順、API コントラクト仕様(`Solver`, `SolveModelData`, `CheckModelData`, `SolverResult`)、およびテスト手法については [カスタムソルバー開発ガイド](docs/ja/solvers/custom-solver.md) をご覧ください。
|
|
185
|
+
> **ブラウザでの Z3 利用**: Z3 の WebAssembly は `SharedArrayBuffer` を使用するため、Cross-Origin Isolation(`COOP: same-origin` / `COEP: require-corp`)が必要です。詳細は [Cross-Origin Isolation 設定](docs/ja/getting-started/cross-origin.md) および [`examples/distribution/`](examples/distribution/README.md) を参照してください。
|
|
405
186
|
|
|
406
187
|
---
|
|
407
188
|
|
|
408
|
-
##
|
|
189
|
+
## 🤝 コントリビューション・開発
|
|
409
190
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
- **はじめに**: [クイックスタート](docs/ja/getting-started/index.md) · [AIエージェント向けクイックリファレンス](docs/ja/getting-started/ai-agents.md) · [ランタイム環境とデプロイ構成](docs/ja/getting-started/runtimes.md) · [Cross-Origin Isolation (Z3)](docs/ja/getting-started/cross-origin.md)
|
|
413
|
-
- **モデリングガイド**: [決定変数 (`Var`, `BoolVar`)](docs/ja/guide/variables.md) · [数式と集計 (`expr`, `sum`, `dot`)](docs/ja/guide/expressions.md) · [制約と論理条件 (`indicator`, SMT)](docs/ja/guide/constraints.md) · [目的関数と求解 (`solve`, `validateSolution`)](docs/ja/guide/objectives.md) · [充足可能性と Unsat Core (`check`)](docs/ja/guide/unsat-core.md)
|
|
414
|
-
- **ソルバー**: [ソルバー概要](docs/ja/solvers/index.md) · [HiGHS](docs/ja/solvers/highs.md) · [Z3](docs/ja/solvers/z3.md) · [GLPK](docs/ja/solvers/glpk.md) · [カスタムソルバー](docs/ja/solvers/custom-solver.md)
|
|
191
|
+
ローカル開発、テスト・ベンチマークの実行、WebAssembly アセットの再ビルド、およびリリース手順については [CONTRIBUTING.md](./CONTRIBUTING.md) を参照してください。
|
|
415
192
|
|
|
416
193
|
---
|
|
417
194
|
|
|
418
|
-
##
|
|
419
|
-
|
|
420
|
-
[サンプル一覧](https://github.com/ohtaman/washi/blob/main/examples/README.md)および[オンライン実践レシピ集・API逆引き索引](https://ohtaman.github.io/washi/ja/examples/)では、目的別・WaSHI の API 機能別にサンプルを探せます。
|
|
195
|
+
## 🙏 謝辞
|
|
421
196
|
|
|
422
|
-
|
|
423
|
-
| :--- | :--- | :--- | :--- |
|
|
424
|
-
| **基本モデル** | [生産計画](https://github.com/ohtaman/washi/blob/main/examples/node/01-production-planning.ts) | 整数変数、利益の最大化、資源制約 (`expr`) | HiGHS |
|
|
425
|
-
| **基本モデル** | [輸送・物流ネットワーク](https://github.com/ohtaman/washi/blob/main/examples/node/09-transportation-problem.ts) | 2次元マトリクス変数 (`continuous(rows, cols)`) と供給・需要バランス | HiGHS |
|
|
426
|
-
| **基本モデル** | [栄養問題と感度分析](https://github.com/ohtaman/washi/blob/main/examples/node/10-diet-sensitivity.ts) | 潜在価格 (`constr.dual`)、余剰 (`constr.slack`)、被約費用 (`var.reducedCost`) | HiGHS |
|
|
427
|
-
| **実践応用** | [スタッフのシフト作成](https://github.com/ohtaman/washi/blob/main/examples/node/11-shift-scheduling.ts) | 週間シフト最適化と、土曜日の希望休が衝突した際の原因特定 | HiGHS + Z3 |
|
|
428
|
-
| **実践応用** | [ECカートのクーポン最適適用](https://github.com/ohtaman/washi/blob/main/examples/node/12-ecommerce-coupon-optimizer.ts) | 条件付き購入金額閾値 (`indicator`)、併用不可ルール、追加購入提案 | HiGHS |
|
|
429
|
-
| **実践応用** | [ポートフォリオ配分](https://github.com/ohtaman/washi/blob/main/examples/node/03-portfolio-qp.ts) | 凸二次目的関数 (`QuadExpr`) と配分の制約 | HiGHS |
|
|
430
|
-
| **論理 / SMT** | [業務ルールの検証](https://github.com/ohtaman/washi/blob/main/examples/node/04-smt-security-rules.ts) | 数値・論理制約 (`bool`, `implies`) の充足可能性の確認 | Z3 |
|
|
431
|
-
| **論理 / SMT** | [矛盾する制約の診断](https://github.com/ohtaman/washi/blob/main/examples/node/05-unsat-core-diagnosis.ts) | 名前付き制約と Unsat Core (`unsatCore`) | Z3 |
|
|
432
|
-
|
|
433
|
-
[公開ブラウザデモ](https://ohtaman.github.io/washi/demo/)では、モデルを編集して実行できます。ブラウザ標準 ESM、script タグ、CodePen での使い方は[配布形式のサンプル](https://github.com/ohtaman/washi/blob/main/examples/distribution/README.md)を参照してください。Z3 は Cross-Origin Isolation が必要です。詳細は上記のブラウザ要件に記載しています。
|
|
434
|
-
|
|
435
|
-
ローカルで実行する場合は、リポジトリを取得して開発用依存をインストールします。
|
|
436
|
-
|
|
437
|
-
```bash
|
|
438
|
-
git clone https://github.com/ohtaman/washi.git
|
|
439
|
-
cd washi
|
|
440
|
-
npm ci
|
|
441
|
-
npx tsx examples/node/01-production-planning.ts
|
|
442
|
-
npx tsx examples/node/09-transportation-problem.ts
|
|
443
|
-
npx tsx examples/node/10-diet-sensitivity.ts
|
|
444
|
-
npx tsx examples/node/11-shift-scheduling.ts
|
|
445
|
-
npx tsx examples/node/12-ecommerce-coupon-optimizer.ts
|
|
446
|
-
|
|
447
|
-
# ローカルのブラウザデモ: http://localhost:5173/demo/
|
|
448
|
-
npm run dev
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
サンプルはリポジトリの `src/` モジュールを import しています。公開パッケージを使うアプリでは、`@ohtaman/washi` と必要なソルバープラグインから import してください。
|
|
452
|
-
|
|
453
|
-
---
|
|
454
|
-
|
|
455
|
-
## 🧪 テスト & 再現可能なベンチマーク
|
|
456
|
-
|
|
457
|
-
リポジトリのユニット・統合テストを実行し、配布物をビルドできます:
|
|
458
|
-
|
|
459
|
-
```bash
|
|
460
|
-
# すべてのユニット・統合テストを実行
|
|
461
|
-
npm test
|
|
462
|
-
|
|
463
|
-
# プロダクション用バンドルと型定義を生成
|
|
464
|
-
npm run build
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
### オプションの再現可能なベンチマーク
|
|
468
|
-
|
|
469
|
-
正しさのテストの合否閾値に実行時間を含めることなく、決定論的な `small-lp`(24変数・18制約)および `scheduling-mip`(315変数・231制約、再構築モデルの `initialValue` ウォームスタートを含む)の各フェーズを計測できます:
|
|
470
|
-
|
|
471
|
-
```bash
|
|
472
|
-
# Node.js インプロセス WASM ベンチマークを実行(HiGHS・GLPK、デフォルト5回反復)
|
|
473
|
-
npm run bench
|
|
474
|
-
|
|
475
|
-
# 反復回数の指定や JSON 出力
|
|
476
|
-
node scripts/run-benchmarks.mjs --iterations=10 --json
|
|
477
|
-
|
|
478
|
-
# ヘッドレス Chromium の Web Worker 実行も計測(Playwright Chromium が必要)
|
|
479
|
-
node scripts/run-benchmarks.mjs --browser
|
|
480
|
-
```
|
|
197
|
+
WaSHI は、数理最適化および自動推論分野の素晴らしいオープンソースソフトウェアの上に成り立っています:
|
|
481
198
|
|
|
482
|
-
-
|
|
483
|
-
-
|
|
199
|
+
- **[HiGHS](https://highs.dev/)**([`ERGO-Code/HiGHS`](https://github.com/ERGO-Code/HiGHS))— エディンバラ大学の Julian Hall 氏、Qi Huangfu 氏、Ivet Galabova 氏、Leona Gottwald 氏、Michael Feldmeier 氏をはじめとする開発チームによる高性能なオープンソース LP / MIP / 凸 QP ソルバーであり、WaSHI の標準エンジンを支えています(*Huangfu & Hall, Mathematical Programming Computation, 2018*, [DOI: 10.1007/s12532-017-0130-5](https://doi.org/10.1007/s12532-017-0130-5))。
|
|
200
|
+
- **[Z3 Theorem Prover](https://github.com/Z3Prover/z3)**([`z3-solver`](https://www.npmjs.com/package/z3-solver))— Microsoft Research により開発された SMT ソルバーであり、オプションの論理充足判定および `unsatCore` 矛盾診断プラグインを支えています。
|
|
201
|
+
- **[GLPK](https://www.gnu.org/software/glpk/) & [`glpk.js`](https://github.com/jvail/glpk.js)** — オプションの GPL-3.0 LP / MIP ソルバープラグインを支えています。
|
|
202
|
+
- **[PuLP](https://github.com/coin-or/pulp)** — WaSHI の直感的な代数モデリング API 設計に大きな着想を与えました。
|
|
484
203
|
|
|
485
204
|
---
|
|
486
205
|
|
|
487
206
|
## 📄 ライセンス
|
|
488
207
|
|
|
489
208
|
- **`@ohtaman/washi`**: [MIT ライセンス](./LICENSE)
|
|
490
|
-
-
|
|
491
|
-
- **Z3**(オプション): MIT ライセンス
|
|
492
|
-
- **GLPK**(オプション): GPL-3.0 ライセンス
|
|
209
|
+
- **同梱・外部ソルバー**: HiGHS (MIT)、Z3 (MIT)、GLPK (GPL-3.0)。詳細は [THIRD_PARTY_LICENSES.md](./THIRD_PARTY_LICENSES.md) を参照してください。
|