@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
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { Highs } from "highs";
|
|
2
1
|
import type { SolveOptions } from "../../types.js";
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { Highs, HIGHS_STATUS_NAMES, HIGHS_CONSTANTS, HighsUnsupportedOptionError } from "./driver.js";
|
|
3
|
+
export declare const OFFICIAL_HIGHS_CDN_WASM_URL = "https://cdn.jsdelivr.net/npm/highs@1.15.1/build/highs.wasm";
|
|
4
|
+
export type HighsInstance = Highs;
|
|
5
|
+
export { HIGHS_STATUS_NAMES, HIGHS_CONSTANTS, HighsUnsupportedOptionError, Highs };
|
|
5
6
|
export declare function setHighsWasmUrl(url: string | null): void;
|
|
6
7
|
export declare function getHighsWasmUrl(): string | null;
|
|
7
8
|
/**
|
|
@@ -76,5 +77,4 @@ export declare function solveLpWithHighs(lpString: string, options?: SolveOption
|
|
|
76
77
|
result: RawHighsSolveResult;
|
|
77
78
|
runTime: number;
|
|
78
79
|
}>;
|
|
79
|
-
export {};
|
|
80
80
|
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../../src/modeler/solvers/highs/loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../../src/modeler/solvers/highs/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-runtime.d.ts","sourceRoot":"","sources":["../../../../../src/modeler/solvers/highs/node-runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"node-runtime.d.ts","sourceRoot":"","sources":["../../../../../src/modeler/solvers/highs/node-runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,wBAAsB,aAAa,IAAI,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CA+ChF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solver.d.ts","sourceRoot":"","sources":["../../../../../src/modeler/solvers/highs/solver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAItE;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,OAAO,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,iBAAiB,CAsInB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,OAAO,EAClB,UAAU,CAAC,EAAE,MAAM,EACnB,iBAAiB,CAAC,EAAE,OAAO,GAC1B,YAAY,CA6Bd;AAED;;;GAGG;AACH,qBAAa,WAAY,YAAW,MAAM;IACxC,gBAAuB,YAAY;QACjC,WAAW;QACX,UAAU;QACV,iBAAiB;MACjB;IACF,SAAgB,IAAI,WAAW;IAC/B,SAAgB,OAAO,YAAY;IACnC,SAAgB,YAAY;;;;MAA4B;IACjD,OAAO,EAAE,aAAa,CAAC;IAE9B,YAAY,OAAO,GAAE,aAAkB,EAEtC;IAED,KAAK,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACjF,KAAK,CACH,SAAS,EAAE,WAAW,EACtB,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"solver.d.ts","sourceRoot":"","sources":["../../../../../src/modeler/solvers/highs/solver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAItE;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,OAAO,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,iBAAiB,CAsInB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,OAAO,EAClB,UAAU,CAAC,EAAE,MAAM,EACnB,iBAAiB,CAAC,EAAE,OAAO,GAC1B,YAAY,CA6Bd;AAED;;;GAGG;AACH,qBAAa,WAAY,YAAW,MAAM;IACxC,gBAAuB,YAAY;QACjC,WAAW;QACX,UAAU;QACV,iBAAiB;MACjB;IACF,SAAgB,IAAI,WAAW;IAC/B,SAAgB,OAAO,YAAY;IACnC,SAAgB,YAAY;;;;MAA4B;IACjD,OAAO,EAAE,aAAa,CAAC;IAE9B,YAAY,OAAO,GAAE,aAAkB,EAEtC;IAED,KAAK,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACjF,KAAK,CACH,SAAS,EAAE,WAAW,EACtB,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC,CAAC;CAqN1B;AAED;;GAEG;AACH,eAAO,MAAM,KAAK,oBAAc,CAAC;AAGjC,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-client.d.ts","sourceRoot":"","sources":["../../../../../src/modeler/solvers/highs/worker-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAsB,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAEL,KAAK,mBAAmB,EAGzB,MAAM,aAAa,CAAC;AAmMrB;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,YAAY,GAAG;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACnD,OAAO,CAAC;IAAE,MAAM,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"worker-client.d.ts","sourceRoot":"","sources":["../../../../../src/modeler/solvers/highs/worker-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAsB,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAEL,KAAK,mBAAmB,EAGzB,MAAM,aAAa,CAAC;AAmMrB;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,YAAY,GAAG;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACnD,OAAO,CAAC;IAAE,MAAM,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAqF3D"}
|
|
@@ -86,6 +86,8 @@ export interface SolverOptions {
|
|
|
86
86
|
threads?: number;
|
|
87
87
|
/** Enable verbose solver logging */
|
|
88
88
|
verbose?: boolean;
|
|
89
|
+
/** Solve the continuous/LP relaxation of the model by relaxing integer and binary variables */
|
|
90
|
+
relax?: boolean;
|
|
89
91
|
/** Use Web Worker for non-blocking browser execution */
|
|
90
92
|
useWorker?: boolean;
|
|
91
93
|
/** AbortSignal to cancel an in-flight solve */
|
|
@@ -134,6 +136,8 @@ export interface Solver {
|
|
|
134
136
|
readonly version?: string;
|
|
135
137
|
/** Feature capabilities of this solver */
|
|
136
138
|
readonly capabilities?: SolverCapabilities;
|
|
139
|
+
/** Default options configured on this solver instance */
|
|
140
|
+
readonly options?: SolverOptions;
|
|
137
141
|
/**
|
|
138
142
|
* Solve the given mathematical programming model data
|
|
139
143
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/modeler/solvers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,GAAG,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,KAAK,EAAE,iBAAiB,CAAC;IACzB,SAAS,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,wFAAwF;IACxF,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gGAAgG;IAChG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,GAAG,CAAC;CACX;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,QAAQ,CAAC;IACnC,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,wEAAwE;IACxE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACpD,yCAAyC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yCAAyC;IACzC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mDAAmD;IACnD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8GAA8G;IAC9G,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,KAAK,GAAG,OAAO,GAAG,SAAS,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;IACzC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,GAAG,CAAC;CACX;AAED;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mCAAmC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,0CAA0C;IAC1C,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAC3C;;OAEG;IACH,KAAK,CACH,SAAS,EAAE,cAAc,EACzB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC,CAAC;IACzB;;OAEG;IACH,KAAK,CAAC,CACJ,SAAS,EAAE,cAAc,EACzB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/modeler/solvers/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Constraint } from "./constraint.js";
|
|
1
2
|
/**
|
|
2
3
|
* HiGHS & Model Types
|
|
3
4
|
*/
|
|
@@ -55,6 +56,8 @@ export interface SolveOptions {
|
|
|
55
56
|
signal?: AbortSignal;
|
|
56
57
|
/** Callback invoked with real solver progress metrics when available */
|
|
57
58
|
onProgress?: (progress: SolveProgressEvent) => void;
|
|
59
|
+
/** Solve the continuous (LP) relaxation of the model by relaxing integer and binary variables */
|
|
60
|
+
relax?: boolean;
|
|
58
61
|
[key: string]: any;
|
|
59
62
|
}
|
|
60
63
|
export interface SolverSolution {
|
|
@@ -87,4 +90,28 @@ export interface CheckResult {
|
|
|
87
90
|
conflicts?: readonly string[];
|
|
88
91
|
runTime?: number;
|
|
89
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Definition for dynamically adding a column (decision variable + constraint coefficients + objective cost).
|
|
95
|
+
* Core primitive for Column Generation and Dantzig-Wolfe decomposition.
|
|
96
|
+
*/
|
|
97
|
+
export interface ColumnDefinition {
|
|
98
|
+
name?: string;
|
|
99
|
+
type?: VarType;
|
|
100
|
+
lb?: number;
|
|
101
|
+
ub?: number;
|
|
102
|
+
/** Objective cost coefficient */
|
|
103
|
+
cost?: number;
|
|
104
|
+
/**
|
|
105
|
+
* Constraint coefficients for this column.
|
|
106
|
+
* Accepts:
|
|
107
|
+
* - Record<string, number> (keyed by constraint name)
|
|
108
|
+
* - Map<Constraint | string, number>
|
|
109
|
+
* - Array<[Constraint | string, number]>
|
|
110
|
+
* - Array<{ constraint: Constraint | string; coeff: number }>
|
|
111
|
+
*/
|
|
112
|
+
coefficients?: Record<string, number> | Map<Constraint | string, number> | Array<[Constraint | string, number]> | Array<{
|
|
113
|
+
constraint: Constraint | string;
|
|
114
|
+
coeff: number;
|
|
115
|
+
}>;
|
|
116
|
+
}
|
|
90
117
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/modeler/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/modeler/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| Problem Class | Solver | Key APIs | Links |
|
|
4
4
|
| :--- | :--- | :--- | :--- |
|
|
5
|
-
| Linear Programming (LP) | HiGHS (default) | `m.continuous()`, `m.constraint()`, `expr
|
|
5
|
+
| Linear Programming (LP) | HiGHS (default) | `m.continuous()`, `m.constraint()`, `expr` (`dot`), `minimize` | <ul><li><a href="https://washi.ohtaman.dev/demo/?preset=diet_sensitivity">Open in Playground</a></li><li><a href="https://github.com/ohtaman/washi/blob/main/examples/node/10-diet-sensitivity.ts">Source Code</a></li></ul> |
|
|
6
6
|
|
|
7
7
|
When solving a Linear Programming model, the optimal variable values (`var.value`) are only half the story. In practice, decision-makers need to know:
|
|
8
8
|
|
|
@@ -28,7 +28,7 @@ We choose daily servings ($0 \le x_i \le 4$) among 6 food items to meet 4 daily
|
|
|
28
28
|
<CodeRunner preset="diet_sensitivity">
|
|
29
29
|
|
|
30
30
|
```typescript
|
|
31
|
-
import { Model, minimize,
|
|
31
|
+
import { Model, minimize, expr } from "@ohtaman/washi";
|
|
32
32
|
|
|
33
33
|
const foods = [
|
|
34
34
|
{ name: "Oats", cost: 0.60, calories: 150, protein: 5, calcium: 20, iron: 1.8 },
|
|
@@ -51,14 +51,16 @@ async function runDietSensitivity() {
|
|
|
51
51
|
const calcs = Object.fromEntries(foods.map((f) => [f.name, f.calcium]));
|
|
52
52
|
const irons = Object.fromEntries(foods.map((f) => [f.name, f.iron]));
|
|
53
53
|
|
|
54
|
-
// Objective: Minimize total daily cost via dot
|
|
55
|
-
m.objective(minimize(dot(costs, srv)));
|
|
54
|
+
// Objective: Minimize total daily cost via dot() inside expr
|
|
55
|
+
m.objective(minimize(expr`dot(${costs}, ${srv})`));
|
|
56
56
|
|
|
57
57
|
// Nutritional constraints defined declaratively with expr and constraint()
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
const nutConstraints = [
|
|
59
|
+
m.constraint(expr`dot(${cals}, ${srv}) >= 2000`, "min_calories"),
|
|
60
|
+
m.constraint(expr`dot(${prots}, ${srv}) >= 105`, "min_protein"),
|
|
61
|
+
m.constraint(expr`dot(${calcs}, ${srv}) >= 1000`, "min_calcium"),
|
|
62
|
+
m.constraint(expr`dot(${irons}, ${srv}) >= 18`, "min_iron"),
|
|
63
|
+
];
|
|
62
64
|
|
|
63
65
|
const status = await m.solve();
|
|
64
66
|
|
|
@@ -69,11 +71,8 @@ async function runDietSensitivity() {
|
|
|
69
71
|
console.log(` ${f.name.padEnd(8)}: value=${v.value?.toFixed(2)}, reducedCost=${v.reducedCost?.toFixed(4)}`);
|
|
70
72
|
}
|
|
71
73
|
console.log("--- Nutritional Constraints (Dual & Slack) ---");
|
|
72
|
-
for (const
|
|
73
|
-
|
|
74
|
-
if (c) {
|
|
75
|
-
console.log(` ${c.name.padEnd(13)}: dual=$${c.dual?.toFixed(4)}, slack=${Math.abs(c.slack ?? 0).toFixed(2)}`);
|
|
76
|
-
}
|
|
74
|
+
for (const c of nutConstraints) {
|
|
75
|
+
console.log(` ${c.name.padEnd(13)}: dual=$${c.dual?.toFixed(4)}, slack=${Math.abs(c.slack ?? 0).toFixed(2)}`);
|
|
77
76
|
}
|
|
78
77
|
}
|
|
79
78
|
|
|
@@ -86,5 +85,7 @@ runDietSensitivity();
|
|
|
86
85
|
|
|
87
86
|
- **Bottleneck constraints (`slack == 0`, `dual > 0`):** Calories (`2000 kcal`) and Iron (`18 mg`) are tight at their lower bounds. Increasing the daily Iron requirement by 1 mg increases the minimum daily diet cost by **$0.3241**.
|
|
88
87
|
- **Constraints with surplus (`slack > 0`, `dual == 0`):** Protein (`+46.46 g` surplus) and Calcium (`+483.02 mg` surplus) are already exceeded with room to spare, so their shadow prices are `$0`.
|
|
89
|
-
- **Reduced cost (`Salmon`):** Unselected `Salmon` (`0.00` servings) has a reduced cost of `+1.5125`, meaning its price per serving would need to drop by at least **$1.51** before it enters the optimal daily menu.
|
|
88
|
+
- **Reduced cost at lower bound (`Salmon`):** Unselected `Salmon` (`0.00` servings) has a reduced cost of `+1.5125`, meaning its price per serving would need to drop by at least **$1.51** before it enters the optimal daily menu.
|
|
89
|
+
- **Negative reduced cost at upper bound (`Oats`, `Eggs`):** Both `Oats` (`reducedCost = -0.2581`) and `Eggs` (`reducedCost = -0.0887`) are pinned against their upper serving cap (`ub = 4.0`). In a minimization LP, a negative reduced cost on an upper-bounded variable tells you how much the total objective would **decrease** per unit increase in `ub`—raising the daily cap on `Oats` from 4 to 5 servings would save **$0.26/day**.
|
|
90
|
+
- **Basis stability range:** Shadow prices (`dual`) and reduced costs (`reducedCost`) represent local marginal rates of change within the current optimal simplex basis. If a right-hand side or bound changes enough to trigger a basis change (for example, once another variable hits its bound), the marginal rate shifts to a new piece of the piecewise-linear optimal cost curve.
|
|
90
91
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| Problem Class | Solver | Key APIs | Links |
|
|
4
4
|
| :--- | :--- | :--- | :--- |
|
|
5
|
-
| Mixed-Integer Programming (MIP) | HiGHS (default) | `m.binary()`, `m.constraint()`, `m.indicator()`, `expr`, `minimize` | <ul><li><a href="https://ohtaman.
|
|
5
|
+
| Mixed-Integer Programming (MIP) | HiGHS (default) | `m.binary()`, `m.constraint()`, `m.indicator()`, `expr`, `minimize` | <ul><li><a href="https://washi.ohtaman.dev/demo/?preset=cart_coupon">Open in Playground</a></li><li><a href="https://github.com/ohtaman/washi/blob/main/examples/node/12-ecommerce-coupon-optimizer.ts">Source Code</a></li></ul> |
|
|
6
6
|
|
|
7
7
|
Modern e-commerce checkouts often feature complex promotional rules: minimum spend thresholds, category-specific discounts, stackable vs. mutually exclusive coupons, and maximum coupon limits per order. Running an optimizer directly in the browser (or an edge worker) lets the checkout UI automatically apply the best coupon combination—and even recommend a small "filler" item when crossing a spend threshold lowers the customer's net bill.
|
|
8
8
|
|
|
@@ -31,7 +31,7 @@ By adding the `$10` cable (`$252` gross), the customer unlocks `MEGA45_250` (`-$
|
|
|
31
31
|
<CodeRunner preset="cart_coupon">
|
|
32
32
|
|
|
33
33
|
```typescript
|
|
34
|
-
import { Model,
|
|
34
|
+
import { Model, minimize, expr } from "@ohtaman/washi";
|
|
35
35
|
|
|
36
36
|
async function optimizeCheckoutCart() {
|
|
37
37
|
const m = new Model("CartCouponOptimizer");
|
|
@@ -52,50 +52,43 @@ async function optimizeCheckoutCart() {
|
|
|
52
52
|
|
|
53
53
|
// Binary decision variables for each coupon
|
|
54
54
|
const useCoupon = m.binary(coupons.map((c) => c.id));
|
|
55
|
+
const discounts = Object.fromEntries(coupons.map((c) => [c.id, c.discount]));
|
|
55
56
|
|
|
56
|
-
const merchSpend = addUsbCable
|
|
57
|
-
const techSpend = addUsbCable
|
|
57
|
+
const merchSpend = expr`${baseCartSubtotal} + ${usbCablePrice} * ${addUsbCable}`;
|
|
58
|
+
const techSpend = expr`${baseTechSubtotal} + ${usbCablePrice} * ${addUsbCable}`;
|
|
58
59
|
|
|
59
|
-
// 1. Indicator constraints: If useCoupon[id] == 1, minimum spend threshold must hold
|
|
60
|
+
// 1. Indicator constraints: If useCoupon[id] == 1, minimum spend threshold must hold.
|
|
61
|
+
// Omitting `M` lets WaSHI automatically derive the tightest Big-M from variable bounds!
|
|
60
62
|
for (const cpn of coupons) {
|
|
61
63
|
if (cpn.minCart > 0) {
|
|
62
|
-
m.indicator(useCoupon[cpn.id], merchSpend
|
|
64
|
+
m.indicator(useCoupon[cpn.id], expr`${merchSpend} >= ${cpn.minCart}`, {
|
|
63
65
|
activeValue: 1,
|
|
64
|
-
M: 500,
|
|
65
66
|
name: `min_spend_${cpn.id}`,
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
69
|
if (cpn.minTech > 0) {
|
|
69
|
-
m.indicator(useCoupon[cpn.id], techSpend
|
|
70
|
+
m.indicator(useCoupon[cpn.id], expr`${techSpend} >= ${cpn.minTech}`, {
|
|
70
71
|
activeValue: 1,
|
|
71
|
-
M: 500,
|
|
72
72
|
name: `min_tech_${cpn.id}`,
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
// 2. Mutual exclusion among non-stackable ("Exclusive") coupons
|
|
78
|
-
const
|
|
79
|
-
m.constraint(
|
|
80
|
-
expr`${sum(exclusiveCoupons, (c) => useCoupon[c.id])} <= 1`,
|
|
81
|
-
"at_most_one_exclusive"
|
|
82
|
-
);
|
|
78
|
+
const exclusiveVars = coupons.filter((c) => !c.stackable).map((c) => useCoupon[c.id]);
|
|
79
|
+
m.constraint(expr`sum(${exclusiveVars}) <= 1`, "at_most_one_exclusive");
|
|
83
80
|
|
|
84
81
|
// 3. Max 2 coupons per order
|
|
85
|
-
m.constraint(
|
|
86
|
-
expr`${sum(coupons, (c) => useCoupon[c.id])} <= 2`,
|
|
87
|
-
"max_two_coupons"
|
|
88
|
-
);
|
|
82
|
+
m.constraint(expr`sum(${useCoupon}) <= 2`, "max_two_coupons");
|
|
89
83
|
|
|
90
84
|
// Objective: Minimize final net payable amount (merchSpend - totalDiscounts)
|
|
91
|
-
|
|
92
|
-
m.objective(minimize(merchSpend.sub(totalDiscount)));
|
|
85
|
+
m.objective(minimize(expr`${merchSpend} - dot(${discounts}, ${useCoupon})`));
|
|
93
86
|
|
|
94
87
|
const status = await m.solve();
|
|
95
88
|
console.log(`Status: ${status}, Optimal Net Payable: $${m.objectiveValue}`);
|
|
96
|
-
console.log(`Recommended Add-on (+$10 USB-C Cable): ${
|
|
89
|
+
console.log(`Recommended Add-on (+$10 USB-C Cable): ${addUsbCable.value === 1 ? "YES" : "NO"}`);
|
|
97
90
|
for (const cpn of coupons) {
|
|
98
|
-
const applied =
|
|
91
|
+
const applied = useCoupon[cpn.id].value === 1;
|
|
99
92
|
console.log(` ${applied ? "✅ [APPLIED]" : " [skipped]"} ${cpn.id.padEnd(11)} (-$${cpn.discount})`);
|
|
100
93
|
}
|
|
101
94
|
}
|
package/docs/examples/index.md
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
# Examples & API Finder
|
|
2
2
|
|
|
3
|
-
Explore runnable optimization and logic formulations built with WaSHI. Every example can be executed directly inside its documentation page, or edited in the [Playground](https://ohtaman.
|
|
3
|
+
Explore runnable optimization and logic formulations built with WaSHI. Every example can be executed directly inside its documentation page, or edited in the [Playground](https://washi.ohtaman.dev/demo/).
|
|
4
4
|
|
|
5
5
|
## Examples
|
|
6
6
|
|
|
7
7
|
| Example | Problem Class | Solver | Key WaSHI APIs | Description | Code Editor |
|
|
8
8
|
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
9
|
-
| **[Production Planning](./production.md)** | LP / MIP | HiGHS | `m.integer()`, `m.constraint()`, `expr` | Basic variables, tagged template literal equations, and maximizing profit under resource limits. | [Playground](https://ohtaman.
|
|
10
|
-
| **[0-1 Knapsack](./knapsack.md)** | Binary MIP | HiGHS | `m.binary(keys)`, `
|
|
11
|
-
| **[Transportation Network](./transportation.md)** | LP | HiGHS | `m.continuous(rows, cols)`, `
|
|
12
|
-
| **[Diet & Sensitivity Analysis](./diet-sensitivity.md)** | LP | HiGHS | `constr.dual`, `constr.slack`, `var.reducedCost` | Reading shadow prices (bottlenecks), constraint surpluses, and reduced costs after solving. | [Playground](https://ohtaman.
|
|
13
|
-
| **[Staff Shift Scheduling](./shift-scheduling.md)** | Binary MIP + Unsat Core | HiGHS + Z3 | `m.binary(staff, days)`, `check()`, `unsatCore` | 5×7 weekly roster planner (coverage, senior duty, max shifts, day-off requests) and diagnosing conflicting vacation requests with Z3 `unsatCore`. | [Playground](https://ohtaman.
|
|
14
|
-
| **[E-Commerce Coupon Optimizer](./ecommerce-coupons.md)** | Indicator MIP | HiGHS | `m.indicator()`, `sum
|
|
15
|
-
| **[Portfolio Optimization](./portfolio-qp.md)** | Convex QP | HiGHS | `m.continuous()`, `m.constraint()`, `dot()`, `QuadExpr` | Markowitz mean-variance risk minimization ($w^T \Sigma w$) using `QuadExpr` subject to return targets. | [Playground](https://ohtaman.
|
|
16
|
-
| **[SMT Security Policies](./smt-security.md)** | SMT Logic | Z3 | `m.bool()`, `m.constraint()`, `m.check()` | Propositional variables (`BoolVar`) and logical connectives (`implies`, `and`, `not`, `xor`) mixed with integer bounds. | [Playground](https://ohtaman.
|
|
17
|
-
| **[Conflict Diagnosis (`unsatCore`)](./unsat-core.md)** | Unsat Core | Z3 | `m.constraint()`, `m.check()`, `m.unsatCore` | Extracting a conflicting constraint subset (`unsatCore`) when staffing and budget rules contradict each other. | [Playground](https://ohtaman.
|
|
9
|
+
| **[Production Planning](./production.md)** | LP / MIP | HiGHS | `m.integer()`, `m.constraint()`, `expr` | Basic variables, tagged template literal equations, and maximizing profit under resource limits. | [Playground](https://washi.ohtaman.dev/demo/?preset=production) |
|
|
10
|
+
| **[0-1 Knapsack](./knapsack.md)** | Binary MIP | HiGHS | `m.binary(keys)`, `expr` (`dot`), `m.constraint()` | 1D dictionary of `Binary` variables and linear aggregation over item arrays. | [Playground](https://washi.ohtaman.dev/demo/?preset=knapsack) |
|
|
11
|
+
| **[Transportation Network](./transportation.md)** | LP | HiGHS | `m.continuous(rows, cols)`, `expr` (`sum`, `dot`), `m.constraint()` | 2D matrix indexing (`ship[factory][store]`) and row/column flow balance constraints. | [Playground](https://washi.ohtaman.dev/demo/?preset=transportation) |
|
|
12
|
+
| **[Diet & Sensitivity Analysis](./diet-sensitivity.md)** | LP | HiGHS | `constr.dual`, `constr.slack`, `var.reducedCost` | Reading shadow prices (bottlenecks), constraint surpluses, and reduced costs after solving. | [Playground](https://washi.ohtaman.dev/demo/?preset=diet_sensitivity) |
|
|
13
|
+
| **[Staff Shift Scheduling](./shift-scheduling.md)** | Binary MIP + Unsat Core | HiGHS + Z3 | `m.binary(staff, days)`, `check()`, `unsatCore` | 5×7 weekly roster planner (coverage, senior duty, max shifts, day-off requests) and diagnosing conflicting vacation requests with Z3 `unsatCore`. | [Playground](https://washi.ohtaman.dev/demo/?preset=shift_scheduling) |
|
|
14
|
+
| **[E-Commerce Coupon Optimizer](./ecommerce-coupons.md)** | Indicator MIP | HiGHS | `m.indicator()`, `expr` (`sum`, `dot`), `m.constraint()` | Checkout optimizer using `m.indicator()` for minimum spend thresholds, exclusive vs. stackable rules, and smart filler add-on suggestions. | [Playground](https://washi.ohtaman.dev/demo/?preset=cart_coupon) |
|
|
15
|
+
| **[Portfolio Optimization](./portfolio-qp.md)** | Convex QP | HiGHS | `m.continuous()`, `m.constraint()`, `dot()`, `QuadExpr` | Markowitz mean-variance risk minimization ($w^T \Sigma w$) using `QuadExpr` subject to return targets. | [Playground](https://washi.ohtaman.dev/demo/?preset=portfolio_qp) |
|
|
16
|
+
| **[SMT Security Policies](./smt-security.md)** | SMT Logic | Z3 | `m.bool()`, `m.constraint()`, `m.check()` | Propositional variables (`BoolVar`) and logical connectives (`implies`, `and`, `not`, `xor`) mixed with integer bounds. | [Playground](https://washi.ohtaman.dev/demo/?preset=smt_security) |
|
|
17
|
+
| **[Conflict Diagnosis (`unsatCore`)](./unsat-core.md)** | Unsat Core | Z3 | `m.constraint()`, `m.check()`, `m.unsatCore` | Extracting a conflicting constraint subset (`unsatCore`) when staffing and budget rules contradict each other. | [Playground](https://washi.ohtaman.dev/demo/?preset=conflict_diagnosis_unsat) |
|
|
18
|
+
| **[Vehicle Routing (CVRP)](./vehicle-routing.md)** | Combinatorial OR / Dantzig-Wolfe | HiGHS | `m.solveColumnGeneration()`, `pricing` | Dynamic route column generation from customer dual shadow prices to minimize total fleet vehicles. | [Decomposition Guide](../guide/decomposition.md) |
|
|
19
|
+
| **[Traveling Salesperson (TSP)](./traveling-salesperson.md)** | Combinatorial OR / Benders | HiGHS | `m.solveBenders()`, `subproblem` | Subtour elimination on degree-assignment relaxation using dynamic Benders feasibility cuts. | [Decomposition Guide](../guide/decomposition.md) |
|
|
18
20
|
|
|
19
21
|
## Find by WaSHI API (Reverse Index)
|
|
20
22
|
|
|
@@ -25,13 +27,15 @@ Looking for a specific modeling method or solver capability? Jump straight to th
|
|
|
25
27
|
| ``m.constraint(expr`...`)`` | Tagged template literal constraints | [Production Planning](./production.md) | [`01-production-planning.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/01-production-planning.ts) |
|
|
26
28
|
| `m.binary(keys)` / `m.continuous(keys)` | 1D dictionary of indexed variables | [0-1 Knapsack](./knapsack.md) | [`02-knapsack-problem.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/02-knapsack-problem.ts) |
|
|
27
29
|
| `m.continuous(rows, cols)` / `m.binary(rows, cols)` | 2D matrix of indexed variables | [Transportation Network](./transportation.md), [Shift Scheduling](./shift-scheduling.md) | [`09-transportation-problem.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/09-transportation-problem.ts) |
|
|
28
|
-
| `dot(
|
|
30
|
+
| ``expr`dot(${A}, ${X})` `` / `dot(A, X)` | Fast vector/matrix dot product | [Transportation Network](./transportation.md), [Portfolio Optimization](./portfolio-qp.md) | [`09-transportation-problem.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/09-transportation-problem.ts) |
|
|
29
31
|
| `constr.dual` & `constr.slack` | Shadow prices & constraint surpluses | [Diet & Sensitivity Analysis](./diet-sensitivity.md) | [`10-diet-sensitivity.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/10-diet-sensitivity.ts) |
|
|
30
32
|
| `var.reducedCost` | Variable reduced costs in LP | [Diet & Sensitivity Analysis](./diet-sensitivity.md) | [`10-diet-sensitivity.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/10-diet-sensitivity.ts) |
|
|
31
33
|
| `m.indicator()` | Big-M conditional constraints (`binVar => constr`) | [E-Commerce Coupon Optimizer](./ecommerce-coupons.md) | [`12-ecommerce-coupon-optimizer.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/12-ecommerce-coupon-optimizer.ts) |
|
|
32
34
|
| `new QuadExpr()` | Convex quadratic objectives ($x^T Q x$) | [Portfolio Optimization](./portfolio-qp.md) | [`03-portfolio-qp.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/03-portfolio-qp.ts) |
|
|
33
|
-
| `m.bool()` &
|
|
35
|
+
| `m.bool()` & `implies()` | Propositional logic & SMT rules | [SMT Security Policies](./smt-security.md) | [`04-smt-security-rules.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/04-smt-security-rules.ts) |
|
|
34
36
|
| `m.check()` & `m.unsatCore` | Feasibility check & conflict diagnosis | [Conflict Diagnosis](./unsat-core.md), [Shift Scheduling](./shift-scheduling.md) | [`05-unsat-core-diagnosis.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/05-unsat-core-diagnosis.ts) |
|
|
37
|
+
| `m.solveColumnGeneration()` | Dantzig-Wolfe Column Generation | [Vehicle Routing](./vehicle-routing.md) | [`13-vehicle-routing-column-generation.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/13-vehicle-routing-column-generation.ts) |
|
|
38
|
+
| `m.solveBenders()` | Benders Decomposition & cut separation | [Traveling Salesperson](./traveling-salesperson.md) | [`14-traveling-salesperson-benders.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/14-traveling-salesperson-benders.ts) |
|
|
35
39
|
| `solver: "glpk"` | Solving LP/MIP with GLPK plugin | [GLPK Solver Guide](../solvers/glpk.md) | [`08-glpk-solver-plugin.ts`](https://github.com/ohtaman/washi/blob/main/examples/node/08-glpk-solver-plugin.ts) |
|
|
36
40
|
|
|
37
41
|
## Running Examples Locally in Node.js
|
|
@@ -50,4 +54,6 @@ npx tsx examples/node/09-transportation-problem.ts
|
|
|
50
54
|
npx tsx examples/node/10-diet-sensitivity.ts
|
|
51
55
|
npx tsx examples/node/11-shift-scheduling.ts
|
|
52
56
|
npx tsx examples/node/12-ecommerce-coupon-optimizer.ts
|
|
57
|
+
npx tsx examples/node/13-vehicle-routing-column-generation.ts
|
|
58
|
+
npx tsx examples/node/14-traveling-salesperson-benders.ts
|
|
53
59
|
```
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| Problem Class | Solver | Key APIs | Links |
|
|
4
4
|
| :--- | :--- | :--- | :--- |
|
|
5
|
-
| 0-1 Binary MIP | HiGHS (default) | `m.binary()`, `m.constraint()`, `expr
|
|
5
|
+
| 0-1 Binary MIP | HiGHS (default) | `m.binary()`, `m.constraint()`, `expr` (`dot`), `maximize` | <ul><li><a href="https://washi.ohtaman.dev/demo/?preset=knapsack">Open in Playground</a></li><li><a href="https://github.com/ohtaman/washi/blob/main/examples/node/02-knapsack-problem.ts">Source Code</a></li></ul> |
|
|
6
6
|
|
|
7
7
|
The 0-1 Knapsack problem is an essential combinatorial optimization problem: given a set of items, each with a weight and a value, determine which items to include in a collection so that the total weight does not exceed a given limit and the total value is maximized.
|
|
8
8
|
|
|
@@ -21,7 +21,7 @@ $$\begin{aligned}
|
|
|
21
21
|
<CodeRunner preset="knapsack">
|
|
22
22
|
|
|
23
23
|
```typescript
|
|
24
|
-
import { Model, maximize,
|
|
24
|
+
import { Model, maximize, expr } from "@ohtaman/washi";
|
|
25
25
|
|
|
26
26
|
async function solveKnapsack() {
|
|
27
27
|
const m = new Model("Knapsack");
|
|
@@ -41,17 +41,18 @@ async function solveKnapsack() {
|
|
|
41
41
|
const values = Object.fromEntries(items.map((it) => [it.name, it.value]));
|
|
42
42
|
const weights = Object.fromEntries(items.map((it) => [it.name, it.weight]));
|
|
43
43
|
|
|
44
|
-
// Maximize total value via dot
|
|
45
|
-
m.objective(maximize(dot(values, x)));
|
|
44
|
+
// Maximize total value via dot() inside expr
|
|
45
|
+
m.objective(maximize(expr`dot(${values}, ${x})`));
|
|
46
46
|
|
|
47
|
-
// Weight capacity constraint using
|
|
48
|
-
m.constraint(expr
|
|
47
|
+
// Weight capacity constraint using expr and constraint()
|
|
48
|
+
m.constraint(expr`dot(${weights}, ${x}) <= ${maxCapacity}`, "capacity_limit");
|
|
49
49
|
|
|
50
50
|
const status = await m.solve();
|
|
51
51
|
|
|
52
52
|
console.log(`Status: ${status}`);
|
|
53
53
|
console.log(`Max Total Value: $${m.objectiveValue}`);
|
|
54
|
-
|
|
54
|
+
const packed = items.filter((it) => x[it.name].value === 1).map((it) => it.name);
|
|
55
|
+
console.log("Packed Items:", packed.join(", "));
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
solveKnapsack();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| Problem Class | Solver | Key APIs | Links |
|
|
4
4
|
| :--- | :--- | :--- | :--- |
|
|
5
|
-
| Convex Quadratic Programming (QP) | HiGHS (default) | `m.continuous()`, `m.constraint()`, `expr`, `minimize`, `dot`, `QuadExpr` | <ul><li><a href="https://ohtaman.
|
|
5
|
+
| Convex Quadratic Programming (QP) | HiGHS (default) | `m.continuous()`, `m.constraint()`, `expr`, `minimize`, `dot`, `QuadExpr` | <ul><li><a href="https://washi.ohtaman.dev/demo/?preset=portfolio_qp">Open in Playground</a></li><li><a href="https://github.com/ohtaman/washi/blob/main/examples/node/03-portfolio-qp.ts">Source Code</a></li></ul> |
|
|
6
6
|
|
|
7
7
|
The Markowitz mean-variance portfolio optimization problem is the foundation of modern quantitative finance: allocate capital across risky assets to minimize overall portfolio variance (risk) subject to achieving a minimum required expected return.
|
|
8
8
|
|
|
@@ -26,7 +26,7 @@ where $\boldsymbol{\Sigma}$ is the positive semi-definite asset return covarianc
|
|
|
26
26
|
<CodeRunner preset="portfolio_qp">
|
|
27
27
|
|
|
28
28
|
```typescript
|
|
29
|
-
import { Model, QuadExpr,
|
|
29
|
+
import { Model, QuadExpr, dot, minimize, expr } from "@ohtaman/washi";
|
|
30
30
|
|
|
31
31
|
async function solvePortfolio() {
|
|
32
32
|
const m = new Model("PortfolioQP");
|
|
@@ -48,11 +48,12 @@ async function solvePortfolio() {
|
|
|
48
48
|
const w = m.continuous(assets, { lb: 0, ub: 1 });
|
|
49
49
|
|
|
50
50
|
// 1. Budget constraint: sum(w_i) == 1.0 (100%)
|
|
51
|
-
m.constraint(expr
|
|
51
|
+
m.constraint(expr`sum(${w}) == 1.0`, "budget_limit");
|
|
52
52
|
|
|
53
53
|
// 2. Expected return constraint: sum(r_i * w_i) >= 8.5%
|
|
54
54
|
const retMap = Object.fromEntries(assets.map((a, i) => [a, expectedReturns[i]]));
|
|
55
|
-
|
|
55
|
+
const portfolioReturn = dot(retMap, w);
|
|
56
|
+
m.constraint(expr`${portfolioReturn} >= ${targetReturn}`, "target_return");
|
|
56
57
|
|
|
57
58
|
// 3. Quadratic Objective: minimize risk w^T * Sigma * w
|
|
58
59
|
let risk = new QuadExpr();
|
|
@@ -71,6 +72,7 @@ async function solvePortfolio() {
|
|
|
71
72
|
console.log(`Status: ${status}`);
|
|
72
73
|
console.log(`Variance: ${m.objectiveValue?.toFixed(6)}`);
|
|
73
74
|
console.log(`Volatility (Std Dev): ${((Math.sqrt(m.objectiveValue || 0)) * 100).toFixed(2)}%`);
|
|
75
|
+
console.log(`Expected Return: ${((portfolioReturn.value ?? 0) * 100).toFixed(2)}% (target >= ${(targetReturn * 100).toFixed(2)}%)`);
|
|
74
76
|
|
|
75
77
|
assets.forEach((name) => {
|
|
76
78
|
console.log(` ${name.padEnd(10)}: ${((w[name].value ?? 0) * 100).toFixed(2)}%`);
|
|
@@ -81,3 +83,8 @@ solvePortfolio();
|
|
|
81
83
|
```
|
|
82
84
|
|
|
83
85
|
</CodeRunner>
|
|
86
|
+
|
|
87
|
+
## Practical Notes
|
|
88
|
+
|
|
89
|
+
- **Tracing the Efficient Frontier (`targetReturn` & `portfolioReturn.value`)**: Because the achieved return (`8.50%`) matches `targetReturn` exactly, the return constraint is tightly binding on the Markowitz efficient frontier. Varying `targetReturn` across `[0.05, 0.12]` traces out the full risk-return frontier.
|
|
90
|
+
- **Risk-Aversion Scalarization vs. Target Return Constraint**: If `targetReturn` is set above the highest single-asset return ($12\%$ for `Tech` under long-only weights), the hard constraint $\mathbf{r}^T \mathbf{w} \ge R_{\text{target}}$ becomes `"Infeasible"`. An alternative formulation that is always feasible for any risk appetite $\lambda > 0$ is to minimize the risk-adjusted objective $\min (\lambda \, \mathbf{w}^T \boldsymbol{\Sigma} \mathbf{w} - \mathbf{r}^T \mathbf{w})$.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| Problem Class | Solver | Key APIs | Links |
|
|
4
4
|
| :--- | :--- | :--- | :--- |
|
|
5
|
-
| Linear / Integer Programming (LP / MIP) | HiGHS (default) | `m.integer()`, `m.constraint()`, `expr` | <ul><li><a href="https://ohtaman.
|
|
5
|
+
| Linear / Integer Programming (LP / MIP) | HiGHS (default) | `m.integer()`, `m.constraint()`, `expr` | <ul><li><a href="https://washi.ohtaman.dev/demo/?preset=production">Open in Playground</a></li><li><a href="https://github.com/ohtaman/washi/blob/main/examples/node/01-production-planning.ts">Source Code</a></li></ul> |
|
|
6
6
|
|
|
7
7
|
Production planning is a classic Linear Programming problem: determine the optimal quantity of each product to manufacture in order to maximize total profit while respecting resource constraints (raw materials, machine time, labor hours).
|
|
8
8
|
|
|
@@ -34,9 +34,9 @@ async function runProductionOptimization() {
|
|
|
34
34
|
// Objective: Maximize total profit ($45 per chair, $80 per table)
|
|
35
35
|
m.objective(maximize(expr`45 * ${chairs} + 80 * ${tables}`));
|
|
36
36
|
|
|
37
|
-
// Resource constraints: declarative formulas via expr and
|
|
38
|
-
m.constraint(expr`5 * ${chairs} + 20 * ${tables} <= 400`, "mahogany_limit")
|
|
39
|
-
|
|
37
|
+
// Resource constraints: declarative formulas via expr and constraint()
|
|
38
|
+
m.constraint(expr`5 * ${chairs} + 20 * ${tables} <= 400`, "mahogany_limit");
|
|
39
|
+
m.constraint(expr`10 * ${chairs} + 15 * ${tables} <= 450`, "labor_limit");
|
|
40
40
|
|
|
41
41
|
const status = await m.solve();
|
|
42
42
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| Problem Class | Solver | Key APIs | Links |
|
|
4
4
|
| :--- | :--- | :--- | :--- |
|
|
5
|
-
| Binary MIP & SMT Unsat Core | HiGHS + Z3 | `m.binary(staff, days)`, `m.constraint()`, `expr
|
|
5
|
+
| Binary MIP & SMT Unsat Core | HiGHS + Z3 | `m.binary(staff, days)`, `m.constraint()`, `expr` (`sum`, `dot`), `minimize`, `m.check()` | <ul><li><a href="https://washi.ohtaman.dev/demo/?preset=shift_scheduling">Playground (Roster)</a></li><li><a href="https://washi.ohtaman.dev/demo/?preset=shift_conflict_unsat">Playground (Conflict)</a></li><li><a href="https://github.com/ohtaman/washi/blob/main/examples/node/11-shift-scheduling.ts">Source Code</a></li></ul> |
|
|
6
6
|
|
|
7
7
|
Staff shift scheduling is a classic real-world application of Mixed-Integer Programming in SaaS and workforce management tools. However, in real applications, **staff vacation requests frequently collide with minimum coverage or leadership rules**, causing the solver to return `Infeasible`.
|
|
8
8
|
|
|
@@ -35,7 +35,7 @@ We evaluate two distinct, named scenarios with different vacation inputs to illu
|
|
|
35
35
|
<CodeRunner preset="shift_scheduling">
|
|
36
36
|
|
|
37
37
|
```typescript
|
|
38
|
-
import { Model,
|
|
38
|
+
import { Model, minimize, expr } from "@ohtaman/washi";
|
|
39
39
|
import "@ohtaman/washi/solvers/z3";
|
|
40
40
|
|
|
41
41
|
const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] as const;
|
|
@@ -68,12 +68,12 @@ function buildShiftModel(name: string, dayOffRequests: Array<{ staff: string; da
|
|
|
68
68
|
),
|
|
69
69
|
])
|
|
70
70
|
);
|
|
71
|
-
m.objective(minimize(dot(costMatrix, shift)));
|
|
71
|
+
m.objective(minimize(expr`dot(${costMatrix}, ${shift})`));
|
|
72
72
|
|
|
73
73
|
// Rule 1: Daily headcount coverage
|
|
74
74
|
for (const d of days) {
|
|
75
75
|
m.constraint(
|
|
76
|
-
expr
|
|
76
|
+
expr`sum(${staffList}, ${(s) => shift[s.name][d]}) >= ${requiredCoverage[d]}`,
|
|
77
77
|
`coverage_${d}`
|
|
78
78
|
);
|
|
79
79
|
}
|
|
@@ -82,7 +82,7 @@ function buildShiftModel(name: string, dayOffRequests: Array<{ staff: string; da
|
|
|
82
82
|
const seniors = staffList.filter((s) => s.isSenior);
|
|
83
83
|
for (const d of days) {
|
|
84
84
|
m.constraint(
|
|
85
|
-
expr
|
|
85
|
+
expr`sum(${seniors}, ${(s) => shift[s.name][d]}) >= 1`,
|
|
86
86
|
`senior_duty_${d}`
|
|
87
87
|
);
|
|
88
88
|
}
|
|
@@ -90,7 +90,7 @@ function buildShiftModel(name: string, dayOffRequests: Array<{ staff: string; da
|
|
|
90
90
|
// Rule 3: Max working days per staff member
|
|
91
91
|
for (const s of staffList) {
|
|
92
92
|
m.constraint(
|
|
93
|
-
expr
|
|
93
|
+
expr`sum(${shift[s.name]}) <= ${s.maxShifts}`,
|
|
94
94
|
`max_shifts_${s.name}`
|
|
95
95
|
);
|
|
96
96
|
}
|
|
@@ -126,7 +126,7 @@ async function runScenario(
|
|
|
126
126
|
if (status === "Optimal") {
|
|
127
127
|
console.log(`Optimal Weekly Payroll: $${model.objectiveValue}`);
|
|
128
128
|
for (const s of staffList) {
|
|
129
|
-
const schedule = days.map((d) => (
|
|
129
|
+
const schedule = days.map((d) => (shift[s.name][d].value === 1 ? "ON" : " ·"));
|
|
130
130
|
console.log(` ${s.name.padEnd(8)}: ${schedule.join(" ")}`);
|
|
131
131
|
}
|
|
132
132
|
console.log("Schedule resolved successfully (no UNSAT diagnosis needed).\n");
|
|
@@ -173,3 +173,16 @@ main();
|
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
</CodeRunner>
|
|
176
|
+
|
|
177
|
+
## Auto-Repairing Conflicts with Soft Constraints (Elastic Requests)
|
|
178
|
+
|
|
179
|
+
Once Z3 `unsatCore` diagnoses that `senior_duty_Sat` conflicts with `day_off_Alice_Sat` and `day_off_Bob_Sat`, you can offer managers an automatic repair option by relaxing day-off requests from hard constraints (`shift[staff][day] == 0`) into **soft preferences** penalized in the objective (e.g., `+$500` per overridden day off):
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
// Soft constraint pattern: penalize working on a requested day off by $500
|
|
183
|
+
// instead of enforcing hard shift[req.staff][req.day] == 0
|
|
184
|
+
const requestedShiftVars = dayOffRequests.map((req) => shift[req.staff][req.day]);
|
|
185
|
+
m.objective(minimize(expr`dot(${costMatrix}, ${shift}) + 500 * sum(${requestedShiftVars})`));
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
With this soft formulation on Scenario B, HiGHS automatically finds a valid roster that honors 3 of the 4 requests (`Alice (Sat)`, `Charlie (Sat)`, and `Diana (Wed)`) and overrides only `Bob (Sat)`—choosing Bob over Alice because Bob's daily wage (`$210`) is `$10` lower than Alice's (`$220`).
|