@ohtaman/washi 0.4.0 → 0.6.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 +149 -121
- package/README.md +149 -121
- package/README.zh-CN.md +150 -122
- package/THIRD_PARTY_LICENSES.md +3 -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 +21 -3
- 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 +433 -286
- package/dist/browser/solvers/glpk.min.js +1 -1
- package/dist/browser/solvers/z3.js +1008 -981
- package/dist/browser/solvers/z3.min.js +2 -2
- package/dist/browser/washi.js +2778 -673
- 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 +21 -3
- 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-C20sxTwm.js +964 -0
- package/dist/lib/solvers/glpk.js +201 -90
- package/dist/lib/solvers/z3.js +399 -259
- package/dist/lib/washi.js +2363 -1056
- 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 +5 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modeler/big-m.d.ts +75 -0
- package/dist/types/modeler/big-m.d.ts.map +1 -0
- package/dist/types/modeler/boolean-expr.d.ts +103 -14
- package/dist/types/modeler/boolean-expr.d.ts.map +1 -1
- package/dist/types/modeler/constraint.d.ts +47 -9
- package/dist/types/modeler/constraint.d.ts.map +1 -1
- package/dist/types/modeler/expression.d.ts +123 -28
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/index.d.ts +11 -6
- 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 +30 -3
- package/dist/types/modeler/lp-writer.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +623 -131
- package/dist/types/modeler/model.d.ts.map +1 -1
- package/dist/types/modeler/objective.d.ts +59 -0
- package/dist/types/modeler/objective.d.ts.map +1 -0
- package/dist/types/modeler/parser.d.ts +34 -10
- package/dist/types/modeler/parser.d.ts.map +1 -1
- package/dist/types/modeler/quad-expr.d.ts +26 -7
- package/dist/types/modeler/quad-expr.d.ts.map +1 -1
- package/dist/types/modeler/solution-validator.d.ts +93 -0
- package/dist/types/modeler/solution-validator.d.ts.map +1 -0
- package/dist/types/modeler/solvers/glpk/solver.d.ts +26 -2
- 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 +38 -13
- 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 +12 -5
- 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/mock.d.ts +14 -5
- package/dist/types/modeler/solvers/mock.d.ts.map +1 -1
- package/dist/types/modeler/solvers/types.d.ts +73 -11
- package/dist/types/modeler/solvers/types.d.ts.map +1 -1
- package/dist/types/modeler/solvers/z3/loader.d.ts +2 -3
- package/dist/types/modeler/solvers/z3/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/z3/solver.d.ts +15 -5
- package/dist/types/modeler/solvers/z3/solver.d.ts.map +1 -1
- package/dist/types/modeler/types.d.ts +86 -1
- package/dist/types/modeler/types.d.ts.map +1 -1
- package/dist/types/modeler/validation.d.ts +56 -0
- package/dist/types/modeler/validation.d.ts.map +1 -0
- package/dist/types/modeler/variable.d.ts +48 -14
- package/dist/types/modeler/variable.d.ts.map +1 -1
- package/docs/examples/diet-sensitivity.md +90 -0
- package/docs/examples/ecommerce-coupons.md +106 -0
- package/docs/examples/index.md +57 -0
- package/docs/examples/knapsack.md +60 -0
- package/docs/examples/portfolio-qp.md +83 -0
- package/docs/examples/production.md +51 -0
- package/docs/examples/shift-scheduling.md +175 -0
- package/docs/examples/smt-security.md +74 -0
- package/docs/examples/transportation.md +90 -0
- package/docs/examples/traveling-salesperson.md +173 -0
- package/docs/examples/unsat-core.md +64 -0
- package/docs/examples/vehicle-routing.md +206 -0
- package/docs/getting-started/ai-agents.md +271 -0
- package/docs/getting-started/cross-origin.md +87 -0
- package/docs/getting-started/index.md +116 -0
- package/docs/getting-started/runtimes.md +227 -0
- package/docs/guide/constraints.md +177 -0
- package/docs/guide/decomposition.md +399 -0
- package/docs/guide/expressions.md +204 -0
- package/docs/guide/objectives.md +170 -0
- package/docs/guide/unsat-core.md +154 -0
- package/docs/guide/variables.md +188 -0
- package/docs/ja/getting-started/ai-agents.md +270 -0
- package/docs/solvers/custom-solver.md +525 -0
- package/docs/solvers/glpk.md +66 -0
- package/docs/solvers/highs.md +115 -0
- package/docs/solvers/index.md +42 -0
- package/docs/solvers/z3.md +78 -0
- package/docs/zh/getting-started/ai-agents.md +270 -0
- package/llms-full.txt +4065 -0
- package/llms.txt +201 -0
- package/package.json +32 -16
- package/skills/washi/SKILL.md +197 -0
- package/dist/browser/browser-runtime-D13gHOT5.js +0 -4189
- package/dist/browser/loader-CVt4CloI.js +0 -58
- package/dist/lib/async-mutex-Duo4jwzn.js +0 -195
- package/dist/lib/constraint-BRuB3ooC.js +0 -90
- package/dist/lib/loader-Dti0v9yC.js +0 -50
- package/dist/lib/registry-DksqCSjI.js +0 -32
package/dist/lib/washi.js
CHANGED
|
@@ -1,531 +1,119 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as l, n as
|
|
3
|
-
import {
|
|
4
|
-
import { createHighsWorker as ee } from "./highs-worker-factory.js";
|
|
1
|
+
import { A as e, C as t, D as n, E as r, M as i, N as a, O as o, S as s, T as c, _ as l, a as u, b as d, c as f, d as p, f as m, g as h, h as g, i as _, j as v, k as y, l as b, m as x, n as S, o as C, p as w, r as T, s as E, t as D, u as O, v as k, w as A, x as j, y as ee } from "./registry-C20sxTwm.js";
|
|
2
|
+
import { a as M, c as N, d as P, f as te, h as ne, i as re, l as ie, m as ae, n as oe, o as F, p as se, r as I, s as L, t as ce, u as le } from "./loader-BZUQNvh4.js";
|
|
3
|
+
import { createHighsWorker as ue } from "./highs-worker-factory.js";
|
|
5
4
|
//#region \0rolldown/runtime.js
|
|
6
|
-
var
|
|
5
|
+
var de = Object.defineProperty, fe = Object.getOwnPropertyDescriptor, pe = Object.getOwnPropertyNames, me = Object.prototype.hasOwnProperty, he = (e, t) => {
|
|
7
6
|
let n = {};
|
|
8
|
-
for (var r in e)
|
|
7
|
+
for (var r in e) de(n, r, {
|
|
9
8
|
get: e[r],
|
|
10
9
|
enumerable: !0
|
|
11
10
|
});
|
|
12
|
-
return t ||
|
|
13
|
-
},
|
|
14
|
-
if (t && typeof t == "object" || typeof t == "function") for (var i =
|
|
11
|
+
return t || de(n, Symbol.toStringTag, { value: "Module" }), n;
|
|
12
|
+
}, ge = (e, t, n, r) => {
|
|
13
|
+
if (t && typeof t == "object" || typeof t == "function") for (var i = pe(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !me.call(e, s) && s !== n && de(e, s, {
|
|
15
14
|
get: ((e) => t[e]).bind(null, s),
|
|
16
|
-
enumerable: !(r =
|
|
15
|
+
enumerable: !(r = fe(t, s)) || r.enumerable
|
|
17
16
|
});
|
|
18
17
|
return e;
|
|
19
|
-
},
|
|
18
|
+
}, R = (e, t, n) => (ge(e, t, "default"), n && ge(n, t, "default"));
|
|
20
19
|
//#endregion
|
|
21
20
|
//#region src/modeler/types.ts
|
|
22
|
-
function
|
|
23
|
-
|
|
21
|
+
function _e(e) {
|
|
22
|
+
if (e === void 0) return "Minimize";
|
|
23
|
+
if (typeof e == "string") {
|
|
24
|
+
let t = e.toLowerCase();
|
|
25
|
+
if (t === "maximize") return "Maximize";
|
|
26
|
+
if (t === "minimize") return "Minimize";
|
|
27
|
+
}
|
|
28
|
+
throw Error(`Invalid optimization sense "${String(e)}": expected "Maximize", "Minimize", "maximize", or "minimize".`);
|
|
24
29
|
}
|
|
25
30
|
//#endregion
|
|
26
|
-
//#region src/modeler/quad-expr.ts
|
|
27
|
-
function E(e, t) {
|
|
28
|
-
let n = e.id, r = t.id;
|
|
29
|
-
return n <= r ? `${n}:${r}` : `${r}:${n}`;
|
|
30
|
-
}
|
|
31
|
-
var D = class e {
|
|
32
|
-
linearTerms;
|
|
33
|
-
quadTerms;
|
|
34
|
-
constant;
|
|
35
|
-
constructor(e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map(), n = 0) {
|
|
36
|
-
this.linearTerms = new Map(e), this.quadTerms = /* @__PURE__ */ new Map();
|
|
37
|
-
for (let [e, n] of t) this.quadTerms.set(e, { ...n });
|
|
38
|
-
this.constant = n;
|
|
39
|
-
}
|
|
40
|
-
clone() {
|
|
41
|
-
return new e(this.linearTerms, this.quadTerms, this.constant);
|
|
42
|
-
}
|
|
43
|
-
getQuadCoeff(e, t) {
|
|
44
|
-
let n = E(e, t), r = this.quadTerms.get(n);
|
|
45
|
-
return r ? r.coeff : 0;
|
|
46
|
-
}
|
|
47
|
-
add(t) {
|
|
48
|
-
let n = this.clone();
|
|
49
|
-
if (typeof t == "number") return n.constant += t, n;
|
|
50
|
-
if (t instanceof e) {
|
|
51
|
-
for (let [e, r] of t.quadTerms) {
|
|
52
|
-
let t = n.quadTerms.get(e), i = (t ? t.coeff : 0) + r.coeff;
|
|
53
|
-
Math.abs(i) < 1e-12 ? n.quadTerms.delete(e) : n.quadTerms.set(e, {
|
|
54
|
-
var1: r.var1,
|
|
55
|
-
var2: r.var2,
|
|
56
|
-
coeff: i
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
for (let [e, r] of t.linearTerms) {
|
|
60
|
-
let t = (n.linearTerms.get(e) || 0) + r;
|
|
61
|
-
Math.abs(t) < 1e-12 ? n.linearTerms.delete(e) : n.linearTerms.set(e, t);
|
|
62
|
-
}
|
|
63
|
-
return n.constant += t.constant, n;
|
|
64
|
-
}
|
|
65
|
-
if ("terms" in t && t.terms instanceof Map) {
|
|
66
|
-
for (let [e, r] of t.terms) {
|
|
67
|
-
let t = (n.linearTerms.get(e) || 0) + r;
|
|
68
|
-
Math.abs(t) < 1e-12 ? n.linearTerms.delete(e) : n.linearTerms.set(e, t);
|
|
69
|
-
}
|
|
70
|
-
return n.constant += t.constant, n;
|
|
71
|
-
}
|
|
72
|
-
let r = t, i = (n.linearTerms.get(r) || 0) + 1;
|
|
73
|
-
return Math.abs(i) < 1e-12 ? n.linearTerms.delete(r) : n.linearTerms.set(r, i), n;
|
|
74
|
-
}
|
|
75
|
-
sub(t) {
|
|
76
|
-
return typeof t == "number" ? this.add(-t) : t instanceof e ? this.add(t.neg()) : ("terms" in t && t.terms instanceof Map, this.add(t.mul(-1)));
|
|
77
|
-
}
|
|
78
|
-
mul(t) {
|
|
79
|
-
if (typeof t == "number") {
|
|
80
|
-
let n = new e(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), this.constant * t);
|
|
81
|
-
for (let [e, r] of this.linearTerms) {
|
|
82
|
-
let i = r * t;
|
|
83
|
-
Math.abs(i) >= 1e-12 && n.linearTerms.set(e, i);
|
|
84
|
-
}
|
|
85
|
-
for (let [e, r] of this.quadTerms) {
|
|
86
|
-
let i = r.coeff * t;
|
|
87
|
-
Math.abs(i) >= 1e-12 && n.quadTerms.set(e, {
|
|
88
|
-
var1: r.var1,
|
|
89
|
-
var2: r.var2,
|
|
90
|
-
coeff: i
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
return n;
|
|
94
|
-
}
|
|
95
|
-
if ("id" in t && "name" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
96
|
-
if (this.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
97
|
-
let n = new e();
|
|
98
|
-
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(t, this.constant);
|
|
99
|
-
for (let [r, i] of this.linearTerms) n = n.add(e.fromProduct(r, t, i));
|
|
100
|
-
return n;
|
|
101
|
-
}
|
|
102
|
-
let n = t, r = "quadTerms" in n ? n.quadTerms.size : 0, i = "quadTerms" in n ? n.linearTerms : n.terms;
|
|
103
|
-
if (this.quadTerms.size > 0 && (r > 0 || i.size > 0) || r > 0 && this.linearTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
104
|
-
if (r === 0 && i.size === 0) return this.mul(n.constant);
|
|
105
|
-
if (this.quadTerms.size === 0 && this.linearTerms.size === 0) {
|
|
106
|
-
let t = n.mul(this.constant);
|
|
107
|
-
if (t instanceof e) return t;
|
|
108
|
-
let r = new e();
|
|
109
|
-
r.constant = t.constant;
|
|
110
|
-
for (let [e, n] of t.terms) r.linearTerms.set(e, n);
|
|
111
|
-
return r;
|
|
112
|
-
}
|
|
113
|
-
let a = new e();
|
|
114
|
-
if (a.constant = this.constant * n.constant, Math.abs(n.constant) >= 1e-12) for (let [e, t] of this.linearTerms) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * n.constant);
|
|
115
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [e, t] of i) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * this.constant);
|
|
116
|
-
for (let [t, n] of this.linearTerms) for (let [r, o] of i) a = a.add(e.fromProduct(t, r, n * o));
|
|
117
|
-
return a;
|
|
118
|
-
}
|
|
119
|
-
div(e) {
|
|
120
|
-
if (Math.abs(e) < 1e-12) throw Error("Division by zero in QuadExpr.div()");
|
|
121
|
-
return this.mul(1 / e);
|
|
122
|
-
}
|
|
123
|
-
neg() {
|
|
124
|
-
return this.mul(-1);
|
|
125
|
-
}
|
|
126
|
-
get value() {
|
|
127
|
-
let e = this.constant;
|
|
128
|
-
for (let [t, n] of this.linearTerms) {
|
|
129
|
-
if (t.value === null) return null;
|
|
130
|
-
e += n * t.value;
|
|
131
|
-
}
|
|
132
|
-
for (let t of this.quadTerms.values()) {
|
|
133
|
-
if (t.var1.value === null || t.var2.value === null) return null;
|
|
134
|
-
e += t.coeff * t.var1.value * t.var2.value;
|
|
135
|
-
}
|
|
136
|
-
return e;
|
|
137
|
-
}
|
|
138
|
-
getValue() {
|
|
139
|
-
return this.value;
|
|
140
|
-
}
|
|
141
|
-
toString() {
|
|
142
|
-
let e = [], t = !0;
|
|
143
|
-
for (let n of this.quadTerms.values()) {
|
|
144
|
-
let r = n.coeff, i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
|
|
145
|
-
n.var1 === n.var2 ? e.push(`${i}${o}${n.var1.name}^2`) : e.push(`${i}${o}${n.var1.name} * ${n.var2.name}`), t = !1;
|
|
146
|
-
}
|
|
147
|
-
for (let [n, r] of this.linearTerms) {
|
|
148
|
-
let i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
|
|
149
|
-
e.push(`${i}${o}${n.name}`), t = !1;
|
|
150
|
-
}
|
|
151
|
-
if (this.constant !== 0 || e.length === 0) {
|
|
152
|
-
let n = this.constant >= 0 ? t ? "" : "+ " : "- ";
|
|
153
|
-
e.push(`${n}${Math.abs(this.constant)}`);
|
|
154
|
-
}
|
|
155
|
-
return e.join(" ") || "0";
|
|
156
|
-
}
|
|
157
|
-
static fromProduct(t, n, r = 1) {
|
|
158
|
-
let i = new e(), a = E(t, n);
|
|
159
|
-
return i.quadTerms.set(a, {
|
|
160
|
-
var1: t.id <= n.id ? t : n,
|
|
161
|
-
var2: t.id <= n.id ? n : t,
|
|
162
|
-
coeff: r
|
|
163
|
-
}), i;
|
|
164
|
-
}
|
|
165
|
-
}, O = class e {
|
|
166
|
-
terms;
|
|
167
|
-
constant;
|
|
168
|
-
constructor(e = /* @__PURE__ */ new Map(), t = 0) {
|
|
169
|
-
this.terms = new Map(e), this.constant = t;
|
|
170
|
-
}
|
|
171
|
-
clone() {
|
|
172
|
-
return new e(this.terms, this.constant);
|
|
173
|
-
}
|
|
174
|
-
add(e) {
|
|
175
|
-
if (e instanceof D) return e.add(this);
|
|
176
|
-
let t = this.clone();
|
|
177
|
-
if (typeof e == "number") t.constant += e;
|
|
178
|
-
else if ("terms" in e) {
|
|
179
|
-
for (let [n, r] of e.terms) {
|
|
180
|
-
let e = (t.terms.get(n) || 0) + r;
|
|
181
|
-
Math.abs(e) < 1e-12 ? t.terms.delete(n) : t.terms.set(n, e);
|
|
182
|
-
}
|
|
183
|
-
t.constant += e.constant;
|
|
184
|
-
} else {
|
|
185
|
-
let n = (t.terms.get(e) || 0) + 1;
|
|
186
|
-
Math.abs(n) < 1e-12 ? t.terms.delete(e) : t.terms.set(e, n);
|
|
187
|
-
}
|
|
188
|
-
return t;
|
|
189
|
-
}
|
|
190
|
-
sub(e) {
|
|
191
|
-
return e instanceof D ? e.neg().add(this) : typeof e == "number" ? this.add(-e) : ("terms" in e, this.add(e.mul(-1)));
|
|
192
|
-
}
|
|
193
|
-
mul(t) {
|
|
194
|
-
if (typeof t == "number") {
|
|
195
|
-
let n = new e(/* @__PURE__ */ new Map(), this.constant * t);
|
|
196
|
-
for (let [e, r] of this.terms) {
|
|
197
|
-
let i = r * t;
|
|
198
|
-
Math.abs(i) >= 1e-12 && n.terms.set(e, i);
|
|
199
|
-
}
|
|
200
|
-
return n;
|
|
201
|
-
}
|
|
202
|
-
if (t instanceof M || typeof t == "object" && t && "id" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
203
|
-
let e = t, n = new D();
|
|
204
|
-
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(e, this.constant);
|
|
205
|
-
for (let [t, r] of this.terms) n = n.add(D.fromProduct(t, e, r));
|
|
206
|
-
return n;
|
|
207
|
-
}
|
|
208
|
-
if (t instanceof D) {
|
|
209
|
-
if (t.quadTerms.size > 0 && this.terms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
210
|
-
if (this.terms.size === 0) return t.mul(this.constant);
|
|
211
|
-
let e = new D();
|
|
212
|
-
if (e.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [n, r] of this.terms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * t.constant);
|
|
213
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [n, r] of t.linearTerms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * this.constant);
|
|
214
|
-
for (let [n, r] of this.terms) for (let [i, a] of t.linearTerms) e = e.add(D.fromProduct(n, i, r * a));
|
|
215
|
-
return e;
|
|
216
|
-
}
|
|
217
|
-
if (this.terms.size === 0) return t.mul(this.constant);
|
|
218
|
-
if (t.terms.size === 0) return this.mul(t.constant);
|
|
219
|
-
let n = new D();
|
|
220
|
-
if (n.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, r] of this.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * t.constant);
|
|
221
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [e, r] of t.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * this.constant);
|
|
222
|
-
for (let [e, r] of this.terms) for (let [i, a] of t.terms) n = n.add(D.fromProduct(e, i, r * a));
|
|
223
|
-
return n;
|
|
224
|
-
}
|
|
225
|
-
div(e) {
|
|
226
|
-
if (Math.abs(e) < 1e-12) throw Error("Division by zero in LinExpr.div()");
|
|
227
|
-
return this.mul(1 / e);
|
|
228
|
-
}
|
|
229
|
-
neg() {
|
|
230
|
-
return this.mul(-1);
|
|
231
|
-
}
|
|
232
|
-
get value() {
|
|
233
|
-
let e = this.constant;
|
|
234
|
-
for (let [t, n] of this.terms) {
|
|
235
|
-
if (t.value === null) return null;
|
|
236
|
-
e += n * t.value;
|
|
237
|
-
}
|
|
238
|
-
return e;
|
|
239
|
-
}
|
|
240
|
-
getValue() {
|
|
241
|
-
return this.value;
|
|
242
|
-
}
|
|
243
|
-
le(e, t) {
|
|
244
|
-
return this.toConstraint("<=", e, t);
|
|
245
|
-
}
|
|
246
|
-
lessThanOrEqual(e, t) {
|
|
247
|
-
return this.le(e, t);
|
|
248
|
-
}
|
|
249
|
-
ge(e, t) {
|
|
250
|
-
return this.toConstraint(">=", e, t);
|
|
251
|
-
}
|
|
252
|
-
greaterThanOrEqual(e, t) {
|
|
253
|
-
return this.ge(e, t);
|
|
254
|
-
}
|
|
255
|
-
eq(e, t) {
|
|
256
|
-
return this.toConstraint("==", e, t);
|
|
257
|
-
}
|
|
258
|
-
equalTo(e, t) {
|
|
259
|
-
return this.eq(e, t);
|
|
260
|
-
}
|
|
261
|
-
toConstraint(t, n, r) {
|
|
262
|
-
let i = this.clone(), a = 0;
|
|
263
|
-
typeof n == "number" ? a = n : "terms" in n ? (i = i.sub(new e(n.terms, 0)), a = n.constant) : i = i.sub(n);
|
|
264
|
-
let o = a - i.constant;
|
|
265
|
-
return i.constant = 0, new c(i, t, o, r);
|
|
266
|
-
}
|
|
267
|
-
toString() {
|
|
268
|
-
let e = [], t = !0;
|
|
269
|
-
for (let [n, r] of this.terms) {
|
|
270
|
-
let i = r >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(r), o = a === 1 ? "" : `${a} `;
|
|
271
|
-
e.push(`${i}${o}${n.name}`), t = !1;
|
|
272
|
-
}
|
|
273
|
-
if (this.constant !== 0 || e.length === 0) {
|
|
274
|
-
let n = this.constant >= 0 ? t ? "" : "+ " : "- ";
|
|
275
|
-
e.push(`${n}${Math.abs(this.constant)}`);
|
|
276
|
-
}
|
|
277
|
-
return e.join(" ") || "0";
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
function k(e, t) {
|
|
281
|
-
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
282
|
-
function i(e) {
|
|
283
|
-
if (e != null) {
|
|
284
|
-
if (typeof e == "number") r += e;
|
|
285
|
-
else if (typeof e == "object" && "terms" in e) {
|
|
286
|
-
let t = e;
|
|
287
|
-
for (let [e, r] of t.terms) {
|
|
288
|
-
let t = n.get(e) || 0;
|
|
289
|
-
n.set(e, t + r);
|
|
290
|
-
}
|
|
291
|
-
r += t.constant;
|
|
292
|
-
} else {
|
|
293
|
-
let t = e, r = n.get(t) || 0;
|
|
294
|
-
n.set(t, r + 1);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
if (typeof e == "number") {
|
|
299
|
-
let n = e, r = t;
|
|
300
|
-
for (let e = 0; e < n; e++) i(r(e, e));
|
|
301
|
-
} else {
|
|
302
|
-
let n = 0;
|
|
303
|
-
for (let r of e) i(t ? t(r, n++) : r);
|
|
304
|
-
}
|
|
305
|
-
for (let [e, t] of n) Math.abs(t) < 1e-12 && n.delete(e);
|
|
306
|
-
return new O(n, r);
|
|
307
|
-
}
|
|
308
|
-
function A(e, t) {
|
|
309
|
-
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
310
|
-
function i(e) {
|
|
311
|
-
return typeof e == "object" && !!e && typeof e.id == "number" && typeof e.name == "string" && typeof e.mul == "function" && typeof e.le == "function";
|
|
312
|
-
}
|
|
313
|
-
function a(e) {
|
|
314
|
-
return i(e) || e instanceof O || e instanceof D;
|
|
315
|
-
}
|
|
316
|
-
function o(e, t) {
|
|
317
|
-
if (typeof t == "number") r += e * t;
|
|
318
|
-
else if (t instanceof O) {
|
|
319
|
-
for (let [r, i] of t.terms) {
|
|
320
|
-
let t = n.get(r) || 0;
|
|
321
|
-
n.set(r, t + e * i);
|
|
322
|
-
}
|
|
323
|
-
r += e * t.constant;
|
|
324
|
-
} else if (i(t)) {
|
|
325
|
-
let r = t, i = n.get(r) || 0;
|
|
326
|
-
n.set(r, i + e);
|
|
327
|
-
} else throw Error("Cannot multiply number by non-variable/expression operand in dot().");
|
|
328
|
-
}
|
|
329
|
-
function s(e) {
|
|
330
|
-
return typeof e == "object" && !!e && !Array.isArray(e) && !a(e);
|
|
331
|
-
}
|
|
332
|
-
function c(e, t, n = "") {
|
|
333
|
-
if (e === void 0 || t === void 0 || e === null || t === null) throw Error(`Nullish or undefined operand encountered in dot() at '${n || "root"}'.`);
|
|
334
|
-
if (typeof e == "number") {
|
|
335
|
-
o(e, t);
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
if (typeof t == "number") {
|
|
339
|
-
o(t, e);
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
if (Array.isArray(e) || Array.isArray(t)) {
|
|
343
|
-
if (Array.isArray(e) && Array.isArray(t)) {
|
|
344
|
-
if (e.length !== t.length) throw Error(`Array length mismatch in dot() at '${n || "root"}': received lengths ${e.length} and ${t.length}.`);
|
|
345
|
-
for (let r = 0; r < e.length; r++) c(e[r], t[r], n ? `${n}[${r}]` : `[${r}]`);
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
let r = Array.isArray(e) ? e : t, i = Array.isArray(e) ? t : e;
|
|
349
|
-
if (s(i)) {
|
|
350
|
-
let a = Object.keys(i);
|
|
351
|
-
if (a.length > 0 && a.every((e) => /^\d+$/.test(e))) {
|
|
352
|
-
if (a.length !== r.length) throw Error(`Array length mismatch in dot() at '${n || "root"}': array has length ${r.length}, but object has ${a.length} indices.`);
|
|
353
|
-
let o = [];
|
|
354
|
-
for (let e = 0; e < r.length; e++) !(e in i) && !(String(e) in i) && o.push(e);
|
|
355
|
-
if (o.length > 0) throw Error(`Key mismatch in dot() at '${n || "root"}': missing indices [${o.join(", ")}] in numeric record.`);
|
|
356
|
-
for (let i = 0; i < r.length; i++) c(e[i], t[i], n ? `${n}[${i}]` : `[${i}]`);
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
359
|
-
throw Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is an Object with keys [${a.slice(0, 5).join(", ")}].`);
|
|
360
|
-
}
|
|
361
|
-
throw Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is not.`);
|
|
362
|
-
}
|
|
363
|
-
if (s(e) && s(t)) {
|
|
364
|
-
let r = Object.keys(e), i = Object.keys(t), a = r.filter((e) => !(e in t)), o = i.filter((t) => !(t in e));
|
|
365
|
-
if (a.length > 0 || o.length > 0) {
|
|
366
|
-
let e = [];
|
|
367
|
-
throw a.length > 0 && e.push(`missing in second operand: [${a.join(", ")}]`), o.length > 0 && e.push(`missing in first operand: [${o.join(", ")}]`), Error(`Key mismatch in dot() at '${n || "root"}': ${e.join("; ")}.`);
|
|
368
|
-
}
|
|
369
|
-
for (let i of r) c(e[i], t[i], n ? `${n}.${i}` : i);
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
throw Error(`Unsupported operand types in dot() at '${n || "root"}'.`);
|
|
373
|
-
}
|
|
374
|
-
c(e, t);
|
|
375
|
-
for (let [e, t] of n) Math.abs(t) < 1e-12 && n.delete(e);
|
|
376
|
-
return new O(n, r);
|
|
377
|
-
}
|
|
378
|
-
//#endregion
|
|
379
|
-
//#region src/modeler/variable.ts
|
|
380
|
-
var j = 0;
|
|
381
|
-
function ie(e) {
|
|
382
|
-
if (!e) return "Continuous";
|
|
383
|
-
let t = e.toLowerCase();
|
|
384
|
-
return t === "binary" || t === "bin" ? "Binary" : t === "integer" || t === "int" ? "Integer" : "Continuous";
|
|
385
|
-
}
|
|
386
|
-
var M = class e {
|
|
387
|
-
id;
|
|
388
|
-
name;
|
|
389
|
-
type;
|
|
390
|
-
lb;
|
|
391
|
-
ub;
|
|
392
|
-
value = null;
|
|
393
|
-
reducedCost = null;
|
|
394
|
-
constructor(e = {}) {
|
|
395
|
-
this.id = ++j, this.name = e.name || `x_${this.id}`, this.type = ie(e.type), this.type === "Binary" ? (this.lb = 0, this.ub = 1) : (this.lb = e.lb === void 0 ? 0 : e.lb, this.ub = e.ub === void 0 ? Infinity : e.ub);
|
|
396
|
-
}
|
|
397
|
-
mul(t) {
|
|
398
|
-
if (typeof t == "number") return new O(/* @__PURE__ */ new Map([[this, t]]), 0);
|
|
399
|
-
if (t instanceof e) return D.fromProduct(this, t, 1);
|
|
400
|
-
if (t instanceof D) {
|
|
401
|
-
if (t.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
402
|
-
let e = new D();
|
|
403
|
-
Math.abs(t.constant) >= 1e-12 && e.linearTerms.set(this, t.constant);
|
|
404
|
-
for (let [n, r] of t.linearTerms) e = e.add(D.fromProduct(this, n, r));
|
|
405
|
-
return e;
|
|
406
|
-
}
|
|
407
|
-
let n = new D();
|
|
408
|
-
Math.abs(t.constant) >= 1e-12 && n.linearTerms.set(this, t.constant);
|
|
409
|
-
for (let [e, r] of t.terms) {
|
|
410
|
-
let t = D.fromProduct(this, e, r);
|
|
411
|
-
n = n.add(t);
|
|
412
|
-
}
|
|
413
|
-
return n;
|
|
414
|
-
}
|
|
415
|
-
add(e) {
|
|
416
|
-
return e instanceof D ? e.add(this) : new O(/* @__PURE__ */ new Map([[this, 1]]), 0).add(e);
|
|
417
|
-
}
|
|
418
|
-
sub(e) {
|
|
419
|
-
return e instanceof D ? e.neg().add(this) : new O(/* @__PURE__ */ new Map([[this, 1]]), 0).sub(e);
|
|
420
|
-
}
|
|
421
|
-
neg() {
|
|
422
|
-
return this.mul(-1);
|
|
423
|
-
}
|
|
424
|
-
le(e, t) {
|
|
425
|
-
return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).le(e, t);
|
|
426
|
-
}
|
|
427
|
-
lessThanOrEqual(e, t) {
|
|
428
|
-
return this.le(e, t);
|
|
429
|
-
}
|
|
430
|
-
ge(e, t) {
|
|
431
|
-
return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).ge(e, t);
|
|
432
|
-
}
|
|
433
|
-
greaterThanOrEqual(e, t) {
|
|
434
|
-
return this.ge(e, t);
|
|
435
|
-
}
|
|
436
|
-
eq(e, t) {
|
|
437
|
-
return new O(/* @__PURE__ */ new Map([[this, 1]]), 0).eq(e, t);
|
|
438
|
-
}
|
|
439
|
-
equalTo(e, t) {
|
|
440
|
-
return this.eq(e, t);
|
|
441
|
-
}
|
|
442
|
-
toString() {
|
|
443
|
-
return this.name;
|
|
444
|
-
}
|
|
445
|
-
};
|
|
446
|
-
//#endregion
|
|
447
31
|
//#region src/modeler/parser.ts
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
32
|
+
var ve = /^(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
|
|
33
|
+
function ye(e, t) {
|
|
34
|
+
let n = [], r = 0, i = e.length;
|
|
35
|
+
for (; r < i;) {
|
|
36
|
+
let a = e[r];
|
|
37
|
+
if (/\s/.test(a)) {
|
|
38
|
+
r++;
|
|
454
39
|
continue;
|
|
455
40
|
}
|
|
456
|
-
if (
|
|
41
|
+
if (a === "+") n.push({
|
|
457
42
|
type: "PLUS",
|
|
458
43
|
value: "+"
|
|
459
|
-
}),
|
|
460
|
-
else if (
|
|
44
|
+
}), r++;
|
|
45
|
+
else if (a === "-") n.push({
|
|
461
46
|
type: "MINUS",
|
|
462
47
|
value: "-"
|
|
463
|
-
}),
|
|
464
|
-
else if (
|
|
48
|
+
}), r++;
|
|
49
|
+
else if (a === "*") r + 1 < i && e[r + 1] === "*" ? (n.push({
|
|
465
50
|
type: "CARET",
|
|
466
51
|
value: "**"
|
|
467
|
-
}),
|
|
52
|
+
}), r += 2) : (n.push({
|
|
468
53
|
type: "STAR",
|
|
469
54
|
value: "*"
|
|
470
|
-
}),
|
|
471
|
-
else if (
|
|
55
|
+
}), r++);
|
|
56
|
+
else if (a === "^") n.push({
|
|
472
57
|
type: "CARET",
|
|
473
58
|
value: "^"
|
|
474
|
-
}),
|
|
475
|
-
else if (
|
|
59
|
+
}), r++;
|
|
60
|
+
else if (a === "/") n.push({
|
|
476
61
|
type: "SLASH",
|
|
477
62
|
value: "/"
|
|
478
|
-
}),
|
|
479
|
-
else if (
|
|
63
|
+
}), r++;
|
|
64
|
+
else if (a === "(") n.push({
|
|
480
65
|
type: "LPAREN",
|
|
481
66
|
value: "("
|
|
482
|
-
}),
|
|
483
|
-
else if (
|
|
67
|
+
}), r++;
|
|
68
|
+
else if (a === ")") n.push({
|
|
484
69
|
type: "RPAREN",
|
|
485
70
|
value: ")"
|
|
486
|
-
}),
|
|
487
|
-
else if (
|
|
488
|
-
let
|
|
489
|
-
|
|
71
|
+
}), r++;
|
|
72
|
+
else if (a === "<" || a === ">" || a === "=") {
|
|
73
|
+
let t = a;
|
|
74
|
+
r + 1 < i && (e[r + 1] === "=" || e[r + 1] === "<" || e[r + 1] === ">") ? (t += e[r + 1], r += 2) : r++, n.push({
|
|
490
75
|
type: "COMP",
|
|
491
|
-
value:
|
|
76
|
+
value: t
|
|
492
77
|
});
|
|
493
|
-
} else if (/[0-9.]/.test(
|
|
494
|
-
let
|
|
495
|
-
for (;
|
|
496
|
-
|
|
78
|
+
} else if (/[0-9.]/.test(a)) {
|
|
79
|
+
let t = r, a = "";
|
|
80
|
+
for (; r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
81
|
+
if (r < i && e[r] === ".") for (a += e[r++]; r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
82
|
+
if (r < i && (e[r] === "e" || e[r] === "E")) {
|
|
83
|
+
let t = r + 1 < i ? e[r + 1] : "";
|
|
84
|
+
if (!/[a-zA-Z_]/.test(t)) {
|
|
85
|
+
for (a += e[r++], r < i && (e[r] === "+" || e[r] === "-") && (a += e[r++]); r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
86
|
+
for (; r < i && (e[r] === "." || e[r] === "e" || e[r] === "E" || /[0-9]/.test(e[r]));) a += e[r++];
|
|
87
|
+
}
|
|
88
|
+
} else for (; r < i && (e[r] === "." || /[0-9]/.test(e[r]));) a += e[r++];
|
|
89
|
+
if (!ve.test(a)) throw Error(`Invalid numeric literal '${a}' at position ${t} in: "${e}"`);
|
|
90
|
+
let o = Number(a);
|
|
91
|
+
if (!Number.isFinite(o)) throw Error(`Numeric literal '${a}' overflows finite floating-point range in: "${e}"`);
|
|
92
|
+
if (o === 0 && !/^[0.]+(?:[eE][+-]?\d+)?$/.test(a)) throw Error(`Numeric literal '${a}' underflows to zero at position ${t} in: "${e}"`);
|
|
93
|
+
n.push({
|
|
497
94
|
type: "NUMBER",
|
|
498
|
-
value:
|
|
95
|
+
value: a,
|
|
96
|
+
numericValue: o
|
|
499
97
|
});
|
|
500
|
-
} else if (/[a-zA-Z_]/.test(
|
|
501
|
-
let
|
|
502
|
-
for (;
|
|
503
|
-
t.
|
|
98
|
+
} else if (/[a-zA-Z_]/.test(a)) {
|
|
99
|
+
let a = "";
|
|
100
|
+
for (; r < i && /[a-zA-Z0-9_]/.test(e[r]);) a += e[r], r++;
|
|
101
|
+
if (t && t.has(a)) {
|
|
102
|
+
let e = t.get(a);
|
|
103
|
+
n.push({
|
|
104
|
+
type: "NUMBER",
|
|
105
|
+
value: String(e),
|
|
106
|
+
numericValue: e
|
|
107
|
+
});
|
|
108
|
+
} else n.push({
|
|
504
109
|
type: "IDENT",
|
|
505
|
-
value:
|
|
110
|
+
value: a
|
|
506
111
|
});
|
|
507
|
-
} else throw Error(`Unexpected character '${
|
|
112
|
+
} else throw Error(`Unexpected character '${a}' at position ${r} in: "${e}"`);
|
|
508
113
|
}
|
|
509
|
-
return
|
|
510
|
-
}
|
|
511
|
-
function oe(e, t) {
|
|
512
|
-
return e instanceof D ? e.add(t) : t instanceof D ? t.add(e) : e.add(t);
|
|
513
|
-
}
|
|
514
|
-
function se(e, t) {
|
|
515
|
-
return e instanceof D ? e.sub(t) : t instanceof D ? t.neg().add(e) : e.sub(t);
|
|
114
|
+
return n;
|
|
516
115
|
}
|
|
517
|
-
|
|
518
|
-
let n = e instanceof D ? e.quadTerms : /* @__PURE__ */ new Map(), r = t instanceof D ? t.quadTerms : /* @__PURE__ */ new Map(), i = e instanceof D ? e.linearTerms : e.terms, a = t instanceof D ? t.linearTerms : t.terms;
|
|
519
|
-
if (n.size > 0 && (r.size > 0 || a.size > 0) || r.size > 0 && (n.size > 0 || i.size > 0)) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
520
|
-
if (n.size === 0 && i.size === 0) return t.mul(e.constant);
|
|
521
|
-
if (r.size === 0 && a.size === 0) return e.mul(t.constant);
|
|
522
|
-
let o = new D();
|
|
523
|
-
if (o.constant = e.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, n] of i) o.linearTerms.set(e, (o.linearTerms.get(e) || 0) + n * t.constant);
|
|
524
|
-
if (Math.abs(e.constant) >= 1e-12) for (let [t, n] of a) o.linearTerms.set(t, (o.linearTerms.get(t) || 0) + n * e.constant);
|
|
525
|
-
for (let [e, t] of i) for (let [n, r] of a) o = o.add(D.fromProduct(e, n, t * r));
|
|
526
|
-
return o;
|
|
527
|
-
}
|
|
528
|
-
var ce = class {
|
|
116
|
+
var be = class {
|
|
529
117
|
tokens;
|
|
530
118
|
pos = 0;
|
|
531
119
|
resolver;
|
|
@@ -546,28 +134,20 @@ var ce = class {
|
|
|
546
134
|
for (; this.pos < this.tokens.length;) {
|
|
547
135
|
let t = this.peek();
|
|
548
136
|
if (!t) break;
|
|
549
|
-
if (t.type === "PLUS") this.consume(), e =
|
|
550
|
-
else if (t.type === "MINUS") this.consume(), e =
|
|
137
|
+
if (t.type === "PLUS") this.consume(), e = e.add(this.parseTerm());
|
|
138
|
+
else if (t.type === "MINUS") this.consume(), e = e.sub(this.parseTerm());
|
|
551
139
|
else break;
|
|
552
140
|
}
|
|
553
|
-
return e instanceof
|
|
141
|
+
return e instanceof A && e.quadTerms.size === 0 ? new j(e.linearTerms, e.constant) : e;
|
|
554
142
|
}
|
|
555
143
|
parseTerm() {
|
|
556
144
|
let e = this.parseFactor();
|
|
557
145
|
for (; this.pos < this.tokens.length;) {
|
|
558
146
|
let t = this.peek();
|
|
559
147
|
if (!t) break;
|
|
560
|
-
if (t.type === "STAR")
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
e = N(e, t);
|
|
564
|
-
} else if (t.type === "SLASH") {
|
|
565
|
-
this.consume();
|
|
566
|
-
let t = this.parseFactor(), n = t instanceof D ? t.linearTerms : t.terms, r = t instanceof D ? t.quadTerms.size : 0;
|
|
567
|
-
if (n.size > 0 || r > 0) throw Error("Cannot divide by variable in expression");
|
|
568
|
-
if (Math.abs(t.constant) < 1e-12) throw Error("Division by zero in expression");
|
|
569
|
-
e = e.div(t.constant);
|
|
570
|
-
} else break;
|
|
148
|
+
if (t.type === "STAR") this.consume(), e = e.mul(this.parseFactor());
|
|
149
|
+
else if (t.type === "SLASH") this.consume(), e = e.div(this.parseFactor());
|
|
150
|
+
else break;
|
|
571
151
|
}
|
|
572
152
|
return e;
|
|
573
153
|
}
|
|
@@ -579,20 +159,20 @@ var ce = class {
|
|
|
579
159
|
let t;
|
|
580
160
|
if (e.type === "NUMBER") {
|
|
581
161
|
this.consume();
|
|
582
|
-
let n =
|
|
162
|
+
let n = e.numericValue ?? Number(e.value);
|
|
583
163
|
if (this.peek()?.type === "IDENT" || this.peek()?.type === "LPAREN") {
|
|
584
164
|
let e;
|
|
585
165
|
if (this.peek()?.type === "IDENT") {
|
|
586
166
|
let t = this.consume(), n = this.resolve(t.value);
|
|
587
|
-
e = n instanceof
|
|
167
|
+
e = n instanceof b || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new j(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
588
168
|
} else this.consume("LPAREN"), e = this.parseExpression(), this.consume("RPAREN");
|
|
589
169
|
return this.applyPower(e).mul(n);
|
|
590
170
|
}
|
|
591
|
-
t = new
|
|
171
|
+
t = new j(/* @__PURE__ */ new Map(), n);
|
|
592
172
|
} else if (e.type === "IDENT") {
|
|
593
173
|
this.consume();
|
|
594
174
|
let n = this.resolve(e.value);
|
|
595
|
-
t = n instanceof
|
|
175
|
+
t = n instanceof b || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new j(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
596
176
|
} else if (e.type === "LPAREN") this.consume("LPAREN"), t = this.parseExpression(), this.consume("RPAREN");
|
|
597
177
|
else throw Error(`Unexpected token '${e.value}' in expression`);
|
|
598
178
|
return this.applyPower(t);
|
|
@@ -602,24 +182,27 @@ var ce = class {
|
|
|
602
182
|
let t = [];
|
|
603
183
|
for (; this.peek()?.type === "CARET";) {
|
|
604
184
|
this.consume();
|
|
605
|
-
let e = this.
|
|
606
|
-
|
|
607
|
-
this.
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
185
|
+
let e = this.tokens[this.pos]?.type === "LPAREN" && this.tokens[this.pos + 1]?.type === "NUMBER" && this.tokens[this.pos + 2]?.type === "RPAREN";
|
|
186
|
+
e && this.consume("LPAREN");
|
|
187
|
+
let n = this.peek();
|
|
188
|
+
if (!n || n.type !== "NUMBER") throw Error("Exponent must be a non-negative integer number");
|
|
189
|
+
this.consume(), e && this.consume("RPAREN");
|
|
190
|
+
let r = n.numericValue ?? Number(n.value);
|
|
191
|
+
if (!Number.isInteger(r) || r < 0) throw Error("Exponent must be a non-negative integer");
|
|
192
|
+
t.push(r);
|
|
611
193
|
}
|
|
612
194
|
let n = t[t.length - 1];
|
|
613
195
|
for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
|
|
614
196
|
if (!Number.isFinite(n) || n < 0) throw Error("Exponent creates an invalid or out-of-range power");
|
|
615
|
-
let r = e instanceof
|
|
197
|
+
let r = e instanceof A, i = r ? e.quadTerms.size : 0, a = r ? e.linearTerms.size : e.terms.size;
|
|
616
198
|
if (i === 0 && a === 0) {
|
|
617
199
|
let t = e.constant ** +n;
|
|
618
|
-
|
|
200
|
+
if (e.constant !== 0 && n > 0 && t === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
201
|
+
return new j(/* @__PURE__ */ new Map(), t);
|
|
619
202
|
}
|
|
620
|
-
if (n === 0) return new
|
|
203
|
+
if (n === 0) return new j(/* @__PURE__ */ new Map(), 1);
|
|
621
204
|
if (n === 1) return e;
|
|
622
|
-
if (n === 2) return
|
|
205
|
+
if (n === 2) return e.mul(e);
|
|
623
206
|
throw Error(`Exponent ${n} creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)`);
|
|
624
207
|
}
|
|
625
208
|
getRemainingToken() {
|
|
@@ -631,193 +214,270 @@ var ce = class {
|
|
|
631
214
|
return t;
|
|
632
215
|
}
|
|
633
216
|
};
|
|
634
|
-
function
|
|
635
|
-
let
|
|
636
|
-
if (
|
|
637
|
-
return
|
|
217
|
+
function xe(e, t, n) {
|
|
218
|
+
let r = new be(ye(e, n), t), i = r.parseExpression(), a = r.getRemainingToken();
|
|
219
|
+
if (a) throw Error(`Unexpected token '${a.value}' after expression in "${e}"`);
|
|
220
|
+
return Ee(i), i;
|
|
221
|
+
}
|
|
222
|
+
function Se(e, t) {
|
|
223
|
+
return xe(e, t);
|
|
224
|
+
}
|
|
225
|
+
function Ce(e, t, n, r) {
|
|
226
|
+
let i = e.match(/(<=|>=|==|=<|=>|=)/);
|
|
227
|
+
if (!i) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
228
|
+
let a = i[0], o = i.index, s = e.substring(0, o).trim(), c = e.substring(o + a.length).trim(), l;
|
|
229
|
+
if (a === "<=" || a === "=<") l = "<=";
|
|
230
|
+
else if (a === ">=" || a === "=>") l = ">=";
|
|
231
|
+
else if (a === "==" || a === "=") l = "==";
|
|
232
|
+
else throw Error(`Unsupported operator "${a}"`);
|
|
233
|
+
let u = xe(s, t, r), d = xe(c, t, r);
|
|
234
|
+
if (u instanceof A && u.quadTerms.size > 0 || d instanceof A && d.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
|
|
235
|
+
let f = u instanceof A ? new j(u.linearTerms, u.constant) : u, p = d instanceof A ? new j(d.linearTerms, d.constant) : d, m;
|
|
236
|
+
if (m = l === "<=" ? f.le(p, n) : l === ">=" ? f.ge(p, n) : f.eq(p, n), Ee(m.lhs), !Number.isFinite(m.rhs)) throw Error(`Invalid non-finite right-hand side "${m.rhs}" in constraint.`);
|
|
237
|
+
return m;
|
|
238
|
+
}
|
|
239
|
+
function we(e, t, n) {
|
|
240
|
+
return Ce(e, t, n);
|
|
241
|
+
}
|
|
242
|
+
function Te(e) {
|
|
243
|
+
return e instanceof b || e instanceof j || e instanceof A ? !0 : typeof e != "object" || !e ? !1 : "terms" in e && e.terms instanceof Map || "quadTerms" in e && e.quadTerms instanceof Map || "id" in e && "name" in e && "lb" in e && "ub" in e && "type" in e && typeof e.mul == "function";
|
|
244
|
+
}
|
|
245
|
+
function Ee(e) {
|
|
246
|
+
if ("constant" in e && !Number.isFinite(e.constant)) throw Error(`Invalid non-finite constant "${e.constant}" in expression.`);
|
|
247
|
+
if ("terms" in e && e.terms instanceof Map) {
|
|
248
|
+
for (let [, t] of e.terms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
249
|
+
}
|
|
250
|
+
if ("linearTerms" in e && e.linearTerms instanceof Map) {
|
|
251
|
+
for (let [, t] of e.linearTerms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
252
|
+
}
|
|
253
|
+
if ("quadTerms" in e && e.quadTerms instanceof Map) {
|
|
254
|
+
for (let [, t] of e.quadTerms) if (!Number.isFinite(t.coeff)) throw Error(`Invalid non-finite quadratic coefficient "${t.coeff}" in expression.`);
|
|
255
|
+
}
|
|
638
256
|
}
|
|
639
|
-
function
|
|
640
|
-
|
|
641
|
-
if (!r) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
642
|
-
let i = r[0], a = r.index, o = e.substring(0, a).trim(), s = e.substring(a + i.length).trim(), c;
|
|
643
|
-
if (i === "<=" || i === "=<") c = "<=";
|
|
644
|
-
else if (i === ">=" || i === "=>") c = ">=";
|
|
645
|
-
else if (i === "==" || i === "=") c = "==";
|
|
646
|
-
else throw Error(`Unsupported operator "${i}"`);
|
|
647
|
-
let l = P(o, t), u = P(s, t);
|
|
648
|
-
if (l instanceof D && l.quadTerms.size > 0 || u instanceof D && u.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
|
|
649
|
-
let d = l instanceof D ? new O(l.linearTerms, l.constant) : l, f = u instanceof D ? new O(u.linearTerms, u.constant) : u;
|
|
650
|
-
return c === "<=" ? d.le(f, n) : c === ">=" ? d.ge(f, n) : d.eq(f, n);
|
|
257
|
+
function De(e) {
|
|
258
|
+
return e instanceof c || typeof e == "object" && !!e && "sense" in e && "lhs" in e && "rhs" in e;
|
|
651
259
|
}
|
|
652
|
-
function
|
|
653
|
-
let n = /* @__PURE__ */ new Map(), r = "";
|
|
654
|
-
for (
|
|
260
|
+
function Oe(e, t) {
|
|
261
|
+
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = e.join(""), a = "__washi_";
|
|
262
|
+
for (; i.includes(a);) a += "_";
|
|
263
|
+
let o = "";
|
|
264
|
+
for (let i = 0; i < e.length; i++) if (o += e[i], i < t.length) {
|
|
655
265
|
let e = t[i];
|
|
656
|
-
if (typeof e == "number")
|
|
657
|
-
|
|
658
|
-
let t =
|
|
659
|
-
|
|
660
|
-
}
|
|
266
|
+
if (typeof e == "number") {
|
|
267
|
+
if (!Number.isFinite(e)) throw Error(`Invalid numeric value "${e}" in template expression: interpolated numbers must be finite.`);
|
|
268
|
+
let t = `${a}num_${i}__`;
|
|
269
|
+
r.set(t, e), o += `(${t})`;
|
|
270
|
+
} else if (De(e)) throw Error("Cannot interpolate a constraint comparison (<=, >=, ==) inside a template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
271
|
+
else if (Te(e)) {
|
|
272
|
+
Ee(e);
|
|
273
|
+
let t = `${a}ph_${i}__`;
|
|
274
|
+
n.set(t, e), o += ` ${t} `;
|
|
275
|
+
} else throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
661
276
|
}
|
|
662
277
|
return {
|
|
663
|
-
fullText:
|
|
664
|
-
resolver: (e) => n.get(e)
|
|
278
|
+
fullText: o,
|
|
279
|
+
resolver: (e) => n.get(e),
|
|
280
|
+
numberMap: r
|
|
665
281
|
};
|
|
666
282
|
}
|
|
667
|
-
function
|
|
668
|
-
let { fullText: n, resolver: r } =
|
|
669
|
-
return
|
|
670
|
-
}
|
|
671
|
-
function R(e, ...t) {
|
|
672
|
-
let { fullText: n, resolver: r } = I(e, t);
|
|
673
|
-
return /(<=|>=|==|=<|=>|=)/.test(n) ? F(n, r) : P(n, r);
|
|
283
|
+
function ke(e, ...t) {
|
|
284
|
+
let { fullText: n, resolver: r, numberMap: i } = Oe(e, t);
|
|
285
|
+
return /(<=|>=|==|=<|=>|=)/.test(n) ? Ce(n, r, void 0, i) : xe(n, r, i);
|
|
674
286
|
}
|
|
675
287
|
//#endregion
|
|
676
|
-
//#region src/modeler/
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
return
|
|
288
|
+
//#region src/modeler/solvers/highs/worker-client.ts
|
|
289
|
+
var z = null, Ae = 0, B = /* @__PURE__ */ new Map();
|
|
290
|
+
function je(e, t) {
|
|
291
|
+
return e ? {
|
|
292
|
+
Status: "Interrupted",
|
|
293
|
+
StatusCode: 17,
|
|
294
|
+
HasPrimalSolution: !0,
|
|
295
|
+
IsMip: !0,
|
|
296
|
+
ObjectiveValue: e.objectiveValue,
|
|
297
|
+
ObjectiveOffsetApplied: !0,
|
|
298
|
+
...t?.objectiveBound === void 0 ? e.mipDualBound === void 0 ? {} : { MipDualBound: e.mipDualBound } : { MipDualBound: t.objectiveBound },
|
|
299
|
+
...t?.relGap === void 0 ? e.mipGap === void 0 ? {} : { MipGap: e.mipGap } : { MipGap: t.relGap },
|
|
300
|
+
Columns: e.columns,
|
|
301
|
+
Rows: []
|
|
302
|
+
} : {
|
|
303
|
+
Status: "Interrupted",
|
|
304
|
+
StatusCode: 17,
|
|
305
|
+
HasPrimalSolution: !1,
|
|
306
|
+
ObjectiveValue: NaN,
|
|
307
|
+
ObjectiveOffsetApplied: !0,
|
|
308
|
+
...t?.objectiveBound === void 0 ? {} : { MipDualBound: t.objectiveBound },
|
|
309
|
+
...t?.relGap === void 0 ? {} : { MipGap: t.relGap },
|
|
310
|
+
Columns: {},
|
|
311
|
+
Rows: []
|
|
312
|
+
};
|
|
680
313
|
}
|
|
681
|
-
function
|
|
682
|
-
let
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
d.push(t && t.toLowerCase() === "maximize" ? "Maximize" : "Minimize");
|
|
696
|
-
let f = [], p = !0, m = n instanceof D ? n.linearTerms : n.terms;
|
|
697
|
-
if (m) for (let [e, t] of m) {
|
|
698
|
-
if (Math.abs(t) < 1e-12) continue;
|
|
699
|
-
let n = o.get(e), r = t >= 0 ? p ? "" : "+ " : "- ", i = Math.abs(t), a = i === 1 ? "" : `${i} `;
|
|
700
|
-
f.push(`${r}${a}${n}`), p = !1;
|
|
701
|
-
}
|
|
702
|
-
if (n instanceof D && n.quadTerms.size > 0) {
|
|
703
|
-
let e = [], t = !0;
|
|
704
|
-
for (let r of n.quadTerms.values()) {
|
|
705
|
-
if (Math.abs(r.coeff) < 1e-12) continue;
|
|
706
|
-
let n = 2 * r.coeff, i = n >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(n), s = a === 1 ? "" : `${a} `, c = o.get(r.var1), l = o.get(r.var2);
|
|
707
|
-
r.var1 === r.var2 ? e.push(`${i}${s}${c} ^ 2`) : e.push(`${i}${s}${c} * ${l}`), t = !1;
|
|
708
|
-
}
|
|
709
|
-
if (e.length > 0) {
|
|
710
|
-
let t = `[ ${e.join(" ")} ] / 2`;
|
|
711
|
-
f.length > 0 ? f.push("+", t) : f.push(t);
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
let h = f.length > 0 ? f.join(" ") : "0";
|
|
715
|
-
d.push(` obj: ${h}`), d.push("Subject To");
|
|
716
|
-
for (let e of r) {
|
|
717
|
-
let t = u.get(e), n = [], r = !0;
|
|
718
|
-
for (let [t, i] of e.lhs.terms) {
|
|
719
|
-
if (Math.abs(i) < 1e-12) continue;
|
|
720
|
-
let e = o.get(t), a = i >= 0 ? r ? "" : "+ " : "- ", s = Math.abs(i), c = s === 1 ? "" : `${s} `;
|
|
721
|
-
n.push(`${a}${c}${e}`), r = !1;
|
|
722
|
-
}
|
|
723
|
-
let i = n.length > 0 ? n.join(" ") : "0", a = e.sense === "==" ? "=" : e.sense;
|
|
724
|
-
d.push(` ${t}: ${i} ${a} ${e.rhs}`);
|
|
725
|
-
}
|
|
726
|
-
d.push("Bounds");
|
|
727
|
-
let g = [], _ = [];
|
|
728
|
-
for (let e of i) {
|
|
729
|
-
let t = o.get(e);
|
|
730
|
-
if (e.type === "Binary") {
|
|
731
|
-
_.push(t);
|
|
732
|
-
continue;
|
|
314
|
+
function Me(e) {
|
|
315
|
+
let t = B.values().next().value;
|
|
316
|
+
if (t && !t.dispatched) {
|
|
317
|
+
t.dispatched = !0;
|
|
318
|
+
try {
|
|
319
|
+
e.postMessage({
|
|
320
|
+
type: "SOLVE",
|
|
321
|
+
id: t.id,
|
|
322
|
+
lpString: t.lpString,
|
|
323
|
+
options: t.workerOptions,
|
|
324
|
+
...t.reportProgress ? { reportProgress: !0 } : {}
|
|
325
|
+
});
|
|
326
|
+
} catch (n) {
|
|
327
|
+
B.delete(t.id), t.cleanupAbort?.(), t.reject(n), Me(e);
|
|
733
328
|
}
|
|
734
|
-
e.type === "Integer" && g.push(t);
|
|
735
|
-
let n = e.lb === -Infinity, r = e.ub === Infinity;
|
|
736
|
-
n && r ? d.push(` ${t} free`) : n && !r ? d.push(` -infinity <= ${t} <= ${e.ub}`) : !n && r ? e.lb !== 0 && d.push(` ${t} >= ${e.lb}`) : d.push(` ${e.lb} <= ${t} <= ${e.ub}`);
|
|
737
|
-
}
|
|
738
|
-
if (g.length > 0) {
|
|
739
|
-
d.push("Generals");
|
|
740
|
-
for (let e = 0; e < g.length; e += 10) d.push(" " + g.slice(e, e + 10).join(" "));
|
|
741
329
|
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
330
|
+
}
|
|
331
|
+
function Ne() {
|
|
332
|
+
let e = z;
|
|
333
|
+
e && (z = null, e.terminate());
|
|
334
|
+
for (let e of B.values()) e.dispatched = !1;
|
|
335
|
+
if (B.size > 0) {
|
|
336
|
+
let e = Pe();
|
|
337
|
+
if (e) Me(e);
|
|
338
|
+
else {
|
|
339
|
+
let e = /* @__PURE__ */ Error("[WaSHI] Failed to recreate HiGHS Worker after interruption.");
|
|
340
|
+
for (let t of Array.from(B.values())) B.delete(t.id), t.cleanupAbort?.(), t.reject(e);
|
|
341
|
+
}
|
|
745
342
|
}
|
|
746
|
-
return d.push("End"), {
|
|
747
|
-
lpString: d.join("\n") + "\n",
|
|
748
|
-
nameToVar: a,
|
|
749
|
-
nameToConstraint: s
|
|
750
|
-
};
|
|
751
343
|
}
|
|
752
|
-
|
|
753
|
-
//#region src/modeler/solvers/highs/worker-client.ts
|
|
754
|
-
var V = null, le = 0, H = /* @__PURE__ */ new Map();
|
|
755
|
-
function ue() {
|
|
344
|
+
function Pe() {
|
|
756
345
|
if (typeof window > "u" || typeof Worker > "u") return null;
|
|
757
|
-
if (!
|
|
758
|
-
|
|
759
|
-
let e =
|
|
760
|
-
|
|
761
|
-
let { type:
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
346
|
+
if (!z) try {
|
|
347
|
+
z = ue();
|
|
348
|
+
let e = z;
|
|
349
|
+
z.onmessage = (t) => {
|
|
350
|
+
let { type: n, id: r, result: i, runTime: a, error: o, progress: s, incumbent: c } = t.data, l = B.get(r);
|
|
351
|
+
if (l) {
|
|
352
|
+
if (n === "SOLVE_PROGRESS") {
|
|
353
|
+
if (s) {
|
|
354
|
+
l.lastProgress = s;
|
|
355
|
+
try {
|
|
356
|
+
l.onProgress?.(s);
|
|
357
|
+
} catch (e) {
|
|
358
|
+
let t = B.get(r);
|
|
359
|
+
if (t) {
|
|
360
|
+
let n = B.keys().next().value;
|
|
361
|
+
B.delete(r), t.cleanupAbort?.(), n === r && Ne(), t.reject(e);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (n === "SOLVE_INCUMBENT") {
|
|
368
|
+
c && (l.lastIncumbent = c);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
B.delete(r), l.cleanupAbort?.(), n === "SOLVE_SUCCESS" ? l.resolve({
|
|
372
|
+
result: i,
|
|
373
|
+
runTime: a
|
|
374
|
+
}) : l.reject(Error(o || "Worker solve failed")), z === e && Me(e);
|
|
375
|
+
}
|
|
766
376
|
};
|
|
767
377
|
let t = (t) => {
|
|
768
|
-
if (
|
|
769
|
-
|
|
770
|
-
for (let e of
|
|
771
|
-
|
|
378
|
+
if (z === e) {
|
|
379
|
+
z = null, e.terminate();
|
|
380
|
+
for (let e of B.values()) e.cleanupAbort?.(), e.reject(t);
|
|
381
|
+
B.clear();
|
|
772
382
|
}
|
|
773
383
|
};
|
|
774
|
-
|
|
384
|
+
z.onerror = (e) => t(/* @__PURE__ */ Error(`[WaSHI] HiGHS Worker failed to load or execute. Check Worker assets, CORS and CSP. ${e?.message || ""}`)), z.onmessageerror = () => t(/* @__PURE__ */ Error("[WaSHI] Could not deserialize the HiGHS Worker response."));
|
|
775
385
|
} catch {
|
|
776
|
-
|
|
386
|
+
z = null;
|
|
777
387
|
}
|
|
778
|
-
return
|
|
388
|
+
return z;
|
|
779
389
|
}
|
|
780
|
-
async function
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
390
|
+
async function V(e, t = {}) {
|
|
391
|
+
if (t.signal?.aborted) return {
|
|
392
|
+
result: je(),
|
|
393
|
+
runTime: 0
|
|
394
|
+
};
|
|
395
|
+
let n = await F(t.wasmUrl);
|
|
396
|
+
if (t.signal?.aborted) return {
|
|
397
|
+
result: je(),
|
|
398
|
+
runTime: 0
|
|
399
|
+
};
|
|
400
|
+
let r = t.useWorker ?? typeof window < "u" ? Pe() : null;
|
|
401
|
+
if (!r) return N(e, t);
|
|
402
|
+
let { signal: i, onProgress: a, ...o } = t, s = {};
|
|
403
|
+
for (let [e, t] of Object.entries(o)) typeof t != "function" && (s[e] = t);
|
|
404
|
+
s.wasmUrl = n;
|
|
405
|
+
let c = !!(a || i), l = `req_${++Ae}`, u = performance.now();
|
|
787
406
|
return new Promise((t, n) => {
|
|
788
|
-
|
|
407
|
+
let o = {
|
|
408
|
+
id: l,
|
|
409
|
+
lpString: e,
|
|
410
|
+
workerOptions: s,
|
|
411
|
+
reportProgress: c,
|
|
412
|
+
startTime: u,
|
|
413
|
+
onProgress: a,
|
|
789
414
|
resolve: t,
|
|
790
415
|
reject: n
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
416
|
+
};
|
|
417
|
+
if (i) {
|
|
418
|
+
let e = () => {
|
|
419
|
+
let e = B.get(l);
|
|
420
|
+
if (!e) return;
|
|
421
|
+
let t = B.keys().next().value;
|
|
422
|
+
B.delete(l), e.cleanupAbort?.(), t === l && Ne();
|
|
423
|
+
let n = (performance.now() - e.startTime) / 1e3;
|
|
424
|
+
e.resolve({
|
|
425
|
+
result: je(e.lastIncumbent, e.lastProgress),
|
|
426
|
+
runTime: n
|
|
427
|
+
});
|
|
428
|
+
};
|
|
429
|
+
i.addEventListener("abort", e, { once: !0 }), o.cleanupAbort = () => i.removeEventListener("abort", e);
|
|
801
430
|
}
|
|
431
|
+
B.set(l, o), Me(r);
|
|
802
432
|
});
|
|
803
433
|
}
|
|
804
434
|
//#endregion
|
|
805
435
|
//#region src/modeler/solvers/highs/solver.ts
|
|
806
|
-
function
|
|
436
|
+
function H(e, t) {
|
|
437
|
+
if (typeof t == "number") switch (t) {
|
|
438
|
+
case 0: return "NotSolved";
|
|
439
|
+
case 1:
|
|
440
|
+
case 2:
|
|
441
|
+
case 3:
|
|
442
|
+
case 4:
|
|
443
|
+
case 5: return "Error";
|
|
444
|
+
case 6: return "Unknown";
|
|
445
|
+
case 7: return "Optimal";
|
|
446
|
+
case 8: return "Infeasible";
|
|
447
|
+
case 9: return "InfeasibleOrUnbounded";
|
|
448
|
+
case 10: return "Unbounded";
|
|
449
|
+
case 11: return "ObjectiveBound";
|
|
450
|
+
case 12: return "ObjectiveTarget";
|
|
451
|
+
case 13: return "TimeLimit";
|
|
452
|
+
case 14: return "IterationLimit";
|
|
453
|
+
case 15: return "Unknown";
|
|
454
|
+
case 16: return "SolutionLimit";
|
|
455
|
+
case 17: return "Interrupted";
|
|
456
|
+
case 18: return "MemoryLimit";
|
|
457
|
+
}
|
|
807
458
|
if (typeof e != "string") return "Unknown";
|
|
808
|
-
let
|
|
809
|
-
if (!
|
|
810
|
-
switch (
|
|
459
|
+
let n = e.trim();
|
|
460
|
+
if (!n) return "Unknown";
|
|
461
|
+
switch (n) {
|
|
811
462
|
case "Optimal": return "Optimal";
|
|
812
463
|
case "Infeasible": return "Infeasible";
|
|
813
464
|
case "Unbounded": return "Unbounded";
|
|
814
|
-
case "Primal infeasible or unbounded":
|
|
465
|
+
case "Primal infeasible or unbounded":
|
|
466
|
+
case "InfeasibleOrUnbounded": return "InfeasibleOrUnbounded";
|
|
815
467
|
case "Time limit reached":
|
|
816
468
|
case "TimeLimit": return "TimeLimit";
|
|
817
469
|
case "Iteration limit reached":
|
|
818
470
|
case "IterationLimit": return "IterationLimit";
|
|
471
|
+
case "Solution limit reached":
|
|
472
|
+
case "SolutionLimit": return "SolutionLimit";
|
|
473
|
+
case "Memory limit reached":
|
|
474
|
+
case "MemoryLimit": return "MemoryLimit";
|
|
819
475
|
case "Bound on objective reached":
|
|
476
|
+
case "ObjectiveBound": return "ObjectiveBound";
|
|
820
477
|
case "Target for objective reached":
|
|
478
|
+
case "ObjectiveTarget": return "ObjectiveTarget";
|
|
479
|
+
case "Interrupted":
|
|
480
|
+
case "User interrupt": return "Interrupted";
|
|
821
481
|
case "Feasible": return "Feasible";
|
|
822
482
|
case "Not Set": return "NotSolved";
|
|
823
483
|
case "Load error":
|
|
@@ -829,307 +489,1657 @@ function W(e) {
|
|
|
829
489
|
case "Empty":
|
|
830
490
|
case "Unknown": return "Unknown";
|
|
831
491
|
}
|
|
832
|
-
let
|
|
833
|
-
return
|
|
492
|
+
let r = n.toLowerCase();
|
|
493
|
+
return r.includes("infeasible") && r.includes("unbounded") ? "InfeasibleOrUnbounded" : r.includes("infeasible") ? "Infeasible" : r.includes("unbounded") ? "Unbounded" : r.includes("time limit") || r.includes("timelimit") ? "TimeLimit" : r.includes("iteration limit") || r.includes("iterationlimit") ? "IterationLimit" : r.includes("solution limit") || r.includes("solutionlimit") ? "SolutionLimit" : r.includes("memory limit") || r.includes("memorylimit") ? "MemoryLimit" : r.includes("bound on objective") ? "ObjectiveBound" : r.includes("target for objective") ? "ObjectiveTarget" : r.includes("interrupt") ? "Interrupted" : r.includes("error") ? "Error" : r === "optimal" ? "Optimal" : "Unknown";
|
|
494
|
+
}
|
|
495
|
+
function U(e, t, n) {
|
|
496
|
+
switch (H(e, t)) {
|
|
497
|
+
case "Optimal": return "Optimal";
|
|
498
|
+
case "Infeasible": return "Infeasible";
|
|
499
|
+
case "Unbounded": return "Unbounded";
|
|
500
|
+
case "TimeLimit": return "TimeLimit";
|
|
501
|
+
case "IterationLimit": return "IterationLimit";
|
|
502
|
+
case "Feasible": return "Feasible";
|
|
503
|
+
case "ObjectiveBound":
|
|
504
|
+
case "ObjectiveTarget":
|
|
505
|
+
case "SolutionLimit": return n === !1 ? "Unknown" : "Feasible";
|
|
506
|
+
case "MemoryLimit":
|
|
507
|
+
case "Interrupted": return n ? "Feasible" : "Unknown";
|
|
508
|
+
case "NotSolved": return "NotSolved";
|
|
509
|
+
case "Error": return "Error";
|
|
510
|
+
default: return "Unknown";
|
|
511
|
+
}
|
|
834
512
|
}
|
|
835
|
-
var
|
|
513
|
+
var W = class e {
|
|
836
514
|
static capabilities = {
|
|
837
515
|
supportsMIP: !0,
|
|
838
|
-
supportsQP: !0
|
|
516
|
+
supportsQP: !0,
|
|
517
|
+
supportsWarmStart: !0
|
|
839
518
|
};
|
|
840
519
|
name = "HiGHS";
|
|
841
|
-
version = "1.15.
|
|
520
|
+
version = "1.15.1";
|
|
842
521
|
capabilities = e.capabilities;
|
|
843
522
|
options;
|
|
844
523
|
constructor(e = {}) {
|
|
845
524
|
this.options = e;
|
|
846
525
|
}
|
|
847
|
-
async solve(e, t, n = {}) {
|
|
848
|
-
let r = {
|
|
526
|
+
async solve(e, t = {}, n = {}) {
|
|
527
|
+
let r = E(t), i = r ? n : t, a = {
|
|
849
528
|
...this.options,
|
|
850
|
-
...
|
|
851
|
-
},
|
|
852
|
-
|
|
853
|
-
|
|
529
|
+
...i
|
|
530
|
+
}, o = e.objective.constant || 0;
|
|
531
|
+
for (let t of e.variables) d(t);
|
|
532
|
+
let { lpString: s, nameToVar: c, nameToConstraint: l } = r ? t : C(e, { relax: a.relax }), u = Object.create(null), p = !1, m = /* @__PURE__ */ new Set();
|
|
533
|
+
for (let [e, t] of c.entries()) {
|
|
534
|
+
m.add(t);
|
|
535
|
+
let n = w(t);
|
|
536
|
+
n !== void 0 && (u[e] = n, p = !0);
|
|
537
|
+
}
|
|
538
|
+
for (let t = 0; t < e.variables.length; t++) {
|
|
539
|
+
let n = e.variables[t];
|
|
540
|
+
if (!m.has(n)) {
|
|
541
|
+
let e = w(n);
|
|
542
|
+
if (e !== void 0) {
|
|
543
|
+
let r = f(n.name, "x", t);
|
|
544
|
+
Object.prototype.hasOwnProperty.call(u, r) || (u[r] = e, p = !0);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
let h = a;
|
|
549
|
+
(o !== 0 || p || h.initialValues !== void 0) && (h = {
|
|
550
|
+
...h,
|
|
551
|
+
...o === 0 ? {} : { objectiveOffset: o },
|
|
552
|
+
initialValues: p ? u : void 0
|
|
553
|
+
});
|
|
554
|
+
let { result: g, runTime: _ } = await V(s, h), v = g?.ObjectiveOffsetApplied ? 0 : o, y = H(g?.Status, g?.StatusCode), b = a.relax ? !1 : typeof g?.IsMip == "boolean" ? g.IsMip : e.variables.some((e) => e.type === "Integer" || e.type === "Binary"), x;
|
|
555
|
+
if (typeof g?.HasPrimalSolution == "boolean") x = g.HasPrimalSolution;
|
|
556
|
+
else {
|
|
557
|
+
let e = g?.Columns ? Object.values(g.Columns) : [], t = e.length > 0 && e.some((e) => typeof e?.Primal == "number" && Number.isFinite(e.Primal)), n = typeof g?.ObjectiveValue == "number" && Number.isFinite(g.ObjectiveValue);
|
|
558
|
+
x = y === "Infeasible" || y === "Unbounded" || y === "InfeasibleOrUnbounded" || y === "Error" || y === "NotSolved" ? !1 : y === "Optimal" || y === "Feasible" ? n || t : n && (e.length === 0 || t);
|
|
559
|
+
}
|
|
560
|
+
let S = U(g?.Status, g?.StatusCode, x), T = null;
|
|
561
|
+
x && typeof g?.ObjectiveValue == "number" && Number.isFinite(g.ObjectiveValue) && (T = g.ObjectiveValue + v);
|
|
562
|
+
let D, O, k;
|
|
563
|
+
if (typeof g?.MipDualBound == "number" && Number.isFinite(g.MipDualBound) ? D = g.MipDualBound + v : !b && y === "Optimal" && T !== null && (D = T), T !== null && D !== void 0 && Number.isFinite(D) && (k = Math.abs(T - D)), v !== 0 && b && T !== null && D !== void 0 && k !== void 0) {
|
|
564
|
+
if (k === 0) O = 0;
|
|
565
|
+
else if (Math.abs(T) > 0) {
|
|
566
|
+
let e = k / Math.abs(T);
|
|
567
|
+
O = Number.isFinite(e) ? e : void 0;
|
|
568
|
+
} else O = void 0;
|
|
569
|
+
} else typeof g?.MipGap == "number" && Number.isFinite(g.MipGap) ? O = g.MipGap : b && y === "Optimal" && x && (k === void 0 || k === 0) && (O = 0);
|
|
570
|
+
if (!x) return {
|
|
571
|
+
status: S,
|
|
572
|
+
terminationStatus: y,
|
|
573
|
+
hasPrimalSolution: !1,
|
|
854
574
|
objectiveValue: null,
|
|
575
|
+
...D === void 0 ? {} : { objectiveBound: D },
|
|
576
|
+
...O === void 0 ? {} : {
|
|
577
|
+
relGap: O,
|
|
578
|
+
mipGap: O
|
|
579
|
+
},
|
|
580
|
+
...k === void 0 ? {} : { absGap: k },
|
|
855
581
|
values: {},
|
|
856
582
|
reducedCosts: {},
|
|
857
583
|
duals: {},
|
|
858
584
|
slacks: {},
|
|
859
|
-
runTime:
|
|
860
|
-
raw:
|
|
585
|
+
runTime: _,
|
|
586
|
+
raw: g
|
|
861
587
|
};
|
|
862
|
-
let
|
|
863
|
-
|
|
864
|
-
|
|
588
|
+
let A = (e, t, n) => {
|
|
589
|
+
Object.defineProperty(e, t, {
|
|
590
|
+
value: n,
|
|
591
|
+
enumerable: !0,
|
|
592
|
+
writable: !0,
|
|
593
|
+
configurable: !0
|
|
594
|
+
});
|
|
595
|
+
}, j = {}, ee = {}, M = {}, N = {};
|
|
596
|
+
if (g.Columns) for (let [e, t] of Object.entries(g.Columns)) {
|
|
597
|
+
let n = c.get(e);
|
|
865
598
|
if (n) {
|
|
866
|
-
|
|
867
|
-
|
|
599
|
+
if (typeof t.Primal == "number" && Number.isFinite(t.Primal)) {
|
|
600
|
+
let e = Math.abs(t.Primal) < 1e-9 ? 0 : t.Primal;
|
|
601
|
+
A(j, n.name, e);
|
|
602
|
+
}
|
|
603
|
+
typeof t.Dual == "number" && Number.isFinite(t.Dual) && A(M, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual);
|
|
868
604
|
}
|
|
869
605
|
}
|
|
870
|
-
if (
|
|
871
|
-
let e = Array.isArray(
|
|
606
|
+
if (g.Rows) {
|
|
607
|
+
let e = Array.isArray(g.Rows) ? g.Rows : Object.values(g.Rows);
|
|
872
608
|
for (let t of e) {
|
|
873
|
-
let e = t.Name, n =
|
|
874
|
-
if (n && (t.Dual
|
|
609
|
+
let e = t.Name, n = e ? l.get(e) : void 0;
|
|
610
|
+
if (n && (typeof t.Dual == "number" && Number.isFinite(t.Dual) && A(ee, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual), typeof t.Primal == "number" && Number.isFinite(t.Primal))) {
|
|
875
611
|
let e = n.rhs - t.Primal;
|
|
876
|
-
|
|
612
|
+
A(N, n.name, Math.abs(e) < 1e-9 ? 0 : e);
|
|
877
613
|
}
|
|
878
614
|
}
|
|
879
615
|
}
|
|
880
616
|
return {
|
|
881
|
-
status:
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
617
|
+
status: S,
|
|
618
|
+
terminationStatus: y,
|
|
619
|
+
hasPrimalSolution: !0,
|
|
620
|
+
objectiveValue: T,
|
|
621
|
+
...D === void 0 ? {} : { objectiveBound: D },
|
|
622
|
+
...O === void 0 ? {} : {
|
|
623
|
+
relGap: O,
|
|
624
|
+
mipGap: O
|
|
625
|
+
},
|
|
626
|
+
...k === void 0 ? {} : { absGap: k },
|
|
627
|
+
values: j,
|
|
628
|
+
reducedCosts: M,
|
|
629
|
+
duals: ee,
|
|
630
|
+
slacks: N,
|
|
631
|
+
runTime: _,
|
|
632
|
+
raw: g
|
|
889
633
|
};
|
|
890
634
|
}
|
|
891
|
-
},
|
|
892
|
-
function
|
|
893
|
-
|
|
635
|
+
}, G = W;
|
|
636
|
+
function K() {
|
|
637
|
+
T("highs", (e) => new W(e)), _((e) => new W(e));
|
|
894
638
|
}
|
|
895
|
-
|
|
639
|
+
K();
|
|
896
640
|
//#endregion
|
|
897
641
|
//#region src/modeler/solvers/highs/index.ts
|
|
898
|
-
var
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
642
|
+
var Fe = /* @__PURE__ */ he({
|
|
643
|
+
HIGHS_CONSTANTS: () => ie,
|
|
644
|
+
HIGHS_STATUS_NAMES: () => le,
|
|
645
|
+
HiGHS: () => G,
|
|
646
|
+
Highs: () => P,
|
|
647
|
+
HighsError: () => te,
|
|
648
|
+
HighsModel: () => se,
|
|
649
|
+
HighsSolver: () => W,
|
|
650
|
+
HighsUnsupportedOptionError: () => ae,
|
|
651
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => ce,
|
|
652
|
+
bindHighsFunctions: () => ne,
|
|
653
|
+
getHighs: () => oe,
|
|
654
|
+
getHighsWasmUrl: () => I,
|
|
655
|
+
isValidWasmHeader: () => re,
|
|
656
|
+
mapHighsStatus: () => U,
|
|
657
|
+
mapHighsTerminationStatus: () => H,
|
|
658
|
+
probeWasmUrl: () => M,
|
|
659
|
+
registerHighsSolver: () => K,
|
|
660
|
+
resolveBrowserWasmUrl: () => F,
|
|
661
|
+
setHighsWasmUrl: () => L,
|
|
662
|
+
solveLp: () => V,
|
|
663
|
+
solveLpWithHighs: () => N
|
|
912
664
|
});
|
|
913
|
-
import * as
|
|
914
|
-
|
|
915
|
-
import * as
|
|
916
|
-
|
|
665
|
+
import * as Ie from "./highs-worker-factory.js";
|
|
666
|
+
R(Fe, Ie);
|
|
667
|
+
import * as Le from "./highs-assets.js";
|
|
668
|
+
R(Fe, Le);
|
|
917
669
|
//#endregion
|
|
918
670
|
//#region src/modeler/solvers/highs.ts
|
|
919
|
-
var
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
671
|
+
var Re = /* @__PURE__ */ he({
|
|
672
|
+
HIGHS_CONSTANTS: () => ie,
|
|
673
|
+
HIGHS_STATUS_NAMES: () => le,
|
|
674
|
+
HiGHS: () => G,
|
|
675
|
+
Highs: () => P,
|
|
676
|
+
HighsError: () => te,
|
|
677
|
+
HighsModel: () => se,
|
|
678
|
+
HighsSolver: () => W,
|
|
679
|
+
HighsUnsupportedOptionError: () => ae,
|
|
680
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => ce,
|
|
681
|
+
bindHighsFunctions: () => ne,
|
|
682
|
+
getHighs: () => oe,
|
|
683
|
+
getHighsWasmUrl: () => I,
|
|
684
|
+
isValidWasmHeader: () => re,
|
|
685
|
+
mapHighsStatus: () => U,
|
|
686
|
+
mapHighsTerminationStatus: () => H,
|
|
687
|
+
probeWasmUrl: () => M,
|
|
688
|
+
registerHighsSolver: () => K,
|
|
689
|
+
resolveBrowserWasmUrl: () => F,
|
|
690
|
+
setHighsWasmUrl: () => L,
|
|
691
|
+
solveLp: () => V,
|
|
692
|
+
solveLpWithHighs: () => N
|
|
933
693
|
});
|
|
934
|
-
|
|
694
|
+
R(Re, Fe);
|
|
935
695
|
//#endregion
|
|
936
696
|
//#region src/modeler/solvers/mock.ts
|
|
937
|
-
var
|
|
697
|
+
var ze = class {
|
|
938
698
|
name;
|
|
939
699
|
capabilities;
|
|
940
700
|
options;
|
|
941
701
|
constructor(e = {}) {
|
|
942
702
|
this.name = e.name || "MockSolver", this.capabilities = e.capabilities || {
|
|
943
703
|
supportsMIP: !0,
|
|
944
|
-
supportsQP: !0
|
|
704
|
+
supportsQP: !0,
|
|
705
|
+
supportsWarmStart: !0
|
|
945
706
|
}, this.options = e;
|
|
946
707
|
}
|
|
947
|
-
async solve(e, t, n = {}) {
|
|
948
|
-
let r = {
|
|
708
|
+
async solve(e, t = {}, n = {}) {
|
|
709
|
+
let r = E(t) ? n : t, i = {
|
|
949
710
|
...this.options,
|
|
950
|
-
...
|
|
711
|
+
...r
|
|
712
|
+
}, a = !!(i.values && Object.keys(i.values).length > 0 || i.boolValues && Object.keys(i.boolValues).length > 0);
|
|
713
|
+
if (i.signal?.aborted) return {
|
|
714
|
+
status: "Unknown",
|
|
715
|
+
terminationStatus: "Interrupted",
|
|
716
|
+
hasPrimalSolution: !1,
|
|
717
|
+
objectiveValue: null,
|
|
718
|
+
values: {},
|
|
719
|
+
runTime: 0,
|
|
720
|
+
raw: { mock: !0 }
|
|
951
721
|
};
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
722
|
+
if (i.delayMs && i.delayMs > 0 && (await new Promise((e) => {
|
|
723
|
+
let t = setTimeout(() => {
|
|
724
|
+
i.signal?.removeEventListener("abort", n), e();
|
|
725
|
+
}, i.delayMs), n = () => {
|
|
726
|
+
clearTimeout(t), e();
|
|
727
|
+
};
|
|
728
|
+
i.signal?.addEventListener("abort", n, { once: !0 });
|
|
729
|
+
}), i.signal?.aborted)) {
|
|
730
|
+
let e = !!(i.hasPrimalSolution ?? a);
|
|
731
|
+
return {
|
|
732
|
+
status: e ? "Feasible" : "Unknown",
|
|
733
|
+
terminationStatus: "Interrupted",
|
|
734
|
+
hasPrimalSolution: e,
|
|
735
|
+
objectiveValue: e ? i.objectiveValue ?? 0 : null,
|
|
736
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
737
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
738
|
+
relGap: i.mipGap,
|
|
739
|
+
mipGap: i.mipGap
|
|
740
|
+
} : {
|
|
741
|
+
relGap: i.relGap,
|
|
742
|
+
mipGap: i.relGap
|
|
743
|
+
},
|
|
744
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap },
|
|
745
|
+
values: e && i.values || {},
|
|
746
|
+
...e && i.boolValues !== void 0 ? { boolValues: i.boolValues } : {},
|
|
747
|
+
runTime: .001,
|
|
748
|
+
raw: { mock: !0 }
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
if (i.onProgress && Array.isArray(i.progressEvents)) for (let e of i.progressEvents) {
|
|
752
|
+
if (i.signal?.aborted) break;
|
|
753
|
+
i.onProgress(e);
|
|
754
|
+
}
|
|
755
|
+
let o = i.status || "Optimal", s = i.terminationStatus ?? o, c = i.hasPrimalSolution === void 0 ? o === "Optimal" || o === "Feasible" || o === "Sat" || (o === "TimeLimit" || o === "IterationLimit" || s === "Interrupted") && a : i.hasPrimalSolution;
|
|
756
|
+
if (i.onProgress && !Array.isArray(i.progressEvents) && !i.signal?.aborted) {
|
|
757
|
+
let e = c ? i.objectiveValue ?? 0 : void 0;
|
|
758
|
+
i.onProgress({
|
|
759
|
+
elapsedTime: .001,
|
|
760
|
+
elapsedSeconds: .001,
|
|
761
|
+
...typeof e == "number" && Number.isFinite(e) ? { objectiveValue: e } : {},
|
|
762
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
763
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
764
|
+
relGap: i.mipGap,
|
|
765
|
+
mipGap: i.mipGap
|
|
766
|
+
} : {
|
|
767
|
+
relGap: i.relGap,
|
|
768
|
+
mipGap: i.relGap
|
|
769
|
+
},
|
|
770
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap }
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
return i.signal?.aborted && (s = "Interrupted", c = i.hasPrimalSolution === void 0 ? a : i.hasPrimalSolution, o = c ? "Feasible" : "Unknown"), {
|
|
774
|
+
status: o,
|
|
775
|
+
terminationStatus: s,
|
|
776
|
+
hasPrimalSolution: c,
|
|
777
|
+
objectiveValue: c ? i.objectiveValue ?? 0 : null,
|
|
778
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
779
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
780
|
+
relGap: i.mipGap,
|
|
781
|
+
mipGap: i.mipGap
|
|
782
|
+
} : {
|
|
783
|
+
relGap: i.relGap,
|
|
784
|
+
mipGap: i.relGap
|
|
785
|
+
},
|
|
786
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap },
|
|
787
|
+
values: c && i.values || {},
|
|
788
|
+
...c && i.boolValues !== void 0 ? { boolValues: i.boolValues } : {},
|
|
789
|
+
reducedCosts: i.reducedCosts,
|
|
790
|
+
duals: i.duals,
|
|
791
|
+
slacks: i.slacks,
|
|
959
792
|
runTime: .001,
|
|
960
793
|
raw: { mock: !0 }
|
|
961
794
|
};
|
|
962
795
|
}
|
|
963
796
|
};
|
|
964
|
-
function
|
|
965
|
-
|
|
797
|
+
function Be() {
|
|
798
|
+
T("mock", (e) => new ze(e));
|
|
966
799
|
}
|
|
967
|
-
|
|
800
|
+
Be();
|
|
968
801
|
//#endregion
|
|
969
802
|
//#region src/modeler/solvers/index.ts
|
|
970
|
-
var
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
803
|
+
var Ve = /* @__PURE__ */ he({
|
|
804
|
+
HIGHS_CONSTANTS: () => ie,
|
|
805
|
+
HIGHS_STATUS_NAMES: () => le,
|
|
806
|
+
HiGHS: () => G,
|
|
807
|
+
Highs: () => P,
|
|
808
|
+
HighsError: () => te,
|
|
809
|
+
HighsModel: () => se,
|
|
810
|
+
HighsSolver: () => W,
|
|
811
|
+
HighsUnsupportedOptionError: () => ae,
|
|
812
|
+
MockSolver: () => ze,
|
|
813
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => ce,
|
|
814
|
+
bindHighsFunctions: () => ne,
|
|
815
|
+
getHighs: () => oe,
|
|
816
|
+
getHighsWasmUrl: () => I,
|
|
817
|
+
getSolver: () => D,
|
|
818
|
+
isValidWasmHeader: () => re,
|
|
819
|
+
listAvailableSolvers: () => S,
|
|
820
|
+
mapHighsStatus: () => U,
|
|
821
|
+
mapHighsTerminationStatus: () => H,
|
|
822
|
+
probeWasmUrl: () => M,
|
|
823
|
+
registerHighsSolver: () => K,
|
|
824
|
+
registerMockSolver: () => Be,
|
|
825
|
+
registerSolver: () => T,
|
|
826
|
+
resolveBrowserWasmUrl: () => F,
|
|
827
|
+
setDefaultSolver: () => _,
|
|
828
|
+
setHighsWasmUrl: () => L,
|
|
829
|
+
solveLp: () => V,
|
|
830
|
+
solveLpWithHighs: () => N
|
|
990
831
|
});
|
|
991
|
-
|
|
832
|
+
R(Ve, Re);
|
|
992
833
|
//#endregion
|
|
993
|
-
//#region src/modeler/
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
}
|
|
1020
|
-
get vars() {
|
|
1021
|
-
return this.variables;
|
|
1022
|
-
}
|
|
1023
|
-
get constrs() {
|
|
1024
|
-
return this.constraints;
|
|
1025
|
-
}
|
|
1026
|
-
get numVars() {
|
|
1027
|
-
return this.variables.length;
|
|
1028
|
-
}
|
|
1029
|
-
get numConstrs() {
|
|
1030
|
-
return this.constraints.length;
|
|
1031
|
-
}
|
|
1032
|
-
createDomainVars(e, t, n, r) {
|
|
1033
|
-
if (typeof n == "number" || Array.isArray(n)) {
|
|
1034
|
-
let i = typeof t == "number" ? Array.from({ length: t }, (e, t) => t) : t, a = typeof n == "number" ? Array.from({ length: n }, (e, t) => t) : n, o = r || {}, s = o.prefix || o.name || "x", c = {};
|
|
1035
|
-
for (let t of i) {
|
|
1036
|
-
c[t] = {};
|
|
1037
|
-
for (let n of a) c[t][n] = this.addVar({
|
|
1038
|
-
...o,
|
|
1039
|
-
type: e,
|
|
1040
|
-
name: `${s}_${t}_${n}`
|
|
1041
|
-
});
|
|
1042
|
-
}
|
|
1043
|
-
return c;
|
|
834
|
+
//#region src/modeler/solution-validator.ts
|
|
835
|
+
function He(e, t) {
|
|
836
|
+
if (e === void 0) return 1e-6;
|
|
837
|
+
if (typeof e != "number" || !Number.isFinite(e) || e < 0) throw Error(`Invalid ${t}: expected a finite non-negative number, received ${String(e)}.`);
|
|
838
|
+
return e;
|
|
839
|
+
}
|
|
840
|
+
function Ue(e, t = {}) {
|
|
841
|
+
let r = He(t.feasibilityTolerance, "feasibilityTolerance"), i = He(t.integralityTolerance, "integralityTolerance"), a = t.evaluateLogicalConstraints === void 0 || !!t.evaluateLogicalConstraints, s = t.values !== void 0 && t.values !== null;
|
|
842
|
+
if (t.values !== void 0 && (typeof t.values != "object" || t.values === null || Array.isArray(t.values))) throw Error("Invalid values option: expected a plain object mapping variable names to values.");
|
|
843
|
+
let l = t.values, u = [], d = Object.create(null), f = [], p = [], m = 0, h = (e) => {
|
|
844
|
+
typeof e == "number" && !Number.isNaN(e) && e > m && (m = e);
|
|
845
|
+
}, g = (e) => {
|
|
846
|
+
u.push(e), Object.prototype.hasOwnProperty.call(d, e.name) || (d[e.name] = []), d[e.name].push(e), e.type !== "missing_value" && e.type !== "unchecked_constraint" && h(e.violation);
|
|
847
|
+
}, _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = 0, b = 0, x = 0, S = 0;
|
|
848
|
+
for (let t of e.variables) {
|
|
849
|
+
let e = s ? Object.prototype.hasOwnProperty.call(l, t.name) ? l[t.name] : void 0 : t.value;
|
|
850
|
+
if (e == null) {
|
|
851
|
+
p.push(t.name), g({
|
|
852
|
+
type: "missing_value",
|
|
853
|
+
target: "variable",
|
|
854
|
+
name: t.name,
|
|
855
|
+
actual: e ?? null,
|
|
856
|
+
violation: Infinity,
|
|
857
|
+
message: `Variable "${t.name}" has no assigned solution value.`
|
|
858
|
+
});
|
|
859
|
+
continue;
|
|
1044
860
|
}
|
|
1045
|
-
if (typeof
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
861
|
+
if (typeof e != "number" || !Number.isFinite(e)) {
|
|
862
|
+
g({
|
|
863
|
+
type: "non_finite_value",
|
|
864
|
+
target: "variable",
|
|
865
|
+
name: t.name,
|
|
866
|
+
actual: e,
|
|
867
|
+
violation: Infinity,
|
|
868
|
+
message: `Variable "${t.name}" has non-finite or non-numeric value: ${String(e)}.`
|
|
1051
869
|
});
|
|
870
|
+
continue;
|
|
1052
871
|
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
872
|
+
_.set(t, e), y++;
|
|
873
|
+
let n = t.type === "Binary" || t.type === "BINARY", a = n || t.type === "Integer" || t.type === "INTEGER", o = n ? Math.max(0, t.lb) : t.lb, c = n ? Math.min(1, t.ub) : t.ub, u = typeof t.lb == "number" && !Number.isNaN(t.lb) && t.lb !== Infinity, d = typeof t.ub == "number" && !Number.isNaN(t.ub) && t.ub !== -Infinity;
|
|
874
|
+
if (!u) g({
|
|
875
|
+
type: "lower_bound",
|
|
876
|
+
target: "variable",
|
|
877
|
+
name: t.name,
|
|
878
|
+
actual: e,
|
|
879
|
+
limit: t.lb,
|
|
880
|
+
violation: Infinity,
|
|
881
|
+
message: `Variable "${t.name}" has invalid lower bound (${String(t.lb)}).`
|
|
882
|
+
});
|
|
883
|
+
else if (o !== -Infinity) {
|
|
884
|
+
let n = e - o, i = Math.max(0, o - e);
|
|
885
|
+
h(i), i > r && g({
|
|
886
|
+
type: "lower_bound",
|
|
887
|
+
target: "variable",
|
|
888
|
+
name: t.name,
|
|
889
|
+
actual: e,
|
|
890
|
+
limit: o,
|
|
891
|
+
violation: i,
|
|
892
|
+
signedViolation: n,
|
|
893
|
+
message: `Variable "${t.name}" value (${e}) violates lower bound (${o}) by ${i}.`
|
|
894
|
+
});
|
|
1062
895
|
}
|
|
1063
|
-
if (
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
896
|
+
if (!d) g({
|
|
897
|
+
type: "upper_bound",
|
|
898
|
+
target: "variable",
|
|
899
|
+
name: t.name,
|
|
900
|
+
actual: e,
|
|
901
|
+
limit: t.ub,
|
|
902
|
+
violation: Infinity,
|
|
903
|
+
message: `Variable "${t.name}" has invalid upper bound (${String(t.ub)}).`
|
|
904
|
+
});
|
|
905
|
+
else if (c !== Infinity) {
|
|
906
|
+
let n = e - c, i = Math.max(0, e - c);
|
|
907
|
+
h(i), i > r && g({
|
|
908
|
+
type: "upper_bound",
|
|
909
|
+
target: "variable",
|
|
910
|
+
name: t.name,
|
|
911
|
+
actual: e,
|
|
912
|
+
limit: c,
|
|
913
|
+
violation: i,
|
|
914
|
+
signedViolation: n,
|
|
915
|
+
message: `Variable "${t.name}" value (${e}) violates upper bound (${c}) by ${i}.`
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
if (u && d && o > c && o - e <= r && e - c <= r) {
|
|
919
|
+
let n = o - c;
|
|
920
|
+
g({
|
|
921
|
+
type: "lower_bound",
|
|
922
|
+
target: "variable",
|
|
923
|
+
name: t.name,
|
|
924
|
+
actual: e,
|
|
925
|
+
limit: o,
|
|
926
|
+
violation: n,
|
|
927
|
+
signedViolation: e - o,
|
|
928
|
+
message: `Variable "${t.name}" has inverted bounds [${o}, ${c}].`
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
if (a) {
|
|
932
|
+
let r = Math.round(e), a = e - r, o = Math.abs(a);
|
|
933
|
+
h(o), o > i && g({
|
|
934
|
+
type: "integrality",
|
|
935
|
+
target: "variable",
|
|
936
|
+
name: t.name,
|
|
937
|
+
varType: n ? "Binary" : "Integer",
|
|
938
|
+
actual: e,
|
|
939
|
+
nearestInteger: r,
|
|
940
|
+
violation: o,
|
|
941
|
+
signedViolation: a,
|
|
942
|
+
message: `${n ? "Binary" : "Integer"} variable "${t.name}" value (${e}) violates integrality by ${o} (nearest integer: ${r}).`
|
|
943
|
+
});
|
|
1074
944
|
}
|
|
1075
|
-
throw Error(`Invalid arguments provided for ${e.toLowerCase()} variable creation`);
|
|
1076
|
-
}
|
|
1077
|
-
binary(e, t, n) {
|
|
1078
|
-
return this.createDomainVars("Binary", e, t, n);
|
|
1079
|
-
}
|
|
1080
|
-
integer(e, t, n) {
|
|
1081
|
-
return this.createDomainVars("Integer", e, t, n);
|
|
1082
|
-
}
|
|
1083
|
-
continuous(e, t, n) {
|
|
1084
|
-
return this.createDomainVars("Continuous", e, t, n);
|
|
1085
945
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
946
|
+
for (let t of e.boolVars) {
|
|
947
|
+
let e = s ? Object.prototype.hasOwnProperty.call(l, t.name) ? l[t.name] : void 0 : t.value;
|
|
948
|
+
if (e == null) {
|
|
949
|
+
p.push(t.name), g({
|
|
950
|
+
type: "missing_value",
|
|
951
|
+
target: "bool_variable",
|
|
952
|
+
name: t.name,
|
|
953
|
+
actual: e ?? null,
|
|
954
|
+
violation: Infinity,
|
|
955
|
+
message: `Boolean variable "${t.name}" has no assigned solution value.`
|
|
956
|
+
});
|
|
957
|
+
continue;
|
|
1094
958
|
}
|
|
1095
|
-
if (typeof e
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
959
|
+
if (typeof e != "boolean") {
|
|
960
|
+
g({
|
|
961
|
+
type: "invalid_boolean_value",
|
|
962
|
+
target: "bool_variable",
|
|
963
|
+
name: t.name,
|
|
964
|
+
actual: e,
|
|
965
|
+
violation: Infinity,
|
|
966
|
+
message: `Boolean variable "${t.name}" has non-boolean value: ${String(e)}.`
|
|
967
|
+
});
|
|
968
|
+
continue;
|
|
1101
969
|
}
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
970
|
+
v.set(t, e), b++;
|
|
971
|
+
}
|
|
972
|
+
let C = (e) => {
|
|
973
|
+
let t = e.constant === void 0 ? 0 : e.constant;
|
|
974
|
+
if (typeof t != "number" || !Number.isFinite(t)) return {
|
|
975
|
+
ok: !1,
|
|
976
|
+
reason: `non-finite constant (${String(t)})`
|
|
977
|
+
};
|
|
978
|
+
let n = t;
|
|
979
|
+
for (let [t, r] of e.terms) {
|
|
980
|
+
if (typeof r != "number" || !Number.isFinite(r)) return {
|
|
981
|
+
ok: !1,
|
|
982
|
+
reason: `non-finite coefficient (${String(r)}) for variable "${t.name}"`
|
|
983
|
+
};
|
|
984
|
+
if (r !== 0) {
|
|
985
|
+
if (!_.has(t)) return {
|
|
986
|
+
ok: !1,
|
|
987
|
+
reason: `missing or invalid value for variable "${t.name}"`
|
|
988
|
+
};
|
|
989
|
+
if (n += r * _.get(t), !Number.isFinite(n)) return {
|
|
990
|
+
ok: !1,
|
|
991
|
+
reason: "linear expression evaluation overflowed finite range"
|
|
992
|
+
};
|
|
1107
993
|
}
|
|
1108
|
-
return t;
|
|
1109
994
|
}
|
|
995
|
+
return {
|
|
996
|
+
ok: !0,
|
|
997
|
+
value: n
|
|
998
|
+
};
|
|
999
|
+
}, w = (e, t = r) => {
|
|
1000
|
+
if (typeof e.rhs != "number" || !Number.isFinite(e.rhs)) return {
|
|
1001
|
+
status: "unchecked",
|
|
1002
|
+
reason: `non-finite right-hand side (${String(e.rhs)})`
|
|
1003
|
+
};
|
|
1004
|
+
let n = C(e.lhs);
|
|
1005
|
+
if (!n.ok) return {
|
|
1006
|
+
status: "unchecked",
|
|
1007
|
+
reason: n.reason
|
|
1008
|
+
};
|
|
1009
|
+
let i = n.value, a = i - e.rhs;
|
|
1010
|
+
if (!Number.isFinite(a)) return {
|
|
1011
|
+
status: "unchecked",
|
|
1012
|
+
reason: "constraint residual overflowed finite range"
|
|
1013
|
+
};
|
|
1014
|
+
let o = e.sense === "<=" ? Math.max(0, a) : e.sense === ">=" ? Math.max(0, -a) : Math.abs(a);
|
|
1015
|
+
return o > t ? {
|
|
1016
|
+
status: "violated",
|
|
1017
|
+
lhsVal: i,
|
|
1018
|
+
signed: a,
|
|
1019
|
+
violation: o,
|
|
1020
|
+
message: `Constraint "${e.name}" (${i} ${e.sense} ${e.rhs}) violated by ${o}.`
|
|
1021
|
+
} : {
|
|
1022
|
+
status: "satisfied",
|
|
1023
|
+
lhsVal: i,
|
|
1024
|
+
signed: a,
|
|
1025
|
+
violation: o
|
|
1026
|
+
};
|
|
1027
|
+
};
|
|
1028
|
+
for (let t of e.constraints) {
|
|
1029
|
+
let e = w(t);
|
|
1030
|
+
e.status === "unchecked" ? (f.push(t.name), g({
|
|
1031
|
+
type: "unchecked_constraint",
|
|
1032
|
+
target: "constraint",
|
|
1033
|
+
name: t.name,
|
|
1034
|
+
sense: t.sense,
|
|
1035
|
+
limit: t.rhs,
|
|
1036
|
+
rhs: t.rhs,
|
|
1037
|
+
violation: Infinity,
|
|
1038
|
+
message: `Constraint "${t.name}" could not be evaluated: ${e.reason}.`
|
|
1039
|
+
})) : e.status === "violated" ? (x++, g({
|
|
1040
|
+
type: "linear_constraint",
|
|
1041
|
+
target: "constraint",
|
|
1042
|
+
name: t.name,
|
|
1043
|
+
sense: t.sense,
|
|
1044
|
+
actual: e.lhsVal,
|
|
1045
|
+
limit: t.rhs,
|
|
1046
|
+
rhs: t.rhs,
|
|
1047
|
+
violation: e.violation,
|
|
1048
|
+
signedViolation: e.signed,
|
|
1049
|
+
message: e.message
|
|
1050
|
+
})) : (x++, h(e.violation));
|
|
1051
|
+
}
|
|
1052
|
+
let T = (e) => {
|
|
1053
|
+
if (e instanceof o) return v.has(e) ? {
|
|
1054
|
+
ok: !0,
|
|
1055
|
+
value: v.get(e),
|
|
1056
|
+
violation: 0
|
|
1057
|
+
} : {
|
|
1058
|
+
ok: !1,
|
|
1059
|
+
reason: `missing or invalid value for Boolean variable "${e.name}"`
|
|
1060
|
+
};
|
|
1061
|
+
if (e instanceof c) {
|
|
1062
|
+
let t = w(e, 0);
|
|
1063
|
+
if (t.status === "unchecked") return {
|
|
1064
|
+
ok: !1,
|
|
1065
|
+
reason: t.reason
|
|
1066
|
+
};
|
|
1067
|
+
if (r > 0) {
|
|
1068
|
+
let n = Math.abs(t.lhsVal - e.rhs);
|
|
1069
|
+
if (n > 0 && n <= r) return {
|
|
1070
|
+
ok: !1,
|
|
1071
|
+
reason: `numeric comparison "${e.name}" lies within feasibilityTolerance (${r}) of boundary (${t.lhsVal} vs ${e.rhs})`
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
return {
|
|
1075
|
+
ok: !0,
|
|
1076
|
+
value: t.status === "satisfied",
|
|
1077
|
+
violation: 0
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
1080
|
+
if (e instanceof n) switch (e.op) {
|
|
1081
|
+
case "not": {
|
|
1082
|
+
let t = T(e.children[0]);
|
|
1083
|
+
return t.ok ? {
|
|
1084
|
+
ok: !0,
|
|
1085
|
+
value: !t.value,
|
|
1086
|
+
violation: 0
|
|
1087
|
+
} : t;
|
|
1088
|
+
}
|
|
1089
|
+
case "and": {
|
|
1090
|
+
let t = 0;
|
|
1091
|
+
for (let n of e.children) {
|
|
1092
|
+
let e = T(n);
|
|
1093
|
+
if (!e.ok) return e;
|
|
1094
|
+
if (!e.value) return {
|
|
1095
|
+
ok: !0,
|
|
1096
|
+
value: !1,
|
|
1097
|
+
violation: 0
|
|
1098
|
+
};
|
|
1099
|
+
e.violation > t && (t = e.violation);
|
|
1100
|
+
}
|
|
1101
|
+
return {
|
|
1102
|
+
ok: !0,
|
|
1103
|
+
value: !0,
|
|
1104
|
+
violation: t
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1107
|
+
case "or": {
|
|
1108
|
+
let t = !1, n = Infinity;
|
|
1109
|
+
for (let r of e.children) {
|
|
1110
|
+
let e = T(r);
|
|
1111
|
+
if (!e.ok) return e;
|
|
1112
|
+
e.value && (t = !0, e.violation < n && (n = e.violation));
|
|
1113
|
+
}
|
|
1114
|
+
return {
|
|
1115
|
+
ok: !0,
|
|
1116
|
+
value: t,
|
|
1117
|
+
violation: t ? n : 0
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
case "implies": {
|
|
1121
|
+
let t = T(e.children[0]);
|
|
1122
|
+
if (!t.ok) return t;
|
|
1123
|
+
if (!t.value) return {
|
|
1124
|
+
ok: !0,
|
|
1125
|
+
value: !0,
|
|
1126
|
+
violation: 0
|
|
1127
|
+
};
|
|
1128
|
+
let n = T(e.children[1]);
|
|
1129
|
+
return n.ok ? {
|
|
1130
|
+
ok: !0,
|
|
1131
|
+
value: n.value,
|
|
1132
|
+
violation: n.value ? n.violation : 0
|
|
1133
|
+
} : n;
|
|
1134
|
+
}
|
|
1135
|
+
case "xor": {
|
|
1136
|
+
let t = !1, n = 0;
|
|
1137
|
+
for (let r of e.children) {
|
|
1138
|
+
let e = T(r);
|
|
1139
|
+
if (!e.ok) return e;
|
|
1140
|
+
e.value && (t = !t, e.violation > n && (n = e.violation));
|
|
1141
|
+
}
|
|
1142
|
+
return {
|
|
1143
|
+
ok: !0,
|
|
1144
|
+
value: t,
|
|
1145
|
+
violation: t ? n : 0
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
default: return {
|
|
1149
|
+
ok: !1,
|
|
1150
|
+
reason: `unsupported logical operator "${String(e.op)}"`
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1153
|
+
return {
|
|
1154
|
+
ok: !1,
|
|
1155
|
+
reason: "unsupported logical expression node"
|
|
1156
|
+
};
|
|
1157
|
+
};
|
|
1158
|
+
for (let t = 0; t < e.logicalConstraints.length; t++) {
|
|
1159
|
+
let n = e.logicalConstraints[t], r = n.name || `lc_${t + 1}`;
|
|
1160
|
+
if (!a) {
|
|
1161
|
+
f.push(r), g({
|
|
1162
|
+
type: "unchecked_constraint",
|
|
1163
|
+
target: "logical_constraint",
|
|
1164
|
+
name: r,
|
|
1165
|
+
violation: Infinity,
|
|
1166
|
+
message: `Logical constraint "${r}" was not evaluated because evaluateLogicalConstraints is false.`
|
|
1167
|
+
});
|
|
1168
|
+
continue;
|
|
1169
|
+
}
|
|
1170
|
+
let i = T(n.expr);
|
|
1171
|
+
if (!i.ok) {
|
|
1172
|
+
f.push(r), g({
|
|
1173
|
+
type: "unchecked_constraint",
|
|
1174
|
+
target: "logical_constraint",
|
|
1175
|
+
name: r,
|
|
1176
|
+
violation: Infinity,
|
|
1177
|
+
message: `Logical constraint "${r}" could not be evaluated: ${i.reason}.`
|
|
1178
|
+
});
|
|
1179
|
+
continue;
|
|
1180
|
+
}
|
|
1181
|
+
S++, i.value ? h(i.violation) : g({
|
|
1182
|
+
type: "logical_constraint",
|
|
1183
|
+
target: "logical_constraint",
|
|
1184
|
+
name: r,
|
|
1185
|
+
actual: !1,
|
|
1186
|
+
limit: !0,
|
|
1187
|
+
violation: 1,
|
|
1188
|
+
signedViolation: -1,
|
|
1189
|
+
message: `Logical constraint "${r}" evaluated to false.`
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
let E = y === e.variables.length && b === e.boolVars.length && x === e.constraints.length && S === e.logicalConstraints.length && f.length === 0 && p.length === 0;
|
|
1193
|
+
return {
|
|
1194
|
+
valid: E && u.length === 0,
|
|
1195
|
+
complete: E,
|
|
1196
|
+
violations: u,
|
|
1197
|
+
violationsByName: d,
|
|
1198
|
+
uncheckedConstraints: f,
|
|
1199
|
+
missingVariables: p,
|
|
1200
|
+
maxViolation: m,
|
|
1201
|
+
summary: {
|
|
1202
|
+
checkedVariables: y,
|
|
1203
|
+
totalVariables: e.variables.length,
|
|
1204
|
+
checkedBoolVariables: b,
|
|
1205
|
+
totalBoolVariables: e.boolVars.length,
|
|
1206
|
+
checkedLinearConstraints: x,
|
|
1207
|
+
totalLinearConstraints: e.constraints.length,
|
|
1208
|
+
checkedLogicalConstraints: S,
|
|
1209
|
+
totalLogicalConstraints: e.logicalConstraints.length
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
//#endregion
|
|
1214
|
+
//#region src/modeler/big-m.ts
|
|
1215
|
+
function We(e, t) {
|
|
1216
|
+
if (typeof e != "number" || !Number.isFinite(e) || e <= 0) throw Error(`Invalid Big-M value for indicator constraint "${t}": expected a finite positive number, received ${e}.`);
|
|
1217
|
+
}
|
|
1218
|
+
function Ge(e, t, n) {
|
|
1219
|
+
let r = e.constant === void 0 ? 0 : e.constant;
|
|
1220
|
+
if (!Number.isFinite(t) || !Number.isFinite(r)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": constraint contains non-finite constant (${r}) or right-hand side (${t}).`);
|
|
1221
|
+
let i = t - r;
|
|
1222
|
+
if (!Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": effective right-hand side (${t} - ${r}) overflows finite floating-point range. Please rescale coefficients/constants.`);
|
|
1223
|
+
for (let [t, r] of e.terms) {
|
|
1224
|
+
if (!Number.isFinite(r)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" has non-finite coefficient (${r}).`);
|
|
1225
|
+
if (Number.isNaN(t.lb) || Number.isNaN(t.ub) || t.lb === Infinity || t.ub === -Infinity || t.lb > t.ub) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" has invalid bounds [${t.lb}, ${t.ub}].`);
|
|
1226
|
+
}
|
|
1227
|
+
return i;
|
|
1228
|
+
}
|
|
1229
|
+
function q(e, t, n) {
|
|
1230
|
+
let r = Ge(e, t, n), i = 0;
|
|
1231
|
+
for (let [t, r] of e.terms) {
|
|
1232
|
+
if (r === 0) continue;
|
|
1233
|
+
let e;
|
|
1234
|
+
if (r > 0) {
|
|
1235
|
+
if (!Number.isFinite(t.ub)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite upper bound (required because coefficient ${r} is positive in <= constraint). Please set an explicit finite upper bound on the variable or specify { M } explicitly in indicator options.`);
|
|
1236
|
+
e = t.ub;
|
|
1237
|
+
} else {
|
|
1238
|
+
if (!Number.isFinite(t.lb)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite lower bound (required because coefficient ${r} is negative in <= constraint). Please set an explicit finite lower bound on the variable or specify { M } explicitly in indicator options.`);
|
|
1239
|
+
e = t.lb;
|
|
1240
|
+
}
|
|
1241
|
+
let a = r * e;
|
|
1242
|
+
if (i += a, !Number.isFinite(a) || !Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while bounding contribution of variable "${t.name}". Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
1243
|
+
}
|
|
1244
|
+
let a = i - r;
|
|
1245
|
+
if (!Number.isFinite(a)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while computing Big-M (${i} - ${r}). Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
1246
|
+
let o = Math.max(0, a);
|
|
1247
|
+
if (!Number.isFinite(o) || !Number.isFinite(r + o)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": derived Big-M (${o}) or shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
1248
|
+
return o;
|
|
1249
|
+
}
|
|
1250
|
+
function J(e, t, n) {
|
|
1251
|
+
let r = Ge(e, t, n), i = 0;
|
|
1252
|
+
for (let [t, r] of e.terms) {
|
|
1253
|
+
if (r === 0) continue;
|
|
1254
|
+
let e;
|
|
1255
|
+
if (r > 0) {
|
|
1256
|
+
if (!Number.isFinite(t.lb)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite lower bound (required because coefficient ${r} is positive in >= constraint). Please set an explicit finite lower bound on the variable or specify { M } explicitly in indicator options.`);
|
|
1257
|
+
e = t.lb;
|
|
1258
|
+
} else {
|
|
1259
|
+
if (!Number.isFinite(t.ub)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite upper bound (required because coefficient ${r} is negative in >= constraint). Please set an explicit finite upper bound on the variable or specify { M } explicitly in indicator options.`);
|
|
1260
|
+
e = t.ub;
|
|
1261
|
+
}
|
|
1262
|
+
let a = r * e;
|
|
1263
|
+
if (i += a, !Number.isFinite(a) || !Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while bounding contribution of variable "${t.name}". Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
1264
|
+
}
|
|
1265
|
+
let a = r - i;
|
|
1266
|
+
if (!Number.isFinite(a)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while computing Big-M (${r} - ${i}). Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
1267
|
+
let o = Math.max(0, a);
|
|
1268
|
+
if (!Number.isFinite(o) || !Number.isFinite(r - o)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": derived Big-M (${o}) or shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
1269
|
+
return o;
|
|
1270
|
+
}
|
|
1271
|
+
function Y(e, t, n, r, i, a, o) {
|
|
1272
|
+
if (!(e instanceof b && (e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1))) throw Error(`Indicator variable "${e?.name ?? String(e)}" must be a Binary variable (or Integer variable with bounds [0, 1]), received "${e?.type ?? typeof e}" with bounds [${e?.lb}, ${e?.ub}].`);
|
|
1273
|
+
if (!Number.isFinite(e.lb) || !Number.isFinite(e.ub) || e.lb < 0 || e.ub > 1 || e.lb > e.ub) throw Error(`Binary indicator variable "${e.name}" has invalid bounds [${e.lb}, ${e.ub}]. Binary variables must stay within [0, 1] with lb <= ub.`);
|
|
1274
|
+
let s = Ge(t, r, o);
|
|
1275
|
+
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activation value must be 0 or 1.`);
|
|
1276
|
+
if (n !== "<=" && n !== ">=") throw Error(`Invalid indicator sense for "${o}": expected "<=" or ">=", received "${String(n)}".`);
|
|
1277
|
+
if (!Number.isFinite(a) || a < 0) throw Error(`Invalid Big-M value for indicator constraint "${o}": expected a finite non-negative number, received ${a}.`);
|
|
1278
|
+
let c = t.terms.get(e);
|
|
1279
|
+
if (c !== void 0 && c !== 0) throw Error(`Indicator constraint "${o}" cannot include its own binary activation variable "${e.name}" in the linear expression.`);
|
|
1280
|
+
let l, u;
|
|
1281
|
+
if (i === 1 ? n === "<=" ? (l = a, u = s + a) : (l = -a, u = s - a) : n === "<=" ? (l = -a, u = s) : (l = a, u = s), !Number.isFinite(u)) throw Error(`Cannot construct finite indicator constraint "${o}": shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a smaller finite { M }.`);
|
|
1282
|
+
let d = /* @__PURE__ */ new Map();
|
|
1283
|
+
for (let [e, n] of t.terms) n !== 0 && d.set(e, n);
|
|
1284
|
+
return l !== 0 && d.set(e, l), {
|
|
1285
|
+
lhs: new j(d, 0),
|
|
1286
|
+
rhs: u
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
//#endregion
|
|
1290
|
+
//#region src/modeler/linearizer.ts
|
|
1291
|
+
function X(e, t = 0) {
|
|
1292
|
+
return new j(new Map(e), t);
|
|
1293
|
+
}
|
|
1294
|
+
function Ke(e, t, r, i) {
|
|
1295
|
+
let a = [...e], s = [...r], l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
|
|
1296
|
+
for (let e of r) u.set(e, e.name);
|
|
1297
|
+
let d = new Set(e.map((e) => e.name)), f = 0;
|
|
1298
|
+
function p(e) {
|
|
1299
|
+
let t;
|
|
1300
|
+
do
|
|
1301
|
+
t = `__washi_${e}_${++f}`;
|
|
1302
|
+
while (d.has(t));
|
|
1303
|
+
return d.add(t), t;
|
|
1304
|
+
}
|
|
1305
|
+
for (let e of t) {
|
|
1306
|
+
let t = e.name;
|
|
1307
|
+
d.has(t) ? t = p(`bool_${e.name}`) : d.add(t);
|
|
1308
|
+
let n = new b({
|
|
1309
|
+
name: t,
|
|
1310
|
+
type: "Binary",
|
|
1311
|
+
lb: 0,
|
|
1312
|
+
ub: 1
|
|
1313
|
+
});
|
|
1314
|
+
l.set(e, n), a.push(n);
|
|
1315
|
+
}
|
|
1316
|
+
function m(e, t) {
|
|
1317
|
+
if (e instanceof qe) return e.wrappedVar;
|
|
1318
|
+
if (e instanceof o) {
|
|
1319
|
+
let n = l.get(e);
|
|
1320
|
+
if (!n) throw Error(`Unregistered BoolVar "${e.name}" in logical constraint "${t}".`);
|
|
1321
|
+
return n;
|
|
1322
|
+
}
|
|
1323
|
+
let n = new b({
|
|
1324
|
+
name: p("expr"),
|
|
1325
|
+
type: "Binary",
|
|
1326
|
+
lb: 0,
|
|
1327
|
+
ub: 1
|
|
1328
|
+
});
|
|
1329
|
+
return a.push(n), g(n, e, t), n;
|
|
1330
|
+
}
|
|
1331
|
+
function h(e, t, n, r) {
|
|
1332
|
+
let i = new c(X([
|
|
1333
|
+
[e, 1],
|
|
1334
|
+
[t, -1],
|
|
1335
|
+
[n, -1]
|
|
1336
|
+
], 0), "<=", 0, `${r}_xor_1`), a = new c(X([
|
|
1337
|
+
[e, 1],
|
|
1338
|
+
[t, -1],
|
|
1339
|
+
[n, 1]
|
|
1340
|
+
], 0), ">=", 0, `${r}_xor_2`), o = new c(X([
|
|
1341
|
+
[e, 1],
|
|
1342
|
+
[n, -1],
|
|
1343
|
+
[t, 1]
|
|
1344
|
+
], 0), ">=", 0, `${r}_xor_3`), l = new c(X([
|
|
1345
|
+
[e, 1],
|
|
1346
|
+
[t, 1],
|
|
1347
|
+
[n, 1]
|
|
1348
|
+
], 0), "<=", 2, `${r}_xor_4`);
|
|
1349
|
+
s.push(i, a, o, l), u.set(i, r), u.set(a, r), u.set(o, r), u.set(l, r);
|
|
1350
|
+
}
|
|
1351
|
+
function g(e, t, r) {
|
|
1352
|
+
if (t instanceof o) {
|
|
1353
|
+
let n = l.get(t), i = new c(X([[e, 1], [n, -1]], 0), "==", 0, `${r}_equiv`);
|
|
1354
|
+
s.push(i), u.set(i, r);
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
if (t instanceof n) {
|
|
1358
|
+
if (t.op === "not") {
|
|
1359
|
+
let n = m(t.children[0], r), i = new c(X([[e, 1], [n, 1]], 0), "==", 1, `${r}_not`);
|
|
1360
|
+
s.push(i), u.set(i, r);
|
|
1361
|
+
return;
|
|
1362
|
+
}
|
|
1363
|
+
if (t.op === "and") {
|
|
1364
|
+
let n = t.children.map((e) => m(e, r));
|
|
1365
|
+
for (let t = 0; t < n.length; t++) {
|
|
1366
|
+
let i = new c(X([[e, 1], [n[t], -1]], 0), "<=", 0, `${r}_and_ub_${t}`);
|
|
1367
|
+
s.push(i), u.set(i, r);
|
|
1368
|
+
}
|
|
1369
|
+
let i = [[e, 1], ...n.map((e) => [e, -1])], a = new c(X(i, 0), ">=", 1 - n.length, `${r}_and_lb`);
|
|
1370
|
+
s.push(a), u.set(a, r);
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
if (t.op === "or") {
|
|
1374
|
+
let n = t.children.map((e) => m(e, r));
|
|
1375
|
+
for (let t = 0; t < n.length; t++) {
|
|
1376
|
+
let i = new c(X([[e, 1], [n[t], -1]], 0), ">=", 0, `${r}_or_lb_${t}`);
|
|
1377
|
+
s.push(i), u.set(i, r);
|
|
1378
|
+
}
|
|
1379
|
+
let i = [[e, 1], ...n.map((e) => [e, -1])], a = new c(X(i, 0), "<=", 0, `${r}_or_ub`);
|
|
1380
|
+
s.push(a), u.set(a, r);
|
|
1381
|
+
return;
|
|
1382
|
+
}
|
|
1383
|
+
if (t.op === "implies") {
|
|
1384
|
+
let n = m(t.children[0], r), i = m(t.children[1], r), a = new c(X([
|
|
1385
|
+
[e, 1],
|
|
1386
|
+
[i, -1],
|
|
1387
|
+
[n, 1]
|
|
1388
|
+
], 0), ">=", 0, `${r}_imp_1`), o = new c(X([
|
|
1389
|
+
[e, 1],
|
|
1390
|
+
[n, 1],
|
|
1391
|
+
[i, -1]
|
|
1392
|
+
], 0), "<=", 1, `${r}_imp_2`);
|
|
1393
|
+
s.push(a, o), u.set(a, r), u.set(o, r);
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
if (t.op === "xor") {
|
|
1397
|
+
if (t.children.length === 0) {
|
|
1398
|
+
let t = new c(X([[e, 1]], 0), "==", 0, `${r}_xor_empty`);
|
|
1399
|
+
s.push(t), u.set(t, r);
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
if (t.children.length === 1) {
|
|
1403
|
+
let n = m(t.children[0], r), i = new c(X([[e, 1], [n, -1]], 0), "==", 0, `${r}_xor_single`);
|
|
1404
|
+
s.push(i), u.set(i, r);
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1407
|
+
let n = t.children.map((e) => m(e, r)), i = n[0];
|
|
1408
|
+
for (let e = 1; e < n.length - 1; e++) {
|
|
1409
|
+
let t = new b({
|
|
1410
|
+
name: p(`xor_fold_${e}`),
|
|
1411
|
+
type: "Binary",
|
|
1412
|
+
lb: 0,
|
|
1413
|
+
ub: 1
|
|
1414
|
+
});
|
|
1415
|
+
a.push(t), h(t, i, n[e], `${r}_xor_fold_${e}`), i = t;
|
|
1416
|
+
}
|
|
1417
|
+
h(e, i, n[n.length - 1], r);
|
|
1418
|
+
return;
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
throw Error(`Unsupported logical element in equivalence linearization: ${t}`);
|
|
1422
|
+
}
|
|
1423
|
+
for (let e of i) {
|
|
1424
|
+
let t = e.name, n = e.expr;
|
|
1425
|
+
_(n, t);
|
|
1426
|
+
}
|
|
1427
|
+
function _(e, t) {
|
|
1428
|
+
if (e instanceof o) {
|
|
1429
|
+
let n = l.get(e), r = new c(X([[n, 1]], 0), ">=", 1, t);
|
|
1430
|
+
s.push(r), u.set(r, t);
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
if (e instanceof n) {
|
|
1434
|
+
if (e.op === "not") {
|
|
1435
|
+
let n = e.children[0];
|
|
1436
|
+
if (n instanceof o) {
|
|
1437
|
+
let e = l.get(n), r = new c(X([[e, 1]], 0), "<=", 0, t);
|
|
1438
|
+
s.push(r), u.set(r, t);
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
let r = m(n, t), i = new c(X([[r, 1]], 0), "<=", 0, t);
|
|
1442
|
+
s.push(i), u.set(i, t);
|
|
1443
|
+
return;
|
|
1444
|
+
}
|
|
1445
|
+
if (e.op === "and") {
|
|
1446
|
+
for (let n = 0; n < e.children.length; n++) _(e.children[n], `${t}_and_${n}`);
|
|
1447
|
+
return;
|
|
1448
|
+
}
|
|
1449
|
+
if (e.op === "or") {
|
|
1450
|
+
if (e.children.every((e) => e instanceof o || e instanceof n)) {
|
|
1451
|
+
let n = e.children.map((e) => m(e, t)).map((e) => [e, 1]), r = new c(X(n, 0), ">=", 1, t);
|
|
1452
|
+
s.push(r), u.set(r, t);
|
|
1453
|
+
return;
|
|
1454
|
+
}
|
|
1455
|
+
let r = [];
|
|
1456
|
+
for (let n = 0; n < e.children.length; n++) {
|
|
1457
|
+
let i = e.children[n], o = new b({
|
|
1458
|
+
name: p(`or_branch_${n}`),
|
|
1459
|
+
type: "Binary",
|
|
1460
|
+
lb: 0,
|
|
1461
|
+
ub: 1
|
|
1462
|
+
});
|
|
1463
|
+
if (a.push(o), r.push(o), i instanceof c) v(o, i, 1, `${t}_or_branch_${n}`, t);
|
|
1464
|
+
else {
|
|
1465
|
+
let e = m(i, t), r = new c(X([[o, 1], [e, -1]], 0), "<=", 0, `${t}_or_bool_${n}`);
|
|
1466
|
+
s.push(r), u.set(r, t);
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
let i = r.map((e) => [e, 1]), l = new c(X(i, 0), ">=", 1, t);
|
|
1470
|
+
s.push(l), u.set(l, t);
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
if (e.op === "xor") {
|
|
1474
|
+
if (e.children.length === 0) {
|
|
1475
|
+
let e = new b({
|
|
1476
|
+
name: p("unsat"),
|
|
1477
|
+
type: "Binary",
|
|
1478
|
+
lb: 0,
|
|
1479
|
+
ub: 0
|
|
1480
|
+
});
|
|
1481
|
+
a.push(e);
|
|
1482
|
+
let n = new c(X([[e, 1]], 0), ">=", 1, t);
|
|
1483
|
+
s.push(n), u.set(n, t);
|
|
1484
|
+
return;
|
|
1485
|
+
}
|
|
1486
|
+
if (e.children.length === 1) {
|
|
1487
|
+
_(e.children[0], t);
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
let n = e.children.map((e) => m(e, t));
|
|
1491
|
+
if (n.length === 2) {
|
|
1492
|
+
let e = new c(X([[n[0], 1], [n[1], 1]], 0), "==", 1, t);
|
|
1493
|
+
s.push(e), u.set(e, t);
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
let r = n[0];
|
|
1497
|
+
for (let e = 1; e < n.length - 1; e++) {
|
|
1498
|
+
let i = new b({
|
|
1499
|
+
name: p(`xor_fold_${e}`),
|
|
1500
|
+
type: "Binary",
|
|
1501
|
+
lb: 0,
|
|
1502
|
+
ub: 1
|
|
1503
|
+
});
|
|
1504
|
+
a.push(i), h(i, r, n[e], `${t}_xor_fold_${e}`), r = i;
|
|
1505
|
+
}
|
|
1506
|
+
let i = n[n.length - 1], o = new c(X([[r, 1], [i, 1]], 0), "==", 1, t);
|
|
1507
|
+
s.push(o), u.set(o, t);
|
|
1508
|
+
return;
|
|
1509
|
+
}
|
|
1510
|
+
if (e.op === "implies") {
|
|
1511
|
+
let [r, i] = e.children;
|
|
1512
|
+
if (r instanceof c && r.lhs.terms.size === 1 && r.lhs.constant === 0) {
|
|
1513
|
+
let [[e, n]] = Array.from(r.lhs.terms.entries());
|
|
1514
|
+
if ((e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1) && n === 1) {
|
|
1515
|
+
let n = null;
|
|
1516
|
+
if (r.sense === "==" && r.rhs === 1 ? n = 1 : r.sense === "==" && r.rhs === 0 || r.sense === "<=" && r.rhs === 0 ? n = 0 : r.sense === ">=" && r.rhs === 1 && (n = 1), n !== null && i instanceof c) {
|
|
1517
|
+
v(e, i, n, t, t);
|
|
1518
|
+
return;
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
let d;
|
|
1523
|
+
if (r instanceof c ? (d = new b({
|
|
1524
|
+
name: p("ante"),
|
|
1525
|
+
type: "Binary",
|
|
1526
|
+
lb: 0,
|
|
1527
|
+
ub: 1
|
|
1528
|
+
}), a.push(d), v(d, r, 1, `${t}_ante_active`, t)) : d = m(r, t), i instanceof c) {
|
|
1529
|
+
v(d, i, 1, t, t);
|
|
1530
|
+
return;
|
|
1531
|
+
}
|
|
1532
|
+
if (i instanceof o) {
|
|
1533
|
+
let e = l.get(i), n = new c(X([[e, 1], [d, -1]], 0), ">=", 0, t);
|
|
1534
|
+
s.push(n), u.set(n, t);
|
|
1535
|
+
return;
|
|
1536
|
+
}
|
|
1537
|
+
if (i instanceof n) {
|
|
1538
|
+
if (i.op === "and") {
|
|
1539
|
+
for (let e = 0; e < i.children.length; e++) _(new n("implies", [d instanceof b ? new qe(d) : r, i.children[e]]), `${t}_and_${e}`);
|
|
1540
|
+
return;
|
|
1541
|
+
}
|
|
1542
|
+
if (i.op === "not") {
|
|
1543
|
+
let e = i.children[0], n = m(e, t), r = new c(X([[d, 1], [n, 1]], 0), "<=", 1, t);
|
|
1544
|
+
s.push(r), u.set(r, t);
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1547
|
+
let e = m(i, t), a = new c(X([[e, 1], [d, -1]], 0), ">=", 0, t);
|
|
1548
|
+
s.push(a), u.set(a, t);
|
|
1549
|
+
return;
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
throw Error(`Unsupported top-level logical constraint "${t}": ${e}`);
|
|
1554
|
+
}
|
|
1555
|
+
function v(e, t, n, r, i) {
|
|
1556
|
+
let { lhs: a, sense: o, rhs: l } = t;
|
|
1557
|
+
if (o === "<=" || o === ">=") {
|
|
1558
|
+
let t = Y(e, a, o, l, n, o === "<=" ? q(a, l, r) : J(a, l, r), r), d = new c(t.lhs, o, t.rhs, r);
|
|
1559
|
+
s.push(d), u.set(d, i);
|
|
1560
|
+
} else {
|
|
1561
|
+
let t = q(a, l, `${r}_le`), o = J(a, l, `${r}_ge`), d = Y(e, a, "<=", l, n, t, `${r}_le`), f = Y(e, a, ">=", l, n, o, `${r}_ge`), p = new c(d.lhs, "<=", d.rhs, `${r}_le`), m = new c(f.lhs, ">=", f.rhs, `${r}_ge`);
|
|
1562
|
+
s.push(p, m), u.set(p, i), u.set(m, i);
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
return {
|
|
1566
|
+
variables: a,
|
|
1567
|
+
constraints: s,
|
|
1568
|
+
boolVarToBinary: l,
|
|
1569
|
+
constraintToOriginalName: u
|
|
1570
|
+
};
|
|
1571
|
+
}
|
|
1572
|
+
var qe = class extends o {
|
|
1573
|
+
wrappedVar;
|
|
1574
|
+
constructor(e) {
|
|
1575
|
+
super(e.name), this.wrappedVar = e;
|
|
1576
|
+
}
|
|
1577
|
+
};
|
|
1578
|
+
//#endregion
|
|
1579
|
+
//#region src/decomposition/column-generation.ts
|
|
1580
|
+
async function Je(e) {
|
|
1581
|
+
let t = e.master;
|
|
1582
|
+
if (!t) throw Error("A master Model must be provided for solveColumnGeneration.");
|
|
1583
|
+
let { pricing: n, maxIterations: r = 100, reducedCostTolerance: i = 1e-6, finalizeAsMIP: a = !0, solver: o, solverOptions: s, onIteration: c } = e, l = t.sense.toLowerCase() === "maximize", u = n;
|
|
1584
|
+
if (!u) throw Error("The 'pricing' callback must be provided in ColumnGenerationOptions.");
|
|
1585
|
+
let d = [], f = null, p = 0, m = t.status;
|
|
1586
|
+
for (let e = 1; e <= r; e++) {
|
|
1587
|
+
p = e;
|
|
1588
|
+
let n = await t.relax(o, s);
|
|
1589
|
+
if (m = n, n !== "Optimal" && n !== "Feasible" || !t.solution) break;
|
|
1590
|
+
f = t.objectiveValue;
|
|
1591
|
+
let r = t.solution, a = r.duals || {}, h = (e) => typeof e == "string" ? a[e] ?? 0 : e.dual ?? (e.name ? a[e.name] ?? 0 : 0), g = await u({
|
|
1592
|
+
iteration: e,
|
|
1593
|
+
duals: a,
|
|
1594
|
+
getDual: h,
|
|
1595
|
+
masterSolution: r,
|
|
1596
|
+
reducedCostTolerance: i,
|
|
1597
|
+
master: t
|
|
1598
|
+
}), _ = [];
|
|
1599
|
+
g && (Array.isArray(g) ? _.push(...g) : _.push(g));
|
|
1600
|
+
let v = [];
|
|
1601
|
+
for (let e of _) {
|
|
1602
|
+
let t = e.reducedCost;
|
|
1603
|
+
if (typeof t != "number" || !Number.isFinite(t)) {
|
|
1604
|
+
let n = 0, r = e.coefficients;
|
|
1605
|
+
if (Array.isArray(r)) for (let e of r) Array.isArray(e) ? n += e[1] * h(e[0]) : e && typeof e == "object" && (n += e.coeff * h(e.constraint));
|
|
1606
|
+
else if (r instanceof Map) for (let [e, t] of r.entries()) n += t * h(e);
|
|
1607
|
+
else if (r && typeof r == "object") for (let [e, t] of Object.entries(r)) n += t * h(e);
|
|
1608
|
+
t = e.cost - n;
|
|
1609
|
+
}
|
|
1610
|
+
(l ? t > i : t < -i) && v.push(e);
|
|
1611
|
+
}
|
|
1612
|
+
if (c && c({
|
|
1613
|
+
iteration: e,
|
|
1614
|
+
relaxationObjective: f,
|
|
1615
|
+
columnsAdded: d.length + v.length,
|
|
1616
|
+
proposedColumns: v
|
|
1617
|
+
}), v.length === 0) break;
|
|
1618
|
+
for (let e of v) {
|
|
1619
|
+
let n = t.addColumn({
|
|
1620
|
+
name: e.name,
|
|
1621
|
+
type: e.type || "Continuous",
|
|
1622
|
+
lb: e.lb,
|
|
1623
|
+
ub: e.ub,
|
|
1624
|
+
cost: e.cost,
|
|
1625
|
+
coefficients: e.coefficients
|
|
1626
|
+
});
|
|
1627
|
+
d.push({
|
|
1628
|
+
variable: n,
|
|
1629
|
+
proposal: e
|
|
1630
|
+
});
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
let h = f;
|
|
1634
|
+
a && (m === "Optimal" || m === "Feasible") && (m = await t.solve(o, s), h = t.objectiveValue);
|
|
1635
|
+
let g = {};
|
|
1636
|
+
for (let e of t.variables) e.value !== null && (g[e.name] = e.value);
|
|
1637
|
+
let _ = {
|
|
1638
|
+
status: m,
|
|
1639
|
+
objectiveValue: h,
|
|
1640
|
+
relaxationObjectiveValue: f,
|
|
1641
|
+
iterations: p,
|
|
1642
|
+
columnsAdded: d.length,
|
|
1643
|
+
generatedColumns: d,
|
|
1644
|
+
master: t,
|
|
1645
|
+
values: g
|
|
1646
|
+
};
|
|
1647
|
+
return t.decomposition = _, _;
|
|
1648
|
+
}
|
|
1649
|
+
//#endregion
|
|
1650
|
+
//#region src/modeler/objective.ts
|
|
1651
|
+
function Ye(e, t) {
|
|
1652
|
+
let n = e;
|
|
1653
|
+
if (n instanceof c || typeof n == "object" && n && "sense" in n && "lhs" in n && "rhs" in n) throw Error(`Cannot use a Constraint as an objective in ${t}(). Use m.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}(), e.g. m.objective(${t}(expr\`30 * \${x}\`)).`);
|
|
1654
|
+
if (typeof n == "string" && /(<=|>=|==|=<|=>|=)/.test(n)) throw Error(`Cannot use a comparison constraint as an objective in ${t}(). Use m.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}(), e.g. m.objective(${t}(expr\`30 * \${x}\`)).`);
|
|
1655
|
+
if (typeof n == "number") {
|
|
1656
|
+
if (!Number.isFinite(n)) throw Error(`Invalid non-finite objective constant "${n}" passed to ${t}().`);
|
|
1657
|
+
return n;
|
|
1658
|
+
}
|
|
1659
|
+
if (typeof n == "string" || n instanceof j || n instanceof A || n instanceof b || typeof n == "object" && n && ("terms" in n && n.terms instanceof Map && typeof n.constant == "number" || "quadTerms" in n && n.quadTerms instanceof Map && "linearTerms" in n && n.linearTerms instanceof Map && typeof n.constant == "number" || "id" in n && "name" in n && "lb" in n && "ub" in n)) return n;
|
|
1660
|
+
throw Error(`Invalid expression passed to ${t}(): expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.`);
|
|
1661
|
+
}
|
|
1662
|
+
function Xe(e) {
|
|
1663
|
+
return {
|
|
1664
|
+
expr: Ye(e, "maximize"),
|
|
1665
|
+
sense: "Maximize"
|
|
1666
|
+
};
|
|
1667
|
+
}
|
|
1668
|
+
function Ze(e) {
|
|
1669
|
+
return {
|
|
1670
|
+
expr: Ye(e, "minimize"),
|
|
1671
|
+
sense: "Minimize"
|
|
1672
|
+
};
|
|
1673
|
+
}
|
|
1674
|
+
//#endregion
|
|
1675
|
+
//#region src/decomposition/benders.ts
|
|
1676
|
+
function Qe(e) {
|
|
1677
|
+
return !!(e && typeof e == "object" && "constraints" in e && "variables" in e && typeof e.solve == "function");
|
|
1678
|
+
}
|
|
1679
|
+
async function $e(e, t, n, r, i, a, o, s, l = 1) {
|
|
1680
|
+
let u = [];
|
|
1681
|
+
for (let r = 0; r < t.length; r++) {
|
|
1682
|
+
let a = t[r], o = a.lhs, s = a.sense, d = a.rhs - (o.constant || 0), f = [], p = [], m = 0;
|
|
1683
|
+
for (let [e, t] of o.terms.entries()) if (e.ownerModel === n || n.getVarByName(e.name) !== void 0) {
|
|
1684
|
+
p.push([e, t]);
|
|
1685
|
+
let n = i[e.name] ?? 0;
|
|
1686
|
+
m += t * n;
|
|
1687
|
+
} else f.push([e, t]);
|
|
1688
|
+
let h = d - m, g = new j();
|
|
1689
|
+
for (let [e, t] of f) g.addTerm(e, t);
|
|
1690
|
+
let _ = `__benders_link_${l}_${r}`, v = new c(g, s, h, _);
|
|
1691
|
+
e.constraint(v), u.push({
|
|
1692
|
+
origConstraint: a,
|
|
1693
|
+
subConstr: v,
|
|
1694
|
+
masterTerms: p,
|
|
1695
|
+
baseRhs: d
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1698
|
+
let d = await e.solve(o, {
|
|
1699
|
+
...s,
|
|
1700
|
+
relax: !0
|
|
1701
|
+
});
|
|
1702
|
+
if (d !== "Optimal" && d !== "Feasible") return null;
|
|
1703
|
+
let f = e.objectiveValue ?? 0, p = i[r.name] ?? 0, m = 1e-4;
|
|
1704
|
+
if (!(a ? p < f - m : p > f + m)) return null;
|
|
1705
|
+
let h = 0, g = /* @__PURE__ */ new Map(), _ = new Set(u.map((e) => e.subConstr.name));
|
|
1706
|
+
for (let t of e.constraints) {
|
|
1707
|
+
if (_.has(t.name)) continue;
|
|
1708
|
+
let n = e.solution?.duals[t.name] ?? t.dual ?? 0;
|
|
1709
|
+
if (Math.abs(n) > 1e-12) {
|
|
1710
|
+
let e = t.rhs - (t.lhs.constant || 0);
|
|
1711
|
+
h += n * e;
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
for (let t of u) {
|
|
1715
|
+
let n = e.solution?.duals[t.subConstr.name] ?? t.subConstr.dual ?? 0;
|
|
1716
|
+
if (Math.abs(n) > 1e-12) {
|
|
1717
|
+
h += n * t.baseRhs;
|
|
1718
|
+
for (let [e, r] of t.masterTerms) {
|
|
1719
|
+
let t = g.get(e) ?? 0;
|
|
1720
|
+
g.set(e, t + n * r);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
let v = new j();
|
|
1725
|
+
v.addTerm(r, 1);
|
|
1726
|
+
for (let [e, t] of g.entries()) Math.abs(t) > 1e-12 && v.addTerm(e, t);
|
|
1727
|
+
let y = new c(v, a ? ">=" : "<=", h, `__benders_opt_cut_${l}`), b = (n.objectiveValue ?? 0) - p + f;
|
|
1728
|
+
return {
|
|
1729
|
+
kind: "optimality",
|
|
1730
|
+
constraint: y,
|
|
1731
|
+
name: y.name,
|
|
1732
|
+
subproblemObjective: b
|
|
1733
|
+
};
|
|
1734
|
+
}
|
|
1735
|
+
async function et(e) {
|
|
1736
|
+
let t = e.master;
|
|
1737
|
+
if (!t) throw Error("A master Model must be provided for solveBenders.");
|
|
1738
|
+
let { subproblem: n, maxIterations: r = 100, gapTolerance: i = 1e-4, solver: a, solverOptions: o, onIteration: s } = e, c;
|
|
1739
|
+
e.theta && (c = typeof e.theta == "string" ? t.getVarByName(e.theta) : e.theta), c ||= t.variables.find((e) => e.name === "theta" || e.name === "__benders_theta");
|
|
1740
|
+
let l = 0, u = 0, d = t.status, f, p, m, h = {}, g = null;
|
|
1741
|
+
for (let e = 1; e <= r; e++) {
|
|
1742
|
+
u = e;
|
|
1743
|
+
let r = await t.solve(a, o);
|
|
1744
|
+
if (d = r, r !== "Optimal" && r !== "Feasible") break;
|
|
1745
|
+
let _ = t.objectiveValue, v = t.sense.toLowerCase() === "minimize";
|
|
1746
|
+
v ? f = _ === null ? f : _ : p = _ === null ? p : _;
|
|
1747
|
+
let y = {};
|
|
1748
|
+
for (let e of t.variables) e.value !== null && (y[e.name] = e.value);
|
|
1749
|
+
let b = await n({
|
|
1750
|
+
iteration: e,
|
|
1751
|
+
masterValues: y,
|
|
1752
|
+
getMasterValue: (e) => typeof e == "string" ? y[e] ?? 0 : e.value ?? (e.name ? y[e.name] ?? 0 : 0),
|
|
1753
|
+
masterObjective: _,
|
|
1754
|
+
lowerBound: f,
|
|
1755
|
+
upperBound: p,
|
|
1756
|
+
master: t
|
|
1757
|
+
}), x = [];
|
|
1758
|
+
if (b) {
|
|
1759
|
+
if (Qe(b)) {
|
|
1760
|
+
let n = b, r = n.linkingConstraints;
|
|
1761
|
+
c || (c = t.continuous("__benders_theta", { lb: 0 }), v ? t.objective(Ze(t.objectiveExpr.add(c))) : t.objective(Xe(t.objectiveExpr.sub(c))));
|
|
1762
|
+
let i = await $e(n, r, t, c, y, v, a, o, e);
|
|
1763
|
+
i && x.push(i);
|
|
1764
|
+
} else Array.isArray(b) ? x.push(...b) : x.push(b);
|
|
1765
|
+
}
|
|
1766
|
+
for (let e of x) if (typeof e.subproblemObjective == "number" && Number.isFinite(e.subproblemObjective)) {
|
|
1767
|
+
if (v) {
|
|
1768
|
+
let t = e.subproblemObjective;
|
|
1769
|
+
(p === void 0 || t < p) && (p = t, g = t, h = { ...y });
|
|
1770
|
+
} else {
|
|
1771
|
+
let t = e.subproblemObjective;
|
|
1772
|
+
(f === void 0 || t > f) && (f = t, g = t, h = { ...y });
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
if (f !== void 0 && p !== void 0) {
|
|
1776
|
+
let e = Math.abs(p) + 1e-10;
|
|
1777
|
+
m = Math.abs(p - f) / e;
|
|
1778
|
+
}
|
|
1779
|
+
if (s && s({
|
|
1780
|
+
iteration: e,
|
|
1781
|
+
masterObjective: _,
|
|
1782
|
+
lowerBound: f,
|
|
1783
|
+
upperBound: p,
|
|
1784
|
+
cutsAdded: l + x.length,
|
|
1785
|
+
proposedCuts: x
|
|
1786
|
+
}), x.length === 0) {
|
|
1787
|
+
g = _, h = { ...y };
|
|
1788
|
+
break;
|
|
1789
|
+
}
|
|
1790
|
+
if (m !== void 0 && m <= i) break;
|
|
1791
|
+
for (let e of x) t.constraint(e.constraint, e.name), l++;
|
|
1792
|
+
}
|
|
1793
|
+
let _ = Object.keys(h).length > 0 ? h : (() => {
|
|
1794
|
+
let e = {};
|
|
1795
|
+
for (let n of t.variables) n.value !== null && (e[n.name] = n.value);
|
|
1796
|
+
return e;
|
|
1797
|
+
})(), v = g === null ? t.objectiveValue : g, y = {
|
|
1798
|
+
status: d,
|
|
1799
|
+
objectiveValue: v,
|
|
1800
|
+
lowerBound: f,
|
|
1801
|
+
upperBound: p,
|
|
1802
|
+
gap: m,
|
|
1803
|
+
iterations: u,
|
|
1804
|
+
cutsAdded: l,
|
|
1805
|
+
master: t,
|
|
1806
|
+
values: _
|
|
1807
|
+
};
|
|
1808
|
+
return t.decomposition = y, y;
|
|
1809
|
+
}
|
|
1810
|
+
//#endregion
|
|
1811
|
+
//#region src/modeler/model.ts
|
|
1812
|
+
function Z(e) {
|
|
1813
|
+
return Array.isArray(e) || typeof e == "object" && !!e && !(e instanceof String) && typeof e[Symbol.iterator] == "function";
|
|
1814
|
+
}
|
|
1815
|
+
function Q(e) {
|
|
1816
|
+
return typeof e == "object" && !!e && !Array.isArray(e) && !(e instanceof String) && typeof e[Symbol.iterator] != "function";
|
|
1817
|
+
}
|
|
1818
|
+
function tt(e) {
|
|
1819
|
+
return e instanceof b || typeof e == "object" && !!e && !(e instanceof r) && !(e instanceof c) && "id" in e && "name" in e && "lb" in e && "ub" in e && !("terms" in e) && !("quadTerms" in e) && !("sense" in e);
|
|
1820
|
+
}
|
|
1821
|
+
function $(e, t) {
|
|
1822
|
+
if (!Number.isInteger(e) || e < 0) throw Error(`Invalid count (${e}) for ${t} variable creation: count must be a non-negative integer.`);
|
|
1823
|
+
}
|
|
1824
|
+
var nt = class {
|
|
1825
|
+
name;
|
|
1826
|
+
_sense;
|
|
1827
|
+
_objectiveExpr;
|
|
1828
|
+
variables = [];
|
|
1829
|
+
constraints = [];
|
|
1830
|
+
boolVars = [];
|
|
1831
|
+
logicalConstraints = [];
|
|
1832
|
+
unsatCore = void 0;
|
|
1833
|
+
_conflicts = void 0;
|
|
1834
|
+
values = /* @__PURE__ */ new Map();
|
|
1835
|
+
varMapByName = /* @__PURE__ */ new Map();
|
|
1836
|
+
varPrefixCounters = /* @__PURE__ */ new Map();
|
|
1837
|
+
boolVarMapByName = /* @__PURE__ */ new Map();
|
|
1838
|
+
boolVarPrefixCounters = /* @__PURE__ */ new Map();
|
|
1839
|
+
constrMapByName = /* @__PURE__ */ new Map();
|
|
1840
|
+
constrPrefixCounters = /* @__PURE__ */ new Map();
|
|
1841
|
+
logicalConstrMapByName = /* @__PURE__ */ new Map();
|
|
1842
|
+
logicalConstrCounter = 0;
|
|
1843
|
+
status = "NotSolved";
|
|
1844
|
+
terminationStatus = "NotSolved";
|
|
1845
|
+
hasPrimalSolution = !1;
|
|
1846
|
+
objectiveValue = null;
|
|
1847
|
+
objectiveBound = void 0;
|
|
1848
|
+
relGap = void 0;
|
|
1849
|
+
mipGap = void 0;
|
|
1850
|
+
absGap = void 0;
|
|
1851
|
+
runTime = 0;
|
|
1852
|
+
solution = null;
|
|
1853
|
+
solver = null;
|
|
1854
|
+
decomposition;
|
|
1855
|
+
_linkingConstraints;
|
|
1856
|
+
hasSolutionState = !1;
|
|
1857
|
+
modelRevision = 0;
|
|
1858
|
+
activeOperationId = 0;
|
|
1859
|
+
batchDepth = 0;
|
|
1860
|
+
batchMutated = !1;
|
|
1861
|
+
batchUndoActions = [];
|
|
1862
|
+
constructor(e = {}, t) {
|
|
1863
|
+
let n;
|
|
1864
|
+
n = typeof e == "string" ? {
|
|
1865
|
+
...t,
|
|
1866
|
+
name: e
|
|
1867
|
+
} : e, this.name = n.name || "OptimizationModel", this._sense = _e(n.sense), this._objectiveExpr = new j(), n.solver && (this.solver = D(n.solver));
|
|
1868
|
+
}
|
|
1869
|
+
get sense() {
|
|
1870
|
+
return this._sense;
|
|
1871
|
+
}
|
|
1872
|
+
set sense(e) {
|
|
1873
|
+
let t = _e(e);
|
|
1874
|
+
this._sense !== t && (this._sense = t, this.recordModelMutation());
|
|
1875
|
+
}
|
|
1876
|
+
get objectiveExpr() {
|
|
1877
|
+
return this._objectiveExpr.clone();
|
|
1878
|
+
}
|
|
1879
|
+
set objectiveExpr(e) {
|
|
1880
|
+
this.applyObjective(e);
|
|
1881
|
+
}
|
|
1882
|
+
get conflicts() {
|
|
1883
|
+
return this._conflicts ?? this.unsatCore;
|
|
1884
|
+
}
|
|
1885
|
+
set conflicts(e) {
|
|
1886
|
+
this._conflicts = e;
|
|
1887
|
+
}
|
|
1888
|
+
get numVars() {
|
|
1889
|
+
return this.variables.length;
|
|
1890
|
+
}
|
|
1891
|
+
get numConstrs() {
|
|
1892
|
+
return this.constraints.length;
|
|
1893
|
+
}
|
|
1894
|
+
clearSolutionFields() {
|
|
1895
|
+
if (this.hasSolutionState || this.status !== "NotSolved" || this.terminationStatus !== "NotSolved" || this.hasPrimalSolution || this.solution !== null || this.unsatCore !== void 0) {
|
|
1896
|
+
this.hasSolutionState = !1, this.status = "NotSolved", this.terminationStatus = "NotSolved", this.hasPrimalSolution = !1, this.objectiveValue = null, this.objectiveBound = void 0, this.relGap = void 0, this.mipGap = void 0, this.absGap = void 0, this.solution = null, this.runTime = 0, this.unsatCore = void 0, this._conflicts = void 0, this.values.clear();
|
|
1897
|
+
for (let e of this.variables) e.value = null, e.reducedCost = null;
|
|
1898
|
+
for (let e of this.boolVars) e.value = null;
|
|
1899
|
+
for (let e of this.constraints) e.dual = null, e.slack = null;
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
recordModelMutation() {
|
|
1903
|
+
if (this.batchDepth > 0) {
|
|
1904
|
+
this.batchMutated = !0;
|
|
1905
|
+
return;
|
|
1906
|
+
}
|
|
1907
|
+
this.modelRevision++, this.clearSolutionFields();
|
|
1908
|
+
}
|
|
1909
|
+
notifyMutation() {
|
|
1910
|
+
this.recordModelMutation();
|
|
1911
|
+
}
|
|
1912
|
+
resetSolutionState() {
|
|
1913
|
+
this.recordModelMutation();
|
|
1914
|
+
}
|
|
1915
|
+
runTransactionalBatch(e) {
|
|
1916
|
+
if (this.batchDepth > 0) return e();
|
|
1917
|
+
let t = this.variables.length, n = this.boolVars.length, r = this.constraints.length, i = this.logicalConstraints.length, a = new Map(this.varPrefixCounters), o = new Map(this.boolVarPrefixCounters), s = new Map(this.constrPrefixCounters), c = this.logicalConstrCounter;
|
|
1918
|
+
this.batchDepth = 1, this.batchMutated = !1, this.batchUndoActions = [];
|
|
1919
|
+
try {
|
|
1920
|
+
let t = e();
|
|
1921
|
+
this.batchDepth = 0;
|
|
1922
|
+
let n = this.batchMutated;
|
|
1923
|
+
return this.batchMutated = !1, this.batchUndoActions = [], n && this.recordModelMutation(), t;
|
|
1924
|
+
} catch (e) {
|
|
1925
|
+
this.batchDepth = 0, this.batchMutated = !1;
|
|
1926
|
+
for (let e = t; e < this.variables.length; e++) {
|
|
1927
|
+
let t = this.variables[e];
|
|
1928
|
+
this.varMapByName.delete(t.name), t.ownerModel = null, g(t, this);
|
|
1929
|
+
}
|
|
1930
|
+
this.variables.length = t;
|
|
1931
|
+
for (let e = n; e < this.boolVars.length; e++) {
|
|
1932
|
+
let t = this.boolVars[e];
|
|
1933
|
+
this.boolVarMapByName.delete(t.name);
|
|
1934
|
+
}
|
|
1935
|
+
this.boolVars.length = n;
|
|
1936
|
+
for (let e = r; e < this.constraints.length; e++) {
|
|
1937
|
+
let t = this.constraints[e];
|
|
1938
|
+
this.constrMapByName.delete(t.name);
|
|
1939
|
+
}
|
|
1940
|
+
this.constraints.length = r;
|
|
1941
|
+
for (let e = i; e < this.logicalConstraints.length; e++) {
|
|
1942
|
+
let t = this.logicalConstraints[e];
|
|
1943
|
+
this.logicalConstrMapByName.delete(t.name);
|
|
1944
|
+
}
|
|
1945
|
+
this.logicalConstraints.length = i;
|
|
1946
|
+
for (let e = this.batchUndoActions.length - 1; e >= 0; e--) this.batchUndoActions[e]();
|
|
1947
|
+
throw this.batchUndoActions = [], this.varPrefixCounters = a, this.boolVarPrefixCounters = o, this.constrPrefixCounters = s, this.logicalConstrCounter = c, e;
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
createDomainVars(e, t, n, r) {
|
|
1951
|
+
let i = e.toLowerCase(), a = typeof t == "number", o = typeof n == "number", s = Z(t), c = Z(n);
|
|
1952
|
+
if (o || c) {
|
|
1953
|
+
if (a && $(t, i), o && $(n, i), !a && !s || r !== void 0 && !Q(r)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
1954
|
+
let c = a ? Array.from({ length: t }, (e, t) => t) : Array.from(t), l = o ? Array.from({ length: n }, (e, t) => t) : n === t ? c : Array.from(n), u = r || {}, d = u.prefix || u.name || "x";
|
|
1955
|
+
return this.runTransactionalBatch(() => {
|
|
1956
|
+
let t = a ? [] : {};
|
|
1957
|
+
for (let n of c) {
|
|
1958
|
+
let r = o ? [] : {};
|
|
1959
|
+
for (let t of l) r[t] = this.addVar({
|
|
1960
|
+
...u,
|
|
1961
|
+
type: e,
|
|
1962
|
+
name: `${d}_${n}_${t}`
|
|
1963
|
+
});
|
|
1964
|
+
t[n] = r;
|
|
1965
|
+
}
|
|
1966
|
+
return t;
|
|
1967
|
+
});
|
|
1968
|
+
}
|
|
1969
|
+
if (typeof t == "string" || t === void 0) {
|
|
1970
|
+
if (n !== void 0 && !Q(n)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
1971
|
+
let r = n || {}, a = typeof t == "string" ? t : r.name;
|
|
1972
|
+
return this.addVar({
|
|
1973
|
+
...r,
|
|
1974
|
+
type: e,
|
|
1975
|
+
name: a
|
|
1976
|
+
});
|
|
1977
|
+
}
|
|
1978
|
+
if (Q(t)) {
|
|
1979
|
+
if (n !== void 0) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
1980
|
+
let r = t;
|
|
1981
|
+
return this.addVar({
|
|
1982
|
+
...r,
|
|
1983
|
+
type: e
|
|
1984
|
+
});
|
|
1985
|
+
}
|
|
1986
|
+
if (n !== void 0 && !Q(n)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
1987
|
+
let l = n || {}, u = l.prefix || l.name;
|
|
1988
|
+
if (typeof t == "number") return $(t, i), this.runTransactionalBatch(() => {
|
|
1989
|
+
let n = [], r = u || "x";
|
|
1990
|
+
for (let i = 0; i < t; i++) n.push(this.addVar({
|
|
1991
|
+
...l,
|
|
1992
|
+
type: e,
|
|
1993
|
+
name: void 0,
|
|
1994
|
+
prefix: r
|
|
1995
|
+
}));
|
|
1996
|
+
return n;
|
|
1997
|
+
});
|
|
1998
|
+
if (Z(t)) return this.runTransactionalBatch(() => {
|
|
1999
|
+
let n = {};
|
|
2000
|
+
for (let r of t) {
|
|
2001
|
+
let t = u ? `${u}_${r}` : `${r}`;
|
|
2002
|
+
n[r] = this.addVar({
|
|
2003
|
+
...l,
|
|
2004
|
+
type: e,
|
|
2005
|
+
name: t
|
|
2006
|
+
});
|
|
2007
|
+
}
|
|
2008
|
+
return n;
|
|
2009
|
+
});
|
|
2010
|
+
throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
2011
|
+
}
|
|
2012
|
+
binary(e, t, n) {
|
|
2013
|
+
return this.createDomainVars("Binary", e, t, n);
|
|
2014
|
+
}
|
|
2015
|
+
integer(e, t, n) {
|
|
2016
|
+
return this.createDomainVars("Integer", e, t, n);
|
|
2017
|
+
}
|
|
2018
|
+
continuous(e, t, n) {
|
|
2019
|
+
return this.createDomainVars("Continuous", e, t, n);
|
|
2020
|
+
}
|
|
2021
|
+
addColumn(e) {
|
|
2022
|
+
let t = e.type || "Continuous", n = this.addVar({
|
|
2023
|
+
name: e.name,
|
|
2024
|
+
type: t,
|
|
2025
|
+
lb: e.lb,
|
|
2026
|
+
ub: e.ub
|
|
2027
|
+
});
|
|
2028
|
+
if (typeof e.cost == "number" && e.cost !== 0 && (this._objectiveExpr = this._objectiveExpr.add(n.mul(e.cost)), this.recordModelMutation()), e.coefficients) {
|
|
2029
|
+
if (Array.isArray(e.coefficients)) {
|
|
2030
|
+
for (let t of e.coefficients) if (Array.isArray(t)) {
|
|
2031
|
+
let [e, r] = t, i = typeof e == "string" ? this.getConstraintByName(e) : e;
|
|
2032
|
+
if (!i) throw Error(`Constraint '${String(e)}' not found in model when adding column`);
|
|
2033
|
+
i.addTerm(n, r);
|
|
2034
|
+
} else if (typeof t == "object" && t) {
|
|
2035
|
+
let e = typeof t.constraint == "string" ? this.getConstraintByName(t.constraint) : t.constraint;
|
|
2036
|
+
if (!e) throw Error(`Constraint '${String(t.constraint)}' not found in model when adding column`);
|
|
2037
|
+
e.addTerm(n, t.coeff);
|
|
2038
|
+
}
|
|
2039
|
+
} else if (e.coefficients instanceof Map) for (let [t, r] of e.coefficients.entries()) {
|
|
2040
|
+
let e = typeof t == "string" ? this.getConstraintByName(t) : t;
|
|
2041
|
+
if (!e) throw Error(`Constraint '${String(t)}' not found in model when adding column`);
|
|
2042
|
+
e.addTerm(n, r);
|
|
2043
|
+
}
|
|
2044
|
+
else if (typeof e.coefficients == "object") for (let [t, r] of Object.entries(e.coefficients)) {
|
|
2045
|
+
let e = this.getConstraintByName(t);
|
|
2046
|
+
if (!e) throw Error(`Constraint '${t}' not found in model when adding column`);
|
|
2047
|
+
e.addTerm(n, r);
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
return n;
|
|
2051
|
+
}
|
|
2052
|
+
bool(e, t, n) {
|
|
2053
|
+
let r = typeof e == "number", i = typeof t == "number", a = Z(e), o = Z(t);
|
|
2054
|
+
if (i || o) {
|
|
2055
|
+
if (r && $(e, "boolean"), i && $(t, "boolean"), !r && !a || n !== void 0 && !Q(n)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2056
|
+
let o = r ? Array.from({ length: e }, (e, t) => t) : Array.from(e), s = i ? Array.from({ length: t }, (e, t) => t) : t === e ? o : Array.from(t), c = n || {}, l = c.prefix || c.name || "p";
|
|
2057
|
+
return this.runTransactionalBatch(() => {
|
|
2058
|
+
let e = r ? [] : {};
|
|
2059
|
+
for (let t of o) {
|
|
2060
|
+
let n = i ? [] : {};
|
|
2061
|
+
for (let e of s) n[e] = this.createBoolVar(`${l}_${t}_${e}`);
|
|
2062
|
+
e[t] = n;
|
|
2063
|
+
}
|
|
2064
|
+
return e;
|
|
2065
|
+
});
|
|
2066
|
+
}
|
|
2067
|
+
if (typeof e == "string" || e === void 0) {
|
|
2068
|
+
if (t !== void 0 && !Q(t)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2069
|
+
let n = t || {}, r = typeof e == "string" ? e : n.name;
|
|
2070
|
+
return this.createBoolVar(r, n.prefix);
|
|
2071
|
+
}
|
|
2072
|
+
if (Q(e)) {
|
|
2073
|
+
if (t !== void 0) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2074
|
+
let n = e;
|
|
2075
|
+
return this.createBoolVar(n.name, n.prefix);
|
|
2076
|
+
}
|
|
2077
|
+
if (t !== void 0 && !Q(t)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2078
|
+
let s = t || {}, c = s.prefix || s.name;
|
|
2079
|
+
if (typeof e == "number") return $(e, "boolean"), this.runTransactionalBatch(() => {
|
|
2080
|
+
let t = [], n = c || "p";
|
|
2081
|
+
for (let r = 0; r < e; r++) t.push(this.createBoolVar(void 0, n));
|
|
2082
|
+
return t;
|
|
2083
|
+
});
|
|
2084
|
+
if (Z(e)) return this.runTransactionalBatch(() => {
|
|
2085
|
+
let t = {};
|
|
2086
|
+
for (let n of e) {
|
|
2087
|
+
let e = c ? `${c}_${n}` : `${n}`;
|
|
2088
|
+
t[n] = this.createBoolVar(e);
|
|
2089
|
+
}
|
|
2090
|
+
return t;
|
|
2091
|
+
});
|
|
1110
2092
|
throw Error("Invalid arguments provided for boolean variable creation");
|
|
1111
2093
|
}
|
|
1112
2094
|
hasVarName(e) {
|
|
1113
2095
|
return this.varMapByName.has(e) || this.boolVarMapByName.has(e);
|
|
1114
2096
|
}
|
|
2097
|
+
getNextVarName(e) {
|
|
2098
|
+
let t = this.varPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
|
|
2099
|
+
for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
|
|
2100
|
+
return this.varPrefixCounters.set(e, t + 1), n;
|
|
2101
|
+
}
|
|
1115
2102
|
getNextBoolVarName(e) {
|
|
1116
2103
|
let t = this.boolVarPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
|
|
1117
|
-
for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
|
|
2104
|
+
for (; this.hasVarName(n) || this.hasConstraintName(n);) t++, n = `${e}_${t}`;
|
|
1118
2105
|
return this.boolVarPrefixCounters.set(e, t + 1), n;
|
|
1119
2106
|
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
return this.
|
|
2107
|
+
hasConstraintName(e) {
|
|
2108
|
+
return this.constrMapByName.has(e) || this.logicalConstrMapByName.has(e);
|
|
2109
|
+
}
|
|
2110
|
+
hasBoolVarName(e) {
|
|
2111
|
+
return this.boolVarMapByName.has(e);
|
|
2112
|
+
}
|
|
2113
|
+
getNextConstrName(e = "c") {
|
|
2114
|
+
let t = this.constrPrefixCounters.get(e) ?? 1, n = `${e}_${t}`;
|
|
2115
|
+
for (; this.hasConstraintName(n) || this.hasBoolVarName(n);) t++, n = `${e}_${t}`;
|
|
2116
|
+
return this.constrPrefixCounters.set(e, t + 1), n;
|
|
2117
|
+
}
|
|
2118
|
+
getNextLogicalConstrName() {
|
|
2119
|
+
let e = this.logicalConstrCounter + 1, t = `lc_${e}`;
|
|
2120
|
+
for (; this.hasConstraintName(t) || this.hasBoolVarName(t);) e++, t = `lc_${e}`;
|
|
2121
|
+
return this.logicalConstrCounter = e, t;
|
|
2122
|
+
}
|
|
2123
|
+
createBoolVar(e, t) {
|
|
2124
|
+
let n = typeof e == "string" ? e.trim() : void 0, r = typeof t == "string" ? t.trim() : "", i = r.length > 0 ? r : "p", a = n && n.length > 0 ? n : this.getNextBoolVarName(i);
|
|
2125
|
+
if (this.hasVarName(a)) throw Error(`Variable with name '${a}' already exists in model`);
|
|
2126
|
+
if (this.hasConstraintName(a)) throw Error(`Boolean variable name '${a}' conflicts with an existing constraint in model`);
|
|
2127
|
+
let s = new o(a);
|
|
2128
|
+
return this.boolVars.push(s), this.boolVarMapByName.set(s.name, s), this.recordModelMutation(), s;
|
|
1125
2129
|
}
|
|
1126
2130
|
addVar(e) {
|
|
1127
|
-
let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i =
|
|
1128
|
-
|
|
1129
|
-
name
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
2131
|
+
let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i = typeof t.prefix == "string" ? t.prefix.trim() : "", a = i.length > 0 ? i : "x", o = this.varPrefixCounters.get(a), s = r ?? this.getNextVarName(a);
|
|
2132
|
+
try {
|
|
2133
|
+
if (this.hasVarName(s)) throw Error(`Variable with name '${s}' already exists in model`);
|
|
2134
|
+
let e = new b({
|
|
2135
|
+
...t,
|
|
2136
|
+
name: s,
|
|
2137
|
+
prefix: a
|
|
2138
|
+
});
|
|
2139
|
+
return e.hasExplicitName = r !== void 0, d(e), m(e, this), e.ownerModel = this, this.variables.push(e), this.varMapByName.set(e.name, e), this.recordModelMutation(), e;
|
|
2140
|
+
} catch (e) {
|
|
2141
|
+
throw r === void 0 && (o === void 0 ? this.varPrefixCounters.delete(a) : this.varPrefixCounters.set(a, o)), e;
|
|
2142
|
+
}
|
|
1133
2143
|
}
|
|
1134
2144
|
getVarByName(e) {
|
|
1135
2145
|
return this.varMapByName.get(e);
|
|
@@ -1140,28 +2150,46 @@ var $ = class {
|
|
|
1140
2150
|
getConstraintByName(e) {
|
|
1141
2151
|
return this.constrMapByName.get(e);
|
|
1142
2152
|
}
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
this.
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
if (
|
|
1155
|
-
|
|
2153
|
+
getLogicalConstraintByName(e) {
|
|
2154
|
+
return this.logicalConstrMapByName.get(e);
|
|
2155
|
+
}
|
|
2156
|
+
objective(e) {
|
|
2157
|
+
if (arguments.length === 0) return this.objectiveExpr;
|
|
2158
|
+
let t = e;
|
|
2159
|
+
if (t instanceof c || typeof t == "object" && t && "sense" in t && "lhs" in t && "rhs" in t || typeof t == "string" && /(<=|>=|==|=<|=>|=)/.test(t)) throw Error("Cannot use a Constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)? To set an objective, wrap an unconstrained expression with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`)).");
|
|
2160
|
+
if (typeof t != "object" || !t || !("expr" in t) || !("sense" in t)) throw Error("m.objective(...) expects an ObjectiveSpec created with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`)).");
|
|
2161
|
+
return this.applyObjective(t.expr, t.sense), this;
|
|
2162
|
+
}
|
|
2163
|
+
applyObjective(e, t) {
|
|
2164
|
+
if (e instanceof c || typeof e == "object" && e && "sense" in e && "lhs" in e && "rhs" in e || typeof e == "string" && /(<=|>=|==|=<|=>|=)/.test(e)) throw Error(typeof e == "string" ? "Cannot use a comparison constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)? To set an objective, wrap an unconstrained expression with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`))." : "Cannot use a Constraint as an objective. Did you mean to use m.constraint(expr`... <= ...`)? To set an objective, wrap an unconstrained expression with maximize(...) or minimize(...), e.g. m.objective(maximize(expr`30 * ${x}`)).");
|
|
2165
|
+
let n = t === void 0 ? this.sense : _e(t), r;
|
|
2166
|
+
if (typeof e == "string") r = Se(e, (e) => this.getVarByName(e));
|
|
2167
|
+
else if (typeof e == "number") r = new j(/* @__PURE__ */ new Map(), e);
|
|
2168
|
+
else if (e instanceof A) r = e.clone();
|
|
2169
|
+
else if (e instanceof j) r = e.clone();
|
|
2170
|
+
else if (typeof e == "object" && e && "quadTerms" in e && e.quadTerms instanceof Map && "linearTerms" in e && e.linearTerms instanceof Map && typeof e.constant == "number") {
|
|
2171
|
+
let t = e;
|
|
2172
|
+
r = new A(t.linearTerms, t.quadTerms, t.constant);
|
|
2173
|
+
} else if (typeof e == "object" && e && "terms" in e && e.terms instanceof Map && typeof e.constant == "number") {
|
|
2174
|
+
let t = e;
|
|
2175
|
+
r = new j(t.terms, t.constant);
|
|
2176
|
+
} else if (e instanceof b || typeof e == "object" && e && "id" in e && "name" in e && "lb" in e && "ub" in e) r = new j(/* @__PURE__ */ new Map([[e, 1]]), 0);
|
|
2177
|
+
else throw Error("Invalid objective expression: expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.");
|
|
2178
|
+
ee(r, this.name, (e) => this.varMapByName.get(e.name) === e), this._sense = n, this._objectiveExpr = r, this.recordModelMutation();
|
|
2179
|
+
}
|
|
2180
|
+
constraint(e, t) {
|
|
2181
|
+
if (Array.isArray(e)) return this.runTransactionalBatch(() => {
|
|
2182
|
+
for (let t of e) this.constraint(t);
|
|
1156
2183
|
return this;
|
|
1157
|
-
}
|
|
1158
|
-
if (e instanceof
|
|
1159
|
-
if (e instanceof
|
|
2184
|
+
});
|
|
2185
|
+
if (e instanceof A || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
2186
|
+
if (e instanceof j || typeof e == "object" && e && "terms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a linear expression without a comparison operator. Use expr`... <= ...` or .le(), .ge(), .eq().");
|
|
2187
|
+
if (tt(e)) throw Error(`Cannot add numeric variable "${e.name}" directly as a constraint without a comparison operator (<=, >=, ==). Numeric variables require a comparison such as expr\`\${x} <= 10\` or x.le(10), whereas propositional BoolVar variables must be created with m.bool().`);
|
|
1160
2188
|
return this.addConstraint(e, t), this;
|
|
1161
2189
|
}
|
|
1162
2190
|
getValues(e) {
|
|
1163
2191
|
if (e == null) return null;
|
|
1164
|
-
if (e instanceof
|
|
2192
|
+
if (e instanceof b || e instanceof o) return e.value;
|
|
1165
2193
|
if (Array.isArray(e)) return e.map((e) => this.getValues(e));
|
|
1166
2194
|
if (typeof e == "object") {
|
|
1167
2195
|
let t = {};
|
|
@@ -1171,198 +2199,477 @@ var $ = class {
|
|
|
1171
2199
|
return null;
|
|
1172
2200
|
}
|
|
1173
2201
|
addConstraint(e, t) {
|
|
1174
|
-
if (e instanceof
|
|
1175
|
-
if (e instanceof
|
|
1176
|
-
if (e
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
2202
|
+
if (e instanceof A || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
2203
|
+
if (e instanceof j || typeof e == "object" && e && "terms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a linear expression without a comparison operator. Use expr`... <= ...` or .le(), .ge(), .eq().");
|
|
2204
|
+
if (tt(e)) throw Error(`Cannot add numeric variable "${e.name}" directly as a constraint without a comparison operator (<=, >=, ==). Numeric variables require a comparison such as expr\`\${x} <= 10\` or x.le(10), whereas propositional BoolVar variables must be created with m.bool().`);
|
|
2205
|
+
if (e instanceof r) {
|
|
2206
|
+
let n = typeof t == "string" && t.trim().length > 0 ? t.trim() : void 0;
|
|
2207
|
+
if (n !== void 0) {
|
|
2208
|
+
if (this.hasConstraintName(n)) throw Error(`Constraint with name '${n}' already exists in model`);
|
|
2209
|
+
if (this.hasBoolVarName(n)) throw Error(`Constraint name '${n}' conflicts with an existing Boolean variable in model`);
|
|
2210
|
+
}
|
|
2211
|
+
let r = this.logicalConstrCounter, i = n ?? this.getNextLogicalConstrName();
|
|
2212
|
+
try {
|
|
2213
|
+
l(e, i, this.name, (e) => this.varMapByName.get(e.name) === e, (e) => this.boolVarMapByName.get(e.name) === e, this);
|
|
2214
|
+
} catch (e) {
|
|
2215
|
+
throw n === void 0 && (this.logicalConstrCounter = r), e;
|
|
2216
|
+
}
|
|
2217
|
+
O(e, this, this.batchDepth > 0 ? this.batchUndoActions : void 0);
|
|
2218
|
+
let a = {
|
|
2219
|
+
name: i,
|
|
1180
2220
|
expr: e
|
|
1181
|
-
}
|
|
2221
|
+
};
|
|
2222
|
+
return this.logicalConstraints.push(a), this.logicalConstrMapByName.set(i, a), this.recordModelMutation(), e;
|
|
1182
2223
|
}
|
|
1183
|
-
let n;
|
|
1184
|
-
if (typeof
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
return this;
|
|
2224
|
+
let n = typeof e == "string" ? we(e, (e) => this.getVarByName(e), t) : e;
|
|
2225
|
+
if (typeof n != "object" || !n || !("sense" in n) || !("lhs" in n) || !("rhs" in n)) throw Error("Invalid constraint passed to m.constraint(...): expected a linear Constraint (e.g. expr`${x} <= 10` or x.le(10)), a propositional BoolVar/BoolExpr (created with m.bool()), or an array of constraints.");
|
|
2226
|
+
n.ownerModel && n.ownerModel !== this && (h(n, this.name, (e) => this.varMapByName.get(e.name) === e, n.name), p(n, this));
|
|
2227
|
+
let i = typeof t == "string" && t.trim().length > 0 ? t.trim() : n.hasExplicitName ? n.name.trim() : void 0;
|
|
2228
|
+
if (i !== void 0) {
|
|
2229
|
+
if (this.hasConstraintName(i)) throw Error(`Constraint with name '${i}' already exists in model`);
|
|
2230
|
+
if (this.hasBoolVarName(i)) throw Error(`Constraint name '${i}' conflicts with an existing Boolean variable in model`);
|
|
1191
2231
|
}
|
|
1192
|
-
|
|
2232
|
+
let a = this.constrPrefixCounters.get("c"), o = i ?? this.getNextConstrName("c"), s;
|
|
2233
|
+
try {
|
|
2234
|
+
h(n, this.name, (e) => this.varMapByName.get(e.name) === e, o), s = p(n, this);
|
|
2235
|
+
} catch (e) {
|
|
2236
|
+
throw i === void 0 && (a === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", a)), e;
|
|
2237
|
+
}
|
|
2238
|
+
let c = n.name, u = n.hasExplicitName, d = n.ownerModel, f = s;
|
|
2239
|
+
return this.batchUndoActions.push(() => {
|
|
2240
|
+
n.ownerModel = d, n._assignModelName(c, u), x(n, this, f);
|
|
2241
|
+
}), this.batchDepth === 0 && (this.batchUndoActions = []), n._assignModelName(o, !0), n.ownerModel = this, this.constraints.push(n), this.constrMapByName.set(n.name, n), this.recordModelMutation(), n;
|
|
1193
2242
|
}
|
|
1194
2243
|
indicator(e, t, n = {}) {
|
|
1195
|
-
if (
|
|
1196
|
-
if (!(
|
|
1197
|
-
|
|
1198
|
-
if (
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
2244
|
+
if (e instanceof r) throw Error("Invalid binary variable passed to indicator(): received a propositional BoolVar/BoolExpr, but m.indicator() requires a 0-1 numeric binary Var created with m.binary(). For general boolean logic with m.bool(), use m.constraint(implies(flag, expr`${x} <= 10`)) with the Z3 solver.");
|
|
2245
|
+
if (!(e instanceof b)) throw Error("Invalid binary variable passed to indicator(). Expected a 0-1 binary Var instance created with m.binary() (or use implies(flag, ...) with m.bool() and the Z3 solver for general boolean logic).");
|
|
2246
|
+
if (!(e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1)) throw Error(`Invalid variable "${e.name}" passed to indicator(): variable has type "${e.type}" with bounds [${e.lb}, ${e.ub}]. Indicator activation variable must be a Binary variable created with m.binary() (or Integer variable with bounds [0, 1]).`);
|
|
2247
|
+
if (t instanceof A || typeof t == "object" && t && "quadTerms" in t) throw Error("Quadratic expressions or constraints are not supported in indicator constraints (only linear Constraints with <=, >=, or == such as expr`${x} <= 10` are allowed).");
|
|
2248
|
+
if (typeof t != "object" || !t || !("sense" in t) || !("lhs" in t) || !("rhs" in t)) throw Error("Invalid constraint expression passed to indicator(). Expression must include a comparison operator (<=, >=, ==), e.g. m.indicator(b, expr`${x} <= 10`). For general boolean logic (such as BoolVar or implies/and/or/not), use m.constraint(implies(flag, ...)) with the Z3 solver.");
|
|
2249
|
+
let i = t, a = n.activeValue === void 0 ? 1 : n.activeValue;
|
|
2250
|
+
if (a !== 0 && a !== 1) throw Error(`Invalid activeValue: ${a}. Indicator activeValue must be 0 or 1.`);
|
|
2251
|
+
if (this.varMapByName.get(e.name) !== e) throw Error(`Variable "${e.name}" passed to indicator() does not belong to model "${this.name}". All variables must belong to the model by object identity.`);
|
|
2252
|
+
let o = typeof n.name == "string" && n.name.trim().length > 0 ? n.name.trim() : void 0, s = this.constrPrefixCounters.get("c"), { lhs: l, sense: u, rhs: d } = i, f, p, m;
|
|
2253
|
+
if (o !== void 0) f = o, p = u === "==" ? `${f}_le` : f, m = u === "==" ? `${f}_ge` : f;
|
|
2254
|
+
else if (i.hasExplicitName) f = `ind_${e.name}_${i.name.trim()}`, p = u === "==" ? `${f}_le` : f, m = u === "==" ? `${f}_ge` : f;
|
|
2255
|
+
else do {
|
|
2256
|
+
let t = this.getNextConstrName("c");
|
|
2257
|
+
f = `ind_${e.name}_${t}`, p = u === "==" ? `${f}_le` : f, m = u === "==" ? `${f}_ge` : f;
|
|
2258
|
+
} while ((u === "<=" || u === "==") && (this.hasConstraintName(p) || this.hasBoolVarName(p)) || (u === ">=" || u === "==") && (this.hasConstraintName(m) || this.hasBoolVarName(m)));
|
|
2259
|
+
let g = [];
|
|
2260
|
+
try {
|
|
2261
|
+
if ((u === "<=" || u === "==") && (this.hasConstraintName(p) || this.hasBoolVarName(p))) throw Error(this.hasBoolVarName(p) ? `Constraint name '${p}' conflicts with an existing Boolean variable in model` : `Constraint with name '${p}' already exists in model`);
|
|
2262
|
+
if ((u === ">=" || u === "==") && (this.hasConstraintName(m) || this.hasBoolVarName(m))) throw Error(this.hasBoolVarName(m) ? `Constraint name '${m}' conflicts with an existing Boolean variable in model` : `Constraint with name '${m}' already exists in model`);
|
|
2263
|
+
n.M !== void 0 && We(n.M, f);
|
|
2264
|
+
let t = (e) => this.varMapByName.get(e.name) === e;
|
|
2265
|
+
for (let [e] of l.terms) if (!t(e)) throw Error(`Variable "${e.name}" in constraint "${f}" does not belong to model "${this.name}". All variables must belong to the model by object identity.`);
|
|
2266
|
+
if (u === "<=" || u === "==") {
|
|
2267
|
+
let t = Y(e, l, "<=", d, a, n.M === void 0 ? q(l, d, p) : n.M, p);
|
|
2268
|
+
g.push([new c(t.lhs, "<=", t.rhs, p), p]);
|
|
1211
2269
|
}
|
|
1212
|
-
if (
|
|
1213
|
-
let t =
|
|
1214
|
-
|
|
2270
|
+
if (u === ">=" || u === "==") {
|
|
2271
|
+
let t = Y(e, l, ">=", d, a, n.M === void 0 ? J(l, d, m) : n.M, m);
|
|
2272
|
+
g.push([new c(t.lhs, ">=", t.rhs, m), m]);
|
|
1215
2273
|
}
|
|
2274
|
+
for (let [e, n] of g) h(e, this.name, t, n);
|
|
2275
|
+
} catch (e) {
|
|
2276
|
+
throw s === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", s), e;
|
|
1216
2277
|
}
|
|
1217
|
-
return
|
|
2278
|
+
return this.runTransactionalBatch(() => g.map(([e, t]) => this.addConstraint(e, t)));
|
|
1218
2279
|
}
|
|
1219
2280
|
toLpString() {
|
|
1220
|
-
|
|
2281
|
+
this.validateIntegrity();
|
|
2282
|
+
let { lpString: e } = C({
|
|
1221
2283
|
name: this.name,
|
|
1222
2284
|
sense: this.sense,
|
|
1223
|
-
objective: this.
|
|
2285
|
+
objective: this.objectiveExpr,
|
|
1224
2286
|
constraints: this.constraints,
|
|
1225
2287
|
variables: this.variables
|
|
1226
2288
|
});
|
|
1227
2289
|
return e;
|
|
1228
2290
|
}
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
2291
|
+
validateIntegrity() {
|
|
2292
|
+
k(this);
|
|
2293
|
+
}
|
|
2294
|
+
ensureExecutionValid(e, t, n) {
|
|
2295
|
+
if (this.modelRevision !== e) throw this.activeOperationId === t && this.clearSolutionFields(), Error(`Model "${this.name}" was modified while ${n}() was in progress; stale solver result was discarded.`);
|
|
2296
|
+
if (this.activeOperationId !== t) throw Error(`Stale ${n}() result discarded because a newer solve or check operation was started on model "${this.name}".`);
|
|
2297
|
+
}
|
|
2298
|
+
wrapSolveOptions(e, t, n) {
|
|
2299
|
+
let r = e.onProgress;
|
|
2300
|
+
return r ? {
|
|
2301
|
+
...e,
|
|
2302
|
+
onProgress: (e) => {
|
|
2303
|
+
this.activeOperationId === n && this.modelRevision === t && r(e);
|
|
2304
|
+
}
|
|
2305
|
+
} : e;
|
|
2306
|
+
}
|
|
2307
|
+
hasPrimalFromResult(e) {
|
|
2308
|
+
if (typeof e.hasPrimalSolution == "boolean") return e.hasPrimalSolution;
|
|
2309
|
+
let t = e.status, n = e.terminationStatus ?? t, r = e.values || {}, i = e.boolValues || {};
|
|
2310
|
+
return t !== "Infeasible" && t !== "Unsat" && t !== "Unbounded" && t !== "Error" && t !== "NotSolved" && n !== "Infeasible" && n !== "Unsat" && n !== "Unbounded" && n !== "InfeasibleOrUnbounded" && n !== "Error" && n !== "NotSolved" && (t === "Optimal" || t === "Feasible" || t === "Sat" || n === "Optimal" || n === "Feasible" || n === "Sat" || typeof e.objectiveValue == "number" && Number.isFinite(e.objectiveValue) || Object.values(r).some((e) => typeof e == "number" && Number.isFinite(e) || typeof e == "boolean") || Object.values(i).some((e) => typeof e == "boolean"));
|
|
2311
|
+
}
|
|
2312
|
+
resolveSolverAndOptions(e, t) {
|
|
2313
|
+
if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function") {
|
|
2314
|
+
let { solver: n, ...r } = t || {};
|
|
2315
|
+
return {
|
|
2316
|
+
activeSolver: e,
|
|
2317
|
+
activeOptions: r
|
|
2318
|
+
};
|
|
2319
|
+
}
|
|
2320
|
+
if (typeof e == "function") {
|
|
2321
|
+
let { solver: n, ...r } = t || {};
|
|
2322
|
+
return {
|
|
2323
|
+
activeSolver: new e(r),
|
|
2324
|
+
activeOptions: r
|
|
2325
|
+
};
|
|
2326
|
+
}
|
|
2327
|
+
if (typeof e == "string") {
|
|
2328
|
+
let { solver: n, ...r } = t || {};
|
|
2329
|
+
return {
|
|
2330
|
+
activeSolver: D(e, r),
|
|
2331
|
+
activeOptions: r
|
|
2332
|
+
};
|
|
2333
|
+
}
|
|
2334
|
+
let { solver: n, ...r } = e || {};
|
|
2335
|
+
return n ? {
|
|
2336
|
+
activeSolver: D(n, r),
|
|
2337
|
+
activeOptions: r
|
|
2338
|
+
} : {
|
|
2339
|
+
activeSolver: this.solver || D(),
|
|
2340
|
+
activeOptions: r
|
|
2341
|
+
};
|
|
2342
|
+
}
|
|
2343
|
+
async relax(e, t) {
|
|
2344
|
+
let n = typeof e == "object" && !!e && !("solve" in e), r = n ? {
|
|
2345
|
+
...e,
|
|
2346
|
+
relax: !0
|
|
2347
|
+
} : {
|
|
2348
|
+
...t || {},
|
|
2349
|
+
relax: !0
|
|
2350
|
+
}, i = n ? void 0 : e;
|
|
2351
|
+
return i ? this.solve(i, r) : this.solve(r);
|
|
2352
|
+
}
|
|
2353
|
+
async solve(e, t) {
|
|
2354
|
+
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
2355
|
+
this.clearSolutionFields(), this.validateIntegrity();
|
|
2356
|
+
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
2357
|
+
if (this._objectiveExpr instanceof A && this._objectiveExpr.quadTerms.size > 0 && i.capabilities?.supportsQP === !1) throw Error(`Solver "${i.name}" does not support quadratic objectives (QP). Please use a QP-capable solver such as HiGHS or Clarabel.`);
|
|
2358
|
+
let o, s = null;
|
|
2359
|
+
if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0 ? (s = Ke(this.variables, this.boolVars, this.constraints, this.logicalConstraints), o = {
|
|
2360
|
+
name: this.name,
|
|
2361
|
+
sense: this.sense,
|
|
2362
|
+
objective: this._objectiveExpr,
|
|
2363
|
+
constraints: s.constraints,
|
|
2364
|
+
variables: s.variables,
|
|
2365
|
+
logicalConstraints: [],
|
|
2366
|
+
boolVars: []
|
|
2367
|
+
}) : o = {
|
|
1234
2368
|
name: this.name,
|
|
1235
2369
|
sense: this.sense,
|
|
1236
|
-
objective: this.
|
|
2370
|
+
objective: this._objectiveExpr,
|
|
1237
2371
|
constraints: this.constraints,
|
|
1238
2372
|
variables: this.variables,
|
|
1239
2373
|
logicalConstraints: this.logicalConstraints,
|
|
1240
2374
|
boolVars: this.boolVars
|
|
1241
|
-
},
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
2375
|
+
}, this.variables.some((e) => e.initialValue !== void 0) && i.capabilities?.supportsWarmStart !== !0) throw Error(`Solver "${i.name}" does not support primal initial values (initialValue). Please use a solver with warm-start support such as HiGHS.`);
|
|
2376
|
+
let c = this.wrapSolveOptions(a, r, n), l;
|
|
2377
|
+
try {
|
|
2378
|
+
l = await i.solve(o, c);
|
|
2379
|
+
} catch (e) {
|
|
2380
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
2381
|
+
}
|
|
2382
|
+
this.ensureExecutionValid(r, n, "solve"), this.runTime = l.runTime ?? 0, this.status = l.status, this.terminationStatus = l.terminationStatus ?? l.status;
|
|
2383
|
+
let u = this.hasPrimalFromResult(l);
|
|
2384
|
+
this.hasPrimalSolution = u, this.objectiveValue = u && typeof l.objectiveValue == "number" && Number.isFinite(l.objectiveValue) ? l.objectiveValue : null, this.objectiveBound = typeof l.objectiveBound == "number" && Number.isFinite(l.objectiveBound) ? l.objectiveBound : void 0;
|
|
2385
|
+
let d = typeof l.relGap == "number" && Number.isFinite(l.relGap) ? l.relGap : typeof l.mipGap == "number" && Number.isFinite(l.mipGap) ? l.mipGap : void 0;
|
|
2386
|
+
this.relGap = d, this.mipGap = d, this.absGap = typeof l.absGap == "number" && Number.isFinite(l.absGap) ? l.absGap : this.objectiveValue !== null && this.objectiveBound !== void 0 ? Math.abs(this.objectiveValue - this.objectiveBound) : void 0;
|
|
2387
|
+
let f = (e, t, n) => {
|
|
2388
|
+
Object.defineProperty(e, t, {
|
|
2389
|
+
value: n,
|
|
2390
|
+
enumerable: !0,
|
|
2391
|
+
writable: !0,
|
|
2392
|
+
configurable: !0
|
|
2393
|
+
});
|
|
2394
|
+
}, p = {}, m = {}, h = {}, g = {};
|
|
2395
|
+
if (this.values.clear(), u && l.values) {
|
|
2396
|
+
for (let [e, t] of Object.entries(l.values)) if (typeof t == "number" && Number.isFinite(t)) {
|
|
2397
|
+
let n = this.getVarByName(e), r = this.getBoolVarByName(e);
|
|
2398
|
+
n && (n.value = t, f(p, n.name, t), this.values.set(n.name, t)), r && (r.value = !!t, this.values.set(r.name, t)), !n && !r && this.values.set(e, t);
|
|
2399
|
+
} else if (typeof t == "boolean") {
|
|
2400
|
+
let n = t, r = this.getBoolVarByName(e);
|
|
2401
|
+
r ? (r.value = n, f(p, r.name, +!!n), this.values.set(r.name, n)) : this.values.set(e, n);
|
|
2402
|
+
}
|
|
2403
|
+
if (s) for (let e of this.boolVars) {
|
|
2404
|
+
let t = s.boolVarToBinary.get(e);
|
|
2405
|
+
if (t && l.values) {
|
|
2406
|
+
let n = l.values[t.name];
|
|
2407
|
+
if (typeof n == "number" && Number.isFinite(n)) {
|
|
2408
|
+
let t = Math.round(n) === 1;
|
|
2409
|
+
e.value = t, f(p, e.name, +!!t), this.values.set(e.name, t);
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
1257
2412
|
}
|
|
1258
2413
|
}
|
|
1259
|
-
if (
|
|
1260
|
-
|
|
1261
|
-
|
|
2414
|
+
if (u && l.boolValues) for (let [e, t] of Object.entries(l.boolValues)) {
|
|
2415
|
+
if (typeof t != "boolean") continue;
|
|
2416
|
+
let n = this.getBoolVarByName(e);
|
|
2417
|
+
n ? (n.value = t, this.values.has(n.name) || this.values.set(n.name, t)) : this.values.has(e) || this.values.set(e, t);
|
|
2418
|
+
}
|
|
2419
|
+
if (u && l.reducedCosts) for (let [e, t] of Object.entries(l.reducedCosts)) {
|
|
2420
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2421
|
+
let n = this.getVarByName(e);
|
|
2422
|
+
n && (n.reducedCost = t, f(h, n.name, t));
|
|
1262
2423
|
}
|
|
1263
|
-
if (
|
|
1264
|
-
|
|
1265
|
-
|
|
2424
|
+
if (l.duals) for (let [e, t] of Object.entries(l.duals)) {
|
|
2425
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2426
|
+
let n = this.getConstraintByName(e);
|
|
2427
|
+
n && (n.dual = t, f(m, n.name, t));
|
|
1266
2428
|
}
|
|
1267
|
-
if (
|
|
1268
|
-
|
|
1269
|
-
|
|
2429
|
+
if (l.slacks) for (let [e, t] of Object.entries(l.slacks)) {
|
|
2430
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2431
|
+
let n = this.getConstraintByName(e);
|
|
2432
|
+
n && (n.slack = t, f(g, n.name, t));
|
|
1270
2433
|
}
|
|
1271
2434
|
return this.solution = {
|
|
1272
2435
|
status: this.status,
|
|
2436
|
+
terminationStatus: this.terminationStatus,
|
|
2437
|
+
hasPrimalSolution: this.hasPrimalSolution,
|
|
1273
2438
|
objectiveValue: this.objectiveValue,
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
2439
|
+
...this.objectiveBound === void 0 ? {} : { objectiveBound: this.objectiveBound },
|
|
2440
|
+
...this.relGap === void 0 ? {} : {
|
|
2441
|
+
relGap: this.relGap,
|
|
2442
|
+
mipGap: this.mipGap
|
|
2443
|
+
},
|
|
2444
|
+
...this.absGap === void 0 ? {} : { absGap: this.absGap },
|
|
2445
|
+
values: p,
|
|
2446
|
+
duals: m,
|
|
2447
|
+
reducedCosts: h,
|
|
2448
|
+
slacks: g,
|
|
1278
2449
|
runTime: this.runTime,
|
|
1279
|
-
raw:
|
|
1280
|
-
}, this.status;
|
|
1281
|
-
}
|
|
1282
|
-
async solve(e, t) {
|
|
1283
|
-
return this.optimize(e, t);
|
|
2450
|
+
raw: l.raw
|
|
2451
|
+
}, this.hasSolutionState = !0, this.status;
|
|
1284
2452
|
}
|
|
1285
2453
|
async check(e, t) {
|
|
1286
|
-
let n, r;
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
2454
|
+
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
2455
|
+
this.clearSolutionFields(), this.validateIntegrity();
|
|
2456
|
+
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
2457
|
+
if (this.variables.some((e) => e.initialValue !== void 0) && i.capabilities?.supportsWarmStart !== !0) throw Error(`Solver "${i.name}" does not support primal initial values (initialValue). Please use a solver with warm-start support such as HiGHS.`);
|
|
2458
|
+
let o = this.wrapSolveOptions(a, r, n), s = (e, t, n) => {
|
|
2459
|
+
Object.defineProperty(e, t, {
|
|
2460
|
+
value: n,
|
|
2461
|
+
enumerable: !0,
|
|
2462
|
+
writable: !0,
|
|
2463
|
+
configurable: !0
|
|
2464
|
+
});
|
|
2465
|
+
}, l = {
|
|
2466
|
+
name: this.name,
|
|
2467
|
+
variables: this.variables,
|
|
2468
|
+
boolVars: this.boolVars,
|
|
2469
|
+
constraints: this.constraints,
|
|
2470
|
+
logicalConstraints: this.logicalConstraints
|
|
2471
|
+
};
|
|
2472
|
+
if (typeof i.check == "function") {
|
|
2473
|
+
let e;
|
|
2474
|
+
try {
|
|
2475
|
+
e = await i.check(l, o);
|
|
2476
|
+
} catch (e) {
|
|
2477
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
1305
2478
|
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
2479
|
+
this.ensureExecutionValid(r, n, "check"), this.status = e.status, this.terminationStatus = a.signal?.aborted ? "Interrupted" : e.status, this.hasPrimalSolution = e.status === "Sat", this.runTime = e.runTime ?? 0, this.unsatCore = e.unsatCore === void 0 ? void 0 : Object.freeze([...e.unsatCore]), this.conflicts = e.conflicts === void 0 ? this.unsatCore : Object.freeze([...e.conflicts]);
|
|
2480
|
+
let t = {};
|
|
2481
|
+
if (e.values && e.status === "Sat") {
|
|
2482
|
+
for (let [n, r] of Object.entries(e.values)) if (typeof r == "number") {
|
|
2483
|
+
if (!Number.isFinite(r)) continue;
|
|
2484
|
+
let e = this.getVarByName(n), i = this.getBoolVarByName(n);
|
|
2485
|
+
e && (e.value = r, this.values.set(e.name, r), s(t, e.name, r)), i && (i.value = !!r, this.values.set(i.name, i.value), s(t, i.name, i.value)), !e && !i && (this.values.set(n, r), s(t, n, r));
|
|
2486
|
+
} else if (typeof r == "boolean") {
|
|
2487
|
+
let e = this.getBoolVarByName(n);
|
|
2488
|
+
e ? (e.value = r, this.values.set(e.name, r), s(t, e.name, r)) : (this.values.set(n, r), s(t, n, r));
|
|
2489
|
+
}
|
|
1315
2490
|
}
|
|
1316
|
-
return {
|
|
1317
|
-
status:
|
|
1318
|
-
values:
|
|
2491
|
+
return this.hasSolutionState = !0, {
|
|
2492
|
+
status: e.status,
|
|
2493
|
+
values: t,
|
|
2494
|
+
unsatCore: this.unsatCore,
|
|
2495
|
+
conflicts: this.conflicts,
|
|
1319
2496
|
runTime: this.runTime
|
|
1320
2497
|
};
|
|
1321
|
-
} finally {
|
|
1322
|
-
this.objective = i, this.sense = a;
|
|
1323
2498
|
}
|
|
2499
|
+
let u = this.logicalConstraints.length > 0 || this.boolVars.length > 0 ? Ke(this.variables, this.boolVars, this.constraints, this.logicalConstraints) : {
|
|
2500
|
+
variables: [...this.variables],
|
|
2501
|
+
constraints: [...this.constraints],
|
|
2502
|
+
boolVarToBinary: /* @__PURE__ */ new Map(),
|
|
2503
|
+
constraintToOriginalName: new Map(this.constraints.map((e) => [e, e.name]))
|
|
2504
|
+
}, d = [], f = [], p = [], m = /* @__PURE__ */ new Map(), h = 0;
|
|
2505
|
+
for (let e of u.constraints) {
|
|
2506
|
+
let t = u.constraintToOriginalName.get(e) ?? e.name, { lhs: n, sense: r, rhs: i } = e;
|
|
2507
|
+
if (r === "<=") {
|
|
2508
|
+
let r = new b({
|
|
2509
|
+
name: `__slack_${++h}`,
|
|
2510
|
+
type: "Continuous",
|
|
2511
|
+
lb: 0,
|
|
2512
|
+
ub: Infinity
|
|
2513
|
+
});
|
|
2514
|
+
f.push(r), p.push([r, 1]), m.set(r, t);
|
|
2515
|
+
let a = n.clone().add(new j(/* @__PURE__ */ new Map([[r, -1]]), 0));
|
|
2516
|
+
d.push(new c(a, "<=", i, `${e.name}_slack`));
|
|
2517
|
+
} else if (r === ">=") {
|
|
2518
|
+
let r = new b({
|
|
2519
|
+
name: `__slack_${++h}`,
|
|
2520
|
+
type: "Continuous",
|
|
2521
|
+
lb: 0,
|
|
2522
|
+
ub: Infinity
|
|
2523
|
+
});
|
|
2524
|
+
f.push(r), p.push([r, 1]), m.set(r, t);
|
|
2525
|
+
let a = n.clone().add(new j(/* @__PURE__ */ new Map([[r, 1]]), 0));
|
|
2526
|
+
d.push(new c(a, ">=", i, `${e.name}_slack`));
|
|
2527
|
+
} else {
|
|
2528
|
+
let r = new b({
|
|
2529
|
+
name: `__slack_${++h}_p`,
|
|
2530
|
+
type: "Continuous",
|
|
2531
|
+
lb: 0,
|
|
2532
|
+
ub: Infinity
|
|
2533
|
+
}), a = new b({
|
|
2534
|
+
name: `__slack_${++h}_n`,
|
|
2535
|
+
type: "Continuous",
|
|
2536
|
+
lb: 0,
|
|
2537
|
+
ub: Infinity
|
|
2538
|
+
});
|
|
2539
|
+
f.push(r, a), p.push([r, 1], [a, 1]), m.set(r, t), m.set(a, t);
|
|
2540
|
+
let o = n.clone().add(new j(/* @__PURE__ */ new Map([[r, -1], [a, 1]]), 0));
|
|
2541
|
+
d.push(new c(o, "==", i, `${e.name}_slack`));
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
let g = {
|
|
2545
|
+
name: `${this.name}_elastic_check`,
|
|
2546
|
+
sense: "Minimize",
|
|
2547
|
+
objective: new j(new Map(p), 0),
|
|
2548
|
+
constraints: d,
|
|
2549
|
+
variables: [...u.variables, ...f]
|
|
2550
|
+
}, _;
|
|
2551
|
+
try {
|
|
2552
|
+
_ = await i.solve(g, o);
|
|
2553
|
+
} catch (e) {
|
|
2554
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
2555
|
+
}
|
|
2556
|
+
this.ensureExecutionValid(r, n, "check"), this.runTime = _.runTime ?? 0;
|
|
2557
|
+
let v = _.status, y = _.terminationStatus ?? v, x = this.hasPrimalFromResult(_), S = typeof _.objectiveValue == "number" && Number.isFinite(_.objectiveValue) ? _.objectiveValue : Infinity, C = (v === "Optimal" || v === "Feasible" || x) && S <= 1e-5, w = typeof _.objectiveBound == "number" && Number.isFinite(_.objectiveBound) && _.objectiveBound > 1e-5, T = !C && (v === "Infeasible" || v === "Optimal" && S > 1e-5 || w), E = C ? "Sat" : T ? "Unsat" : "Unknown";
|
|
2558
|
+
this.status = E, this.terminationStatus = a.signal?.aborted || y === "Interrupted" ? "Interrupted" : y === "Optimal" || y === "Feasible" || y === "Infeasible" ? E : y, this.hasPrimalSolution = C, this.objectiveValue = null, this.objectiveBound = void 0, this.relGap = void 0, this.mipGap = void 0, this.absGap = void 0, this.solution = null, this.values.clear();
|
|
2559
|
+
let D = {};
|
|
2560
|
+
if (C && _.values) {
|
|
2561
|
+
for (let e of this.variables) {
|
|
2562
|
+
let t = _.values[e.name];
|
|
2563
|
+
typeof t == "number" && Number.isFinite(t) && (e.value = t, this.values.set(e.name, t), s(D, e.name, t));
|
|
2564
|
+
}
|
|
2565
|
+
for (let e of this.boolVars) {
|
|
2566
|
+
let t = u.boolVarToBinary.get(e), n = t ? _.values[t.name] : _.values[e.name];
|
|
2567
|
+
if (typeof n == "number" && Number.isFinite(n)) {
|
|
2568
|
+
let t = Math.round(n) === 1;
|
|
2569
|
+
e.value = t, this.values.set(e.name, t), s(D, e.name, t);
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
let O = /* @__PURE__ */ new Set();
|
|
2574
|
+
if (T && _.values) for (let [e, t] of m.entries()) {
|
|
2575
|
+
let n = _.values[e.name];
|
|
2576
|
+
typeof n == "number" && n > 1e-5 && O.add(t);
|
|
2577
|
+
}
|
|
2578
|
+
return this.conflicts = T ? Object.freeze(Array.from(O)) : void 0, this.unsatCore = void 0, this.hasSolutionState = !0, {
|
|
2579
|
+
status: E,
|
|
2580
|
+
values: D,
|
|
2581
|
+
conflicts: this.conflicts,
|
|
2582
|
+
unsatCore: this.unsatCore,
|
|
2583
|
+
runTime: this.runTime
|
|
2584
|
+
};
|
|
2585
|
+
}
|
|
2586
|
+
validateSolution(e = {}) {
|
|
2587
|
+
return Ue(this, e);
|
|
2588
|
+
}
|
|
2589
|
+
link(e) {
|
|
2590
|
+
if (e instanceof A || typeof e == "object" && e && "quadTerms" in e) throw Error("Linking constraint cannot be a quadratic expression.");
|
|
2591
|
+
if (!(e instanceof c) && (typeof e != "object" || !e || !("sense" in e) || !("lhs" in e) || !("rhs" in e))) throw Error("Linking constraint must contain a comparison operator (<=, >=, ==). Use expr`... <= ...` or .le(), .ge(), .eq().");
|
|
2592
|
+
this._linkingConstraints ||= [];
|
|
2593
|
+
let t = e;
|
|
2594
|
+
return this._linkingConstraints.push(t), t;
|
|
2595
|
+
}
|
|
2596
|
+
get linkingConstraints() {
|
|
2597
|
+
return this._linkingConstraints ?? [];
|
|
2598
|
+
}
|
|
2599
|
+
async solveBenders(e) {
|
|
2600
|
+
let t = await et({
|
|
2601
|
+
master: this,
|
|
2602
|
+
...e
|
|
2603
|
+
});
|
|
2604
|
+
return this.decomposition = t, t;
|
|
2605
|
+
}
|
|
2606
|
+
async solveColumnGeneration(e) {
|
|
2607
|
+
let t = await Je({
|
|
2608
|
+
master: this,
|
|
2609
|
+
...e
|
|
2610
|
+
});
|
|
2611
|
+
return this.decomposition = t, t;
|
|
1324
2612
|
}
|
|
1325
2613
|
};
|
|
1326
|
-
|
|
1327
|
-
BoolExpr: () =>
|
|
1328
|
-
BoolOp: () =>
|
|
1329
|
-
BoolVar: () =>
|
|
2614
|
+
R(/* @__PURE__ */ he({
|
|
2615
|
+
BoolExpr: () => r,
|
|
2616
|
+
BoolOp: () => n,
|
|
2617
|
+
BoolVar: () => o,
|
|
1330
2618
|
Constraint: () => c,
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
2619
|
+
HIGHS_CONSTANTS: () => ie,
|
|
2620
|
+
HIGHS_STATUS_NAMES: () => le,
|
|
2621
|
+
HiGHS: () => G,
|
|
2622
|
+
Highs: () => P,
|
|
2623
|
+
HighsError: () => te,
|
|
2624
|
+
HighsModel: () => se,
|
|
2625
|
+
HighsSolver: () => W,
|
|
2626
|
+
HighsUnsupportedOptionError: () => ae,
|
|
2627
|
+
LinExpr: () => j,
|
|
2628
|
+
MockSolver: () => ze,
|
|
2629
|
+
Model: () => nt,
|
|
2630
|
+
OFFICIAL_HIGHS_CDN_WASM_URL: () => ce,
|
|
2631
|
+
QuadExpr: () => A,
|
|
2632
|
+
Var: () => b,
|
|
2633
|
+
and: () => y,
|
|
2634
|
+
bindHighsFunctions: () => ne,
|
|
2635
|
+
buildIndicatorLinearization: () => Y,
|
|
2636
|
+
buildLpSymbolMaps: () => u,
|
|
2637
|
+
deriveBigMForGe: () => J,
|
|
2638
|
+
deriveBigMForLe: () => q,
|
|
2639
|
+
dot: () => s,
|
|
2640
|
+
expr: () => ke,
|
|
2641
|
+
generateLpString: () => C,
|
|
2642
|
+
getHighs: () => oe,
|
|
2643
|
+
getHighsWasmUrl: () => I,
|
|
2644
|
+
getSolver: () => D,
|
|
2645
|
+
implies: () => e,
|
|
2646
|
+
isLpExportResult: () => E,
|
|
2647
|
+
isValidWasmHeader: () => re,
|
|
2648
|
+
linearizeModelForMip: () => Ke,
|
|
2649
|
+
listAvailableSolvers: () => S,
|
|
2650
|
+
mapHighsStatus: () => U,
|
|
2651
|
+
mapHighsTerminationStatus: () => H,
|
|
2652
|
+
maximize: () => Xe,
|
|
2653
|
+
minimize: () => Ze,
|
|
2654
|
+
not: () => v,
|
|
2655
|
+
or: () => i,
|
|
2656
|
+
parseConstraint: () => we,
|
|
2657
|
+
parseExpr: () => Se,
|
|
2658
|
+
probeWasmUrl: () => M,
|
|
2659
|
+
registerHighsSolver: () => K,
|
|
2660
|
+
registerMockSolver: () => Be,
|
|
2661
|
+
registerSolver: () => T,
|
|
2662
|
+
resolveBrowserWasmUrl: () => F,
|
|
2663
|
+
sanitizeIdentifier: () => f,
|
|
2664
|
+
setDefaultSolver: () => _,
|
|
2665
|
+
setHighsWasmUrl: () => L,
|
|
2666
|
+
solveLp: () => V,
|
|
2667
|
+
solveLpWithHighs: () => N,
|
|
2668
|
+
sum: () => t,
|
|
2669
|
+
validateModelIntegrity: () => k,
|
|
2670
|
+
validateModelSolution: () => Ue,
|
|
2671
|
+
validateUserBigM: () => We,
|
|
2672
|
+
xor: () => a
|
|
2673
|
+
}), Ve);
|
|
1367
2674
|
//#endregion
|
|
1368
|
-
export {
|
|
2675
|
+
export { r as BoolExpr, n as BoolOp, o as BoolVar, c as Constraint, G as HiGHS, P as Highs, W as HighsSolver, j as LinExpr, ze as MockSolver, nt as Model, A as QuadExpr, b as Var, y as and, Y as buildIndicatorLinearization, u as buildLpSymbolMaps, J as deriveBigMForGe, q as deriveBigMForLe, s as dot, ke as expr, C as generateLpString, oe as getHighs, I as getHighsWasmUrl, D as getSolver, e as implies, E as isLpExportResult, Ke as linearizeModelForMip, S as listAvailableSolvers, Xe as maximize, Ze as minimize, _e as normalizeSense, v as not, i as or, we as parseConstraint, Se as parseExpr, T as registerSolver, f as sanitizeIdentifier, _ as setDefaultSolver, L as setHighsWasmUrl, et as solveBenders, Je as solveColumnGeneration, N as solveLpWithHighs, t as sum, k as validateModelIntegrity, Ue as validateModelSolution, We as validateUserBigM, a as xor };
|